Peepcode Facebook 2
-
Upload
brett-huneycutt -
Category
Documents
-
view
224 -
download
0
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.