Developement

Creating A Twitter Bot with Tweepy

""Given a limit of 140 characters, people consistently reaffirm that creativity is a renewable resource." ― Biz Stone, co-founder of Twitter, Medium, and Jelly"

blog image Josh Burgess

8 MIN READ

blog image

In this post I will guide you through the same process I went through to create my Twitter Bot Mr. BlueJay. This bot is built with Python 3.9 and the package Tweepy. Some of these functions I learned from tutorials myself and I have linked some platforms that will help in learning Python and Tweepy below. Python is an object oriented, high-level programming language, which basically just means you use an easier to use and understand variables and expressions compared to machine language or binary. Packages are libraries of functions and work others have made available for other developers to build upon. Tweepy is a package that utilizes the Twitter API (Application Programming Interface) to allow the developer to interact with Twitter's platform. So let's build a robot that interacts with users!


Getting Started

"Given a limit of 140 characters, people consistently reaffirm that creativity is a renewable resource." ― Biz Stone, co-founder of Twitter, Medium, and Jelly

Developer Platform

First we will need to go to the Twitter Developer's Platform and apply for a developer account. You can login with your twitter account information. Fill out that you are making a bot to engage with users and agree to their Terms and Conditions. After you confirm your email address you will have to wait until the account is approved, which can take a minute to a day or so. Then you will see an empty dashboard and you will want to click "Create an app" and Twitter will proceed to ask your intentions with their API, and just be concise and honest, after naming and describing the app, the process should be done and you can proceed to the app permissions where you should change it to read + write, maybe direct message if you want that too. This is where you get the important information– the API Key & Secret and the Access Token & Secret.

Python & Coding Environment

I, and most, code in a text editor, which is an app that has autocomplete and correct for code. My preferred text editor is Visual Studio Code developed by Microsoft and you can find the download here. In VS code you can install add-ons that support languages like JavaScript, SCSS, and Python, you will want to install the Python support add-on. Congrats, you have most of the tools at your disposal to develop applications!

Create a folder on your desktop and label it with no spaces (you can use a dash or underscore or CamelCase instead) either from right clicking or the terminal, which we will dive deeper into in another post. After your folder  is created you can access it by opening the folder through VS code.

Now, a good habit when making programs in Python is to create something called a Virtual environment, this way, the packages and dependencies you download for a project stay with that project and stay the same versions, in case future updates clash with your program.

Venv

When programming with Python, the user can select something called an interpreter. An interpreter is basically the version of python you are intending to code with and how the program will read your code. In VS code, you can select your interpreter and see what is selected in the bottom left corner (displayed here).

I currently have my venv selected and set up

To set up a venv, you will need to use your terminal, for ease of use we will use the VS code terminal with ⌘ + ~ or ⊞ + ~ depending on your machine. This should bring up a terminal where you can enter the command:

# macOS/Linux
# You may need to run 
# sudo apt-get install python3-venv first
python3 -m venv .venv

# Windows
# You can also use py -3 -m venv .venv
python -m venv .venv
Source: VS code's docs

Coding

Keeping it Secret

Now we need to keep your keys and tokens private, so you are not hacked. I choose to list them in a .env file, which I will explain why later. For simplicity, create a .env file and in the file write export CONSUMER_KEY=yourKeyHere CONSUMER_SECRET=yourSecretKeyHere ACCESS_TOKEN=yourAccessTokenHere ACCESS_TOKEN_SECRET=yourSecretTokenHere with one space between each. This is so you can copy this line and paste it in your terminal each time you fire up the project.

Configuring

Now we can import tweepy using pip or pip3 install tweepy in the terminal. Before we start coding any functions to the bot we will need to set up a configuration file, which will authenticate our bot before it runs a task! So create a file called config.py (.py extension will define a file as a python file) like this:

import tweepy
import logging
import os

logger = logging.getLogger()

def create_api():
    consumer_key = os.getenv("CONSUMER_KEY")
    consumer_secret = os.getenv("CONSUMER_SECRET")
    access_token = os.getenv("ACCESS_TOKEN")
    access_token_secret = os.getenv("ACCESS_TOKEN_SECRET")

    auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
    auth.set_access_token(access_token, access_token_secret)
    api = tweepy.API(auth, wait_on_rate_limit=True, 
        wait_on_rate_limit_notify=True)
    try:
        api.verify_credentials()
    except Exception as e:
        logger.error("Error creating API", exc_info=True)
        raise e
    logger.info("API created")
    return api

    #safely stores Tokens

To break this down, we import the dependencies we are utilizing, then initialize logger, and create the Authorization API. The OS import allows the file to use the export command of keys and tokens you pasted in your terminal! Lastly we use Tweepy's library to verify credentials, call an exception in case we get an error, and return the API so we can call it in other files that have more specific functions.

Follow for a Follow

One key feature of social media platforms is that you get to follow subjects, trends, and people you want to hear from. So why not provide a follow for a follow function from your bot!

I also want to explain the purpose of making a main function because they will be present in all of our programs. This is a best practice in programming where a main function is the entry point to executing the program, it works by calling sub functions and logic. It is important for organization of the program and creating reusability.

import tweepy
import time
from config import create_api
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()

def follow_followers(api):
    logger.info("Following your followers")
    for follower in tweepy.Cursor(api.followers).items():
        if not follower.following:
            logger.info(f"Followed {follower.name}")
            follower.follow()

def main():
    api = create_api()
    while True:
        follow_followers(api)
        logger.info("Sleeping...")
        time.sleep(200)

if __name__ == "__main__":
    main()

So in this program we use logger, time, our config's create_api function, and tweepy. Logger is providing information to our terminal so we know what is happening when the program is executed. Time is providing the time.sleep method to cause the program to wait for 200 seconds before looping again. Our create_api function is creating our connection to the Twitter api from our config file we made. Tweepy allows us to use the tweepy.Cursor method that allows us to paginate through our followers and call a following method to check if we follow our followers, and if not, then we follow them. The While loop in our main function will loop over our follow_followers function as long as our api credentials are correct, so forever unless interrupted with ctrl+c .

Tweeting

To tweet, it is as easy as creating a function and providing the update_status method to post a tweet (or what tweepy calls a status). You can get all kinds of creative with using the twitter API to tweet information or pre-made tweets!

import tweepy
import logging
from config import create_api

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()

def updates(api):
    logger.info("Tweeting your status")
    api.update_status("Hi I am a bot posting on Twitter!")


def main():
    api = create_api()
    while True:
        updates(api)


if __name__ == "__main__":
    main()

Favorites

Favoriting or liking a tweet is used with the class function that tweepy gives us. This lets us tap into the twitter tweet timeline and favorite quotes with keywords or something up to your imagination!

import tweepy
import logging
from config import create_api
import time

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()


class TListener(tweepy.StreamListener):
    def __init__(self, api):
        self.api = api
        self.me = api.me()

    def on_status(self, tweet):
        logger.info(f"The tweet ids {tweet.id}")
        
        # ignores replies and if I'm the author
        
        if tweet.in_reply_to_status_id is not None or \
                tweet.user.id == self.me.id:
            return
            
        # Liking if not liked yet
        
        if not tweet.favorited:
        
            try:
                tweet.favorite()
                time.sleep(180)
            except Exception as e:
                logger.error("There was a fav error", exec_info=True)

    def on_error(self, status):
        logger.error(status)


def main(keywords):
    api = create_api()
    tweets_listener = TListener(api)
    stream = tweepy.Stream(api.auth, tweets_listener)
    stream.filter(track=keywords, languages=["en"])


if __name__ == "__main__":

#List your keywords to like here!
    main(["bot", "#tweepy", "hello, world"])

Retweet

Retweeting is as simple as liking and you can even combine the two functions to like and retweet keywords, or keep them as separate functions, it is all up to what you can think of!

import tweepy
import logging
from config import create_api
import time

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()

class TListener(tweepy.StreamListener):
    def __init__(self, api):
        self.api = api
        self.me = api.me()

    def on_status(self, tweet):
        logger.info(f"The tweet ids {tweet.id}")
        
        # ignores replies and if I'm the author
        if tweet.in_reply_to_status_id is not None or \
                tweet.user.id == self.me.id:
            return
            
        # Retweeting it for content
        if not tweet.retweeted:
            try:
                tweet.retweet()
                time.sleep(180)
            except Exception as e:
                logger.error("error on Retweet", exc_info=True)

    def on_error(self, status):
        logger.error(status)


def main(keywords):
    api = create_api()
    tweets_listener = TListener(api)
    stream = tweepy.Stream(api.auth, tweets_listener)
    stream.filter(track=keywords, languages=["en"])


if __name__ == "__main__":
    main(["bot", "#tweepy"])

Hosting

Now we give your bot freedom. We gave it life with code, but now we need to see it walk on it's own. Scary right?

Github

Github is a platform that uses Git, a version control system and language. We can create a save-state of your code, that does not have to be on your machine! Let's go over and create an account on Github.com and create something called a repository (repo). There should be a green button saying New where you can make a new repo and name it whatever you would like, then, it should tell you how to initiate your project in your newly created repo. Now that you have a code repository, we can host your bot!

git add . #adds all project changes
git commit -m 'A small description of changes'
git push -u origin main 
# pushes your changes from your
# origin to the main branch 
# which you should see in GitHub

This is how to use git to push changes to your repository from your terminal!

Heroku

Heroku is a popular hosting platform that has a limited free use tier, but before we create our first build with Heroku, we need to create a couple files first. The pip freeze > requirements.txt command (or pip3) will create a requirements.txt file that contains the dependencies versions that people or platforms can download and use to recreate the functionality of your code. Next we need to create a runtime.txt which you will just type your python version, mine for example reads python-3.9.2 . Lastly, you must create a Procfile, which is exactly Procfile, no extensions. In this file you will write worker: {python command} {a file you want to run constantly}, mine looks like worker: python3 tweet.py .

Now, you will want to create an account and create an app on Heroku. When setting up your app it will ask what kind of deployment method you want, this will be through GitHub. You can then connect your main branch from your new repo, and when you push your code through git, it will automatically build and deploy your bot! It is also important that we make your Config Vars in settings match the ones we created in your project (ie. ACCESS_TOKEN then YOURLONGENCRYPTEDSTRING). The last thing we can do is create Cron jobs (commands fired at specified times) with an add-on in Heroku called Heroku Scheduler. This is where you can specify a daily time or hourly time for your specific functions to fire. When you add a job, under Run Command enter Now you are pretty much set to push a commit through git and watch your bot be built and live on twitter!


Real Python Twitter Bot Guide

Tweepy Docs

Twitter Developers Dashboard

Python Venv

GitHub

Feel free to email me if you have any further questions or need help! burgessj247@gmail.com