redd
Gem Version Build Status MIT License Gem Downloads

**redd** is an API wrapper for [reddit](http://reddit.com/dev/api) written in ruby that focuses on being *simple and extensible*. **Check out the latest documentation on [RubyDoc](http://rubydoc.info/github/avidw/redd/master/frames).** ---

Getting Started | OAuth2 | Extending Redd | Supported Rubies | Copyright

--- ## Getting Started Ruby and redd make creating reddit bots accessible and fun. To demonstrate, let's create a simple bot in four steps that responds to "Hello?" with "World!". *Note: this is just a tutorial; although you're welcome to take it on a test drive on a testing subreddit, don't actually host this bot.* 1. **Installing** You can either install the gem directly by running `gem install redd` or by placing the gem into your `Gemfile` and running `bundle install`. ```ruby source "https://rubygems.org" gem "redd" # or if you're feeling adventurous gem "redd", github: "avidw/redd" ``` 2. **Setting Up** Let's load up redd and create a client for us to work with. (The username and password aren't real!) ```ruby require "redd" #=> true r = Redd::Client::Authenticated.new_from_credentials "HelloWorldBot", "hunter2", user_agent: "HelloWorldBot v1.0 by /u/you" # => # e time_left = e.time sleep(time_left) rescue Redd::Error => e status = e.code # 5-something errors are usually errors on reddit's end. raise e unless (500...600).include?(status) end ``` ## OAuth2 Redd also provides a wrapper to connect to reddit via OAuth2. The client's methods are similar to the authenticated client, given that you have the required scopes. Refer to [reddit's api](https://www.reddit.com/dev/api/oauth) for the various scopes. Getting it running is really simple and can even be used to integrate reddit's features into a [**Rails**](https://github.com/rails/rails) application. Another plus is that logging in via OAuth2 lets you make twice as many requests without hitting a rate limit (1/second). Let's try logging into reddit with [**sinatra**](http://www.sinatrarb.com/). The first thing you need to do is to create an OAuth2 application in reddit [**here**](https://ssl.reddit.com/prefs/apps). For more information, refer to [**"Getting Started"**](https://github.com/reddit/reddit/wiki/OAuth2#getting-started) on reddit's wiki. Note: Although I enter the client id and secret in the code directly, I recommend you store them in environment variables or a **`.env`** file and load it with [**dotenv**](https://github.com/bkeepers/dotenv). ```ruby # config.ru require "./connect_to_reddit" run ConnectToReddit ``` ```ruby # connect_to_reddit.rb require "sinatra/base" require "redd" class ConnectToReddit < Sinatra::Base configure do enable :sessions # If you're on Rails, you can replace the fixed url with a named one (e.g. redirect_url). set :client, Redd::Client::OAuth2.new("sa_xTDcJ3dWz0w", "very-sensitive-secret", "http://localhost:8080/auth/reddit/redirect") end get "/auth/reddit" do # Make use of the state! # SecureRandom, which is included in Ruby, helps create a url-safe random string. state = SecureRandom.urlsafe_base64 session[:state] = state redirect settings.client.auth_url(["identity"], :temporary, state) end get "/auth/reddit/redirect" do raise "Your state doesn't match!" unless session[:state] == params[:state] # access is a Redd::OAuth2Access object. access = settings.client.request_access(params[:code]) me = settings.client.with_access(access) { |client| client.me } # Now use the Redd::Object::User object to create a user, maybe assign some # sort of token to remember their session. redirect to("/success") end end ``` Now let's run the application: ```shell $ rackup -p 8080 ``` #### Remember Me If you want longer control of users' accounts for background tasks like auto-saving to a users' account behind the scenes or not have to ask your user to go through reddit every time, you can choose to have a permanent access by changing the second parameter of `auth_url`. ```ruby client = Redd::Client::OAuth2.new("sa_xTDcJ3dWz0w", "very-sensitive-secret", "http://localhost:8080/auth/reddit/redirect") state = SecureRandom.urlsafe_base64 auth_url = client.auth_url(["identity"], :permanent, state) ``` The access will still only last one hour, but you can refresh the access whenever you want. ```ruby access = client.request_access(params[:code]) # 1 hour or more later client.refresh_access(access) if access.expired? ``` Now if you are running a web application, you can't just store access tokens in memory. `Redd::OAuth2Access` offers a couple of methods for serializing the access to JSON and retrieving it. ```ruby json = access.to_json current_user.update!(access: json) # Rails redis.set("some-token", json) # Redis # After some time access = Redd::OAuth2Access.from_json(current_user.access) client.with_access(access) do |authenticated_client| authenticated_client.do_whatever_redd_client_can_do end ``` #### Who, me? You can also revoke access tokens after the user has logged out to make sure the tokens can't be used for malicious purposes. ```ruby also_revoke_refresh_token = true client.revoke_access(access, also_revoke_refresh_token) ``` ## Extending Redd Extending any ruby library, including redd is incredibly easy. Let's try this out by adding a gilding extension. Reddit provides an api to be able to gild posts and comments, given that you have "creddits". 1. Let's start by creating a module for the methods to live in. ```ruby module MyGildingExtension end ``` 2. Let's add a method to gild a thing, using the [reddit api](http://www.reddit.com/dev/api#section_gold) and following the conventions. ```ruby module MyGildingExtension def gild(thing) # Redd::Client::Unauthenticated::Utilities has some pretty helpful # methods. fullname = extract_fullname(thing) # We're using post instead of object_from_response, because we don't # expect any object from the response. post "/api/v1/gold/gild/#{fullname}" end end ``` 3. Let's add the method to the Authenticated client. You can also add it to the Unauthenticated client, but since unauthenticated users can't gild, there's no point. ```ruby Redd::Client::Authenticated.include(MyGildingExtension) ``` 4. You might also want to add the method to objects to make it easier to access. ```ruby module Gildable def gild # Every Redd::Object is instantiated with the client that created # it, so the method can be called on the client easily, similar to # praw in python. client.gild(self) end end Redd::Object::Submission.include(Gildable) Redd::Object::Comment.include(Gildable) ``` #### Contributing Please do. If you would like to become a contributor, do ask. ## Supported Rubies This gem aims to work on the following rubies: MRI: **1.9.3** - **2.1.2** JRuby: **1.7.x** Rubinius: **2.x.x** ## Copyright Copyright (c) [Avinash Dwarapu](http://github.com/avidw) under the MIT License. See LICENSE.md for more details. Some code has been used from [RedditKit.rb](http://github.com/samsymons/RedditKit.rb). See RedditKit.LICENSE.md for more details. --- Redd not your cup of tea? Check out [RedditKit.rb](http://github.com/samsymons/RedditKit.rb)!