Thoughts and Deeds

Unbowed Unbent Unbroken

Sending New Subreddit Posts to a Slack Channel

This is my first time using Praw so when I was reading up on how to use it I came across Build a reddit bot that was pretty much what I wanted. So I used most of their code for the Reddit side of things.

You can find the source for this on Github: Reddit Slack Bot

I recently became the moderator of the Learn Ruby on Rails subreddit. I want to build out the subreddit and add relevant information on setting up a dev environment, Ruby and Rails tutorials, and foster a community of learning.

To that end I created a free slack team for the subreddit so teachers and learners could come together. Invite yourself to our Slack team!

(I wrote this script in Python and yes, I get the irony of using Python for a Ruby based subreddit.) :)

I thought it would be a good idea to have posts made to the subreddit show up in the Slack channel. I’ve seen the equivalent for subreddits that have IRC channels and I didn’t think it would be very hard to accomplish. And it really wasn’t. Less than 50 lines of code!

There’s two libraries we’re going to need to install via pip.

1
2
pip install praw
pip install slackclient

We’re also going to need the os library but that’s a core part of Python, so nothing to install there.

After we’ve installed those via pip we can start our script.

Import them into our script

1
2
3
import praw
import os
from slackclient import SlackClient

Connect to slack

For this we’ll need a token. You can create an API token for your team in your Slack settings.

1
2
token = "SLACK_API_TOKEN"
sc = SlackClient(token)

Create user agent for Reddit api

Reddit requires you to give the name of a user agent to connect with. It can pretty much be anything (I think) so I gave mine a fairly descriptive name.

1
user_agent = ("LearnRoR-Slack Bot 0.1")

Create connection to reddit

1
r = praw.Reddit(user_agent = user_agent)

Storing id’s of submissions in a text file for now.

That should probably eventually be stored in a database, probably sqlite.

First check to see if the file exists, if it doesn’t create an empty array to store the submission ids

1
2
if not os.path.isfile("posts_replied_to.txt"):
  posts_replied_to = []

If the file does exist then read it in, split on the new line characters and filter out None as it’s possible to have a blank file.

1
2
3
4
5
else:
  with open ("posts_replied_to.txt", "r") as f:
      posts_replied_to = f.read()
      posts_replied_to = posts_replied_to.split("\n")
      posts_replied_to = filter(None, posts_replied_to)

Praw call to connect to our subreddit of choice!

1
subreddit = r.get_subreddit("ENTER_SUBREDDIT_NAME")

Loop through the new submissions. We’re only grabbing 5 each time

1
2
3
4
5
6
7
for submission in subreddit.get_new(limit=5):
  #Does our submission already exist?
  if submission.id not in posts_replied_to:
      # If not, let's make our call to slack to post the submission and store
      # the submission.id in our array of posts we've replied to
      sc.api_call("chat.postMessage", username="new post bot", channel="#ENTER_SLACK_CHANNEL", text=submission.permalink, unfurl_links="true")
      posts_replied_to.append(submission.id)

Open our text file and write out the new submission.id so we don’t post it again.

1
2
3
with open("posts_replied_to.txt", "w") as f:
  for post_id in posts_replied_to:
      f.write(post_id + "\n")

Miscellaneous

Reddit also asks that you only hit their api once every 30 seconds. To monitor the new submissions I set a cron job to run this every minute. I tested this by letting the newest 5 submissions get posted to slack, then I created a test post to make sure it was posted. When it showed up in our Slack channel I knew we were set!

Source