In this post I will teach you most of the stuff you need to know in order to get your bot off the ground.

First of all some screenshots of the final product:

Tech Stack

We will be making use of the following:

  • Flask framework for coding up the backend as it is lightweight and allows us to focus on the logic instead of the folder structure.
  • Heroku – For hosting our code online for free
  • Reddit – As a data source because it get’s new posts every minute

1. Getting things ready

Creating a Reddit app

We will be using Facebook, Heroku and Reddit. Firstly, make sure that you have an account on all three of these services. Next you need to create a Reddit application on this link.

Screen_Shot_2017-04-12_at_4_05_45_PM

In the above image you can already see the “motivation” app which I have created. Click on “create another app…” and follow the on-screen instructions.

Screen Shot 2017-04-12 at 4.14.47 PM

The about and redirect url will not be used hence it is ok to leave them blank. For production apps it is better to put in something related to your project so that if you start making a lot of requests and reddit starts to notice it they can check the about page of you app and act in a more informed manner.

So now that your app is created you need to save the ‘client_id’ and ‘client_secret’ in a safe place.

Screen_Shot_2017-04-12_at_4_17_23_PM

One part of our project is done. Now we need to setup the base for our Heroku app.

Creating an App on Heroku

Go to this dashboard url and create a new application.

Screen_Shot_2017-04-12_at_4_24_23_PM

On the next page give your application a unique name.

Screen_Shot_2017-04-12_at_4_24_50_PM

From the next page click on “Heroku CLI” and download the latest Heroku CLI for your operating system. Follow the on-screen install instructions and come back once it has been installed.

Screen_Shot_2017-04-12_at_4_25_30_PM

Creating a basic Python application

The below code is taken from Konstantinos Tsaprailis’s website.

We will be modifying the file according to our needs. So basically a Facebook bot works like this:

  1. Facebook sends a request to our server whenever a user messages our page on Facebook.
  2. We respond to the Facebook’s request and store the id of the user and the message which was sent to our page.
  3. Respond to user’s message through Graph API using the stored user id and message id.

In this post I will mainly be focusing on the Reddit integration and how to use the Postgres Database on Heroku.

Before moving further let’s deploy the above Python code onto Heroku. For that you have to create a local Git repository. Follow the following steps:

Execute the above commands in a terminal and put the above Python code into the app.py file. Put the following into Procfile:

Now we need to tell Heroku which Python libraries our app will need to function properly. Those libraries will need to be listed in the requirements.txt file. I am going to fast-forward a bit over here and simply copy the requirements from Konstantinos Tsaprailis’s website. Put the following lines into requirements.txt file and you should be good to go for now.

Run the following command in the terminal and you should get a similar output:

Now, we are ready to create a Git repository which can then be pushed onto Heroku servers. We will carry out the following steps now:

  • Login into Heroku
  • Create a new git repository
  • Commit everything into the new repo
  • Push the repo onto Heroku

The commands required to achieve this are listed below:

Save the url which is outputted above after “remote” . It is the url of your Heroku app. We will  need it in the next step when we create a Facebook app.

Creating a Facebook App

Firstly we need a Facebook page. It is a requirement by Facebook to supplement every app with a relevant page.

Now we need to register a new app. Go to this app creation page and follow the instructions below.

Screen_Shot_2017-04-12_at_9_49_02_PM

Screen_Shot_2017-04-12_at_9_50_34_PMScreen_Shot_2017-04-12_at_9_51_41_PMScreen_Shot_2017-04-12_at_9_52_05_PM

Screen_Shot_2017-04-12_at_9_53_20_PM

Screen_Shot_2017-04-12_at_9_54_10_PM

Screen_Shot_2017-04-12_at_9_56_38_PM

Now head over to your app.py file and replace the PAT string on line 9 with the Page Access Token we saved above.

Commit everything and push the code to Heroku.

If you go to the Facebook page and send a message onto that page you will get your own message as a reply from the page. This shows that everything we have done so far is working. If something does not work check your Heroku logs which will give you some clue about what is going wrong. Later, a quick Google search will help you resolve the issue. You can access the logs like this:

Note: Only your msgs will be replied by the Facebook page. If any other random user messages the page his messages will not be replied by the bot because the bot is currently not approved by Facebook. However if you want to enable a couple of users to test your app you can add them as testers. You can do so by going to your Facebook app’s developer page and following the onscreen instructions.

Getting data from Reddit

We will be using data from the following subreddits:

First of all let’s install Reddit’s Python library “praw“. It can easily be done by typing the following instructions in the terminal:

Let’s test some Reddit goodness in a Python shell. I followed the docswhich clearly show how to access Reddit and how to access a subreddit. Now is the best time to grab the “client_id” and “client_secret” which we created in the first part of this post.

Note: Don’t forget to add in your own client_id and client_secret in place of ****

Let’s discuss the important bits here. I am using limit=None because I want to get back as many posts as I can. Initially this feels like an overkill but you will quickly see that when a user starts using the Facebook bot pretty frequently we will run out of new posts if we limit ourselves to 10 or 20 posts. An additional constraint which we will add is that we will only use the image posts from GetMotivated and Memes and only text posts from Jokes and ShowerThoughts. Due to this constraint only one or two posts from top 10 hot posts might be useful to us because a lot of video submissions are also done to GetMotivated.

Now that we know how to access Reddit using the Python library we can go ahead and integrate it into our app.py.

Firstly add some additional libraries into our requirements.txt so that it looks something like this:

Now if we only wanted to send the user an image or text taken from reddit, it wouldn’t have been very difficult. In the “send_message” function we could have done something like this:

But there is one issue with this approach. How will we know whether a user has been sent a particular image/text or not? We need some kind of id for each image/text we send the user so that we don’t send the same post twice. In order to solve this issue we are going to take some help of Postgresql and the reddit posts id (Every post on reddit has a special id).

We are going to use a Many-to-Many relation. There will be two tables:

  • Users
  • Posts

Let’s first define them in our code and then I will explain how it will work:

So the user table has two fields. “name” will be the id sent with the Facebook Messenger Webhook request. The posts will be linked to the other table, “Posts”. Posts table has name and url field. “name” will be populated by the reddit submission id and the url will be populated by the url of that post. We don’t really need to have the “url” field. I will be using it for some other uses in the future hence I included it in the code.

Now the way our final code will work is this:

  • Request a list of posts from a particular subreddit. The following code:

    returns a generator so we don’t need to worry about memory
  • We will check whether the particular post has already been sent to the user in the past or not
  • If the post has been sent in the past we will continue requesting more posts from Reddit until we find a fresh post
  • If the post has not been sent to the user, we send the post and break out of the loop

So the final code of the app.py file is this:

Put this code into app.py file and send it to Heroku.

One last thing is still remaining. We need to tell Heroku that we will be using the database. It is simple. Just issue the following command in the terminal:

This will create a free hobby database which is enough for our project. Now we only need to initialise the database with the correct tables. In order to do that we first need to run the Python shell on our Heroku server:

Now in the Python shell type the following commands:

So now our project is complete. Congrats!

Let me discuss some interesting features of the code. Firstly, I am making use of the “quick-replies” feature of Facebook Messenger Bot API. This allows us to send some pre-formatted inputs which the user can quickly select. They will look something like this:

Screen_Shot_2017-04-13_at_12_26_21_AM.png

It is easy to display these quick replies to the user. With every post request to the Facebook graph API we send some additional data:

Another interesting feature of the code is how we determine whether a post is a text, image or a video post. In the GetMotivated subreddit some images don’t have a “.jpg” or “.png” in their url so we rely on

This way we are able to select even those posts which do not have a known image extension in the url.

You might have noticed this bit of code in the app.py file:

It makes sure that if no new posts are found for a particular user (every subreddit has a maximum number of “hot” posts) we have at least something to return. Otherwise we will get a variable undeclared error.

Create if the User doesn’t exist:

The following function checks whether a user with the particular name exists or not. If it exists it selects that user from the db and returns it. In case it doesn’t exist (user), it creates it and then returns that newly created user:

I hope you guys enjoyed the post. Please comment below if you have any questions. I am also starting premium advertising on the blog. This will either be in the form of sponsored posts or blog sponsorship for a particular time. I am still fleshing out the details. If your company works with Python and wants to reach out to potential customers, please email me on yasoob (at) gmail.com.

3 COMMENTS

  1. I’m impressed, I must say. Rarely do I come across a blog that’s both educative and interesting,
    and without a doubt, you’ve hit the nail on the head.
    The problem is something that too few men and women are speaking intelligently about.
    I am very happy I stumbled across this during my search
    for something concerning this.

LEAVE A REPLY

Please enter your comment!
Please enter your name here