19 MayPost to Facebook from Rails app

Thursday, 19 May 2011 — 10:26

I was dealing recently with this and wanted to leave here the steps to follow for posting to Facebook from a Rails application.

1. Create a Facebook application from your facebook account (http://www.facebook.com/developers/). At some point, users will have to accept your application before you can post things to their facebook walls, so take your time for creating a nice description, logo, and so on. Make sure you write the proper url and domain. From here, we will get an App ID, Key and Secret that we need to save in a file in our RoR project. I added this to my Communications.yml file under app/config

facebook:
        api_key:       'a7498219c5a26e39923f0ecbce817b5a'
        secret:         '8669ddc5a2661ee6fd508281d9fe3de1'
        canvas_url: 'http://apps.facebook.com/ggomeze/'

2. We will use this gem for easiness (v. 0.4.1). Please follow the steps there for installation. Make sure all the dependencies have been installed, and make sure the gem faraday is 0.6.1 or newer.

The process to be implemented consists of getting an access_token that we will use from then on to post things to Facebook. In order to get that token, we first need to get a server code with the application key and then ask for the final access token, using the secret key. Don’t worry too much, you will see it sounds more complicated than it really is

3. Create a Facebook module, where we will implement all the steps necessary for communicating with Facebook:

def initialize
        cfg            = Communications.config['facebook']
        @api_key       = cfg['api_key']
        @secret        = cfg['secret']
      end
      
      def client
        @client ||= OAuth2::Client.new(@api_key, @secret, 
        {
          :site => 'https://graph.facebook.com',
          :ssl => {:ca_path => "/etc/ssl/certs"}
        })
      end
      
      def access_token(token)
        OAuth2::AccessToken.new(client, token)
      end
      
      def get_access_token(server_code, redirect_url)
        access_token = nil
        begin
          access_token = client.web_server.get_access_token(server_code, :redirect_uri => redirect_url)
        rescue Exception => e
          #TODO Add logs
        end
        return access_token
      end

      def get_user_permissions(target_user_secret)
        begin
          permissions = JSON.parse(access_token(target_user_secret).get('/me/permissions'))
          return permissions["data"][0].symbolize_keys!
        rescue Exception => e
           #TODO Add logs
          permissions = {}
        end
        
      end

4. Here is the Communications class

class Communications
  class << self
    def config
      @config ||= YAML::load_file("#{Rails.root}/config/communications.yml")[Rails.env]
    end

    def facebook
      YouFacebookModule.instance
    end

5. We will need a view, with a button so that the user allows our application to post data. This is where everything starts!. Create something like this:

<a href="https://graph.facebook.com/oauth/authorize?client_id=<%=@api_key%>&redirect_uri=<%= request.protocol %><%=request.host_with_port%>/our_controller/facebook_callback&scope=email,publish_stream,offline_access" >

Some comments about this. @api_key is the value we got from Facebook when we created the application. We need to tell the facebook where it must send us the server code generated. We do that with the redirect_uri clause. We will create on the next step that route in our application. And finally, what comes with scope, are all the permissions we are asking for to our users. Here you have a list of all the available permissions. The more you request, the less users will accept your application.

6. Now let’s create the path you passed through in the previous step. In my case: /our_controller/facebook_callback. I will create the controller, will modify the routes.rb file and create the facebook_callback method inside our our_controller_controller:

def facebook_callback
    if !params[:code].nil?
      access_token = Communications.facebook.get_access_token(params[:code], "#{request.protocol}#{request.host_with_port}/our_controller/facebook_callback")
      if access_token
        result = JSON.parse(access_token.get('/me'))
        user_id = result["id"]
        user_secret = access_token.token.to_s
        # TODO Save user_secret on your database for future requests
      end
    end

As you see from this method, once we get the object access token, we are ready for calling facebook on behalf for the user. As an example, i’ve made a request to /me path on facebook that return basic information of the profile. I’ve got from it the user_id and secret. You should save this value for future requests to Facebook, we will see this in a moment. But we’ve already done a request to Facebook!!.

As you see, the get_access_token from our Facebook module, has a second value that will be sent as a redirect_uri. In this case, it doesn’t mean that facebook will call this function once again. It is just a check for Facebook. We just need to use same path here. This is important.

7. And finally, you are ready for creating more requests to facebook, even posting!. How do we post something then?. Very simple:

access_token(user_secret).post('/me/feed', :message => "Posting from my RoR app")

We will be creating the access_token object from the user_secret key, and then, just posting to facebook. You can create more complex posts using these extra parameters. Easy, right?

parameters = { :name => "name", :caption => "caption", :description => "description", :link => post_url, :picture => picture_url }
access_token(user_secret).post('/me/feed', parameters)

Now you just need to look at Facebook reference API to see all the possible endpoints available for you. Have fun!

As always, let me know if you have any problem and i will try to help

Ger

Comentarios

  1. Avatar Robert
    03 Nov 16:13

    Hello, following this tutorial; however, I am running into a error with “communications”. Its saying uninitialized. Where is this communcations being define?

  2. Avatar ggomeze
    03 Nov 16:36

    I will update my post now to specify that information. Thanks for the heads up, as i was missing that part.

    Ger

Añade tu comentario




(textile habilitado)
Negrita: *Google*
Enlace: "google.com":http://www.google.com
Imagen: !http://ggomeze.com/images/avatar.png!

ó Cancelar