Facebooker is a rails plugin that wraps the Facebook REST API's. If you are not a facebook developer, then learning how to use facebooker can be somewhat of a bear. To make things easier there are three links that you should first look at when you have any issues.
- Facebook Developer Tools: You will need to be logged into facebook to see this site. The developer tools section contains important API's as well as tools and documentation to help you use facebook connect.
- Restfull Authentication & Facebook Connect: This is a great tutorial about how to hookup the two plugins and get an out of the box simple authentication system integrated with Facebook Connect.
- Facebooker Home Page: This link takes you to the facebooker documentation. Some of the links are outdated but the API appears to be updated.
For this post we are going to assume that you are somewhat familiar with facebook and the facebook connect concepts. If you are not take a couple of minutes and read up on the links mentioned above.
Feed stories are published using the Facebooker::Rails::Publisher class which works very smilier to the way that action mailer works. First you define a publisher class extending from the facebooker Facebooker::Rails::Publisher class. Then you create different templates for one line, short story, and full post feeds to publish your content. Finally you then call your actions from your model and if you have a valid facebook session you will see something like the following:
We are going to show you how you publish a simple short story feed in three simple steps.
Step 1. Define your story templates and actions within your new publisher class. To do this create an new model for your application and have it inherit from the Facebooker::Rails::Publisher class as you see below:
class FacebookPublisher < Facebooker::Rails::Publisher
# Add template and actions here
end
Now that you have your class you need to define your templates for publishing the stories. The naming convention for templates is the name of the action followed by an _template. If the concept of templates and feed stories are foreign to you, I would recommend checking out the Feed Template Tool from the facebook developer site. This tool will takes you through the steps of defining the templates and acts as a great primer for the terminology and definition of a feed template. Once you are familiar with the concepts of feeds creating your own will be a snap. For our example, below is the template for publishing a battle on 2contenders.com:
def publish_battle_template
one_line_story_template "{*actor*} posted a new 2contenders battle: {*battle_title*}"
short_story_template "{*actor*} posted a new 2contenders battle", "<a href='{*battle_url*}'>{*battle_title*}</a>: {*question*}"
end
Once you have the template defined you will create the action to populate the data within the template. Your method will need to create a couple of the key elements such as the type of action, the person who is sending the action and finally the data to be used by the template. There are a couple of different types of actions available and I would suggest referring the the facebooker documentation for more information. In this case we are going to publish a user action. The from user should be retrieved from the current facebook session. The data section is a hash of elements to match your variables within the feed template. Below is the code to fill in the feed template for our example:
def publish_battle(battle, contender1, contender2, facebook_session)
send_as :user_action
from facebook_session.user
data :images=>[image(battle.comment_image(contender1.id),contender1.plain_url),image(battle.comment_image(contender2.id),contender2.plain_url)], :actor => facebook_session.user.first_name, :battle_title=>battle.show_title, :battle_url=>battle.plain_url, :question=>battle.question
end
As you might have noticed in the data we reference the data element "images" but we don't use that element in our feed template. The "images" data element is inherent to all feed templates and takes an array of image objects. If you are going to be passing images to your template you need to make sure this is the first element in the data hash. Placement is important and if the images element is not first it will be ignored.
Now that we have introduced the different elements of our publisher, your final class should look like the following:
class FacebookPublisher < Facebooker::Rails::Publisher
def publish_battle_template
one_line_story_template "{*actor*} posted a new 2contenders battle: {*battle_title*}"
short_story_template "{*actor*} posted a new 2contenders battle", "<a href='{*battle_url*}'>{*battle_title*}</a>: {*question*}"
end
def publish_battle(battle, contender1, contender2, facebook_session)
send_as :user_action
from facebook_session.user
data :images=>[image(battle.comment_image(contender1.id),contender1.plain_url),image(battle.comment_image(contender2.id),contender2.plain_url)], :actor => facebook_session.user.first_name, :battle_title=>battle.show_title, :battle_url=>battle.plain_url, :question=>battle.question
end
end
Step 2. Now that our template class has been created you have completed 90% of the work involved in publish a feed story to facebook. One of the things that the facebooker plugin does behind the scenes is submit and register our feed template with facebook. Once the template has been registered it is stored in the database for retrieval. In order to do this you will need to create a new table in your database to store the templates. Add the following database migration to your rails application:
class CreateFacebookTemplates < ActiveRecord::Migration
def self.up
create_table :facebook_templates, :force => true do |t|
t.string :template_name, :null => false
t.string :content_hash, :null => false
t.string :bundle_id, :null => true
end
add_index :facebook_templates, :template_name, :unique => true
end
def self.down
remove_index :facebook_templates, :template_name
drop_table :facebook_templates
end
end
Step 3. Finally now that you have created your publisher and the database table to hold the registered templates you need to call the template from your controller. As we mentioned before the syntax for calling your method is very similar to the way you invoke an action mailer method. To call your method you simply add the word "create_" in front of the method call. For our example you would use the following syntax to invoke the publish_battle method:
flash[:user_action_to_publish] = FacebookPublisher.create_publish_battle(@battle, @battle.contenders[0], @battle.contenders[1], session[:facebook_session])
The returned value is the FBXML that is needed to call this action via the Facebook API. Since this is done through javascript you will need to add a section to your site layout to display the new content. In our case we only wanted this to be called after your battle was initially created so we used the flash[] mechanism as a way to invoke our content. To do this add the following code to the head section of your site layout:
<%= fb_connect_javascript_tag %>
<% init_fb_connect "XFBML","Api" do %>
<%= fb_user_action(flash[:user_action_to_publish]) if flash[:user_action_to_publish] %>
<% end %>
Congratulations you did it. Hopefully you found this post to be useful and you are well on your way to publishing content back to facebook. In our next post we are going to talk about how to publish the fb_user_action in response to an AJAX call.
Nice little write up! I've wasted a sad amount of time with the outdated Facebooker rdocs and the otherwise excellent Peepcode materials. This is just what I needed!
Posted by: twitter.com/greghaygood | September 24, 2009 at 05:59 PM
This is extremely helpful. There is very little information out there on how to get this to work.
Posted by: Alexander Kahn | October 09, 2009 at 03:53 PM
I should follow up to say that I hope you do follow up and do more posts on this topic, like you said you would in the last paragraph.
Posted by: Alexander Kahn | October 09, 2009 at 03:54 PM
hey chris ,i find ur post very usefull in my application i done all the steps it gives me one facebook publish popup but when i click on publish button it gave me this error "The application you are using returned an invalid response"
can u tell me what is wrong with application
thanks
Pravin
Posted by: Pravin | February 09, 2010 at 04:41 AM