AmazonWishlist

From Facebook Developer Wiki

Jump to: navigation, search

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):

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.