Pushrod

Old dogs, new tricks

The how and why of my streamlined Rails Facebook library

with 22 comments

As I wrote in my previous post (Rails, Ruby, Facebook and tests — my own itch scratched), I needed a Facebook library for Autopendium :: Stuff about old cars, the classic car community site we built on Ruby on Rails, but couldn’t get to grips with the existing library as there were no tests and the code seemed, well, a bit un-ruby-ish.
The solution, particularly given that no one else seemed to have a problem it, was for me to come up with something myself.

First job, try to understand the Facebook API, and in particular the Request/Response cycle. What exactly was going on and what is this Facebook object the documentation talks about?

The ‘Facebook Object’

First thing to know is that the Facebook API is a REST interface. That means there’s no state between requests. So each time you talk to Facebook it’s a fresh request, and the only info it has is that which you pass to it. Similarly, Facebook’s response tells you everything you need to know in that one response.

With this in mind and trying a few dummy requests from the command line with CURL things began to come a bit clearer, especially after looking through the Facebook php library supplied with the Facebook dummy app (my knowledge of php is elementary to say the least, but the naming of the ‘behaviours’ and the comments helped). With that in mind I began to write some dummy controller code:

facebook.fb_users_get_info(:uids => facebook.user, :fields => "first_name, last_name")

It’s worth stressing that I didn’t know what that meant, or how it would be implemented, I just thought that I should be able to ask the mystical facebook object for some info on a given user if it was going to be useful.

Next step was to write some unit tests:

def test_should_be_able_to_instantiate_a_facebook_object
assert FacebookUtilities::Facebook.new
end

Well, duh! But what is a Facebook object already! The main existing library calls it a FacebookSession, which confused me, as it made me think of server-side sessions (that’s probably my fault though). The php library, however, just calls it an object, and we know about those, don’t we. This is Ruby after all.

So the Facebook object is just an instance of the Facebook Class, which defines the Facebook objects behaviours and attributes. Great. That meant, all I had to do was to go through the php library identifying the behaviours, write the (failing) tests, then write the code that made the tests pass.

Simple. Here, for example is the test for generating the Facebook signature (this is the a verification code that’s passed from you to the Facebook API and from the Facebook API to you to confirm it’s a genuine request, and it’s generated using a secret key that Facebook gives you when you register your application).


def test_should_return_signature_from_given_params
fb_object = FacebookUtilities::Facebook.new
assert fb_object.respond_to?(:signature_from)
assert_equal Digest::MD5.hexdigest(FacebookUtilities::FACEBOOK_API_SECRET), fb_object.signature_from
assert_equal Digest::MD5.hexdigest("a_param=1234xb_param=5678yc_param=97531t#{FacebookUtilities::FACEBOOK_API_SECRET}"), fb_object.signature_from({:b_param => "5678y", :c_param => "97531t", :a_param => "1234x"})
end

I derived that from the folowing php code and the Facebook authentication page:

public static function generate_sig($params_array, $secret) {
$str = '';

ksort($params_array);
// Note: make sure that the signature parameter is not already included in
// $params_array.
foreach ($params_array as $k=>$v) {
$str .= “$k=$v”;
}
$str .= $secret;

return md5($str);
}
Once the test was written the code was straightforward:


def signature_from(params={})
request_str = params.collect {|p| "#{p[0].to_s}=#{p[1]}"}.sort.join # build key value pairs, sort in alpha order then join them
return Digest::MD5.hexdigest("#{request_str}#{FACEBOOK_API_SECRET}")
end

And I went through the library like that, simply looking at the behaviour, writing failing tests, then writing the code to make them pass.

In the end, I had a fairly elementary but streamlined library to get any Rails up and working with Facebook in no time. It doesn’t have lots of bells and whistles, but is (hopefully) fairly easy to understand just by reading the code and the tests, and is a cinch to extend and adapt to your particular needs. Oh, and it works for me.

Quick usage guide (for those who don’t like reading code or tests)

1. Download the library from here and the tests from here

2. Put the library in you /lib folder in a file marked facebook_utilities.rb and the tests in your /tests/unit folder in a file called facebook_utilities_test.rb

3. Update the FACEBOOK_API_KEY and FACEBOOK_API_SECRET constants for the ones Facebook gave you when you registered your application (see here for a good article which explains how to do that, and much more).

4. Put “include FacebookUtilities::ControllerUtilities” at the top of any controller you want to Facebook-enable, or at the top of the Application controller if you want it for all your controllers.

5. Call the Facebook object from your controllers using the #facebook convenience method, e.g. facebook.user returns the facebook user id of the user who’s logged into your Facebook app.

There are also a couple of utility methods to use with before_filters: #require_added_fb_app, #require_logged_in_to_fb_app, and #require_fb_frame. These restrict access to facebook users who have, respectively: added your Facebook application, logged in to your Facebook application, or are acessing the application with a Facebook frame (either through an iframe or an FBML canvas).

There’s also an #fb_redirect_to method (aping the similar php one) to use for redirecting to other pages while you’re in the Facebook frame. Briefly, this does a FBML redirect if you’re in a FBML canvas, a javascript redirect if you’re going to another Facebook page (you’re probably in an iframe, and doing an ordinary redirect would result in an iframe within and iframe), and a plain old vanilla redirect_to otherwise.

6. Call any of the methods in the API using a ruby-ized version of the method name preceded with ‘fb_’. So, groups.getMembers which requires a of group id is called by facebook.fb_groups_get_members(:gid => “12345”). You don’t need the api_key, session_key, call_id, sig, or v parameters that are standard required parameters. These are supplied by the facebook object automatically (after all it wouldn’t be much of a Facebook object if it didn’t).

Still confused? Have a play with a dummy app in iframe mode with your app in development mode and a Facebook controller (put something like localhost:3000/facebook in the canvas URL) and check out the requests and responses the console spits out. In development mode, the library logs all the calls and responses to and from Facebook.

Not enough? If the demand is there I might do a bit of a tutorial if I can get the Autopendium Facebook app finished in the next day or so (still getting the FBML right, but that’s another story)

Cheers
Chris
p.s. Sorry about the code formatting. Still getting to grips with WordPress

Updated 15 Aug 07: Added info about controller methods

Advertisements

Written by ctagg

August 15, 2007 at 7:15 pm

Posted in facebook, rails, ruby, testing

22 Responses

Subscribe to comments with RSS.

  1. I already commented on your previous post (sorry to post in both places), but I thought I would mention here as well – RFacebook (http://rfacebook.rubyforge.org) is hosted over at Rubyforge with the intention of good developers like yourself joining to improve it. The developers and community around RFacebook would really appreciate your contribution of test cases to the project, rather than rolling a separate plugin. If you’re interested, please shoot me an email.

    Matt P

    August 21, 2007 at 7:10 pm

  2. The test suite requires Mocha. Once you have that installed, you can use Mocha in your own controllers to mock out Facebook authentication. Here’s a method I put in my test_helper.rb:

    def login_user(uid)
    FacebookUtilities::Facebook.any_instance.expects(:logged_in_to_app?).returns(true)
    FacebookUtilities::Facebook.any_instance.stubs(:user).returns(uid)
    end

    In your controller you use facebook.user to get the logged in user’s uid.

    Thanks again, Chris!

    Ryan Lowe

    August 28, 2007 at 12:28 am

  3. Hi,
    How do I get in touch with you if I have questions.

    Td

    Todd

    August 30, 2007 at 5:41 am

  4. Leave a comment here, or email me at chris dot taggart at pushrodmedia dot co dot uk

    autopendium

    August 30, 2007 at 7:15 am

  5. wow, your facebook code is great! much easier to install and use than any other option out there. your implementation of method_missing is sheer genius!

    i do have a question, tho:
    using “before_filter :require_logged_in_to_fb_app” in application.rb seems to hit http://www.facebook.com on every page request, prevent POSTs and cause the following error when I press Reload in my browser it throws a FacebookApiError in response to a facebook.auth.getSession request that’s been inplicitly initiated with the existing page’s ?auth_token= value.

    clearly i’m doing something wrong, but i can’t for the life of me figure out what. can you offer some guidance?

    much obliged,

    lenny in california

    Lenny

    November 23, 2007 at 11:06 am

  6. Using before_filter :require_logged_in_to_fb_app in application.rb will mean that before any action is run (and on any controller), the controller will check that the user is logged_in to the your facebook application (I only run it on a couple of my actions — those that are personalized for the user, not the intro page, and not the latest additions page).

    If they’re not, it will redirect the user to the login page.

    I’m not sure I’m understanding the behaviour when you reload. Is the auth_token there in the original request? Can you post or email me (chris dot taggart at pushrodmedia dot co dot uk) the stack trace of the errors you’re getting. You can also change the log levels on lines 83 and 85 to error, so that you get more info even in production env.

    autopendium

    November 23, 2007 at 12:30 pm

  7. Thanks, Chris. I send you a PM but I suspect it got spam-filtered, so here’s the stack trace from reloading http://localhost:3000/things/list/1234335?auth_token=
    My app will be 100% Facebook so all active pages will need login. Thanks again for this great library and your help.

    Processing ThingsController#list (for 127.0.0.1 at 2007-11-23 16:21:37) [GET]
    Session ID: …
    Parameters: {“action”=>”list”, “id”=>”…”, “auth_token”=>”…”, “controller”=>”things”}
    ****facebook API call: {“session_key”=>nil, “v”=>”1.0”, “api_key”=>”…”, “method”=>”facebook.auth.getSession”, “sig”=>”…”, “auth_token”=>”…”, “call_
    id”=>”…”}
    ****Facebook method facebook.auth.getSession called with {:auth_token=>”…”}.
    Response: “<?xml version=\”1.0\” encoding=\”UTF-8\”?\n\n 100\n Invalid parameter\n \n \n session_key\n \n \n \n v\n 1.0\n \n \n api_key\n …\n \n \n method
    \n facebook.auth.getSession\n \n \n
    sig\n …\n \n \n auth_token\n …\n \n \n call_id\n …\n \n \n\n”
    ***Facebook API error: {“xsi:schemaLocation”=>”http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd“, “error_msg”=>[“Invalid parameter”], “request_args”=>[{“arg”=>[{“value”=>[{}], “key”=>[“session_key”]}, {“value”=>[“1.0”],
    “key”=>[“v”]}, {“value”=>[“…”], “key”=>[“api_key”]}, {“value”=>[“facebook.auth.getSession”], “key”=>[“method”]}, {“value”=>[“…”], “key”=>[“sig”]}, {“value”=>[“…”], “key”=>[“auth_token”]}, {“value”=>[“…”], “key”=>[
    “call_id”]}], “list”=>”true”}], “error_code”=>[“100”], “xmlns:xsi”=>”http://www.w3.org/2001/XMLSchema-instance”, “xmlns”=>”http://api.facebook.com/1.0/”}

    FacebookUtilities::Facebook::FacebookApiError (FacebookUtilities::Facebook::FacebookApiError):
    C:/Documents and Settings/lenny/My Documents/giftlist.com/giftlist.com/lib/facebook_utilities.rb:86:in `call’
    C:/Documents and Settings/lenny/My Documents/giftlist.com/giftlist.com/lib/facebook_utilities.rb:165:in `method_missing’
    C:/Documents and Settings/lenny/My Documents/giftlist.com/giftlist.com/lib/facebook_utilities.rb:101:in `get_new_session’
    C:/Documents and Settings/lenny/My Documents/giftlist.com/giftlist.com/lib/facebook_utilities.rb:56:in `initialize’
    C:/Documents and Settings/lenny/My Documents/giftlist.com/giftlist.com/lib/facebook_utilities.rb:182:in `new’
    C:/Documents and Settings/lenny/My Documents/giftlist.com/giftlist.com/lib/facebook_utilities.rb:182:in `facebook’
    C:/Documents and Settings/lenny/My Documents/giftlist.com/giftlist.com/lib/facebook_utilities.rb:205:in `require_logged_in_to_fb_app’
    C:/Documents and Settings/lenny/My Documents/giftlist.com/giftlist.com/app/controllers/application.rb:22:in `require_facebook’
    C:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/filters.rb:469:in `send’
    C:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/filters.rb:469:in `call’
    C:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/filters.rb:442:in `run’
    C:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/filters.rb:714:in `run_before_filters’
    C:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/filters.rb:694:in `call_filters’
    C:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/filters.rb:688:in `perform_action_without_benchmark’
    C:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/benchmarking.rb:66:in `perform_action_without_rescue’
    C:/ruby/lib/ruby/1.8/benchmark.rb:293:in `measure’
    C:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/benchmarking.rb:66:in `perform_action_without_rescue’
    C:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/rescue.rb:83:in `perform_action’
    C:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/base.rb:435:in `send’
    C:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/base.rb:435:in `process_without_filters’
    C:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/filters.rb:684:in `process_without_session_management_support’
    C:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/session_management.rb:114:in `process’
    C:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/base.rb:334:in `process’
    C:/ruby/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/dispatcher.rb:41:in `dispatch’
    C:/ruby/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/webrick_server.rb:113:in `handle_dispatch’
    C:/ruby/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/webrick_server.rb:79:in `service’
    C:/ruby/lib/ruby/1.8/webrick/httpserver.rb:104:in `service’
    C:/ruby/lib/ruby/1.8/webrick/httpserver.rb:65:in `run’
    C:/ruby/lib/ruby/1.8/webrick/server.rb:173:in `start_thread’
    C:/ruby/lib/ruby/1.8/webrick/server.rb:162:in `start’
    C:/ruby/lib/ruby/1.8/webrick/server.rb:162:in `start_thread’
    C:/ruby/lib/ruby/1.8/webrick/server.rb:95:in `start’
    C:/ruby/lib/ruby/1.8/webrick/server.rb:92:in `each’
    C:/ruby/lib/ruby/1.8/webrick/server.rb:92:in `start’
    C:/ruby/lib/ruby/1.8/webrick/server.rb:23:in `start’
    C:/ruby/lib/ruby/1.8/webrick/server.rb:82:in `start’
    C:/ruby/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/webrick_server.rb:63:in `dispatch’
    C:/ruby/lib/ruby/gems/1.8/gems/rails-12.5/lib/commands/servers/webrick.rb:59
    C:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require’
    C:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require’
    C:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:495:in `require’
    C:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:342:in `new_constants_in’
    C:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:495:in `require’
    C:/ruby/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/commands/server.rb:39
    C:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require’
    C:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require’
    C:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:495:in `require’
    C:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:342:in `new_constants_in’
    C:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:495:in `require’
    ./script/server:3
    -e:4:in `load’
    -e:4

    Rendering C:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/templates/rescues/layout.rhtml (500 Internal Error)

    On Nov 23, 2007 3:06 AM, Lenny Turetsky wrote:
    > wow, your facebook code is great! much easier to install and use than
    > any other option out there. your implementation of method_missing is
    > sheer genius!
    >
    > i do have a question, tho:
    > using “before_filter :require_logged_in_to_fb_app” in application.rb
    > seems to hit http://www.facebook.com on every page request, prevent POSTs and
    > cause the following error when I press Reload in my browser it throws
    > a FacebookApiError in response to a facebook.auth.getSession request
    > that’s been inplicitly initiated with the existing page’s ?auth_token=
    > value.
    >
    > clearly i’m doing something wrong, but i can’t for the life of me
    > figure out what. can you offer some guidance?
    >
    > much obliged,
    >
    > lenny in california
    >

    Lenny

    November 24, 2007 at 12:30 am

  8. I’m guessing that you’ve deleted the values for the sensitive params. Assuming that, Facebook seems not to be liking one of the params — possibly the auth code itself. Can you:
    1) Walk me through the URL calls your app is making to get the auth code
    2) Post details of the original auth.getSession call (i.e. before the reload)
    Cheers
    Chris

    autopendium

    November 24, 2007 at 8:13 am

  9. Hi Chris,

    Thanks again for all your help. I can’t tell you how much effort your library has saved me.

    Here’s the full contents of my application.rb:
    include FacebookUtilities::ControllerUtilities
    class ApplicationController “…”, “v”=>”
    1.0″, “fields”=>”name”, “api_key”=>”…”, “method”=>”facebook.users.getInfo”, “uid”=>…, “sig”=>”…”, “call_id”=>”…”}/activesupport-1.4.4/lib/active_support/depend
    ****Facebook method facebook.users.getInfo called with {:fields=>”name”, :uid=>…}. by/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/commands/server.rb:39
    Response: “\n\n”rt-1.4.4/lib/active_support/depend
    Completed in 0.62500 (1 reqs/sec) | Rendering: 0.29700 (47%) | DB: 0.03100 (4%)
    | 200 OK [http://localhost/things?auth_token=…]ndencies.rb:342:in `new_constants_in’

    Yes, I did delete some values above and previously, mostly because I don’t yet understand the API well enough to know which ones are sensitive. But I’m pretty sure they’re valid.
    The issue seems to be when I *reload* a page that already has the “?auth_token=…” in its URL, because that page still causes a hit to the Facebook login server, which doesn’t seem to like getting the auth_token back. (In fact, I get the same behavior when I replace the value for auth_token with “12345”.)

    Probably they don’t like that I’m trying to create another session for the same auth_token. And I don’t want to create another token, but for some reason require_logged_in_to_fb_app thinks I do. 😛

    Why does it think that? Well, that’s where I’m stumped, but here’s what I’ve figured out from the stack trace: when I call require_logged_in_to_fb_app it needs to instantiate a FacebookUtilities::Facebook object to answer the question “facebook.logged_in_to_app?” and when calling facebook.new it finds that “@session_key = @fb_params[:session_key]” yielded nil. And that’s where I’m stumped because I don’t see any place where @fb_params[:session_key] is being set.

    BTW, in case it’s not painfully obvious already, I’m a Ruby newbie. Very impressed with Ruby and Rails so far, as well as how helpful the community is. So with that, I say thanks again.

    Lenny

    November 24, 2007 at 9:44 am

  10. I’m a bit slow this morning, but yes, the problem is, I think, that once you’ve used an auth_token to get a session_key, you can’t re-use that auth token again (and shouldn’t need to given you’ve got the session key).

    The reason you shouldn’t need it again is that each request that Facebook makes to your server (when you request a page on Facebook, Facebook in turn makes a request to your server, either via an iframe or direct, if it’s a canvas page) should contain the session key.

    The Facebook session instance parses all the params and pulls out the session_key, so you can use it when requesting info from Facebook (via its API), or when redirecting to another page.

    Can you email me the contents of one of your controllers (not the application controller), so I can see where the problem might be occurring.

    autopendium

    November 24, 2007 at 10:25 am

  11. Thanks again, Chris.
    I’m guessing this means that if I’m building an FB-app that isn’t only in a canvas-page, this library won’t work. Understandable, tho I’d like to find a way to extend it to apps with their own-presence.

    As for emailing you a controller, I’m a bit shy to share my Ruby-newbie spaghetti code, but the the following mini-Controller exhibits the behavior:
    class PeopleController < ApplicationController
    def index
    end
    end

    Thanks again.

    Lenny

    November 24, 2007 at 7:46 pm

  12. I wouldn’t worry about how it looks — we’ve all been there.

    I’ve got to head off now, but will look at this in the morning. Just to be clear (cos we’re in different time zones), a dummy action (I’m assuming there’s a ‘hello world’ template) is showing this behaviour?

    I’ll set up a basic app tomorrow and try to duplicate the behaviour, and see what’s going wrong. My app’s a bit more complicate these days, so I need to remind myself of the flow on a basic app.

    autopendium

    November 24, 2007 at 9:11 pm

  13. OK. I’ve set up a basic hello world app using an iframe and I’m unable to reproduce the errors. Here’s how I’ve got the app set up so you can see how your basic setup differs.

    — Basic rails app.
    — Single controller (DummyController):

    class DummyController < ApplicationController
    def index
    @user = facebook.user
    end
    end

    The index template is a single line:
    Hello

    — ApplicationController includes Facebook controller methods:

    class ApplicationController < ActionController::Base
    include FacebookUtilities::ControllerUtilities
    end

    The Facebook application (ct_qwiktest) is set up to use an iframe:
    Callback Url: http://localhost:3000/dummy

    and the index action is accessed via this URL:
    http://apps.facebook.com/ct_qwiktest/

    If I add a filter to the dummy controller:
    before_filter :require_logged_in_to_fb_app
    it redirects me to to app’s login page. Agreeing to login then allows the index page to render Hello XXXXX where XXXX is my facebook uid.

    If I change the filter to be :require_added_fb_app instead I get redirect to a page asking me if I want to add the application with a series of check boxes to specify what it should be able to do (i.e. permissions).

    I don’t get into the whole auth_token stuff because at all times I’m staying within the Facebook frame (whether iframe or canvas). I only need the auth_token for an outside page that isn’t render within the confines of the facebook frame — e.g. if I navigate to http://localhost:3000/dummy

    Not sure if this helps, but hopefully it will.

    autopendium

    November 25, 2007 at 4:26 pm

  14. Hi Chris,

    I guess the issue is that your library, while most excellent, is built only for apps that live entirely within Facebook. Fair enough. In fact, it’s encouraged me to make my app live entirely within FB, and use some of their mock AJaX. If you want to see it in action, it’s at http://apps.facebook.com/gimmmee/, and I couldn’t have built it without you.

    Thanks again,

    Lenny

    Lenny

    November 27, 2007 at 6:56 pm

  15. Lenny
    No, that’s not the case at all. The app I initially wrote it for is Autopendium (http://autopendium.com) which is mainly outside of Facebook.

    It’s partly why I needed a more flexible library, because the existing ones assumed that you lived wholly within Facebook.

    If you want, I can explain how I’ve tied up the Facebook users and other users together (and for that you do need to go through the whole auth_token stuff).

    Glad you’ve got your app working though. Like the sound of it. Logged in OK, but when I skipped the adding friends bit it tried to redirect me to http://apps.facebook.com/things/invite and raised an error

    autopendium

    November 27, 2007 at 8:29 pm

  16. […] 13, 2008 After the lightweight Facebook library I wrote to scratch my own itch, a couple of days ago I started to look at adding ebay items to […]

  17. I’d like to get a list of friends. I thought facebook.friends would allow me to do this but it doesn’t work. Any ideas?

    Garth

    February 8, 2008 at 11:36 am

  18. The Facebook call for getting the friends of the session user is friends.get (see http://wiki.developers.facebook.com/index.php/Friends.get), so using this library you should use facebook.fb_friends_get (where facebook is the session object)

    autopendium

    February 8, 2008 at 3:35 pm

  19. Thanks for the reply. I presume I need to parse the XML I get back from the call to get the UIDs? I’m using your library to power a Merb application rather than a Rails one. Thanks for writing this piece of code.

    Garth

    February 10, 2008 at 8:26 pm

  20. Sorry for the delay in replying. Somehow missed the comment notification and been wrapped up in other stuff.

    No, you don’t need to parse the XML, it’s automatically parsed by XMLSImple into a hash, with the object types as keys, e.g “members”.

    See Line 188 of the test suite:
    #test_should_call_facebook_with_given_method_and_params_and_return_parsed_xml_response_from_calling_facebook_method

    autopendium

    February 15, 2008 at 7:07 pm

  21. […] written elsewhere about how I used my own lightweight library to add Facebook functionality to Autopendium :Stuff About Old Cars, the classic car community website I […]

  22. Hi,

    I’m using ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32].

    I’m trying to test unit facebook_utilities.rb.

    Hopefully you are willing to help me. Here is the error message:

    c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/dependencies.rb:155:in `require’: C:/eclipse/Data/test2/lib/facebook_utilities.rb:213: syntax error, unexpected $end, expecting kEND (SyntaxError)
    from c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/dependencies.rb:155:in `require’
    from c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/dependencies.rb:262:in `require_or_load’
    from c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/dependencies.rb:427:in `load_missing_constant’
    from c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/dependencies.rb:77:in `const_missing’
    from c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/dependencies.rb:89:in `const_missing’
    from c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/dependencies.rb:439:in `load_missing_constant’
    from c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/dependencies.rb:93:in `const_missing’
    from ./test\unit\facebook_utilities_test.rb:335
    from C:/eclipse/Data/.metadata/.plugins/org.rubypeople.rdt.testunit/ruby/RemoteTestRunner.rb:302:in `require’
    from C:/eclipse/Data/.metadata/.plugins/org.rubypeople.rdt.testunit/ruby/RemoteTestRunner.rb:302

    Mazz Yon

    January 30, 2009 at 10:06 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: