You might have come across accounts that seem to have an uncanny tweeting pattern on Twitter. They have an extraordinary retweet frequency, do automated tweets, and even interact with users based on a predefined schedule. It's a shocking fact that over 50% of Twitter accounts are managed by bots. A twitter bot can be coded in any programming language and hosted on your favorite cloud, just with an hour of your effort.

In this tutorial, we are going to use AWS Lambda for hosting our bot's code. We will also use AWS CloudWatch events to trigger the function at fixed intervals. You are free to choose any cloud platform of your choice, if you are not comfortable with AWS. Our own Twitter bot has been coded in Python and runs on AWS Lambda. To see what a Twitter bot looks and feels like, check out the Tech Injektion Bot handle on Twitter.

Our Twitter bot created using Python and AWS Lambda

Where to begin?

A good place to start is to create a Twitter Application that you will need to access the Developer API. Go ahead and create a Developer Account, if you don't have one.

Create a developer account on Twitter

Make sure that you are logged in with the appropriate Twitter account that you wish to use for the bot. You can use your personal account too. Navigate to the Getting Started page and choose the Create an App option. In the application menu, click the Create button.

Fill in the details for your Twitter App and what it is going to do

Fill in all the mandatory fields and explain what your bot is going to do in the description. Be very specific so that Twitter doesn't have a reason to reject your App during the review. They usually approve Apps meant for personal or non-profit use within minutes.

Make sure to choose Read, write, and Direct Messages in permissions when you are prompted. The need to have these permissions would depend on your use-case, however, it's a good practice to have all three permissions to avoid any hindrances during development.

Make sure to select the Read, write and Direct Messages permissions

Finally, once your App is created and approved (happens within minutes but can take a little longer in some cases), the last step is to note down some keys and tokens that will help your bot authenticate with Twitter.

Note down the Keys and Tokens for your App

Copy the API key, API secret key, Access token, and Access token secret. You might need to click Regenerate for the access tokens to become visible. Copy them while they are visible and save the data in a txt file or some other secure place. Now that we have the Twitter App's keys and tokens, we can start coding our bot.

Some Prerequisites

You need to have an active AWS account and Python 3 set up on your system before proceeding.

  1. Create an AWS account if you don't have one. You might need to add and verify your credit card to set up your billing account but will not be charged anything. The services that we'd be using are free and included in the AWS free tier by default so you don't need to shed a single penny.
  2. Download and install Python 3 on your system by navigating to the downloads page.
  3. Download and install pip, which is a package manager for Python. It can be installed directly from the command line following this guide.
  4. Any code editor that provides syntax highlighting for python files. The best option is to go for VS Code. However, any python editor or IDE of your choice would work.

Coding your Bot

  1. Create a new folder called "twitter-bot-demo". This will be the root of our python project. Feel free to name it anything you like.
  2. Create the main handler file in the root directory. We will name it handler.py
  3. Copy and paste the code below in handler.py. We would be doing multiple tweets with keywords present in the languages list from your account.
import config
from twython import Twython, TwythonError

languages = ['Python', 'Java', "Go"]
message = ''

twitter = Twython(config.APP_KEY, config.APP_SECRET,
                    config.OAUTH_TOKEN, config.OAUTH_TOKEN_SECRET)

for lang in languages:
    try:
        content = f'Hello World! I am a twitter bot who knows {lang}.'
        twitter.update_status(status=content)
        message += f' Tweeted {lang}  '
    except TwythonError as e:
        message += f'{e}'
        pass

print(message)

We will be using a library called Twython. It is a Twitter library for Python that makes interacting with the Twitter API much easier. Instead of calling the Twitter web service, we can simply use the functions that are packaged in this library to perform all Twitter tasks.

We will be testing the function from your local first before deploying it on AWS. Now, to connect to your Twitter account, we will need the keys and tokens generated earlier.

4. We need to create a config file that stores your Twitter tokens. Create another python file called config.py. Add your keys and tokens replacing the "X" placeholders within double quotes (" ").

APP_KEY="XXXXXXXXXXXXXXXXXXXXXXXX"
APP_SECRET="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
OAUTH_TOKEN="xxxxxxxxxxxxxxxx-XXXXXXXXXXXXXXXXXXXXXXXXXXX"
OAUTH_TOKEN_SECRET="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

5. Install the Twython dependency in python using pip. Run the following command from a terminal or cmd (in case of windows).

MacOS and Linux:

python3 -m pip install twython

On Windows:

py -m pip install twython

6. Now it's time to test this python script from your local. Execute the python script in handler.py using the command line or directly from your IDE.

MacOS and Linux:

python3 handler.py

On Windows:

py handler.py

7. The output will be printed to the console and you'd know if the script ran successfully.

Console output after executing the script

8. Check your Twitter account to verify if it actually worked.

Look for the 3 tweets from your account that were done via the python script

9. Look at the end of the tweet and you will see its source. This source would be the name of your Twitter App, confirming that this was an external tweet made through the API.

Source of the tweet is the name of your Twitter App

10. Now that our simple Hello World script is working, it's time to build something that can be deployed to and triggered routinely from AWS lambda.

11. Edit your handler.py file to include the code below

import json
import config
import logging
from twython import Twython, TwythonError

logger = logging.getLogger()
logger.setLevel(logging.INFO)


def tweet(event, context):
    search_keyword = '#Technology'
    message = ''
    twitter = Twython(config.APP_KEY, config.APP_SECRET,
                      config.OAUTH_TOKEN, config.OAUTH_TOKEN_SECRET)

    search_results = twitter.search(
            q=search_keyword, result_type='recent', lang='en', count=1)
    tweets = search_results['statuses']
    try:
        if len(tweets) > 0:
            tweet = tweets[0]
            tweet_content = tweet['text']
            twitter.retweet(id=tweet['id'])
            twitter.create_favorite(id=tweet['id'])
            message += f'Retweeted and liked tweet: {tweet_content}'
    except TwythonError as e:
        logger.error(f'An error occured wile reading : {e}')
        message += f'{e}'
        pass

    body = {
        "message": message,
        "input": event
    }

    response = {
        "statusCode": 200,
        "body": json.dumps(body)
    }

    logger.info(message)

    return response

We use the Twitter search API to get the most recent tweet for the hashtag "Technology", we then retweet and favorite the tweet. The code above contains the function tweet that can be invoked when hosted on AWS lambda. We also log the response and return it with the HTTP code 200 that signifies a successful response.

Deploying and Testing your Bot

1. We are now ready to deploy our code on AWS lambda which is AWS' serverless computing platform. Login to your AWS console and navigate to lambda.

Create new lambda function in AWS

In the create function menu, select "Author from scratch". Enter other details like function name, select the runtime as Python 3.8. Leave all other options to their defaults.

2. Now, we need to upload our code as a zip file or place it in an S3 bucket. However, there's a small caveat here. Our lambda handler function uses an external library called Twython. This library is not available in python by default and needs to be imported. We achieved it on our local by running the pip install command. For AWS Lambda to have access to this dependency, we need to figure out a way to package this library as a part of our final code package that we would need to upload. To overcome this problem, we will use a python virtual environment.

3. Go back to your root folder and run the command below to create a new virtual environment called env. You will need to install virtualenv if it is not available and the command is different for Windows systems. Install virtualenv and then create a virtual environment by running the commands below. You can follow this guide to ensure that you have virtualenv set up.

MacOS and Linux:

python3 -m pip install --user virtualenv
python3 -m venv env

Windows:

py -m pip install --user virtualenv
py -m venv env

4. A virtual environment named "env" should be created and you will be able to see an env directory in your project.

An env directory is created in the project root

5. Run the following command to activate the virtual environment you just created.

source env/bin/activate

6. This will activate env and your terminal should look like this. Notice the (env) in the beginning.

7. Install the Twython dependency in the virtual environment to include the library.

pip install twython

8. Deactivate the virtual environment to come out of it.

deactivate

9. Once the dependency is installed we are ready to package our code and create a zip file containing all files in the root of your project. Navigate to the env/lib/python3.8/site-packages directory. This directory has all the dependency files.

cd env/lib/python3.8/site-packages

10. Create a zip file in the root directory that will include all dependencies present in site-packages folder.

For macOS and Linux systems run the below commands, one line at a time:

zip -r9 ${OLDPWD}/function.zip .
cd $OLDPWD
zip -g function.zip handler.py
zip -g function.zip config.py

The above commands create a zip file with all the libraries and also add the handler and config files to it. However, the above commands will not work on Windows and you would need to create the zip file manually.

On Windows:

Open the env/lib/python3.8/site-packages directory and copy all folders present there. Create a new folder called build in the root directory and paste the content of site-packages that you copied. Also copy handler.py and config.py to this folder.

Add all the contents of the build folder to a zip file called function.zip. Verify that the final contents of the zip file look like this:

Final contents of function.zip

11. We now have a zip package consisting of our code and all dependencies needed to run our lambda function on AWS. In the AWS Lambda menu, select the upload a .zip file option and click on Save. Make sure to change the Handler function name to "handler.retweet". This is the name of the python file followed by the name of the function.

Uploading the zip package to AWS lambda

12. Once the zip is uploaded we are ready to test the Lambda function invocation. Click on Configure Test Events option next to the Save button and create a new test event. You can name it anything you like.

Creating an empty test event on AWS Lambda

In the body, just add empty braces to signify that the request would be empty JSON. Click Save and Trigger the Test.

13. Verify that the request was successful. The response message from the lambda function is displayed in the logs.

Success response to test event

14. You can check that the tweet was retweeted and favorited from you twitter account.

The searched tweet was retweeted and favorited

15. You can play around with your lambda function to add more features or do different things using the Twython library. You can also edit your code using the inline code editor on AWS.

Using the inline code editor

Scheduling the Bot

You can easily schedule invokes to your lambda function using AWS CloudWatch Event rules. Open AWS CloudWatch from the console and click on Events -> Rules.

Creating an event rule to invoke the lambda function

Add a new rule to invoke the lambda function we just created. Select the "Fixed rate" option in "Schedule" and enter the time in minutes or hours. On the right side, select "Lambda function" as the target and choose your function from the drop-down. Click configure details.

Enter a name and description for the rule and make sure to check "Enabled". Click create rule and you are all set.

The lambda function will now be invoked automatically after the scheduled interval. You can also choose a cron expression instead of using a fixed interval. A cron expression can describe the exact time, date, month, day of week etc. to invoke the function. A cron expression can easily be generated using this tool.

Instead of going through the pain of building the zip package and navigating through the AWS console manually to configure everything on our own, we can also use a framework like Serverless to build, deploy and schedule our lambda function. The serverless framework is built to work with multiple cloud providers and is not just restricted to AWS.

You can do much more with your bot in creative ways. Explore the Twython library and Twitter Search API to see all the available functions and parameters

We will discuss the usage of Serverless to deploy applications on the cloud in another post! I hope you enjoyed coding your bot and have fun with it.