Peepcode Facebook 2

download Peepcode Facebook 2

of 67

Transcript of Peepcode Facebook 2

  • 8/8/2019 Peepcode Facebook 2

    1/67

    by hane Vitarana and avid Clements

    $9

    Hooking into the network

    Rails onFacebook

  • 8/8/2019 Peepcode Facebook 2

    2/67

    2

    ails on acebook

    2008 hane Vitarana and avid Clements

    very eort was made to provide accurate inormation in this document. owever,

    neither the authors nor opunky Corporation shall have any liability or any errors in

    the code or descriptions presented in this book.

    his document is available or U$9 at eepCode.com (http://peepcode.com). Group

    discounts and site licenses can also be purchased by sending email to peepcode@

    topunky.com.

    "ails" and "uby on ails" are trademarks o avid einemeier ansson. "ace-

    book" is a trademark o acebook. ther names are mentioned without any intention

    o inringement on the trademark.

    http://peepcode.com/http://peepcode.com/
  • 8/8/2019 Peepcode Facebook 2

    3/67

    contents

    Introduction 5

    Why Facebook?

    Social Data

    The Facebook Platform 7

    The Facebook API

    FBML

    FBJS

    Getting Started 15Facebook Signup

    Facebooker

    Configuration

    Hello World

    Development Environment

    Facebook Authentication 23

    Verifying Request

    Authenticating a User

    Getting Social Data 26

    User and Friend Data

    Photos

    Events

    Anatomy of an App 28

    Integration Points

    The Profile Page

    New Profile Application Tab

    News Feed and Wall

    Notifications

    Emails

    Invitations

    Info Section

    New Profile Publisher

    Testing 52

    Functional tests

    Test accounts

    Ruby Footprints App 54

    Routes

    Models

    Advanced Topics 58FBML and Image Caching

    Bebo

    Appendix: Terminology 62

    Appendix: Models 63

    The AuthorsCredits

    Revisions

  • 8/8/2019 Peepcode Facebook 2

    4/67

    4

  • 8/8/2019 Peepcode Facebook 2

    5/67

    5

    Introductionchapter 1

    his book assumes that you know how to develop ails applications

    and have a basic understanding o acebook, or at least have setup a

    acebook account and played around with it a bit. ccasionally you

    will nd links to the acebook wiki on various topics; this is because

    the acebook development platorm is constantly changing and the

    wiki is the best place to get the latest inormation about what is going

    on with a particular eature. hese links will look like this: eveloper

    Wiki ink (http://wiki.developers.facebook.com/index.php/Main_Page).

    hroughout the book, we will be citing examples rom a sample appli-

    cation called uby ootprints. uby ootprints is included with this

    book and also available on Gitub (http://github.com/digidigo/ruby_footprints/

    tree/master). We will keep this application up-to-date with acebook APIchanges and anyone is ree to contribute to it.

    Why Facebook?eople are spending an increasing amount o time on social net-

    works (http://lsvp.wordpress.com/2007/07/23/follow-up-on-top-social-networks-by-

    engagement). he ability to engage online with riends is slowly replac-

    ing more traditional orms o entertainment, like watching television.

    pplications on acebook are popular because access to them is

    super easy rom acebook. pps are discovered by getting invita-

    tions to them rom your riends. ince people trust their riends more

    than random people on the web, they are more likely to try out your

    app. urthermore, apps on acebook dont require separate logins.

    Users are more likely to use an app i they dont have to sign up yet

    again on another site. he social elements o acebook apps are also

    responsible or their popularity. t gives people a chance to interact

    with their riends in ways that werent possible beore. laying games

    http://wiki.developers.facebook.com/index.php/Main_Pagehttp://github.com/digidigo/ruby_footprints/tree/masterhttp://github.com/digidigo/ruby_footprints/tree/masterhttp://lsvp.wordpress.com/2007/07/23/follow-up-on-top-social-networks-by-engagementhttp://lsvp.wordpress.com/2007/07/23/follow-up-on-top-social-networks-by-engagementhttp://lsvp.wordpress.com/2007/07/23/follow-up-on-top-social-networks-by-engagementhttp://lsvp.wordpress.com/2007/07/23/follow-up-on-top-social-networks-by-engagementhttp://github.com/digidigo/ruby_footprints/tree/masterhttp://github.com/digidigo/ruby_footprints/tree/masterhttp://wiki.developers.facebook.com/index.php/Main_Page
  • 8/8/2019 Peepcode Facebook 2

    6/67

    6

    with your riends, comparing scores on quizzes, and throwing sheep

    at old high school buddies, are replacing traditional avenues o com-

    munication, like email.

    t is important to realize that acebook is replacing other orms o

    entertainment. acebook is a place where people come to play. pps

    that do well on acebook are those that acilitate social interaction.

    clone o an oce application, like icrosot Word or instance, would

    not do well on the platorm.

    Social Dataany applications can be built simply based on knowing who a per-

    sons riends are. ut most o the data you see on a persons prole

    can be used as part o your app. acebook does not allow you to

    store any user data besides user s, but you can incorporate userdata in real-time in your app. or instance, Video ukebox (http://apps.

    facebook.com/jookbox) scans your avorite music to nd music videos on

    Youube, and allows you to embed them on your prole.

    http://apps.facebook.com/jookboxhttp://apps.facebook.com/jookboxhttp://apps.facebook.com/jookboxhttp://apps.facebook.com/jookbox
  • 8/8/2019 Peepcode Facebook 2

    7/67

    7

    The Facebook Platformchapter 2

    acebook web application is hosted on your own server, just like a

    regular ails application. he application runs within acebook, but

    requests are proxied via acebook to your server. he diagram below

    illustrates this interaction:

    the FaceBooK reQUest/response seQUence

    User fFaceBooK raILs app

    fFaceBooK

    raILs app

    fFaceBooKUser

  • 8/8/2019 Peepcode Facebook 2

    8/67

    8

    ll acebook API responses have extra acebook-specic parameters

    appended to them. hese parameters contain inormation that will

    subsequently be used to communicate with the acebook API.

    note very acebook API request is a POST

    he acebook latorm also allows you to create desktop applications

    that make use o acebooks social data. owever, since were talk-

    ing about ails and acebook, this book will only cover how to make

    acebook web applications.

    The Facebook APIhe acebook API is a REST web service that makes available social

    data about users, and allows you to publish back to acebook. heAPI is documented at the wiki (http://wiki.developers.facebook.com/index.php/

    Main_Page). uckily, we do not have to use this API or parse the XML

    responses manually. Using a uby library like acebooker (https://ruby-

    forge.org/projects/facebooker) can greatly simpliy the task o developing a

    acebook application.

    FBMLFBML is an HTML-like language developed by acebook to make view

    development easier and help your app conorm to the look and eel

    o acebook. FBML also provides many convenience tags to do com-

    mon tasks like displaying user names and constructing riend selec-

    tors. ome uby libraries, such as acebooker, provide ails helpers

    that wrap FBML tags to make the development experience more

    ails-like, and absolve the developers rom learning the HTML-like

    FBML syntax, which ails developers have long orgotten by now.

    http://wiki.developers.facebook.com/index.php/Main_Pagehttp://wiki.developers.facebook.com/index.php/Main_Pagehttps://rubyforge.org/projects/facebookerhttps://rubyforge.org/projects/facebookerhttps://rubyforge.org/projects/facebookerhttps://rubyforge.org/projects/facebookerhttp://wiki.developers.facebook.com/index.php/Main_Pagehttp://wiki.developers.facebook.com/index.php/Main_Page
  • 8/8/2019 Peepcode Facebook 2

    9/67

    9

    Tg

    he countless FBML tags are all described on the developers wiki

    (http://wiki.developers.facebook.com/index.php/FBML). robably the most useul

    tags provided by the platorm are the ones that allow an application

    to render a persons name and/or prole picture while only supplying

    the o the person. his is particularly useul when displaying inor-

    mation about riends o the application users. ere is list o some othe more useul helper methods:

    fb_name(uid, options) With this tag you can not only render

    the users name but also make it possessive, refexive and linked to

    the users prole

    fb_pronoun(uid, options) his also allows or the possessive,

    refexive and objective orms o the pronoun

    fb_prole_pic(uid, options) You can control the size o the

    prole thumbnail and make it a link to the users prole

    fb_comments(comment_id, options) his allows the application

    to provide a comment section without having to store any o the

    data

    fb_error(message) isplays a acebook-styled error message;

    there are also explanation and success messages

    note here are many tags that can be useul in dierent contexts.

    ome provide fow control, others are or specic acebookeatures and still others are used to embed media content

    F

    tandard rails helpers or web orms work as expected on acebook

    Canvas pages. owever, there is a special orm helper to render a

    acebook-styled orm, called an editor. his set o helpers ends up

    rendering custom FBML tags. here are, however, a

    http://wiki.developers.facebook.com/index.php/FBMLhttp://wiki.developers.facebook.com/index.php/FBML
  • 8/8/2019 Peepcode Facebook 2

    10/67

    10

    couple o gotchas with this orm helper. he rst is that the orm is

    rendered in a table and as such it can be dicult to style it in certain

    ways. he second is that the FBML parser seems to strip out under-

    scores rom the names o the eld elements. o text_eld(:users_

    friend, :name) will show up as params[:usersfriend][:name] .

    ere is an example o a facebook_form_for call:

    editor.rhtml

    create_poke_path) do |f| %>message %>

    FBJS

    Ovvw

    FBJS is acebooks approach to allowing developers to use avascript

    in their applications. nstead o orcing developers to use rames or

    all their dynamic content, acebook creates a avascript andbox by

    limiting the abilities o the avascript nvironment, parsing all appli-

    cation avascript, and scoping the methods and variables by prex-

    ing variable names with the application . lso, note that all DOM s

    get changed in this way as well. or example:

    function foo(bar) { var obj = {property: bar}; return obj.property;}

    becomes

    function a12345_foo(a12345_bar) {

  • 8/8/2019 Peepcode Facebook 2

    11/67

    11

    var a12345_obj = {property: a12345_bar}; return a12345_obj.property;}

    call to it would end up looking like:

    var a12345_result = a12345_foo(some_thing)

    acebook also changes many o the core avascript methods used

    or inspecting and interacting with the DOM. he entire list can be

    ound on the wiki at FBJSacebook evelopers Wiki (http://wiki.develop-

    ers.facebook.com/index.php/FBJS). any o these method changes involve

    simply adding the prex get to the method name. o className

    becomes getClassName and id becomes getId, etc.

    T-Py L

    ecause o the way acebook parses all incoming avascript, third-

    party avascript libraries do not work within acebook FBML pages.

    acebooker developers have started re-creating pieces o the ro-

    totype codebase in order to more easily support some o the ails

    avascript elper methods, most notably the jax helper methods.

    his is a moving target in the acebooker codebase and as o this

    writing$(element_id)

    andlink_to_remote

    andremote_forms

    are working when passing a DOM ID to update. RJS is not working

    and may not be able to work due to the absence o the eval method.

    AJAX

    acebook has two kinds o support or AJAX, ock AJAX and the

    ocal roxy. When using ock AJAX, acebook makes the call to

    your server on the browsers behal and the response then goes

    http://wiki.developers.facebook.com/index.php/FBJShttp://wiki.developers.facebook.com/index.php/FBJShttp://wiki.developers.facebook.com/index.php/FBJShttp://wiki.developers.facebook.com/index.php/FBJS
  • 8/8/2019 Peepcode Facebook 2

    12/67

    12

    through acebook, gets processed the same as all requests, and

    returns to the avascript callback. he callback can then either

    process JSO results or insert FBML by calling $(updated_div).

    setInnerFBML(data). When using the ocal roxy, you may opt

    to send requests directly to your server, but in this case you cannot

    use any o the acebook FBML tags in your response since acebook

    will not have the opportunity to parse them beore they reach the

    browser. his ocal roxy method uses a lash ack and requires

    that the lash lugin be installed. eer to the wiki, _ocalroxy

    (http://wiki.developers.facebook.com/index.php/FBJS_LocalProxy) or complete

    setup details. Currently acebooker does not have helper methods or

    the ocalroxy so you will have to roll your own AJAX.

    he current acebooker implementation or link_to_remote does

    not support javascript methods being called ater the request has

    completed, so uby ootprints rolls its own jax call using ock jax.

    t also uses the FBJS ialog class to create a conrmation dialogthat will eventually re o the request. ere is the code rom uby

    ootprints that grabs the riend to step on and sends it as an AJAX

    request. ter the request is complete it does some animation to

    notiy the user what was accomplished.

    function submitForm(varForm, url, div_id){try {

    //Grab the friend ID from the FORMname = varForm.serialize().friend_selector_name;

    friend_uid = parseInt(varForm.serialize().friend_to_step_on); if( friend_uid == undefined || friend_uid == 0 || isNaN(friend_uid) || name.length == 0) throwRangeError;

    //Confirmation Dialog sends request on Confirmdlg = new Dialog();dlg.showChoice(Confirm Request, Are you sure you want to step on + name + ? , Yes,

    No);dlg.onconfirm = function() {

    var ajax = new Ajax();ajax.responseType = Ajax.FBML;

    http://wiki.developers.facebook.com/index.php/FBJS_LocalProxyhttp://wiki.developers.facebook.com/index.php/FBJS_LocalProxy
  • 8/8/2019 Peepcode Facebook 2

    13/67

    13

    ajax.ondone = function(data) {// Replace FBML$(div_id).setInnerFBML(data);//Animate the updated div.obscure(highlight(revealDiv(div_id).checkpoint()).checkpoint()).go();

    };ajax.post(url, varForm.serialize());

    }}catch(err) {

    new Dialog().showMessage(Error,Something weird happened. Did you type in a friend?);}return false;}

    note he obscure, revealDiv and highlight methods are

    provided in the application.js le and are not directly a parto FBJS.

    A Ly

    acebook has actually released their animation library and, while it

    lacks the breadth o eatures o criptaculous, it does have a nice

    approach to animation by using method chaining. ere is a high-

    lighting animation example rom uby ootprints:

    Animation(document.getElementById(div_id).to(background, #FF00FF).duration(2000).checkpoint().to(background, #F7F7F7)

    he library uses tweening o SS attributes in order to get the job

    done. he above example takes 2 seconds to change the background

    to purple, stops or an instant, and then restores the background to

    acebooks standard grey. he library also provides support or hid-

  • 8/8/2019 Peepcode Facebook 2

    14/67

    14

    ing and showing elements, moving elements, and both deault and

    custom ease unctions. or a complete description, reer to the wiki at:

    FBJS/nimation. (http://wiki.developers.facebook.com/index.php/FBJS/Animation).

    http://wiki.developers.facebook.com/index.php/FBJS/Animationhttp://wiki.developers.facebook.com/index.php/FBJS/Animation
  • 8/8/2019 Peepcode Facebook 2

    15/67

    15

    Getting Startedchapter 3

    Facebook Signuphe way you manage your acebook applications is through an

    application created by acebook called eveloper. nstall the app by

    logging into acebook, going to the Get tarted age (http://developers.

    facebook.com/get_started.php), and clicking dd acebook eveloper ppli-

    cation (http://www.facebook.com/developers). ter you have this applica-

    tion installed you can create a new application by clicking the etup

    New pplication button. his will produce a orm page on which to

    submit your application settings. he settings or uby ootprints are

    included at the end o each step.

    http://developers.facebook.com/get_started.phphttp://developers.facebook.com/get_started.phphttp://www.facebook.com/developershttp://www.facebook.com/developershttp://developers.facebook.com/get_started.phphttp://developers.facebook.com/get_started.php
  • 8/8/2019 Peepcode Facebook 2

    16/67

    16

    Alii Nm: I

    q F

    .

    Cllbk R: T URL

    v g

    . F

    URL w

    v

    . M

    v g

    v .

    RAILS_ROOT/g.

    Cv Pg R:

    T q

    F

    w

    v

    w. P v

    . .

    C yu lii

    b ddd

    bk? A

    g YES

    w

    w

    .

    TOS R: E T

    Sv URL. T w w

    g g

    x g g

    F.

  • 8/8/2019 Peepcode Facebook 2

    17/67

    17

    crolling down, you will nd nstallation options or your application.

    C x 'W

    '

    P-Add R: T

    URL g

    . I

    Cv Pg URL:

    ://

    ../

    _

    Dvl Md:

    C x

    .

    Dful M, Dful Ai,

    d Dful Pfil x Clum

    P

    w. Y v

    w.

    Alii Dii: T

    w w

    w gv

    . I w

    A A Pg

    A D. M

    g w

    .

    Next you will congure various integration points or your application.

  • 8/8/2019 Peepcode Facebook 2

    18/67

    18

    Sid Nv R: T v

    g

    w

    ' .

    I g Cv Pg.

    Hl R: T

    x URL, F

    Cv g w ,

    FAQ .

    Pivy R: T w

    w w

    g

    v g. I

    F

    Cv g.

    Piv lli:

    T w v w

    g

    ,

    g g

    v.

  • 8/8/2019 Peepcode Facebook 2

    19/67

    19

    ter you save your application settings you will be taken to a sum-

    mary page that will have your API and ecret keys. ake these keys

    and place them into your facebooker.yml le. he uby ootprints

    facebooker.yml le looks like this:

    development:api_key: 921628d9d70f5e0b5887936802abe9e6

    secret_key: 77sEcRETsecretSECRET3ce96ccanvas_page_name: ruby_footprintscallback_url: http://rfootprints.shacknet.nu

    Facebookeracebooker is our acebook library o choice. acebooker goes to

    great lengths to abstract the XML-based acebook API calls, so you

    only have to be aware o pure uby objects. acebooker can be used

    as a gem or a ails plugin. preer to use it as a plugin, as it takes

    care o all the initialization needed to integrate the acebook API with

    ails.

    acebooker has recently moved the primary repository over to Gitub

    and you can install it in a ew ways. you are on ails 2.1 and have

    installed git, you can use script/plugin:

    script/plugin install git://github.com/mmangino/facebooker.git

    you are on an older version o ails but still have git installed, you

    can clone it to the vendor/plugins directory.

    cd vendor/pluginsgit clone git://github.com/mmangino/facebooker.git

  • 8/8/2019 Peepcode Facebook 2

    20/67

    20

    r, download the source directly rom Gitub (http://github.com/mmang-

    ino/facebooker) and unpack it into your vendor/plugins directory.

    note reerably we would be able to use iston to manage this

    plugin, but it does not currently support git. here are some

    workarounds but the ails community hasnt really settled on

    the correct approach yet.

    acebooker does its best to make acebook app development as

    close to regular ails app development as possible. he plugin mon-

    keypatches ails controllers to include everything you need to access

    acebook, via the facebook_session method.

    Configurationirst, generate a basic facebooker.yml conguration le using:

    rake facebooker:setup

    ill in your server ino appropriately. or example, i your public server

    is shanesbrain.net and it has port 4007 ree, then facebooker.yml

    will look like:

    development:tunnel:public_host_username: shanepublic_host: shanesbrain.netpublic_port: 4007local_port: 3000

    http://github.com/mmangino/facebookerhttp://github.com/mmangino/facebookerhttp://github.com/mmangino/facebookerhttp://github.com/mmangino/facebooker
  • 8/8/2019 Peepcode Facebook 2

    21/67

    21

    Hello Worldhis simple application will print ello ollowed by your rst name.

    hello_world.rb

    class Welcome < ApplicationController

    def index @first_name = facebook_session.user.first_name endend

    Hello

    n order to test this, you will have to set up a development environ-

    ment or deploy your application to acebook.

    Development Environmentdeally, you want to be able to test your app as you develop, like

    you would a normal ails app. imply running the ongrel develop-

    ment server will not suce, since that will not route requests through

    acebook. hankully, the uby community is proud to include smart

    people like van Weaver, who came up with a way to test acebook

    apps locally using a reverse SSH tunnel (http://blog.evanweaver.com/arti-

    cles/2007/07/13/developing-a-facebook-app-locally). here is no need to worryabout the details o setting it up, as acebooker provides rake tasks

    or completing the setup. s long as you have a public acing server

    with available ports, you can set up a reverse tunnel to your local

    machine. acebook will communicate with your public server as i it

    were a normal acebook app, while your server routes the requests to

    your machine.

    tart the tunnel with:

    http://blog.evanweaver.com/articles/2007/07/13/developing-a-facebook-app-locallyhttp://blog.evanweaver.com/articles/2007/07/13/developing-a-facebook-app-locallyhttp://blog.evanweaver.com/articles/2007/07/13/developing-a-facebook-app-locallyhttp://blog.evanweaver.com/articles/2007/07/13/developing-a-facebook-app-locally
  • 8/8/2019 Peepcode Facebook 2

    22/67

    22

    rake facebooker:tunnel:start

    You may check the status o the tunnel with:

    rake facebooker:tunnel:status

    you dont have a public acing server with open ports, you can try a

    service called unnlr (http://tunnlr.com).

    [Tunnlr is] a orwarding service that you can use at home, at

    Starbucks, or anywhere you have an Internet connection

    It securely connects a port on your local machine to an open

    port on our public server. Once you start your Tunnlr client,

    the web server on your local machine will be available to

    the rest o the world through your special Tunnlr URL.

    http://tunnlr.com/http://tunnlr.com/
  • 8/8/2019 Peepcode Facebook 2

    23/67

    23

    Facebook Authenticationchapter 4

    he acebook API uses a shared secret called the secret_key to

    authenticate all communications between your application and the

    acebook API. t is implemented by concatenating all the request

    parameters together with the secret_key and running a hashing unc-

    tion on the result. acebooker gives your application high level access

    to the authentication and permissions mechanisms provided by the

    acebook latorm.

    Verifying Requestven i your application does not require any special permissions

    rom its users, it is still a good idea to veriy that the incoming requesthas not been tampered with. o accomplish this add a beore lter or

    set_facebook_session to your ApplicationController. his call

    will raise an Exception i the request is not valid. ter a successul

    call to set_facebook_session the instance variable @facebook_

    session will be set and session[:facebook_session]will be stored.

    note acebooker overrides the rails ession Key in order to retain

    a session across requests or acebook users. he call to

    set_facebook_sessionwill look into session[:facebook_session] in order to see i there is already a session object

    available.

    Authenticating a Usern order or your application to take action on the behal o a user or

    to gain extra permissions, acebook will issue a session key or that

  • 8/8/2019 Peepcode Facebook 2

    24/67

    24

    user. hese actions can include posting to a news eed or sending

    notications and there are currently two types o session keys, innite

    and expirable. n pplication can request a session key in one o two

    ways, by sending the user to the pplication ogin page or sending

    the user to the pplication dd page. acebooker supports both o

    these through class level calls available in the controller; both o these

    calls take the same options as before_lter.

    he ensure_authenticated_to_facebookmethod will attempt to

    validate the acebook parameters and on ailure will redirect the user

    to the ogin RL. t this RL the user will basically be asked whether

    they want to grant an innite session key or a session key that will

    expire.

    he ensure_application_is_installed_by_facebook_user

    method will validate the acebook parameters and check to see i the

    the parameter indicating that the user has added the application isset. ost applications will require that the user add the application as

    it not only can give the application more permissions but it also will

    publish the choice to the users news eed.

    y deault ater a user adds the application acebook will redirect

    the user to the ost dd RL that was setup in the developer app.

    n some cases this is not ideal, however. verriding this behavior

    is supported by the acebook API, although currently acebooker

    doesnt give easy access to changing this. n order to send your users

    to some other RL you will need to override the controller methodapplication_is_not_installed_by_facebook_userand pass in a

    :next parameter to the install_url. ere is an example rom uby

    ootprints:

    ruby_footprints/app/controllers/application.rb

    def application_is_not_installed_by_facebook_userredirect_to session[:facebook_session].install_url(:next => next_path() )

    end

  • 8/8/2019 Peepcode Facebook 2

    25/67

    25

    private

    def next_path

    non_keys = [ method, format, _method, auth_token]url_hash = {}params.each do |k,v|

    next if non_keys.include?(k.to_s) || k.to_s.match(/^fb/)url_hash[k] = v

    endurl_hash[:only_path] = trueurl_hash[:canvas] = falseurl_for(url_hash)

    end

    note here is surely a cleaner way to create a RL rom the request

    parameters. lease do investigate.

  • 8/8/2019 Peepcode Facebook 2

    26/67

    26

    Getting Social Datachapter 5

    User and Friend DataYou can access nearly all the data that is public on a users prole

    once he or she installs your application. You may use this data in

    your application, but acebook has limits on what you may store

    persistently. You can generally store numerical identiers such as user

    s (Us) and photo s (s), but nothing more. t is also illegal to

    store riend relationship id pairs, such as . eer to the

    developer documentation (http://wiki.developers.facebook.com/index.php/Main_

    Page) or storage guidelines.

    or example, here is how to etch a users avorite music:

    facebook_session.user.populate(:music)music = facebook_session.user.music

    ssuming the user has a comma-separated list o artists, you can

    split the string to get each artist. You can use a similar approach to

    get any number o user data, including activities, interests, avorite

    movies, etc. ee the sidebar or a complete list.

    Photosacebook organizes photos into albums, and each photo has its own

    photo id (pid). You can speciy either a list o photo s, an album id,

    or a subject id. he subject id is the ID o a specic user. peciying

    the subject id will retrieve all the photos in which the particular user

    was tagged.

    complete list of user data

    he facebook_session.user.populate()

    method accepts one or more o the ollowing

    symbols. eave blank to get them all.

    :status, :political, :pic_small,:name, :quotes, :is_app_user, :tv,:profile_update_time, :meeting_sex,:hs_info, :timezone, :relationship_status, :hometown_location, :about_me, :wall_count, :significant_other_id, :pic_big, :music, :uid,:work_history, :sex, :religion,

    :notes_count, :activities, :pic_square, :movies, :has_added_app,:education_history, :birthday,:first_name, :meeting_for, :last_name, :interests, :current_location,:pic, :books, :affiliations

    ll o the above return tring values, except

    or location, high school info, status,

    afliation, education info, and work info.hese return their own model objects that have

    accessors or their attributes. or example:

    location_example.rb

    facebook_session.user(:location)# => Location objectlocation.city# => Chicago

    http://wiki.developers.facebook.com/index.php/Main_Pagehttp://wiki.developers.facebook.com/index.php/Main_Pagehttp://wiki.developers.facebook.com/index.php/Main_Pagehttp://wiki.developers.facebook.com/index.php/Main_Page
  • 8/8/2019 Peepcode Facebook 2

    27/67

    27

    acebooker includes a ew convenience methods or common photo

    tasks:

    acebook_session.user.albums

    acebook_session.user.prole_photos

    he albums method retrieves a list o album s (aids) or the cur-

    rently logged in user. hese can be plugged into facebook_session.get_photos to get the photos or each album. Note that pid, subj_id,

    or aid must be supplied to facebook_session.get_photos. or

    example, all the incriminating photos or user 12345 can be retrieved

    with facebook_session.get_photos(:subj_id => 12345).

    acebook has a special album or prole photos, which cannot be

    retrieved using the method above. You need to do some trickery

    involving complex mathematics to get this album. uckily, the smart

    developers o acebooker have abstracted the complexity with the

    prole_photos method. t simply retrieves all the prole photos or

    the currently logged in user.

    Eventsacebooker provides a convenience method to get the events or a

    user. You can lter events by start time, end time, and RSP status.

    he ollowing returns the events between now and a month rom now:

    @user.events(:start_time => Time.now.to_i, :end_time => 1.month.from_now.to_i)

    nce you have a list o vent objects, you can access the attributes

    o each vent, such as description, venue, host, location, etc.

  • 8/8/2019 Peepcode Facebook 2

    28/67

    28

    Anatomy of an Appchapter 6

    Integration PointsYour main application runs inside a acebook canvas page, but ace-

    book allows additional means to interact with, promote, or advertise

    an action o your application. Your application is entitled to its own

    box on a users acebook prole page. he content o this box can be

    rendered dierently based on whether users are viewing their riends

    proles or their own. You also have the option o adding a link under

    the users prole picture.

    eed items (not to be conused with RSS/tom eeds) are little blocks

    o content that you publish based on actions taken in your applica-tion. or example, i you have an application that spanks a riend,

    then it can publish a eed story inorming the user and his or her

    riends about the spank. Now dont get the bright idea to make a

    spanking application, as it has already been done, and no, not by

    me. here are two types o eed items, the News eed and ini-eed.

    he News eed contains stories about all your riends activities while

    the ini-eed is only or activities that are either initiated by you, or

    involve you in some way (or example, i someone tagged a photo o

    you).

    acebook has two types o notications that are meant to serve as

    individual communication between the application and the user. eg-

    ular notications go to the users notication page, which is accessed

    by a link in the right sidebar on the acebook homepage i the user

    is logged in. his page contains inormation that acebook considers

    relevant yet not important enough to go into the users News eed.

    he other type o notication is email notications. s expected this

    sends an email to the user on behal o your application, as long as

  • 8/8/2019 Peepcode Facebook 2

    29/67

    29

    their privacy settings are set to allow it.

    acebook also has hooks to allow your application content to be

    included in wall and message attachments.

    Sy Ig Pfacebook home pae

    essage nbox

    Notications

    tatus Updates

    News eed

    equests

    profile pae

    Narrow box on let side, under picture

    ink under prole picture (this is not available in the new acebook

    layout)

    tabs

    oxes tab: Narrow or Wide prole box

    pplication tab

    no tab box

    Wall (previously called the ini-eed in the old layout)

    tatus update

    email

    ttachments

    hare messages

  • 8/8/2019 Peepcode Facebook 2

    30/67

    30

    other

    pplication description and image in the pplication irectory

    pplication reviews and discussions in your bout page

    n all pages, your application can be shown on the idebar applica-

    tion list i the user allows it.

    verall, you have quite a ew choices or integrating your application

    tightly with acebook to create a seamless user experience.

    The Profile Pagehe role age on acebook provides a space or your application

    to have a presence. his space involves a ew restrictions.

    he user must add your application and grant permission to your

    application

    he content must be explicitly published to the prole through the

    acebook API

    You can use FBJS but it will not run until the user clicks on the

    space, and it cannot communicate with your server

    he content is restricted to one o two widths: narrow or wide

    here are two main

    parts o a users

    role, the role

    ction and the

    role FBML. he

    role ction is

    simply a link that goes below a users prole picture. he role FBML

  • 8/8/2019 Peepcode Facebook 2

    31/67

    31

    is a piece o FBML that allows a user and the users riends to see

    what the user has been doing with your application. he uby oot-

    prints pplication shows a tally o the number o times the user has

    stepped on and been stepped on. he role ction, i you set it up

    correctly, shows up as a link below every prole that your user looks

    at (see role Wiki link (http://wiki.developers.facebook.com/index.php/Profile)).

    oth the role FBML and the role

    ction can have deaults set or the appli-

    cation. any apps will setup the eault

    FBML to simply contain an b:re tag. his

    way the content can be updated or all

    users o the app with one request. y

    setting the deault role ction or your

    application you actually gain something

    very powerul. he link will appear under

    the prole or every prole your application

    users view, not just the proles o people

    who have added the application. You can

    set both deaults in the application settings

    page. ere is the deault role ction or

    uby ootprints:

    Step On

    here are a couple o ways in acebooker to publish to a users ro-

    le. he simplest way is through methods directly on an instance o a

    acebooker::User. ts available methods are:

    publish_profile.rb

    http://wiki.developers.facebook.com/index.php/Profilehttp://wiki.developers.facebook.com/index.php/Profile
  • 8/8/2019 Peepcode Facebook 2

    32/67

    32

    @facebooker_user.profile_fbml = A string of FBML@facebooker_user.mobile_fbml = A string of FBML for mobile profile@facebooker_user.profile_action = PerformAction @facebook_user.profile_main = FBML for a Profile Box on the Main Profile@facebook_user.set_profile_fbml(profile_fbml, mobile_fbml, profile_action)

    hese methods are o limited use since you will have to code up the

    FBML manually or hack in your own template rendering.

    he preerred method o managing a users role page is through

    what we will call the ublisher API. acebooker::ublisher uses a simi-

    lar approach to ctionailer and it allows you to render templates

    and to use helper methods to create your FBML. he ublisher API

    currently supports sending eed tories, Notications and mails, set-

    ting a users role, and setting FBML reerence handles. ere are thebasic steps to creating a ublisher:

    un the ublisher generator ruby script/generate Pub-

    lisher Facebook. his will create a class that extends

    acebooker::ublisher.

    ene a method with any number o arguments and call it what-

    ever you would like, as long as it does not confict with other

    instance methods.

    n that method call the method send_as with the type o thing youare publishing. vailable choices are :prole, :email, :notica-

    tion, :story, :action, :templatized_action, and :ref.

    Call FacebookPublisher.deliver_(*args).

    ere is an example rom uby ootprints o setting the users role

    FBML and role ction using the ublisher API:

    ruby_footprints/app/models/facebook_publisher.rb

    def profile_for_user(user_to_update)

  • 8/8/2019 Peepcode Facebook 2

    33/67

    33

    send_as :profilefrom user_to_update.facebooker_userrecipients user_to_update.facebooker_userfbml = render({

    :partial =>/footprints/user_profile.fbml.erb, :locals => {:user => user_to_update}

    })profile(fbml)profile_main(fbml)action = render(:partial => /footprints/profile_action.fbml.erb)profile_action(action)

    end

    note he above example calls the recipients method, which might

    seem a little strange but the acebook API allows you to set the

    role or any o your users using a single session key.

    With acebooks New role esign, an applications role ox

    can live in one o two places, inside the oxes ab and on the

    ain role age. n application will need to ask a User to explic-

    itly request the applications presence in one o these places. his

    request is handled via a custom FBML tag, . you notice in the example above, the pub-

    lisher code calls both prole and prole_main. he call to prole

    will set the prole FBML or the oxes ab while prole_main will set

    the FBML or the users ain role.

    note he role ction link has been deprecated by acebook and

    will not be available in their next release o the latorm. his

    change is corresponding with the nal edits o this book so

    we decided to leave it in just in case you see reerences to it

    elsewhere.

  • 8/8/2019 Peepcode Facebook 2

    34/67

    34

    New Profile Application Tabhe new acebook role design gives applications a new integration

    point. Your application can get access to some coveted real estate

    on the users prole. nstead o there being application prole boxes

    on the main user prole, users will have to select applications that

    they would like to highlight on their own proles. o give your users

    access to this tab you congure both the Profle Tab RL and ProfleTab Name in the application settings. he role ab RL is a canvas

    page RL and there a ew dierences with this FBML canvas:

    You cannot use rames

    he session key that you get is a temporary key and is dierent

    rom the users innite session key, it is also a read-only

    t doesnt know who the viewing user is

    lash and avascript have the same restrictions as the role ox

    nce your application is setup to support the role ab, when a user

    loads that particular tab acebook will call the role ab RL. You

    can add dynamic interaction with the ab via AJAX; however, all HREF

    links will go to your canvas page.

    note ince this eature is so new it is likely to change as users and

    application developers interact with it. Check the wiki under

    abbed role (http://wiki.developers.facebook.com/index.php/New_Design_

    Tabbed_Profile) or the latest inormation.

    News Feed and Wallhere are three dierent ways to publish stories to a users eeds.

    ach way gives you access to either the Wall or News eed or both.

    You also get the ability to publish stories to riends that have not

    http://wiki.developers.facebook.com/index.php/New_Design_Tabbed_Profilehttp://wiki.developers.facebook.com/index.php/New_Design_Tabbed_Profilehttp://wiki.developers.facebook.com/index.php/New_Design_Tabbed_Profilehttp://wiki.developers.facebook.com/index.php/New_Design_Tabbed_Profile
  • 8/8/2019 Peepcode Facebook 2

    35/67

    35

    added your application. his last eature may sound very appealing

    or its possibilities o rapidly propagating your application; dont get

    your hopes up too high, though, as acebooks standards appear to

    be very restrictive or this type o messaging. he table below shows

    the dierence between each method:

    F A Sy TzA

    Wall Yes No Yes

    News eed riends with app wn ll riends

    Usage imits 10 times every 48 hours once every 12 hours 10 times every 48 hours

    acebooker exposes each o these API calls via the ublisher API, as

    introduced above.

    Pg Sn the uby ootprints example application we decided to nudge

    users back to the application by notiying them once a day o their

    riends activities. any applications have some sort o visual compo-

    nent, perhaps a photo or an icon o a git. or uby ootprints we will

    include our uby ootprints logo to add some fare to the eed story.

    ruby_footprints/app/models/facebook_publisher.rb

    def nudge_story(user)send_as :storyrecipients(Array(user.facebooker_user))

    db_friends = FacebookUser.find_friends(user.friends)

    if( db_friends.blank? )title = None of your friends stepping on people!!

    elsetitle = db_friends[0..3].compact.collect{ |friend|fb_name(friend.uid)

    }.to_sentence + have been stepping on people.

  • 8/8/2019 Peepcode Facebook 2

    36/67

    36

    end

    body = Get stepping on your friends.

    body = body[0..200] if body.length > 200 self.body( body ) self.title( title )

    image_1(image_path(tiny-footprint.png))image_1_link(footprints_url())

    end

    note here are limits on your title and body length, excluding tags, so

    i these are generated dynamically make sure to truncate them,

    otherwise you will get an error rom acebook.

    Pg Tz A

    ublishing a templatized action adds some complexity to the pro-

    cess. he reason behind this is aggregation. n order or acebook to

    increase the quality o News eed items, they attempt to aggregate

    similar stories into a single item on the News eed. his is a good

    thing or developers as it gives you more o a chance or your story

    to appear on the News eeds o riends. he more stories you pub-

    lish, in theory, the more o a chance you have o your aggregated

    story getting published. n general the body_template, body_data,title_template, title_data, and target need to be identical or

    a story to be aggregated. o the story avid stepped on hane

    can become avid and oug stepped on hane, but only i we both

    stepped on hane. You should denitely read up on the wiki (http://wiki.

    developers.facebook.com/index.php/Feed.publishTemplatizedAction ) to understand

    better how aggregation works; it can be very powerul. nd notice

    that you will need to go through the steps o registering the templates

    beore you can take advantage o the aggregation.

    http://wiki.developers.facebook.com/index.php/Feed.publishTemplatizedActionhttp://wiki.developers.facebook.com/index.php/Feed.publishTemplatizedActionhttp://wiki.developers.facebook.com/index.php/Feed.publishTemplatizedActionhttp://wiki.developers.facebook.com/index.php/Feed.publishTemplatizedAction
  • 8/8/2019 Peepcode Facebook 2

    37/67

    37

    ere is uby ootprints method rom your acebookublisher class:

    ruby_footprints/app/models/facebook_publisher.rb

    def footprint_feed_item(attacker, victim)send_as :templatized_actionfrom(attacker)title_template {actor} stepped on {target}target_ids([victim.id])

    body_general(Check out #{link_to(#{fb_name(victim, :possessive => true)} Ruby Footprints, new_footprint_url(:friend_to_step_on => victim.id )) } )

    image_1(image_path(tiny-footprint.png))image_1_link(footprints_url())

    end

    nd here is what it will look like in the ini-eed and (i you are lucky)

    the News eed:

    note he call to target_ids is a specic parameter or these types

    o actions. acebook will use these s in order to aggregatestories rom many dierent users.

    Pg A

    ublishing ctions is very similar to publishing tories; in act the

    Facebooker::Feed::Action class is a duplicate o the Story class.

    ctions, like stories, have a title, a body, and images. ince we are

  • 8/8/2019 Peepcode Facebook 2

    38/67

    38

    using emplatized ctions in uby ootprints we dont really have any

    use or regular actions. ere is some example code; notice that it is

    very similar to the code or sending a tory.

    ruby_footprints/app/models/facebook_publisher.rb

    def example_action(user)send_as :actionfrom( user)title just learned how to send a Mini-Feed Story using Facebooker.body #{fb_name(user)} just checked out #{link_to(Ruby Footprints, footprints_url)}. A Ruby based

    Facebook example application.image_1(image_path(tiny-footprint.png))image_1_link(footprints_url())

    end

    note Not only can you use helper methods in there, like b_name, but

    you can call render :partial => /some/partial.

    T Nw F F Sy F

    ometime in the ummer o 2008 acebook will nally release its

    new role design and with that comes a new ormat or News eed

    tems. he purpose o this new ormat is to give users a greater

    amount o control over their personal prole pages. Users will be

    given control over how ini-eed stories appear on their proles and

    application developers will have some work to do in order to support

    this greater level o control.

    ini-eed stories will now support three dierent lengths o stories,

    one-line, short, and ull. he API requires that you register these sto-

    ries beore using them and the nice thing is that registering is built

    into the API and acebooker supports it. When generating a new

    ublisher, acebooker will create a database migration to store all the

    needed template s since a template is required to publish eed

  • 8/8/2019 Peepcode Facebook 2

    39/67

    39

    stories. Your ublisher works very much the same way as the Pub-

    lishTemplatizedAction eed stories, only it also need to support

    the registering o the templates. ere are the steps:

    Create a method that describes your template. Call it something

    like mini_feed_template (it must end in template)

    escribe the template with three methods: one_line_story_tem-

    plate, short_story_template(title, body), and full_story_

    template(title, body)

    Create a method or delivering the eed story in the same way that

    emplatizedctions are supported. It must start with the same pre-

    fx as your template method. e.g. def mini_feed

    Call send_as :user_action, from(user), and data(hash_of_

    data_to_populate_the_template) inside the delivery method

    Call FacebookPublisher.register_mini_feedat some point

    during the fow o your app

    nd here is an example rom the uby ootprints application.

    ruby_footprints/app/models/facebook_publisher.rb

    def new_footprint_feed_item_templateone_line_story_template({*actor*} stepped on {*target*})short_story_template({*actor*} stepped on {*target*}, You can {*general_step_link*} on people

    too! With Ruby Footprints. )full_story_template({*actor*} stepped on {*target*}, {*image_link*}

    Dont let them get away

    with treating each other this way.

    {*call_to_action*}

    )

    end

    def new_footprint_feed_item(footprint)victim = Facebooker::User.new(footprint.victim.uid)attacker = Facebooker::User.new(footprint.attacker.uid)send_as :user_actionfrom(attacker)target_ids([victim.id])data({

    :general_step_link => link_to(Step, footprints_url) ,

  • 8/8/2019 Peepcode Facebook 2

    40/67

    40

    :image_link => link_to(image_tag(tiny-footprint.png), footprints_url), :call_to_action => Check out #{link_to(#{fb_name(victim, :possessive => true)} RubyFootprints, new_footprint_url(:friend_to_step_on => victim.id )) }

    })end

    note he place holders or template data have a dierent ormat thanthey did with the TemplatizedAction templates. he key is

    surrounded by asterisks, as in the example above.

    NotificationsNotications are generally shorter than eed items and do not con-

    tain any images. hey are handled by the ublisher API and simply

    have a sender, recipients and a block o FBML. Notication can bea great way to spread your application by notiying riends that a

    user has taken some action that involves them. uby ootprints uses

    notications to let other users know that they have been stepped on

    so that they can retaliate and do some stepping on their own.

    ruby_footprints/app/models/facebook_publisher.rb

    def footprint_created(footprint)send_as :notificationvictim = Facebooker::User.new(footprint.victim.uid)

    attacker = Facebooker::User.new(footprint.attacker.uid)# Note this only works during a request cycle# since the session is being held for us

    self.recipients(victim) self.from(attacker)

    fbml stepped on you. #{link_to(See all your Ruby Footprints , footprints_url) } end

  • 8/8/2019 Peepcode Facebook 2

    41/67

    41

    note ne thing to note is that when you send a notication to a user

    on another users behal, the sender will also get a notication

    that they sent something, so be careul not to abuse the system,

    or your users will know and punish you or it.

    EmailsYour application can send emails to users who have added the

    application. he email can contain both a text version and an HTML

    version. o not try to do anything ancy though, because the set

    o allowed tags is limited to tags that result in text only. he email

    actually appears to come rom your application so you cannot send

    emails rom one o your users to another; that is what notications

    are or.

    ruby_footprints/app/models/facebook_publisher.rb

    def example_email(from,to, title, text, html)send_as :emailrecipients(to)from(from)title(title)fbml(html)text(text)

  • 8/8/2019 Peepcode Facebook 2

    42/67

    42

    end

    ike notications, the limit on emails is calculated per application,

    and once again a big part o that calculation is user eedback. he

    email itsel will have a link or your users to click in order to block your

    application rom sending any more emails, so be kind. ee the side-

    bar or details on allocation limits.

    note your notications or emails ail, make sure that you are not

    sending any markup other than text and links. acebook will

    happily drop your notication on the foor and give you a

    successul response. tart simple.

    Invitationsnvitations in acebook are another way or your users to interact with

    each other. nvitations dier rom previously mentioned ways o com-

    municating with users in that they must be specically initiated by a

    user. robably the most common invitation is a request to install an

    application. ome applications go so ar as to require users to do this

    in order to unlock certain unctionality, while others will oer additional

    points or benets based on the number o riends that get invited.

    he nvitation is handled through a ew specic FBML tags and ace-

    booker has methods or each o those. ere are all the pieces you willneed to put this together:

    ext or the call to action button on the invite itsel

    ext or the send button

    RL or the recipient to click on

    RL to go to ater sending the nvitations. his request will include

    the s o the invite users and can be used or tracking purposes

  • 8/8/2019 Peepcode Facebook 2

    43/67

    43

    Call to action text or user sending the nvitations

    uby ootprints gently encourages users to pass the word by pro-

    viding a link at the bottom right o the layout. his link renders the

    ollowing FBML:

    ruby_footprints/app/views/admin/invite_friends.fbml.erb

    Check out Ruby Footprints.It is an example Facebook app built with Ruby.

    true,:exclude_ids => current_user.friends_with_this_app.map(&:id).join(,)) %>

    he rst part o this template sets up the content or the nvitation

    itsel. his is what the recipient will see. he call to content_or basi-

    cally assigns the FBML rom the block to an instance variable to be

    later used by the request orm. he name passed into this method

    is the same name that is passed into fb_request_form. he con-

    tent includes an fb_req_choice tag which renders the button to beclicked by the recipient o the invitation and includes the RL that the

    user will go to when called to action.

    Next we have the riend selection orm, accessible with the

    fb:request-form tag as shown at the wiki (http://wiki.developers.facebook.

    com/index.php/Fb:request-form). amiliarize yoursel with all the dierent

    permutations, as they can be useul in dierent circumstances. he

    request orm takes a tring or the button the user clicks once all

    the riends are selected, and a RL to go to ater the nvitations are

    http://wiki.developers.facebook.com/index.php/Fb:request-formhttp://wiki.developers.facebook.com/index.php/Fb:request-formhttp://wiki.developers.facebook.com/index.php/Fb:request-formhttp://wiki.developers.facebook.com/index.php/Fb:request-form
  • 8/8/2019 Peepcode Facebook 2

    44/67

    44

    sent out. his callback RL will contain the s o the users that were

    selected. uby ootprints simply stores the s in the session to be

    used in a fash message.

    he request orm takes a block and this block needs to render one

    o the many acebook riend selector widgets. uby ootprints is

    using the multi riend selector, which is rather menacing, but popular

    among applications. You will notice, i you play with uby ootprints,that there is an indication on the orm indicating how many people

    can be invited. his number is one o the allocation limits that your

    application is governed by and is a per day limit.

  • 8/8/2019 Peepcode Facebook 2

    45/67

    45

    Info Sectionn the New acebook role, applications have the ability to provide

    lists o data that users can embed into the no ab on their roles.

    his integration is done with an explicit action rom the user clicking

    on a button provided by a custom FBML tag, . eore the user clicks on this button

  • 8/8/2019 Peepcode Facebook 2

    46/67

    46

    the application must publish some data to acebook in a list ormat.

    You can check out the wiki or all the details at role.setno (http://

    wiki.developers.facebook.com/index.php/Profile.setInfo). he ormat o the JSO

    data is an array o hashes with an array o hashes inside. his can be

    a little tricky, so here is an example script that can be used to publish

    this list data:

    set_info_list.rbrequire File.dirname(__FILE__) + /../config/environmentENV[FACEBOOKER_API] = newdef footprints_info_list

    [{

    :label => Red Footprints, :link => apps.facebook.com/rubyfoot_dev, :image => ActionController::Base.asset_host + /images/tiny-footprint.png

    }]

    end

    info_fields = [{

    :field => Ruby Footprints, :items => footprints_info_list

    }]

    FacebookUser.find(:all).each do |user|user.set_profile_info(Ruby Footprints, info_fields)

    end

    New Profile Publisheracebook recently launched a new way to publish content, that aligns

    with their new ublisher eature. ublisher (not to be conused with

    Facebooker::Publisher) is a new tool that allows applications to

    http://wiki.developers.facebook.com/index.php/Profile.setInfohttp://wiki.developers.facebook.com/index.php/Profile.setInfohttp://wiki.developers.facebook.com/index.php/Profile.setInfohttp://wiki.developers.facebook.com/index.php/Profile.setInfo
  • 8/8/2019 Peepcode Facebook 2

    47/67

    47

    publish any kind o content to a users, or a user s riends, Wall. his

    is going to be an important integration point due to its prominence on

    the users prole page. t is right at the top and sorted by most recent

    activity. he ublisher is much more powerul than the ini-eed it

    replaced. You can now publish FBML, lash, or even load FBJS.

    o begin using the ublisher, you need to speciy an action and a

    callback RL in the application settings.

    here are two sets o actions and callback Us, one or publishing to

    your own prole and one or publishing to your riends proles. When

    you have congured the above, your application will show up in the

    drop-down list near the ublisher bar on the role page, provided

    the user has agreed to show it in your applications erms o ervice:

  • 8/8/2019 Peepcode Facebook 2

    48/67

    48

    Your application rst needs to render its own version o the ublisher

    interace. hen it must generate the eed story or the content to be

    published.

    acebooker comes with support or acebooks ublisher. You rst

    need to check i acebook is requesting the interace or ublisher

    by calling wants_interface? true, you can render the orm using

    render_publisher_interface. his builds the JSO or the ub-lisher interace. the interace has already been rendered, you

    can publish the content using render_publisher_response. his

    method takes in a UserAction object, which is provided by the

    Facebooker::Publisher class.

    reviously we discussed how to publish eed tories using the new

    API provided by acebook. he API and code or this new user-con-

    trolled publishing uses the same mechanism and API as that used

    to publish eed tories. irst the application creates and registers a

    template, then when asked the application returns the data or thattemplate. uby ootprints allows the user to publish his own stats to

    his Wall; the controller logic is in AdminController, and the template

    and template data are in the FacebookPublisher. ere is the con-

    troller:

    ruby_footprints/app/controllers/admin_controller.rb

    def publish_selfuser = FacebookUser.find_by_uid(params[:fb_sig_profile_user])FacebookPublisher.register_publish_self unless

  • 8/8/2019 Peepcode Facebook 2

    49/67

    49

    Facebooker::Rails::Publisher::FacebookTemplate.find_by_template_name(publish_self_item) if wants_interface?

    render_publisher_interface(render_to_string(:partial=>/footprints/user_profile, :locals =>{:user => user})) else

    render_publisher_response(FacebookPublisher.create_publish_self(user)) endend

    his one action must respond to requests or the orm that takes in

    the user data and the request which returns the JSO-encoded data

    or the template. n our case we are not actually requesting any orm

    data rom the user, but typically this is what an application would

    want to do. Notice that we check to see i the template has been

    registered rst; this is not very ecient rom a programming perspec-

    tive but makes the example clearer. Now take a look at the template

    denition and the template data in the FacebookPublisher class.ruby_footprints/app/models/facebook_publisher.rb

    def publish_self_templatetitle = {*actor*} Is a Ruby Footprint Masterone_line_story_template(title)short_story_template(title, You can {*general_step_link*} on people too! With Ruby Footprints. )full_story_template(title, {*fbml*})

    end

    def publish_self(user)

    send_as :user_actionfrom(user)data({

    :general_step_link => link_to(Step, footprints_url), :fbml => (render :partial => /footprints/user_profile.fbml.erb, :locals => {:user => user})

    })end

    hese denitions work exactly like the denitions used or publishing

  • 8/8/2019 Peepcode Facebook 2

    50/67

    50

    eed stories.

    note n order to create the UserAction object we call

    FacebookPublisher.create_publish_self. his is

    another way the that Facebooker::Publisher is built around

    the same concepts as ActionMailer.

  • 8/8/2019 Peepcode Facebook 2

    51/67

    51

    prorammatic confiuration

    acebook continues to add more and more programmatic

    access to conguration and application data. ne o the

    these that you can programmatically veriy is the alloca-

    tion limits put upon your application. here are allocation

    limits or how many emails, notications and requests are

    sent.

    he limit on Notications is calculated per application, and

    a big part o that calculation is user eedback. You can

    check the current limit programatically and rom within the

    eveloper application under tats lloction. he initil

    limit is per d nd cebooker will rise n exception

    ter ou hve reched the limit. Check it b clling:

    @facebook_session.admin.get_allocation(:notifications_per_day)

    ike Notications, the limit on mails is calculated per

    application, and once again a big part o that calculation is

    user eedback. he email itsel will have a link or you users

    to click in order to block your application rom sending

    anymore emails, so be kind. acebook likes your applica-

    tion it will put this disable link at the bottom o the email.

    he initial limit is 5 per day and acebooker will through anexception ater you have reached the limit. You can check

    the limit by calling:

    @facebook_session.admin.get_allocation(:emails_per_day)

    You can also see where the disable message is by calling:

    @facebook_session.admin.get_allocation(:email_disable_message_location)

    certain number o invitations can be sent rom your

    application per user per day. You will see this as a limit on

    the riend selector widgets provided by acebook. Check it

    programmatically:

    @facebook_session.admin.get_allocation(:requests_per_day)

  • 8/8/2019 Peepcode Facebook 2

    52/67

    52

    Testingchapter 7

    Functional testsesting acebook apps is not much dierent rom testing normalails applications using the helpers that come with acebooker. Unit

    tests are pretty much the same as ails tests. owever, unctional

    tests require a little extra work since the acebook parameters must

    be appended to all requests. uckily, acebooker comes with the

    facebook_post method that replaces the normal post method that

    comes with ails. he facebook_post method will handle appending

    the acebook request parameters and generating the signature, so

    you really do not have to know what is going on behind the scenes,

    and can usefacebook_post

    just as you would usepost

    in a ails

    unctional test.

    ere is an example using all the test helper methods available with

    acebooker.

    functional_test.rb

    def test_createassert_difference Footprint.count dofacebook_post create, :id => 2

    end

    assert assigns(:stepped_on_user)assert_facebook_redirect_to(http://apps.facebook.com/rubyfoot_test/)

    end

    ctions that use the acebook canvas use facebook_post to simu-

    late a post to acebook with the required parameters. ails usual

    assert_redirect does not work in the acebook environment since

    the request has to pass through acebooks server rst. ather, a

  • 8/8/2019 Peepcode Facebook 2

    53/67

    53

    acebook redirect is a POST to acebook with a special FBML redirect

    tag. he assert_facebook_redirect_to test helper abstracts these

    details or you.

    Sg F v

    ten in unctional tests, you would want to stub out calls to ace-book so you will not have to make any calls over the network. ince

    the main entry point to acebook is via the facebook_session, it

    is convenient to stub out calls to the facebook_session. eres an

    example:

    stubbing_example.rb

    def test_friendsstubbed_user = stub(:friends => 1,2,3)Facebooker::Session.any_instance.stubs(:user).returns(stubbed_user)facebook_post friendsassert assigns(:friends)

    end

    Test accountsacebook maintains a special network or developers only, where

    you can create ake users or testing. his is great or manual testing

    beore launching an application. You can also automate this processby creating acceptance tests via a tool like elenium. o create a test

    acccount, rst create a normal acebook account. hen go to the test

    account page (http://www.facebook.com/developers/become_test_account.php) to

    automatically join the developer test network. or more ino, see the

    wiki (http://wiki.developers.facebook.com/index.php?title=Test_Accounts).

    http://www.facebook.com/developers/become_test_account.phphttp://wiki.developers.facebook.com/index.php?title=Test_Accountshttp://wiki.developers.facebook.com/index.php?title=Test_Accountshttp://www.facebook.com/developers/become_test_account.php
  • 8/8/2019 Peepcode Facebook 2

    54/67

    54

    Ruby Footprints Appchapter 8

    uby ootprints is a simple application based on the PHP example-

    application ootprints. t is an extension o the integrated acebook

    unctionality called oke and is intended to allow users to nudge their

    riends by stepping on them. user will get a notication that some-one has stepped on them and be given the opportunity to retaliate

    by stepping back. any o the code examples come directly rom the

    running uby ootprints application.

    Routesacebooker tries its best to keep routes looking just like ails routes.

    he main dierence is that i your route is or a canvas page, you

    should have :conditions => { :canvas => true } appended

    to your route. ails resource routes will also work with acebooker.

    lthough all acebook API calls are POST operations, one o the

    b_params actually passes back the HTTP method used when ini-

    tially making the request. acebooker uses this parameter to simulate

    resource routes.

    ere is how to speciy a route or the acebook canvas:

    map.root, :controller => footprints, :action => index, :conditions => { :canvas => true }

    or non-canvas routes:

    map.root, :controller => footprints, :action => web, :conditions => { :canvas => false }

    regular named route:

  • 8/8/2019 Peepcode Facebook 2

    55/67

    55

    map.remove_user(remove_user, :controller => admin, :action => remove_user)

    esource routes work too:

    map.resources :footprints

    Modelst the core o the uby ootprints application is the FacebookUser

    model. he FacebookUser model contains all that we need in order

    to be able to communicate with the acebook API on behal o a

    user. he three pieces o data required are the users acebook , a

    session key, and the expiration time o the session key. ypically an

    application requires access to user data even when the user is not

    directly interacting with it, and this is obtained by requiring that theuser add the application. nce this is done acebook issues an in-

    nite session key or the application to use. he FacebookUser model,

    when created, stores all this inormation in the database and then

    uses it to create a Facebooker::Session and to communicate with

    the acebook API. ere is the application beore lter used in uby

    ootprints to create the FacebookUser:

    ruby_footprints/app/controllers/application.rb

    def setup_db_facebook_user

    # Grab the facebook user if we have one# and store it in the session

    unless( @fb_user || facebook_params.empty? )

    user_id = facebook_params[user]session_key = facebook_params[session_key]expires = facebook_params[expires]

    fb_user = FacebookUser.ensure_create_user(user_id)

    models

    he creation and management o the ace-

    bookUser model has a couple o unique things

    that you dont always see in a ails applica-

    tion. he rst is the call in the before_lter

    to the method FacebookUser.ensure_cre-

    ate_user. ypically what you would see here

    is a call to FacebookUser.nd_or_create_

    by_uid(). his turns out to not be sucient or

    any application that carries a signicant load.

    he reason is that the create is not transaction-ally sae and the database will either end up

    will duplicate rows or i there is a unique key on

    uid then an database constraint error will be

    thrown. he second unique piece o code is the

    check or the session_key changing. his can

    happen i the user removes the application and

    then later adds it again. his check would not

    be necessary i the application deletes users

    rom the database upon remove.

    nother thing to note is that acebook User ids

    are 64 bit integers and the current ails migra-

    tions do not support this as it is not database

    agnostic. yQ and other databases can

    support 64 bit integers and there is a plugin or

    handling it (http://agilewebdevelopment.com/plugins/

    mysql_bigint).

    if( fb i k ! i k || fb l il? || fb l

    http://agilewebdevelopment.com/plugins/mysql_biginthttp://agilewebdevelopment.com/plugins/mysql_biginthttp://agilewebdevelopment.com/plugins/mysql_biginthttp://agilewebdevelopment.com/plugins/mysql_bigint
  • 8/8/2019 Peepcode Facebook 2

    56/67

    56

    if( fb_user.session_key != session_key || fb_user.last_access.nil? || fb_user.last_access err

    if(facebooker_user.respond_to?(symbol))value = facebooker_user.send(symbol,*args)return value

    else throw err end

    endend

    note here are instances inside the acebooker code that

    explicitly validate that it has been passed an instance o a

    acebooker::User, so even though the model delegates its

    methods to an instance o acebooker::User the method will still

    throw an exception.

  • 8/8/2019 Peepcode Facebook 2

    58/67

    58

    Advanced Topicschapter 9

    FBML and Image Caching

    eerences are a little hidden treasure in the acebook platorm. heyallow you to cache a bunch o FBML on acebooks servers that can

    later be retrieved using a special FBML tag, . he advantage

    o caching FBML is that your application doesnt have to dynami-

    cally generate it each time or each user. ut the real magic lies in

    the ability to re o an API command that will instantly push out the

    cached FBML to wherever it is reerenced. or example, i you have

    an application that applies the same FBML to each users prole, you

    can call just one API command that instantly updates it on each pro-

    le without you having to manually publish it or each user.

    es are great or storing large chunks o FBML. You can even use

    them in creative ways, such as making your SS a re and updat-

    ing the re anytime you change the SS in order to update the view

    across all your users proles. common use is to have an admin

    section or your site that uses res to update code that is common

    across all proles, like SS. t is also perect i you have an app that

    publishes static content, like sports scores.

    H R

    here are two ways to cache FBML. he simplest way is to dene a

    key value pair, where the key is a unique handle or identier or the

    reerence, and the value is the FBML content. You set the cache using:

    facebook_session.server_cache.set_ref_handle(handle, FBML content)

    h t t ill b l d ti h

  • 8/8/2019 Peepcode Facebook 2

    59/67

    59

    hen content will be replaced anytime you have:

    URL R

    acebook gives us another option or caching: you can store the

    FBML at a RL which will be cached by acebooks servers. et and

    reresh the RL with:

    facebook_session.sever_cache.refresh_ref_url(:url => http://url_for_cached_fbml)

    his RL will be cached by acebook until you call the method again.

    s with handle res, you can access the content with:

    andle res are preerred over RL res because they are set in real-

    time as opposed to being retrieved rom your server when needed.

    your server happens to be down and has a maintenance page up,

    then it is possible or your content to actually be the maintenance

    page when using RL res. urthermore, i you use RL res exten-

    sively, and a torrent o requests come in, it is possible to overload

    your servers. acebook also seems to have a high rate o ailure withretrieving RL res. nother reason to use handle res is because

    they are let unchanged when a ailure occurs. a ailure occurs while

    requesting a RL re, the content will get lled up with garbage.

    Ig Cg

    mages that are shown on non-canvas pages, such as in proles and

    i i d l b li itl h d b b k

  • 8/8/2019 Peepcode Facebook 2

    60/67

    60

    ini-eeds, can also be explicitly cached by acebook servers.

    facebook_session.sever_cache.refresh_img_src(:url => http://url_for_cached_image)

    hey can be accessed with:

    mages that are served to acebook canvas pages are automatically

    cached by acebook on the rst request. he above is mainly useul

    or the same reason that handle and RL res are useul; an image

    that is identical across many proles can be updated in one go using

    this method.

    Beboecently we added support into acebooker that allows your ails

    instance to simultaneously support both acebook and ebo (http://

    bebo.com). ebo supports the current API provided by acebook; how-

    ever, there is little indication that ebo will be embracing the next

    version o the role and API. hat being said, the dierences are

    not big enough that they cant be coded around. n order to support

    ebo you will have to go through the same steps to create an appli-

    cation on ebo that you did within the acebook developer applica-

    tion. ter doing this you will be given an api_key and a secret_key

    that can be put into your facebooker.yml. o setup your yaml le

    you will need to add 5 key value pairs as shown in the example below:

    development:api_key: 921628d9d70f5e0b5887936802abe9e6secret_key: 77sEcRETsecretSECRET3ce96ccanvas_page_name: ruby_footprintscallback_url: http://rfootprints.shacknet.nu

    bebo api key: abc45673de67f2234682919810adece7

    http://bebo.com/http://bebo.com/http://bebo.com/http://bebo.com/
  • 8/8/2019 Peepcode Facebook 2

    61/67

    61

    bebo_api_key: abc45673de67f2234682919810adece7bebo_secret_key: 77sEcRETsecretSECRET3ce96cbebo_canvas_page_name: bebo_ruby_footbebo_callback_url: http://rfootprints.shacknet.nubebo_adapter: BeboAdpater

    he most important key is bebo_adapter. his key tells ace-

    boker to load the Facebooker::BeboAdpater class instead o the

    Facebook::FacebookAdapter class. his adapter contains all the

    inormation needed to talk to the ebo API and to generate ebo-

    specic canvas page RLS. heyre handled with a beore lter on

    ApplicationController that will look at the incoming api_key, look

    up the correct conguration or that api_key, and load the appropri-

    ate Adapter. ccasionally it will be necessary to load a particular

    dapter manually. his can be done by calling Facebooker.load_

    adapter(bebo) since the deault adapter is always the Facebook-

    Adapter.

    here are some dierences in the ebo container and most o

    these are discovered along the way. n order to support conditional

    rendering o ebo-specic FBML, you can call Facebooker.is_

    for?(:bebo).

    A di T i l

  • 8/8/2019 Peepcode Facebook 2

    62/67

    62

    Appendix: Terminologychapter 10

    T D

    Canvas page he page where your

    application runs insideacebook.

    Callback RL he RL where your appli-

    cation is hosted.

    News eed ecent riend activity that

    shows up on the main

    acebook page

    ini-eed ecent riend activity that

    shows up on user prole

    pagesNotication riend and app invites/

    communication, tab under

    nbox

    Wide prole ox on the right side o the

    prole page

    Narrow prole ox on the let side o the

    prole page

    Wall Comments section on the

    prole page, most recentpost shown on top

    A di M d l

  • 8/8/2019 Peepcode Facebook 2

    63/67

    63

    Appendix: Modelschapter 11

    A

    name

    nid

    status

    type

    year

    A

    aid

    cover_pid

    createddescription

    link

    location

    modied

    name

    owner

    size

    AP

    about_url

    application_name

    callback_url

    dashboard_url

    deault_column

    deault_bml

    description

    desktop

    dev_mode

    edit_urlemail

    help_url

    installable

    ip_list

    is_mobile

    message_action

    message_url

    post_install_urlpreload_ql

    privacy_url

    private_install

    see_all_url

    tos_url

    uninstall_url

    use_irame

    C

    expires

    name

    path

    uid

    value

    EI

    concentrations

    degree

    nameyear

    HgI

    grad_year

    hs1_id

    hs1_name

    hs2_id

    hs2_name

    Ev

    creator

    description

    eid

    end_time

    event_subtype

    event_type

    host

    location

    name

    nidpic

    pic_big

    pic_small

    start_time

    tagline

    update_time

    venue

    A

    eid

    rsvp_status

    uid

    F L I I

  • 8/8/2019 Peepcode Facebook 2

    64/67

    64

    FL

    fid

    name

    G

    creatordescription

    gid

    group_subtype

    group_type

    name

    nid

    oce

    picpic_big

    pic_small

    recent_news

    update_time

    venue

    website

    M

    gid

    position

    uid

    II

    description

    image

    label

    link

    sublabel

    IS

    eld

    items

    L

    city

    country

    state

    zip

    N

    event_invites

    riend_requests

    group_invites

    messages

    pokes

    shares

    P

    aid

    caption

    created

    link

    owner

    pid

    src

    src_big

    src_small

    title

    Tg

    pid

    subject

    xcoord

    ycoord

    U

  • 8/8/2019 Peepcode Facebook 2

    65/67

    65

    U

    about_me

    activities

    aliations

    birthday

    books

    current_location

    education_history

    rst_name

    has_added_app

    hometown_location

    hs_ino

    id

    interestsis_app_user

    last_name

    meeting_or

    meeting_sex

    movies

    music

    name

    notes_count

    pic

    pic_big

    pic_small

    pic_square

    political

    prole_update_time

    U

    quotes

    relationship_status

    religion

    session

    sex

    signicant_other_id

    status

    timezone

    tv

    uid

    wall_count

    work_history

    S

    message

    time

    WI

    company_namedescription

    end_date

    location

    position

    start_date

    The Authors

  • 8/8/2019 Peepcode Facebook 2

    66/67

    66

    The Authors

    Dv C

    avid has been doing uby n ails consulting or over three years

    and is currently acting as irector o Web evelopment or eeting-

    Wave (wwww.meetingwave.com). is current ocus is on providing value

    through ocial Networking integrations on the acebook, ebo and

    the ihone latorms. s regular contributor to the acebooker library

    he also maintains the acebooker utorial (http://apps.facebook.com/

    facebooker_tutorial) application on acebook. e lives in sunny oulder,

    Colorado and occasionally nds time or ountain iking and now-

    boarding. e can be reached at [email protected] or on

    acebook (http://www.facebook.com/profile.php?id=830904376).

    S Vhane is a programmer living in Chicago, , and is one o the com-

    mitters on the acebooker ails plugin. e has built a handul o

    acebook applications, with the most popular being Video ukebox

    (http://apps.facebook.com/jookbox). e has worked or some big companies

    such as otorola and rbitz, but is now an independent developer.

    hane started programming at the tender age o 12 and has worked

    on a broad range o platorms and languages. e is currently trying

    to apply his acebook experience to the ihone application market.

    e has a ew applications in the iunes pp tore and working onmore. When he is not on a coding binge, he likes to play the drums

    and ride a snowboard. is application, rum Kit, is one o the op 25

    selling ihone apps.

    Check out hanes ihone apps in the pp tore (http://phobos.apple.

    com/WebObjects/MZStore.woa/wa/viewArtist?id=284976112 ).

    Credits

    http://wwww.meetingwave.com/http://apps.facebook.com/facebooker_tutorialhttp://apps.facebook.com/facebooker_tutorialhttp://www.facebook.com/profile.php?id=830904376http://apps.facebook.com/jookboxhttp://phobos.apple.com/WebObjects/MZStore.woa/wa/viewArtist?id=284976112http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewArtist?id=284976112http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewArtist?id=284976112http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewArtist?id=284976112http://apps.facebook.com/jookboxhttp://www.facebook.com/profile.php?id=830904376http://apps.facebook.com/facebooker_tutorialhttp://apps.facebook.com/facebooker_tutorialhttp://wwww.meetingwave.com/
  • 8/8/2019 Peepcode Facebook 2

    67/67

    Creditshanks to ichael Neissner or reviewing the book, and everyone at

    eepCode or amazing layout, design, and editing.

    Revisionsanuary 7, 2009 Corrected name o acebooker:setup rake task.