AmazonWishlist
From Facebook Developer Wiki
Contents |
What is this app?
This is a simple Facebook platform application, written in Ruby on Rails, that displays contents of an Amazon wishlist within your profile. Check it out here:
http://apps.f8.facebook.com/amazon_wishlist/
This is running off my laptop at the moment, so you may be greeted with a server error. Let me know at lshepard@facebook.com if you have problems.
To see a demo in a working profile, check out http://www.f8.facebook.com/profile.php?id=676075965 .
Tutorial for Sample Facebook Ruby App (uses the old version of the RFacebook gem)
This little guide assumes that you've already got a working ruby on rails app. This is a description of how I got it working; please feel free to ask or update the wiki with suggestions if your experience differs.
Set up your developer settings correctly
Here's how I set up my Developer Settings (in the Facebook Developer application):
- Callback URL:
http://localhost:3000/wishlist - Canvas page URL:
http://apps.facebook.com/amazon_wishlist - Select "Use iframe"
- Application type: website
- Can your application be added? Yes.
- Post-add URL:
http://apps.f8.facebook.com/amazon_wishlist/install/ - Sidenav URL:
http://apps.f8.facebook.com/amazon_wishlist/sidenav
I prefer to put the actual IP in only one place - the Callback URL - and let all other URLs point to the canvas page. The canvas page just puts a wrapper around the callback URL, and anything after the base canvas url will be appended to your callback. So in this case, I specified the "wishlist" controller as the callback, so anything appended to the canvas page will refer to an action on that controller. This makes it really easy to add new canvas pages.
1. Download the client and put it in lib/
These files go in /lib: facebook_session.rb and facebook_web_session.rb
2. Put application.rb in app/controllers
application.rb is some glue code that will apply to all controllers, to ease the authentication piece of facebook. The key lines are these:
require "facebook_web_session" class ApplicationController < ActionController::Base # Pick a unique cookie name to distinguish our session data from others' session :session_key => '_sidestep_session_id' before_filter :initfb before_filter :require_login, :except => [:view, :index, :list] @@current = nil
which guarantee that any controller will have a variable called @fb, which represents the facebook session.
3. Put user.rb in app/models
I found it helpful to have a User class. The basic class provided in the library just stores the session key, so that you can reload between sessions. Feel free to add fields for use within your application (see the AmazonWishlist app for an example of how I did it)
4. Create controllers for each of the URLs required in your application configuration
The Facebook Developer app requires that you enter certain URLs. I suggest using the "Callback URL" as the address of the controller of your rails application, and then setting each page to be an action on that controller. So for instance, mine was set up like this:
- Callback URL: localhost:3000/wishlist
- Post-add URL: apps.f8.facebook.com/amazon_wishlist/install
- Sidenav URL: apps.f8.facebook.com/amazon_wishlist/sidenav
Then my controller has actions for each of the
class WishlistController < ApplicationController
# default canvas page goes here
def index
@fb = RFacebook::FacebookWebSession.new(API_KEY, API_SECRET)
@install_url = @fb.get_install_url()
end
def install
settings()
end
def sidenav
settings()
end
def settings
if (current_user.nil?)
@wishlist_id = current_user.wishlist_id
@max_items = current_user.max_items
end
render :action => "settings"
end
Application-specific code can go in their own actions:
def update
@wishlist_id = params['wishlist_id']
@max_items = params['max_items']
# here is where the update happens
user = current_user # get current logged in user
if (user.nil?)
flash[:error] = "Unable to find logged-in user"
else
# save
user.wishlist_id = @wishlist_id
user.max_items = @max_items
user.save
end
refresh()
end
# updates the FBML for the user's profile
def refresh
@wishlist_id = current_user.wishlist_id
@max_items = current_user.max_items
if (!@wishlist_id.nil?)
puts "Wishlist ID nil. User:" + current_user.inspect
@items = AmzConnection.instance.search_by_wishlist_id(@wishlist_id)
if (@items.empty?)
flash[:error] = "There were no items found for wishlist ID '" + @wishlist_id + "'"
else
markup = render_to_string(:action => "profile")
@fb.profile_setFBML(
:markup => markup
)
flash[:error] = "Updated profile successfully!"
end
else
flash[:error] = "Wishlist ID was not found"
end
puts @items.inspect
settings()
end
Note the call to profile_setFBML:
@fb.profile_setFBML(
:markup => markup
)
The RFacebook library handles all the extra session-specific fields that you need to send, so you only need to worry about the fields that differ for each API call.
Source code
The source code for the app uses a slightly tweaked RFacebook library. You can download all the source code (which includes the library) at
http://www.lukeshepard.com/wishlist.tgz
There is a README included which details the basic steps necessary to get it up and running.
Questions?
If you have questions, you can find me at the conference (Luke Shepard) or IM me at CodeMonkeyLuke.
