Top shelf web developer training.

Guided Paths

Follow our crafted routes to reach your goals.

Video Courses

Premium videos to build real apps.

Written Tutorials

Code to follow and learn from.

Find Your
Opportunity HIRED
Dismiss
Up

Build A Tweet Bot With Python

Related Course

Get Started with JavaScript for Web Development

JavaScript is the language on fire. Build an app for any platform you want including website, server, mobile, and desktop.

This article demonstrates how to build a tweet bot with Python programming language. Typically, a bot performs tasks that are both simple and repetitive in nature, at a much higher rate than would be possible for a human alone.

The possibilities of what could be achieved on Twitter is endless, and with 500 million+ tweets per day, there’s a lot of data to analyze and to play with. A tweet bot is a program that interacts with Twitter automatically like post tweets follow users, favorite or retweet tweets, or perform any other function possible on Twitter.

Twitter bots can be useful through providing information or updates, and they can also make Twitter more interesting for users.

What We'll Build

There are different classifications of tweet bots depending on the function they perform. This tutorial would work through building a tweet bot that takes any image you tweet at it and randomly rearranges blocks of pixels of the image to create a new scrambled image and replies the tweet with the newly formed image.

Create Your Own Bot

Writing a Twitter bot is easy. You can write a Twitter bot in just about any language you please.

Prerequisites

In this tutorial we would be using Python programming language so one of the prerequisites includes a Python programming environment, other prerequisites are:

  1. A Twitter account
  2. Tweepy: An easy-to-use Python library for accessing the Twitter API
  3. PIL : Python Imaging Library

Create A Twitter Account

The first step is creating a Twitter account https://twitter.com/signup. Once this is done the next step is to create a new application.

Create a Twitter App

  • Go to apps.twitter.com and click on 'Create New App ' button
  • Fill out the details of the form correctly
  • Read the developer agreement section, and check the box at the bottom if you agree. Then click on the ‘Create your Twitter application’ button

Keys and Access Tokens

In order to post to a Twitter account automatically, you have to get access keys for your account.

  1. After creating your new app, you would be redirected to its own page. If you weren’t, go to apps.twitter.com and click on your app's name.
  2. On the app’s page, click on the ‘Keys and Access Tokens’ tab
  3. At the bottom of this page, click on the ‘Create my access token’ button.
  4. Make sure you make note of the following four keys, as you will need these later.

Coding The Bot

Twitter provides REST APIs you can use to interact with their service. There is also a bunch of Python-based clients out there that we can use without re-inventing the wheel. In particular, Tweepy in one of the most interesting and straightforward to use, so let’s install it:

pip install tweepy

We also need to install PIL, a Python Imaging Library (PIL) that adds image processing capabilities to the Python interpreter. This library supports many file formats and provides powerful image processing and graphics capabilities.You can install PIL with pip:

pip install Pillow

Now that we have tweepy and PIL installed, we can begin to lay the structure of the bot application

tweetbot \
|-- bot.py
|-- secrets.py

Storing Credentials

The secrets.py file holds valuable information which would be needed to access your Twitter account. Anyone who has access to these strings can use your Twitter account, so you don’t want to share these, or make them public.

 # secrets.py

consumer_key = 'YOUR-CONSUMER-KEY'
consumer_secret = 'YOUR-CONSUMER-SECRET'
access_token = 'YOUR-ACCESS-TOKEN'
access_secret = 'YOUR-ACCESS-SECRET'

Replace the following variables with values from the "Keys and Access Tokens" tab of your Twitter app.

OAuth Authentication

Tweepy supports OAuth authentication. Authentication is handled by the tweepy.AuthHandler class. In the bot.py add the following

# bot.py

import tweepy
from secrets import *

#create an OAuthHandler instance
# Twitter requires all requests to use OAuth for authentication
auth = tweepy.OAuthHandler(consumer_key, consumer_secret) 

auth.set_access_token(access_token, access_secret)

 #Construct the API instance
api = tweepy.API(auth) # create an API object

The api variable is now our entry point for most of the operations we can perform with Twitter. The API class provides access to the entire Twitter RESTful API methods. Each method can accept various parameters and return responses. Please refer to API Reference for more information.

Some of the many things we can do with the API like read tweets on your timeline


public_tweets = api.home_timeline()
for tweet in public_tweets:
    print(tweet.text)

Or get the list of all your followers


user = api.get_user('picscrambler')
for friend in user.friends():
   print(friend.screen_name)

Streaming With Tweepy

The tweet bot we will build in this tutorial would watch for images that were tweeted at it, and replies with scrambled pixel versions of the original image. To do these we would need a way to keep the connection open to being able to respond to all incoming and upcoming tweets, this is where the streaming API comes in. Tweepy makes it easier to use the Twitter streaming API by handling authentication, connection, creating and destroying the session, reading incoming messages, and partially routing messages.

The streaming API is quite different from the REST API because the REST API is used to pull data from Twitter but the streaming API pushes messages to a persistent session. This allows the streaming API to download more data in real time than could be done using the REST API. To read more about the Streaming API See the Twitter Streaming API Documentation.

Inside bot.py

#bot.py

import tweepy

#create a class inherithing from the tweepy  StreamListener
class BotStreamer(tweepy.StreamListener):

    # Called when a new status arrives which is passed down from the on_data method of the StreamListener
    def on_status(self, status):
        username = status.user.screen_name 
        status_id = status.id

    #entities provide structured data from Tweets including resolved URLs, media, hashtags and mentions without having to parse the text to extract that information
        if 'media' in status.entities:
            for image in status.entities['media']:
                tweet_image(image['media_url'], username, status_id)

Using the streaming API has three steps:

  • Create a class inheriting from StreamListener
  • Using that class create a Stream object
  • Connect to the Twitter API using the Stream

We just created a class that inherits from StreamListener class overriding the on_status method capturing the username of the account that posted the tweet and tweet id and checking if an image exists in the status object (tweet) and passes it all to the tweet_image function which we are yet to write.

Next, we create a stream object

# bots.py

myStreamListener = BotStreamer()

 #Construct the Stream instance
stream = tweepy.Stream(auth, myStreamListener)

A number of Twitter streams are available through Tweepy. Most cases will use the filter, the user_stream, or the sitestream method. For more information on the capabilities and limitations of the different streams, see Twitter Streaming API Documentation.

In this example, we will use a filter to stream all tweets tweeted at our bot . The track parameter is an array of search terms to watch for.

stream.filter(track=['@picscrambler'])

In this case, the track parameter should be the name of your Twitter application.

Scramble Image Pixel

Now let's code up our tweet_image function

# bots.py

import requests
from io import BytesIO
from PIL import Image

def tweet_image(url, username, status_id):

    filename = 'temp.png'
    # send a get request
    request = requests.get(url, stream=True)
    if request.status_code == 200:
        # read data from downloaded bytes and returns a PIL.Image.Image object
        i = Image.open(BytesIO(request.content))
        # Saves the image under the given filename
        i.save(filename)
        scramble(filename)
        # Update the authenticated user’s status
        api.update_with_media('scramble.png', status='@{0}'.format(username), in_reply_to_status_id=status_id)
    else:
        print("unable to download image")

We use the Python request http library to download the image from the url and write its content into a temp.png file using the Python image library then call a scramble function on the PIL image object to produce a scrambled pixel image which is then used to reply the original tweet using the API object.

We are yet to write our image scrambler function

# bots.py

import random

def scramble(filename):
    BLOCKLEN = 64  # Adjust and be careful here.

    img = Image.open(filename)
    width, height = img.size

    xblock = width // BLOCKLEN
    yblock = height // BLOCKLEN
    # creates sequence of 4-tuples (box) defining the left, upper, right, and lower pixel coordinate
    blockmap = [(xb * BLOCKLEN, yb * BLOCKLEN, (xb + 1) * BLOCKLEN, (yb + 1) * BLOCKLEN)
                for xb in range(xblock) for yb in range(yblock)]

    shuffle = list(blockmap)

    #shuffle the sequence
    random.shuffle(shuffle)

    # Creates a new image with the given mode and size.
    result = Image.new(img.mode, (width, height))
    for box, sbox in zip(blockmap, shuffle):
        # Returns a rectangular region from this original image.
        crop = img.crop(sbox)
        # Pastes the cropped pixel into the new image Object
        result.paste(crop, box)
    result.save('scramble.png')

At this point, the bots.py should look like this

# bots.py

import random
from io import BytesIO

import requests
import tweepy
from PIL import Image
from PIL import ImageFile

from secrets import *

ImageFile.LOAD_TRUNCATED_IMAGES = True

auth = OAuthHandler(consumer_key, consumer_secret) # Twitter requires all requests to use OAuth for authentication
auth.set_access_token(access_token, access_secret) 
api = tweepy.API(auth)

def tweet_image(url, username, status_id):
    filename = 'temp.png'
    # send a get request
    request = requests.get(url, stream=True)
    if request.status_code == 200:
        # read data from downloaded bytes and returns a PIL.Image.Image object
        i = Image.open(BytesIO(request.content))
        # Saves the image under the given filename
        i.save(filename)
        scramble(filename)
        # Update the authenticated user’s status
        api.update_with_media('scramble.png', status='@{0}'.format(username), in_reply_to_status_id=status_id)
    else:
        print("unable to download image")

def scramble(filename):
    BLOCKLEN = 64  # Adjust and be careful here.

    img = Image.open(filename)
    width, height = img.size

    xblock = width // BLOCKLEN
    yblock = height // BLOCKLEN
    # creates sequence of 4-tuples (box) defining the left, upper, right, and lower pixel coordinate
    blockmap = [(xb * BLOCKLEN, yb * BLOCKLEN, (xb + 1) * BLOCKLEN, (yb + 1) * BLOCKLEN)
                for xb in range(xblock) for yb in range(yblock)]

    shuffle = list(blockmap)

    # shuffle the sequence
    random.shuffle(shuffle)

    # Creates a new image with the given mode and size.
    result = Image.new(img.mode, (width, height))
    for box, sbox in zip(blockmap, shuffle):
        # Returns a rectangular region from this original image.
        crop = img.crop(sbox)
        # Pastes the cropped pixel into the new image Object
        result.paste(crop, box)
    result.save('scramble.png')

# create a class inheriting from the tweepy  StreamListener
class BotStreamer(tweepy.StreamListener):
    # Called when a new status arrives which is passed down from the on_data method of the StreamListener
    def on_status(self, status):
        username = status.user.screen_name
        status_id = status.id

        # entities provide structured data from Tweets including resolved URLs, media, hashtags and mentions without having to parse the text to extract that information
        if 'media' in status.entities:
            for image in status.entities['media']:
                tweet_image(image['media_url'], username, status_id)

myStreamListener = BotStreamer()
# Construct the Stream instance
stream = tweepy.Stream(auth, myStreamListener)
stream.filter(track=['@picscrambler'])

That's all we need to test this bot. Run bots.py from terminal and post a tweet with an image @picscrambler. After a few seconds the bot replies with a scrambled version of the original picture. You can see a minimal working example of the Twitter bot in this githhub repository tweetbot

Conclusion

This tutorial walked through setting up and running a Twitter bot to automatically interact with the Twitter social media platform. There is a lot more that you can do with the Twitter API and with libraries like Tweepy that make it easy for developers to make use of Twitter.

REFERENCES