Skip to content

awexome/doesfacebook

Repository files navigation

DoesFacebook

Lightweight gem enables your Rails application to quickly and simply integrate with Facebook, while also providing configuration and convenience methods for Facebook app developers.

Install

DoesFacebook is designed to work with Rails applications. To get started, add doesfacebook to your Gemfile:

gem "doesfacebook"

DoesFacebook is built against Rails versions 3.2 and higher, which it requires at runtime. In development, the additional gem requirements include bundler, jeweler, and rspec.

Configure

To work with the Facebook API and handle Canvas application requests, you must specify configuration details for the Facebook applications that your Rails application will support in an initializer file. This file allows you to use a simple DSL to define each application.

To get started, you can generate a boilerplate initializer in your directory by running the included generator:

rails generate does_facebook:config

This generates a file doesfacebook.rb in your config/initializers directory containing a sample app definition and a commented section containing optional selector behavior.

Facebook Applications

DoesFacebook supports any number of Facebook applications within a single Rails application. Facebook applications are created and defined within the Facebook Developers Dashboard.

You can customize the configuration for any number of supported applications in the initializer file. A typical case is to have a Facebook application for each environment in which your Rails application will run (development, staging, production, etc.), but you are not tied to this convention and can define any number of Facebook applications your Rails application will support.

A sample Facebook application definition:

# Support a Facebook application with my Rails app:
config.add_application(
  id: 123456789012345,                                  # <= "App ID" in FB dashboard
  secret: "abcdefghijklmnopqrstuvwxyzABCDEF"            # <= "App Secret" in FB dashboard
  namespace: "your_app_namespace",                      # <= "Namespace" in FB dashboard
  canvas_url: "http://your.dev.server.com/and/path",    # <= Under "App on Facebook"
  secure_canvas_url: "https://secure.dev.server"        # <= Under "App on Facebook"
)

The example above shows a declaration with the required keys defined. App ID, Secret, Namespace, and the callback URLs are used to handle incoming requests from Facebook, parse and validate POST parameters from Facebook, and more.

Add additional applications by adding subsequent config.add_application calls to your initializer.

You can define, for your reference and remote configuration purposes, any configuration key for your application specified in the documentation on developers.facebook.com.

Matching Apps with Requests

By default, the canvas_url and secure_canvas_url keys of your configured applications will be compared against incoming requests to match each request with a single Facebook application.

For example, if a request comes from the Facebook canvas to “dev1.com/abe” and strikes your application, DoesFacebook will match this request with the Facebook application containing a canvas_url that is a part of the request URL “dev1.com/abe”. If the request comes in over SSL/HTTPS, DoesFacebook will compare against the secure_canvas_url key of your applications.

As a Proc, this default selection method is defined like so:

app_selector = Proc.new() do |request, apps|
  apps.find do |a|
    callback_path = request.ssl? && a.supports_ssl? ? a.secure_canvas_url : a.canvas_url
    request.url.match(/^#{callback_path}.*/)
  end
end

You can, however, override this selector logic. In the configure block within your initializer file, you can make a call to the app_selector method to override this logic with a custom Proc operating on the request and list of defined applications. Here’s an example call:

# Select the active Facebook application based on subdomain:
config.app_selector = Proc.new() do |request, apps|
  apps.find do |a|
    request.domains.last.match(/_dev$/) ? a.namespace.match(/_dev$/) : a.namespace.match(/_pro$/)
  end
end

You can change this, too, to seek in your database for an app definition, or elsewhere. You are not limited to solely the list of defined applications.

Usage

To use DoesFacebook in a given controller in your application, you simply add the following invocation to your controller:

does_facebook

Now, with each incoming request to this controller, DoesFacebook will add the following functionality:

  • Convert POST requests from (apps.)facebook.com into GET requests to preserve RESTfulness in your app

  • Select the proper Facebook application from your configuration

  • Validate the signed_request parameter Facebook sends to your application to ensure the request is from Facebook

  • Parse the contents of the signed_request (user, brand page, user auth token, etc.) and make them available to your controller as fb_params

  • Provide controller extensions which give you access to Facebook shortcuts in your controller

  • Include helpers in your views that allow you quick access to configuration

Controller Extensions

Within your controller, you can now access fb_app and fb_params to view the configuration of the currently active application and the parameters passed by Facebook as part of the signed_request. These are available in your regular controller actions and before filters.

Also, you will gain convenience methods url_for_canvas and redirect_to_canvas, which behave just like their non-canvas Rails equivalents, but ensure that the URL given or redirection provided includes the properly-formatted “http(s)://apps.facebook.com/namespace” convention and take place in the top browser frame. These are useful for any end-user activity that requires typical redirects or URL generation.

View Helpers

Within your views, you will now have access to a wealth of helpers that provide shortcuts to configuration and other Facebook features:

  • fb_app - Full configuration of the active Facebook application in use

  • app_id - The active application’s “App ID”, required by some FB JavaScript methods

  • app_namespace - The active application’s “namespace” configuration value.

  • app_canvas_url - The full URL to the active application’s canvas (e.g., apps.facebook.com/myapp)

You also receive a few beneficial link methods:

  • url_for_canvas - Like the standard url_for, but ensures the endpoint is in the Facebook canvas

  • link_to_canvas - Use as you would the regular link_to helper; generates links to the canvas and properly targets the link to “_top” frame to keep app within canvas and not break into your iframe

Quick Facebook helpers for representing users and bootstrapping your application’s JS SDK implementation are also provided:

  • profile_pic - Builds out an image tag containing the profile picture of the specified user. Pass type and basic image_tag options along in the opts hash to customize.

  • fb_init - Bootstrap an FB JS SDK implementation with this call, which will automatically inject the JS SDK with proper values for appId as well as the proper browser-compatibility channelUrl file.

Display a profile photo of a user with Facebook ID 1234567890 in a view with some view customizations:

<%= profile_pic 1234567890, :type=>"small", :style=>"border: 2px solid blue;" %>

Complete a basic invocation of fb_init from your layout:

<%= fb_init() %>

And you will, in effect, be generating this properly-formed JS SDK boot in your layout:

<!-- Facebook JS SDK -->
<div id="fb-root"></div>
<script>
  window.fbAsyncInit = function() {
    FB.init({"appId":123456789012345,"channelUrl":"/channel.html","status":true,"cookie":true,"xfbml":false});
  };
  (function(d){
     var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
     if (d.getElementById(id)) {return;}
     js = d.createElement('script'); js.id = id; js.async = true;
     js.src = "//connect.facebook.net/en_US/all.js";
     ref.parentNode.insertBefore(js, ref);
   }(document));
</script>

You can override any of the standard options to FB.init by passing values for the keys you wish to change in the opts hash to fb_init.

If you pass a block to fb_init, you can include additional JavaScript within the window.fbAsyncInit function. This can be useful to attach Facebook listeners or handlers to events such as edge.create or similar. You can learn the nitty-gritty details of JS SDK initialization at developers.facebook.com/docs/reference/javascript/

Copyright 2011-12 Awexome Labs, LLC awexomelabs.com facebook.com/AwexomeLabs twitter.com/awexomelabs

About

Lightweight gem enables your Rails application to quickly and simply integrate with Facebook

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages