Make a Reddit Bot with Python

Make a Reddit Bot with Python

A few days ago, I was lurking on r/vim when I came across this post

I have never made a Reddit bot before, but I had a feeling it wasn't that difficult. So, I read around a bit, and truly it wasn't that difficult. Within an hour, I made a primitive version of u/vim-help-bot which I improved over the next few days.

I will not go into detail about how it works, mostly because a bulk of it is vim related stuff, and the actual bot related stuff is pretty small. The source code is available here so you can see for yourself.

In this post we'll make a bot that will monitor a subreddit for new comments containing the words "!quote" and it will reply with some random quotes.

Getting Started

In order to use the Reddit APIs, we'll use the praw library. So install it

pip install praw

Next, we'll need to authenticate our bot. For that you will need to create an account for the bot on Reddit. So go ahead and do that. This will be the account our bot uses.

Now we need to create an app for the bot. Go to this link (authenticated as the account you just created) and click on "Create new app"

Here you'll put a name for the app. Let's put "Quote Bot". Next select "script" and in the redirect url write "http://localhost". (The redirect url is not necessary since it is a script, but Reddit wants it for some reason") and click on "create app" and your app is now created.

Copy the client id and client secret. And keep them secret!

Now create a file called praw.ini and put these contents -

[bot1]
client_id=<put your client id here>
client_secret=<put your client secret here>
username=<username of the bot account>
password=<password of the bot account>

Keep this file top secret. If you're using git, do not check it into version control. Put it in .gitignore

Writing the Bot

Alright, now we can start writing the bot. Create a file named bot.py in the same folder as praw.ini

Before we write anything, we need to figure out which subreddit to monitor. For testing purposes, you should not pick up any actual subreddit, because you're probably getting banned. Even if you're not testing, you can still get banned.

There are a few subreddits that give you full permission to test your bots. One such is r/pythonforengineers, so we're going to pick this one.

First we import praw

import praw

Now we need to create necessary variables.

reddit = praw.Reddit("bot1")
subreddit = reddit.subreddit("pythonforengineers")

We first create a Reddit instance from the bot1 we defined in praw.ini. In case you have multiple bots you can define them in praw.ini like so

[bot1]
...
...
[bot2]
...
...
[bot3]
...
...

Next we're creating the SubReddit instance which we will monitor.

Next we will monitor all new comments in this subreddit -

for comment in subreddit.stream.comments(skip_existing=True):
    # Do stuff
    

This for loop is technically an infinite loop. It will be triggered on every new comment posted.

The skip_existing argument tells praw to track new comments which were posted after the bot was started. Without it the loop will be triggered for every existing comment in the subreddit and then it will track new comments.

This is useful if your bot is stopped for sometime. If any comment is posted while the bot is off, it will never reply to them if skip_existing=True. If you want skip_existing to be False (the default), you need to keep track of which comments you have replied to (using the comment id) otherwise you'll reply to already replied comments if your bot is restarted.

Here we're keeping it simple and we don't care about existing comments.

Now we can write the main body of the bot. First, we'll define some quotes -

QUOTES = [ "Be yourself; everyone else is already taken.",
    "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe.",
    "So many books, so little time.",
    "A room without books is like a body without a soul.",
    "You only live once, but if you do it right, once is enough."
]

for comment in subreddit.stream.comments(skip_existing=True):
    # Do stuff

I'm only defining five, but feel free to define as many as you want.

Next, we need to figure out if our comment contains the word "!quote"

if "!quote" in comment.body:
    # Reply

Now we need a random quote. For that we need the random module

import praw
import random

...

Then we can choose one item from the list of quotes -

if "!quote" in comment.body:
    quote = random.choice(QUOTES)

And now we reply:

if "!quote" in comment.body:
    quote = random.choice(QUOTES)
    comment.reply(quote)

And that's it!

Trying It Out

Now you can try out the bot -

python bot.py

Visit r/pythonforengineers and make a new post and under that post a comment containing "!quote" and see your bot respond!

Here's the full code -

import praw
import random

reddit = praw.Reddit("bot1")
subreddit = reddit.subreddit("pythonforengineers")

QUOTES = [ "Be yourself; everyone else is already taken.",
    "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe.",
    "So many books, so little time.",
    "A room without books is like a body without a soul.",
    "You only live once, but if you do it right, once is enough."
]

for comment in subreddit.stream.comments(skip_existing=True):
    if "!quote" in comment.body:
    quote = random.choice(QUOTES)
    comment.reply(quote)

For further reading, check out the official Praw tutorials. If you want to check out my bot and want to help with it, jump right ahead