How to subscribe to a subreddit using Snoo

This post piggybacks on my prior post where I wrote about the difficulty I was having interfacing with Reddit’s API. That problem has now been solved.

Relevant Links

The subscribe method in Snoo’s master repo is unfortunately outdated and will return in a 404 error.


def subscribe subreddit, action = "sub"
  logged_in?
  post('/api/subscribe', body: {action: action, sr: subreddit, uh: @modhash, api_type: 'json'})
end

The reason it returns a 404 error is because the API now requires you to pass the subreddit’s formatted id instead of it’s name. Where do you get this formatted id? Let’s use the r/nba subreddit for our example.

Navigate your browser to http://www.reddit.com/r/nba/about.json. Below is the relevant excerpt.

{

    "kind": "t5",
    "data": {
        "submit_text_html": null,
        "user_is_banned": false,
        "id": "2qo4s",
        "submit_text": "",
        "display_name": "nba",
...
...
}

Per the API docs the formatted id should be “kind” + _ + “id”, which would be “t5_2q04s”. This is what needs to be passed as the subreddit name, not “r/nba”.

Let’s start rewriting the method:


def subscribe(subreddit)
  subreddit_json = self.subreddit_info(subreddit)
  subreddit_id = subreddit_json['kind'] + "_" + subreddit_json['data']['id']
end

In Snoo there is a method named #subreddit_info located in subreddits.rb. It returns the json hash that you saw earlier when you visited http://www.reddit.com/r/nba/about.json. The subreddit_id variable builds the “t5_2q04s” formatted id.


def subscribe(subreddit)
  ...
  ...
  server_response = self.class.post('/api/subscribe.json',
    body:{uh:@modhash, action:'sub', sr: subreddit_id, api_type:'json'})
end

The server_response variable will contain the response from Reddit’s server after we send the request. The self.class.post method comes from the HTTParty gem that is bundled with Snoo. The first parameter is the URL we want to send the post request to. The second parameter is the body of our post request. For what exactly needs to be sent in the body you can see this specific entry in the API docs.

And finally let’s bring it all together with the final method:


def subscribe(subreddit)
  subreddit_json = self.subreddit_info(subreddit)
  subreddit_id = subreddit_json['kind'] + "_" + subreddit_json['data']['id']
  server_response = self.class.post('/api/subscribe.json',
    body:{uh:@modhash, action:'sub', sr: subreddit_id, api_type:'json'})
  return "Successfully subscribed to r/#{subreddit}" if server_response.code == 200
  return "Error code: #{server_response.code}" unless server_response == 200
end

You get notified either way if the request was successful or not. If the request was unsuccessful you are notified of the HTTP error code.

I hope this helps!

Leave a Reply