Creating a Twitter Bot in Python Using Tweepy (Part-1)

Automation TWEEPY SERIES Image

    Part of having a great Twitter presence involves keeping our account active with new tweets and retweets, following interesting accounts, and quickly replying to our followers’ messages. We can do all this work manually, but that can take a lot of time. Instead, we can rely on a Twitter Bot, a program that automates all or part of our Twitter activity. One common use case can be when we want to tweet about posts published by users on a blog. You can find this on this website as well where the bot tweets about the posts published on the website as well as likes and retweets the tweets shared by users on Twitter.

    What Is Tweepy?

    Tweepy is an open source Python package that gives you a very convenient way to access the Twitter API with Python. Tweepy includes a set of classes and methods that represent Twitter’s models and API endpoints, and it transparently handles various implementation details, such as:

    • Data encoding and decoding
    • HTTP requests
    • Results pagination
    • OAuth authentication
    • Rate limits
    • Streams

    If you weren’t using Tweepy, then you would have to deal with low-level details having to do with HTTP requests, data serialization, authentication, and rate limits. This could be time consuming and prone to error. Instead, thanks to Tweepy, you can focus on the functionality you want to build.

    Almost all the functionality provided by Twitter API can be used through Tweepy. The only current limitation, as of version 3.7.0, is that Direct Messages don’t work properly due to some recent changes in the Twitter API.

    Using Tweepy

    In this section, you’ll learn how to install Tweepy for development, configure authentication credentials, and interact with the Twitter API.

    Installation

    Tweepy can be installed using pip, a Python package manager. In this article, we’re going to use a virtual environment (virtualenv) for the projects to avoid depending on system-wide packages.

    You can get started by creating a project called tweepy-bots. The first step is to create a directory and a virtual environment:

    $ mkdir tweepy-bots
    $ cd tweepy-bots
    $ python3 -m venv venv

    The commands above create the virtual environment inside the project directory.

    Then you can install the Tweepy package. First, you need to activate the newly created virtual environment and then use pip to do the installation:

    $ source ./venv/bin/activate
    $ pip install tweepy

    Now that Tweepy is installed, let’s create a requirements.txt file containing the names of your dependencies. You can use the pip command freeze for this task:

    $ pip freeze > requirements.txt

     

    Note: The method used to activate the virtual environment may be different, depending on your operating system and shell. You can learn more about this in the venv documentation.

     

    Creating Twitter API Authentication Credentials

    The Twitter API requires that all requests use OAuth to authenticate. So you need to create the required authentication credentials to be able to use the API. These credentials are four text strings:

    1. Consumer key
    2. Consumer secret
    3. Access token
    4. Access secret

    If you already have a Twitter user account, then follow these steps to create the key, token, and secrets. Otherwise, you have to sign up as a Twitter user before proceeding.

     Step 1: Apply for a Twitter Developer Account

    Go to the Twitter developer site to apply for a developer account. Here, you have to select the Twitter user responsible for this account. It should probably be you or your organization. Twitter then requests some information about how you plan to use the developer account. You have to specify the developer account name and whether you are planning to use it for personal purpose or for your organization.

    Step 2: Create an Application

    Twitter grants authentication credentials to apps, not accounts. An app can be any tool or bot that uses the Twitter API. So you need to register your an app to be able to make API calls.

    To register your app, go to your Twitter apps page and select the Create an app option.

    You need to provide the following information about your app and its purpose:

    • App name: a name to identify your application (such as examplebot)
    • Application description: the purpose of your application (such as An example bot for a Real Python article)
    • Your or your application’s website URL: required, but can be your personal site’s URL since bots don’t need a URL to work
    • Use of the app: how users will use your app (such as This app is a bot that will automatically respond to users)

    Step 3: Create the Authentication Credentials

    To create the authentication credentials, go to your Twitter apps page.
    Here you’ll find the Details button of your app. Clicking this button takes you to the next page, where you can generate the credentials.
    By selecting the Keys and tokens tab, you can generate and copy the key, token, and secrets to use them in your code. After generating the credentials, save them to later use them in your code.

    Review of Tweepy Functionality

    Tweepy gives you an interface to access the Twitter API from Python. It does so by encapsulating much of the Twitter API’s complexity and adding a model layer and other useful functionalities on top of it.

    Since, over time, the names of various Twitter concepts have evolved, some old names are still used in Tweepy. So keep in mind that, in the context of this article, these equivalences hold:

    • status is a tweet .
    • friendship is a follow-follower relationship.
    • favorite is a like.

    Now that you know how Tweepy names things, let’s see how it works.

    Tweepy’s functionality can be divided into the following groups:

    • OAuth
    • The API class
    • Models
    • Cursors
    • Streams

    Now you’re going to look into these groups to learn about the functionality each one provides.

    OAuth

    Tweepy takes care of all the details for using OAuth required by the Twitter API to authenticate each request. It provides an OAuthHandler class that you can use to set the credentials to be used in all API calls.

    This code snippet shows how you can create an OAuthHandler object that can later be used for API calls:

    import tweepy
    
    # Authenticate to Twitter
    auth = tweepy.OAuthHandler("CONSUMER_KEY", "CONSUMER_SECRET")
    auth.set_access_token("ACCESS_TOKEN", "ACCESS_TOKEN_SECRET")

    Here you’re telling Tweepy to use the credentials that you created in Step 3: Create the Authentication Credentials. You must replace CONSUMER_KEYCONSUMER_SECRETACCESS_TOKEN, and ACCESS_TOKEN_SECRET with the values you previously generated.

    The API Class

    The API class has many methods that provide access to Twitter API endpoints. Using these methods, you can access the Twitter API’s functionality.

    The following code snippet creates an API object that you can use to invoke Twitter API methods. Setting wait_on_rate_limit and wait_on_rate_limit_notify to True makes the API object print a message and wait if the rate limit is exceeded:

    import tweepy
    
    # Authenticate to Twitter
    auth = tweepy.OAuthHandler("CONSUMER_KEY", "CONSUMER_SECRET")
    auth.set_access_token("ACCESS_TOKEN", "ACCESS_TOKEN_SECRET")
    
    # Create API object
    api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True)

    In the code above, we’ve set the authentication credentials and created an api object. You can invoke this object’s methods to do any API call.

    How to Make a Twitter Bot in Python With Tweepy

    Let’s see how you can make a Twitter bot in Python with Tweepy. Bots work by continuously watching for some Twitter activity and automatically reacting to it.

    Watching for Twitter Activity

    There are two ways to continuously watch for Twitter activity:

    1. Using streams: to be notified when new content, such as tweets, that matches certain criteria is created
    2. Using polling: to periodically make Tweepy API calls and then check their results to see if they contain something new

    Which option to choose depends on your use case. Using streams is the most efficient option, but then you can only watch activity related to tweets, so it’s less flexible. In this section, both options are used to build different bots.

    Presenting the Example Bots

    In this article, you’ll learn how to build three different bots that perform automatic actions to react to some Twitter events:

    1. The Follow Followers Bot automatically follows anyone who follows you.
    2. The Fav & Retweet Bot automatically likes and retweets tweets that match certain criteria.
    3. The Reply to Mentions Bot automatically replies to tweets mentioning you that contain the words help or support.

    We are going to use a directory named bots to store all the Python files of the project as shown below:

    tweepy-bots/
    │
    ├── bots/
    │   ├── config.py
    │   └── followfollowers.py
    │   └── favretweet.py
    │   └── autoreply.py
    │
    └── requirements.txt

    The next section explains the config module.

    The Config Module

    All the bots we are building have some functionality in common. For example, they need to authenticate to the Twitter API.

    You can create a reusable Python module containing the logic common to all bots. We named this module config.

    This module reads the authentication credentials from environment variables and creates the Tweepy API object. By reading the credentials from environment variables, you avoid hard coding them into the source code, making it much more secure.

    The bots will read the credentials from these environment variables:

    • CONSUMER_KEY
    • CONSUMER_SECRET
    • ACCESS_TOKEN
    • ACCESS_TOKEN_SECRET

    Later, you’ll see how to set these variables to match the credentials you have previously generated for your Twitter app.

    Below is the complete source code for the config module. It contains create_api(), a function that reads authentication credentials from environment variables and creates the Tweepy API object:

    # tweepy-bots/bots/config.py
    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

    This code uses os.getenv() to read environment variables and then creates the Tweepy auth object. Then the API object is created.

    Passing wait_on_rate_limit and wait_on_rate_limit_notify in the creation of the tweepy.API object makes Tweepy wait and print a message when the rate limit is exceeded.

    Before returning the API object, create_api() calls verify_credentials() to check that the credentials are valid.

    This module and, as you will see later, the bot’s source code, use the logging Python module to inform errors and info messages that help you debug them if any issue arise.

    The Follow Followers Bot

    This bot gets your list of followers from Twitter every minute and then iterates through it to follow each user that you’re not already following.

    Bot Source Code

    Here’s the full source code of this bot. It uses the previously created config module, the Tweepy API, and cursors:

    #!/usr/bin/env python
    # tweepy-bots/bots/followfollowers.py
    
    import tweepy
    import logging
    from config import create_api
    import time
    
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger()
    
    def follow_followers(api):
        logger.info("Retrieving and following followers")
        for follower in tweepy.Cursor(api.followers).items():
            if not follower.following:
                logger.info(f"Following {follower.name}")
                follower.follow()
    
    def main():
        api = create_api()
        while True:
            follow_followers(api)
            logger.info("Waiting...")
            time.sleep(60)
    
    if __name__ == "__main__":
        main()

    main() creates a Tweepy API object using create_api() from the config module you previously created. Then, inside a loop, follow_followers() is called once every minute.

    follow_followers() uses a Tweepy cursor and the Tweepy API method followers() to get your list of followers. This list contains a Tweepy user model for each user that is following you.

    Then the bot iterates through the list and uses following to check if you are already following each user. Users that are not already being followed are followed using follow().

    Running the Bot

    To run the bot, you must first create the environment variables for the authentication credentials. You can do this by running this commands from a terminal and replacing the values with your actual credentials:

    $ export CONSUMER_KEY="your-key-here"
    $ export CONSUMER_SECRET="your-secret-here"
    $ export ACCESS_TOKEN="your-token-here"
    $ export ACCESS_TOKEN_SECRET="your-token-secret-here"

    Note: This assumes that you’re using Linux or macOS. If you’re using Windows, then the steps might be a little different.

    After you run the commands, your environment variables will contain the credentials needed to use the Twitter API.

    Next, you have to activate your virtual environment and run the bot’s main file, bots/followfollowers.py:

    $ source ./venv/bin/activate
    $ python bots/followfollowers.py

     

    While it’s running, the bot will follow anybody who follows you. You can test that it works by unfollowing someone that is following you. After a minute, they will be followed again. You can stop the bot using Ctrl-C.

    The Fav & Retweet Bot

    This bot uses the previously introduced Tweepy stream to actively watch for tweets that contain certain keywords. For each tweet, if you’re not the tweet author, it will mark the tweet as Liked and then retweet it.

    You can use this bot to feed your account with content that is relevant to your interests.

    Bot Source Code

    Below, you can see the full source code of this bot. It uses a stream to filter tweets that contain the words "Python" or "Tweepy". Each tweet from the stream is marked as Liked and retweeted:

    #!/usr/bin/env python
    # tweepy-bots/bots/favretweet.py
    
    import tweepy
    import logging
    from config import create_api
    import json
    
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger()
    
    class FavRetweetListener(tweepy.StreamListener):
        def __init__(self, api):
            self.api = api
            self.me = api.me()
    
        def on_status(self, tweet):
            logger.info(f"Processing tweet id {tweet.id}")
            if tweet.in_reply_to_status_id is not None or \
                tweet.user.id == self.me.id:
                # This tweet is a reply or I'm its author so, ignore it
                return
            if not tweet.favorited:
                # Mark it as Liked, since we have not done it yet
                try:
                    tweet.favorite()
                except Exception as e:
                    logger.error("Error on fav", exc_info=True)
            if not tweet.retweeted:
                # Retweet, since we have not retweeted it yet
                try:
                    tweet.retweet()
                except Exception as e:
                    logger.error("Error on fav and retweet", exc_info=True)
    
        def on_error(self, status):
            logger.error(status)
    
    def main(keywords):
        api = create_api()
        tweets_listener = FavRetweetListener(api)
        stream = tweepy.Stream(api.auth, tweets_listener)
        stream.filter(track=keywords, languages=["en"])
    
    if __name__ == "__main__":
        main(["Python", "Tweepy"])

    As with the previous bot, the main function uses create_api() from the config module to create a Tweepy API object.

    A Tweepy stream is created to filter tweets that are in the English language and include some of the keywords specified in the main function argument, "Python" or "Tweepy" in this case.

    The on_status() of FavRetweetListener processes tweets from the stream. This method receives a status object and uses favorite() and retweet() to mark the tweet as Liked and retweet.

    To avoid retweeting and liking tweets that are replies to other tweets, on_status() uses an if to see if in_reply_to_status_id is not None. Also, the code checks if you’re the tweet author to avoid retweeting and liking your own content.

    You can run this bot using the same instructions used for the previous bot, changing the Python program to favretweet.py.

    The Reply to Mentions Bot

    This bot periodically fetches tweets in which you are mentioned. If the tweet is not a reply to another tweet, and it contains the words "help" or "support", then the tweet author will be followed, and the tweet will be replied to with another tweet saying "Please reach us via DM".

    You can use this bot to automate the initial process of answering your followers’ questions.

    Bot Source Code

    Here’s the full source code for this bot. It uses a cursor to fetch your mentions:

     

    #!/usr/bin/env python
    # tweepy-bots/bots/autoreply.py
    
    import tweepy
    import logging
    from config import create_api
    import time
    
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger()
    
    def check_mentions(api, keywords, since_id):
        logger.info("Retrieving mentions")
        new_since_id = since_id
        for tweet in tweepy.Cursor(api.mentions_timeline,
            since_id=since_id).items():
            new_since_id = max(tweet.id, new_since_id)
            if tweet.in_reply_to_status_id is not None:
                continue
            if any(keyword in tweet.text.lower() for keyword in keywords):
                logger.info(f"Answering to {tweet.user.name}")
    
                if not tweet.user.following:
                    tweet.user.follow()
    
                api.update_status(
                    status="Please reach us via DM",
                    in_reply_to_status_id=tweet.id,
                )
        return new_since_id
    
    def main():
        api = create_api()
        since_id = 1
        while True:
            since_id = check_mentions(api, ["help", "support"], since_id)
            logger.info("Waiting...")
            time.sleep(60)
    
    if __name__ == "__main__":
        main()

    As with the others bots, the main function creates a Tweepy API object. After that, it initializes the variable since_id with the value 1. This variable is used to only fetch mentions created after those already processed.

    Inside a loop, check_mentions() is called once every minute.

    This function uses a Tweepy cursor and mentions_timeline() to get all the tweets mentioning you that have an id greater than the since_id variable.

    For each tweet mentioning you, its author is followed using tweet.user.follow() if you are not already following them.

    Then a reply to the tweet is created using update_status(), passing the id of the original tweet as in_reply_to_status_id.

    check_mentions() returns the greatest processed tweet id. This information will be used as the since_id in the next call to look only for tweets more recent than the ones already fetched.

    You can run the bot using the same instructions used previously. Just change the Python program to autoreply.py.

    Let's end this part here. In the next part, we shall talk about the deployment of the bot on AWS using Docker.

    Tags: #Coding, #Python

    0 Comments

    To add a comment, please Signup or Login