Status update with Rails and Facebooker

Posted in rails by elisehuard on June 17, 2009

This feature has had me cursing quite a bit. After the breeze that are Twitter updates, and the usual pieces of cake that are other APIs, it appears that Facebook has its own microcosm of requirements, causing me to cry out ‘i only want to update the status, godd****’ in despair more than once – while the documentation doesn’t totally suck, it’s far from complete. And I don’t even like Facebook.

The problem is that Facebook has an involved permission framework, with its own workflow. I ended up installing the Facebooker plugin, which is usually used for anything Rails+Facebook.

First off, you need to declare your app with Facebook. This is done with the Developer Application (Settings – Application Settings – Developer). Once you create an application, you receive an API key and a secret (needed for authentication). These have to be pasted in the facebooker.yml configurations.

After some tribulations, i ended up using the Facebook Connect infrastructure. For this, you first need to generate the pages used to do the connect:
script/generate xd_receiver

You can test the connect by adding the following in the body of a view (assuming you use jQuery, otherwise you include Prototype in your header and remove the :js => :jquery bit):

= fb_connect_javascript_tag
= init_fb_connect "XFBML", :js => :jquery
= fb_login_button

and in your corresponding controller:

before_filter :set_facebook_session
helper_method :facebook_session

Since the idea is that you want your app to post to the feed not only now, but also later, you need to store the connection data, once connected. So you need to either make a model for this, or to include the necessary data in your user model. Let’s assume in this post that i make a model FacebookUser.
The model, in any case, needs to contain following data

t.integer :facebook_id, :limit => 20, :null => false
t.string :session_key

A way to save this is to make sure that on return from facebook (ie when the session is set) the session and user id data are saved away.
In the model, let’s first make a convenient method (this is copied pretty much from the pragmatic programmer’s facebook booklet)

  def self.for(facebook_id,user,facebook_session=nil)
    returning FacebookUser.find_or_create_by_facebook_id(facebook_id) do |fb_user|       fb_user.update_attributes(:user_id => user.id)
      unless facebook_session.nil?
  def store_session(session_key)
    if self.session_key != session_key

Then in the facebook developer application, and the return url of connect needs to be set to the url you want used. Say: http://www.mydomain.com/facebook
which you then declare in your routes.

When this URL is accessed, make sure the following is called, to store your facebook data away.
self.fb_user = FacebookUser.for(facebook_session.user.to_i,current_user,facebook_session)
and in corresponding view, show the user the fact that now, he’s logged in, testing on the presence of the facebook_session (if facebook_session).

Test. But, unfortunately, that’s not the only requirement: updating the status is an ‘extended permission’ in facebook, that is, you need to ask the user pretty please.
How ? Well, in the same action of the controller, you can add this little bit of code:
@permission_dialog = !status_updates_allowed?
and this method corresponds to an FQL query (yes, seriously, they’ve got a query language, too)

def status_updates_allowed?
  res = facebook_session.fql_query("select status_update from permissions where uid == #{facebook_session.user.uid}")
  if res.join =~ /status_update1/
    return true
    return false

This basically asks whether the permission was already granted or not.
Then, include the following in your view:

<%- if @permission_dialog %>
<script type="text/javascript">
    FB.Connect.showPermissionDialog('status_update', function(accepted) { window.location.reload(); } );
<% end %>

This makes sure that when the action is carried out, a second dialog box is shown to the user, asking it to grant status_update to your app. It’s not shown if the permission was already granted. I added some conditional bits in my view, too, to tell the user what’s going on.

When this is done, you should have enough to work with. I added a variation of the above to allow the user to update his facebook data, change to a different facebook user, or simply log out and remove his data completely.

Anyway: now you have the data you need to make status updates. At appropriate moments, recreate the facebook session, and do the update, as follows:
recreate session: add in your model:

def facebook_session
  @facebook_session ||=
  returning Facebooker::Session.create do |session|
    # facebook sessions are only good for 1 hour
    session.secure_with!(session_key, facebook_id, 1.hour.from_now)

and in your application, where you need the update:

facebook_session = fb_user.facebook_session

There, that’s it ! Your application will now be able to update/pollute the user’s status at will ! Yay.


3 Responses

Subscribe to comments with RSS.

  1. Richard Ramsden said, on August 28, 2009 at 12:32 am

    Thank you! 🙂

  2. jpemberthy said, on November 23, 2009 at 8:08 pm

    Thanks! keep up the good work!

  3. Johnny said, on February 20, 2010 at 10:51 pm

    Thanks so much. This was a huge help.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: