Integrating Facebook into your Catalyst application

In this article I want to try to give you a small overview of what is it about Facebook in general, and also about how you can easily make a real Facebook application, and some hints about how you integrate Facebook into your website (for this part you dont actually need Catalyst, but I want to cover it for the overview)

A small overview of Facebook

To understand what you want from Facebook, you must first see what Facebook offers you.

Facebook themself give an overview of all this on the following Facebook Developers Page. For you as Catalyst developer, we can split them into 2 relevant parts:

The first is the pure website integration of Facebook elements, which is covered by the Social Plugins and the Facebook for Webpages guides on Facebook Developers.

The second is the usage of the APIs of Facebook. Over this way you can read or modify the Facebook data. Facebook uses here three for us relevant access ways: Graph API, Facebook Query Language and the soon hopefully outdated Old REST API.

Integration

Lets play through some cases and explain what you need todo for making them happen.

Adding a "Like" button

For the like button and many others of the Social Plugins, you dont even need an account or application registered on Facebook. The only thing, you need todo is adding the specific iframe. In the past, you was also able todo this via FBML, but this is official deprecated and will be dropped by Facebook at some point. It misses features and will not get new ones.

The iframe solution would look like this inside your Template::Toolkit Catalyst::View::TT template for any page (best written in one line):

  <iframe src="http://www.facebook.com/widgets/like.php?href=[% c.uri_for | uri %]"
    scrolling="no" frameborder="0"
    style="border:none; width:450px; height:80px"></iframe>

You could put this into facebook/like.tt and always put it somewhere on all pages where you want a like button with:

  [% INCLUDE facebook/like.tt %]

You can finetune the values for it, see more details on the Like Button Page.

Getting deeper, become an application

Many social plugins require you to be a real Facebook application. This way provides you with an application id, and also gives you the way to manage the content produced by this plugins, for example if you like to integrate the Comments of Facebook.

At first you must add an application to your Facebook acount, which you now need for the further integration. You can do this on your Applications page. If you want to add a new application you will be forced to authenticate yourself with your mobile number, or if this doesn't work, with your credit card number. Facebook will not charge you anything. Sadly on many mobile networks the short message sent by Facebook isn't received, so it could be that it never works for you and you must validate with your credit card number.

After you added your application with the Set Up New Application button on the Applications page, you will be pushed to the setup of the application. You should go there to Web Site and give a Site URL and a Site Domain. For example you would give www.example.com as Site URL and example.com as Site Domain. With this setup you will be able to use this application also on otherservice.example.com, if you start splitting up. Of course its also not bad to fill up the About section of the setup.

Now you should go Back to My Applications for fetching the informations you later need for the further integration. Best is you let this page open, so that you always can copy and paste what you need.

Integrating Catalyst::Model::Facebook

The best way to now use this application informations in Catalyst is Catalyst::Model::Facebook. Not just, cause I made it ;), cause its wrapping around Facebook, which is really more a wrapper for all existing Facebook solutions on CPAN. With a little spice which will help us in the following steps.

For making the Model in Catalyst you need to use the create command of your application, after installing Catalyst::Model::Facebook:

  script/myapp_create.pl model MyFacebook Facebook APPLICATION_ID_FROM_FACEBOOK API_KEY_FROM_FACEBOOK APPLICATION_SECRET_FROM_FACEBOOK

Where MyFacebook is the name of the Model you want to generate. If you want to use now the Facebook modules WWW::Facebook::API or Facebook::Graph. Best is you just install both, so that you never need to think about it deeper. Don't forget to also add them to your requirements of your application. The Facebook package itself doesnt require both of them, but throws an error if you try to use the method of them. I often forget that, cause both modules are normally installed in my environment :).

Warning: Please do not put the code of your application public if you create the model this way. Facebook don't want that you make your secret public, cause this makes it possible for others to make stuff on Facebook in behalf of your application, which in the long line comes down to your personal name. Best is to exclude the application ID and the application secret from outside, like environment and replace this in your MyFacebook model, like using $ENV{MYAPP_MYFACEBOOK_APP_ID} or in that direction and set them on the environment.

Using Catalyst::Model::Facebook independent

After you have installed your own Catalyst::Model::Facebook, you can now already talk to Facebook and fetch public available informations directly. For example you could do this in one controller:

  $c->stash->{gettys_facebook_profile} = $c->model('MyFacebook')->graph->query
    ->find(100001153174797)
	->include_metadata
    ->request
    ->as_hashref;

And later in your template:

  [% gettys_facebook_profile.name %]

And you will get Torsten Raudssus, which is the name of my Facebook Profile. The usage of include_metadata adds some more information, also a longer description about every field that you are getting from the profile. You should not use this in production later, so that you spare resources on the request.

For more informations what you can do with the Graph API, you could checkout Facebook::Graph and the informations on the Facebook Graph API Documentation.

Integrating Facebook Javascript SDK for the advanced Social Plugins

Now we also need to integrate the Facebook Javascript SDK, for having the possibility to bind the Facebook login to our application and also for the other more advanced Social Plugins, like comments and discussion boards.

You need to integrate the following snippet on top inside the <body> tag of your structure template:

  <div id="fb-root"></div>
  <script src="http://connect.facebook.net/en_US/all.js"></script>
  <script>/* <![CDATA[ */

    FB.init({
      appId  : '[% c.model('MyFacebook').app_id %]',
      status : true, // check login status
      cookie : true, // enable cookies to allow the server to access the session
      xfbml  : true  // parse XFBML
    });

  /* ]]> */</script>

Don't put the JavaScript include in the <head> of your HTML, you will get into problems, just add it like Facebook suggests. Of course, you can use other locales, if Facebook offers them. Just test it out with replacing en_US with your language locales definition (or the one the user has choosen for use on your webpage).

The FB.Event.subscribe will be used to reload the page when the user has logged in using Facebook. You can of course make other stuff here, but this is for the beginning the most easy solution. We will integrate the login in the next step.

If you want to get more debugging informations out of the Javascript SDK, you can use http://static.ak.fbcdn.net/connect/en_US/core.debug.js as the javascript include, but this one is only available in en_US locale.

For more detailed information about the integration you can checkout the Javascript SDK Documentation.

Adding the login button to your page

If you now want to go a step further, you can now make a login button for Facebook on your page. Beside that you actually know which Facebook user is on your page, you can also now make API requests on behalf of the user, which means that you are using the Facebook database depending on the rights the user gave you like the user would do it. This can also give you more information, cause you access the Facebook API with the rights of the user.

Generally its a good advice to try as much requests as possible on behalf of a user so that Facebook doesn't see your application as a kind of information leaker.

The implementation itself is now a bit of a problem in the current state of Facebook. Technical you only get official good documentation, which uses FBML, but on the other side on the FBML page you get the information that you should use the Javascript SDK. Interesting is also stuff like Custom User Registration, which allows you to let Facebook store extra fields the user most give on your registration process. It can be integrated over a simple iframe.

So I made up a solution that works, and shows you a bit of the concept, and also gives you a good base to go on with your own way. You definitly should come up with something more clear for yourself :). I use the help of jQuery in this example, cause we need some click events, and the usage of onclick, would make me seriously sick. Lets make a very simple HTML structure for this:

  <div class="header">
    [% IF c.model('MyFacebook').uid %]
      You are logged in with uid [% c.model('MyFacebook').uid %]
    [% ELSE %]
      You are not logged in, who the hell are you?
    [% END %]
  </div>
  <div id="login">
    [% IF c.model('MyFacebook').uid %]
      LOGOUT
    [% ELSE %]
      LOGIN VIA FACEBOOK
    [% END %]
  </div>

Also we extend our FB.init JavaScript block with the following JavaScript code:

  FB.Event.subscribe('auth.sessionChange', function(response) {
    // do something when the user logs in or logs out
    // for a start a page reload is the best solution ;)
    window.location.reload();
  });

  $(function(){

    $('#login').click(function(){
      if (FB.getSession()) {
        FB.logout();
      } else {
        FB.login();
      }
    });

  });

Testing your application in development stage

So for testing your application without touching the live information, you need a bit more stress. I suggest to register 2 applications at Facebook and just use in the development environment the different application id and secret. This way you can make a development database, and use test accounts on Facebook without risking to make your live application dirty. Especially the management of the tokens you get from the Facebook users and the access rights they give to you, could make problems. Even tho i must say, I'm open for good suggestions and tricks for the development stage, just visit me on IRC, if you want to talk deeper about this.

And there is more...

There are much more possibilities that you can do with Facebook in context of Catalyst. Soon I will make a HowTo for Canvas applications with Catalyst, you should follow the Facebook package development to see when its there. Its available on https://github.com/Getty/p5-facebook. A sample Catalyst project where you just need to replace the Facebook application API key, App id and secret with your own, you can get from https://github.com/Getty/p5-catalystadvent-facebook.

Just join us on irc.perl.org in the channel #facebook or contact me on Facebook http://www.facebook.com/raudssus ;).

Have fun and MERRY CHRISTMAS! :).

See also

Author

Torsten Raudssus <torsten@raudssus.de> http://www.raudssus.de/. You can find me on irc.perl.org #facebook or #catalyst as Getty.