Ruby: Write basic Client for Facebook Graph-API

These lines of code might help to get you started… You know, plugins are cool and usually easily setup. But sometimes it’s good to know how to do it on your own.

The following is just a simple and pretty dumb work in progress http client for the facebook graph api (OAuth2). Please keep in mind that this is not a plain copy & paste tutorial. Feel free to customize!

class FBClient
  # bnerd.org
  require 'json'
  require 'net/https'
  require 'uri'
 
  def initialize(app, access_token = nil)
    @app = app
    @access_token = access_token
  end
 
  # request permission(s) from user
  def request(perms)
    #create a random verifier to identify user on fb callback
    verifier = (0...10).map{65.+(rand(25)).chr}.join
    uri = "https://graph.facebook.com/oauth/authorize?client_id=#{@app.app_id}&redirect_uri=#{@app.connect_url}?verifier=#{verifier}&scope=#{perms}"
 
    request = { :verifier => verifier, :uri => uri }
    return request
 
  end
 
  def connect(code, verifier)
 
    uri = URI.parse("https://graph.facebook.com/oauth/access_token?client_id=#{@app.app_id}&redirect_uri=#{@app.connect_url}?verifier=#{verifier}&client_secret=#{@app.secret}&code=#{CGI::escape(code)}")
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
 
    request = Net::HTTP::Get.new(uri.path + "?" + uri.query)
    response = http.request(request)     
    data = response.body
 
    return data.split("=")[1]
  end
 
  # get, post
  def get(path, params = nil)
    uri = URI.parse("https://graph.facebook.com/" + path)
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
 
    if params.nil?
      params = Hash.new
    end
 
    if params["access_token"].nil? 
      params["access_token"] = @access_token unless @access_token.nil?
    end
 
    request = Net::HTTP::Get.new(uri.path) 
    request.set_form_data( params )
    request = Net::HTTP::Get.new(uri.path + "?" + request.body)
 
    response = http.request(request)
    response.code == "200" ? feed = JSON.parse(response.body) : raise("Sorry, an error has occured.")
    return feed
  end
 
  def post(path, params = nil)
    uri = URI.parse("https://graph.facebook.com/" + path)
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true        
 
    if params.nil?
      params = Hash.new
    end
 
    if params[:access_token].nil?
      params[:access_token] = @access_token unless @access_token.nil?
    end
 
    request = Net::HTTP::Post.new(uri.path) 
    request.set_form_data( params )
    request = Net::HTTP::Post.new(uri.path + "?" + request.body)
 
    response = http.request(request)
    response.code == "200" ? feed = JSON.parse(response.body) : raise("Sorry, an error occured. #{response.body}")
    return feed
  end
end

Usage

This client is pretty easy to use.

I like to store application data (app_id, app_secret, connect_url, …) in a database. Makes it easier to handle several facebook applications. So, this clients expects you to pass in an object/model which defines methods for:

application.api_key
application.secret
application.app_id
application.connect_url

Initialize

client = FBClient.new(application)

Request URI to connect fb user with your application

Step 1

Generate a request uri. Redirect user to facebook

request = client.request("offline_access,publish_stream,create_event,rsvp_event,manage_pages,read_stream")
puts request[:uri] # redirect user to this uri
puts request[:verifier] # i use this custom verifier to identify user on fb callback

Step 2

Retrieve access_token.

code = params['code']
verifier = params['verifier']
access_token = client.connect(code, verifier)

Get data from Facebook

client.get("me/home", 
             { :access_token = ACCESS_TOKEN } )

Post data to Facebook

client.post("me/home", 
              { :message => "status update via graph api",
                 :access_token = ACCESS_TOKEN } )

Read the Graph-API-Reference.

Leave a Reply