Tines vs Python: Understanding alternative approaches to automation

Written by Eoin Hinchy and Conor Dunne

We're sometimes asked, "Can you run Bash or Python scripts natively in Tines?" and today, we're sharing the answer, and weighing in on the debate between full-code, low-code and no-code automation.

The short answer is yes, you can run scripts and Linux commands natively in Tines, however, you might not necessarily want to. Many of our customers avoid doing so for security, usability and performance reasons. Let's take a closer look at some of these potential pitfalls.

  • Security risks. By allowing the use of custom code, you’re also allowing any engineer or analyst with access to Tines to potentially write unstable or dangerous code. You then have to deal with importing arbitrary libraries. This introduces new risks of supply chain compromise, additional dependency management, and potentially conflicts between version requirements between workflows.

  • Maintenance. Your workflow automation platform is likely outside the scope of organizational supply-chain controls, so you’ll have to create new processes to manage the security of the custom code you're using in workflows.

  • Performance issues. You'll have to deal with long-running code, timeouts, and max memory usage.

At Tines, we have some customers that want to accept the risk of custom code. For these customers, we provide a feature called Command-over-HTTP. This acts as a hardened sandbox and allows users to execute scripts and commands in a “safer” environment. You'll still have to deal with long-running code, timeouts, and max memory usage, and it's worth noting that these aren’t skills your typical analyst would or should have. Read our how-to guide to learn more.

Given all the above, we find that our customers, even those with a Python development background, prefer using the native Tines builder. With Tines, you can do everything you can do with scripting, but it’s faster, more secure, and more collaborative.

Automation provides a practical solution to the challenges of increasing workloads and higher-than-average levels of burnout. And when it comes to automation, more and more practitioners are considering alternatives to Python, PowerShell, or Bash. This is where Tines comes in.

Tines vs Python automation: Common building components  

When automating tasks, there are building patterns common to all technologies. These are HTTP requests, Webhooks, Data Manipulation, and Scheduling.

HTTP Requests  

One of the most common tasks in automation is making HTTP requests to retrieve data. Below are examples of how Tines and Python can be used to make the same request to VirusTotal.

Webhooks  

Another way of triggering automation is through webhooks. A webhook listens for an HTTP request. These remove the need to constantly query a service to catch an event.

Data Manipulation  

Automation is used to ingest, process, and output data in a more user-friendly or usable form. The act of processing the data is called data manipulation.

Scheduling  

Automations are built to run autonomously, to speed up repetitive tasks. Many of these tasks have to run at regular intervals. Scheduling handles tasks such as: 

  • generating weekly reports, 

  • gathering daily tasks, or 

  • deactivating unused assets or credentials

Credentials  

When accessing data on a system, a process will need to be authenticated. This is to verify that the system accessing the information has the required permissions. When using HTTP requests, this is done through a variety of methods, such as basic auth, OAuth2.0, session keys, and API tokens. Credentials and secrets must be handled carefully to avoid credential leakage.

Layout and Readability  

Python, like most programming languages, uses newlines and indentation to divide itself into sections. Functions can also be used for extra readability. This can lead to long blocks of code which can be difficult to read and intimidating when complicated programming features are used, especially for newer developers.

In Tines, these are naturally broken into simple function-like elements called actions. Each action has unique styling, quickly informing the user what is does. These actions can be grouped to make single actions into user-defined functions. They can also be moved around on the story page to help the user see what actions are working together. The connections between them quickly let a user know what each action follows on from.

Manageability  

As a Python script grows, functions can be used to reduce the amount of code duplication. In Tines, Send to Stories can be used to create a similar solution. The added advantage of using Send to Stories is that these stories can be reused across different automation jobs, much like importing a new Python file.

Case Study: Tines vs Python Automation - Slack News Feed  

A screenshot of a newsfeed from Hacker News

The Hacker News is a well-known and reputable website when it comes to cybersecurity news. There are a few benefits to introducing a feed: 

  • Help a security team stay up to date with potential threats

  • Help employees keep visibility on issues and alerts important to the company

RSS feeds use XML to distribute their information. An RSS Reader works by querying a feed and sending the information to the user. In terms of Slack, you would want to remove all articles previously displayed and only send a message if the article is new. In this case, we are doing this by querying the feed daily and removing any article older than a day. This can be changed to query hourly, or even once every minute.

Slack Preparation  

Before we can build this automation, we need to create a Slack channel to post into, and a Slack bot to post the messages. 

Slack Channel

To create a Slack channel:

  •  Go to your workspace

  • On the top of the second section of the sidebar, click the Channels dropdown

  • Select Create and Create a Channel

  • Name the channel hacker-news-feed.

Creating a channel in Slack

Slackbot

To create a new Slackbot, go to api.slack.com/apps and select Create New App. In the menu that appears, select From an app manifest, choose your workspace, and paste the manifest below into the text box (Make sure YAML is selected).

display_information:
  name: Hacker News Feed
  description: The Hacker News RSS Feed
  background_color: "#3732b3"
features:
  bot_user:
    display_name: Hacker News Feed
    always_online: false
oauth_config:
  scopes:
    bot:
      - chat:write
settings:
  org_deploy_enabled: false
  socket_mode_enabled: false
  token_rotation_enabled: false

The manifest above creates a bot called Hacker News Feed. When added to a channel, the bot has permission to write messages within a channel it’s in.

After creating the Slack bot, you will be in the bot’s settings, in the Basic Information tab. You should see a section called Install your app with a button Install to Workspace. Press this button to install your new bot onto your workspace.

Building apps for Slack - installing an app on your Slack workspace

After installing the bot, go to the OAuth & Permissions tab under Features on the left taskbar. There, you will find a section called OAuth Tokens for Your Workspace. Copy the Bot User OAuth Token. This is your Slack bot Credential (slack_auth_token).

Add the Bot to your Channel

With both your channel and bot created, go back to the Slack channel. In the message bar, tag your slack bot (@hacker-news-feed) and select the button Add to Channel.

Python  

Requirements

For this, we are going to need three libraries in Python. One of these comes installed with Python, but the other two need to be installed. These libraries are:

  • datetime

    • Used to convert the article published date into a DateTime object

  • requests

    • Used to make an HTTP request to retrieve the RSS feed

  • xmltodict

    • Converts the RSS feed from XML to a Python dictionary object

The libraries needed to be installed are requests and xmltodict. Below you can see the commands that need to be run to install the packages.

$ pip3 install requests
$ pip3 install xmltodict

Python Code

Script Configuration

Before we create the RSS feed, the packages should be imported, and important variables should be set. This includes:

  • thn_feed_url

    • The RSS feed URL we are subscribing to

  • slackbot_url

    • Slack API URL to post a message to a channel

  • slack_channel_name

    • Name of the Slack channel to post in (make sure to include the #)

  • slack_auth_token

    • Slackbot’s OAuth token (Blocked out for security)

  • feed_threshold

    • The age limit of the articles to post (created in the last day)

from datetime import datetime
import requests
import xmltodict

thn_feed_url = 'https://feeds.feedburner.com/TheHackersNews'
slackbot_url = 'https://slack.com/api/chat.postMessage'
slack_channel_name = '#hacker-news-feed'
slack_auth_token = 'xoxb-█████████████-█████████████-████████████████████████'
feed_threshold = datetime.date.today() - datetime.timedelta(days=1)
Retrieving the RSS Feed

When retrieving an RSS feed from The Hacker News, no data needs to be passed to the server. Therefore, making an HTTP GET request returns the feed in XML format. This is then parsed using the xmltodict library to get a format we can manipulate the feed with.

thn_feed = requests.get(
  thn_feed_url
)

dict_feed = xmltodict.parse(thn_feed.content)
Extracting the New Articles

To extract the new articles for today, we need to loop over the feed in dictionary format. Each article is stored in the article variable and the published date is extracted. If the publication date is newer than the threshold date, we can post the article to Slack.

for article in dict_feed['rss']['channel']['item']:
  published = datetime.strptime(article['pubDate'], '%a, %d %b %Y %H:%M:%S %z')

  if published > feed_threshold:
Posting to Slack

Before the article can be posted to Slack, it needs to be formatted into an acceptable format. In this case, it is in the format:

Title
Link

Description

Once the message is created, the headers and payload are set with the required variables, and the HTTP POST request is made to Slack.

slack_message = '*{}*\n{}\n\n{}'.format(article['title'], article['link'], article['description'])

headers = {
  'Content-type': 'application/json',
  'Authorization': 'Bearer ' + slack_auth_token
}
payload = {
  'channel': slack_channel_name,
  'text': slack_message
}

slack_response = requests.post(
  slackbot_url,
  headers=headers,
  json=payload
)

Tines  

Requirements

Before creating the story, there are some values we can set. Tines has variables split into Resources and Credentials. Both can be used in multiple stories, but where resources are plain text JSON objects, Credentials are used for hiding generating, and restricting access to auth tokens.

Credentials

After navigating to the Credentials folder in your team, multiple types of credentials can be created after selecting New Credential. You can read more on each type of credential here, but for this story, we will be using a Text Credential for our Slack bots authentication token.

After selecting the Text Credential, give it a name like slackbot_thn and paste The Hacker News Feed’s Bot User OAuth Token into value. For added security, slack.com can be added to the domain field. This ensures that this credential will only be sent for Slack API calls and will throw an error if it tries to be used elsewhere.

Creating the Story

Creating a story in Tines - Slack news feed
Retrieving the RSS Feed

When retrieving the RSS feed, we need to use an HTTP Request. After providing the URL to the feed and specifying that we are using a GET method, we can retrieve the feed. Optionally, we can specify the content type to be XML as this is the data format used by RSS feeds.

After exploding all the items into articles, we can then pass them through an event trigger. These triggers act like if statements, letting us emit events if they pass certain conditions. In this case, we only want to emit an article if it is younger than 1 day old.

To do this, we can use the Date formula to convert the published date into Unix time. To specify the time limit, we use the Date formula again to get the current Unix time and subtract the length of a day (86400 seconds). Instead of putting the day length into the formula, we can use a Local value. This acts as a variable only present in a single action.

There are multiple reasons you would want to do this. You can use a local value to clean up and simplify an input before putting it into an action, or if you wanted to use a value in multiple parts of the action, or in this case, to make the action more descriptive and improve readability and editability later.

Posting to Slack

When posting to Slack, we will be using an HTTP request again. Like before, the URL and method need to be specified. We are also choosing to specify the content type but this is not necessary. Unlike the last HTTP request, a payload and header need to be specified. If these are not present in your HTTP request action, they can be added by going to the + ption button at the bottom of the build action pane.

The payload acts as the body of an HTTP request. In this case, we need to specify the channel name and the text body. To format the body of the text, we can type in this field and add newlines like a simple text editor. In this case, we will be using the same format as used in the Python script.

In order to bring in the article text, we have to use pills in the text field. To create a pill, press ctrl + space. Pills allow you to use formulas and specify values from previous actions. Using the values as seen in the example below will pull the relevant article data into the story.

Finally, we need to specify the authentication token. The headers of an HTTP request are automatically generated but can be added to or changed using the Headers option. To use the Headers option, add a header key-pair value with the plus symbol to the right. This will create two boxes, the first of which is the header and the second is the value. In this case, we are using an Authentication header with the value being the slack bot token we created earlier. 

As we created the credential in the Tines credential store, we can reference this using a pill. Create the pill as before, however, using the CREDENTIAL formula key, we can specify an credential we have access to from the credential store.

And that's it - we're done!

Built by you, powered by Tines

Talk to one of our experts to learn the unique ways your business can leverage Tines.