the two alexs

Koala 1.0.0.beta2 released!

Hey everyone,

We’re excited to announce the release of Koala 1.0 beta 2!  Thank you all for the feedback and ideas that you’ve sent and we’ve incorporated over the last month — thanks to them, Koala is much stronger and easier to use than ever before.

Revised Photo Uploads

With this beta, we’ve revamped photo uploads, making the process simpler by replacing the file hash with a number of convenient options:

# 1) Path to a photo
@graph.put_picture(path_to_my_file)
# 2) Upload a file directly
@graph.put_picture(file_class_object)
# 3) Rails 3 file uploads (ActionDispatch::Http::UploadedFile)
@graph.put_picture(params[:file])
# 4) Sinatra file uploads (Hash)
@graph.put_picture(file_hash)

See more about the new photo interface on the updated Koala wiki.

Important note: the new, final interface is not backwards compatible, so you’ll have to update your code once you upgrade to beta2.  Sorry about that :\

Other Updates

  • Added put_connection and delete_connection convenience methods, which can be used for manipulating albums and provides future compatibility with new Graph API methods.
  • You can now provide an http_options hash to any method as the final parameter (see http_services.rb for more info).
  • You can test your apps against Facebook’s beta tier by passing :beta => true in the http options for any method.
  • TestUser#befriend now requires user info hashes (id and access token) due to Facebook API changes
  • Koala’s APIError is now < StandardError, not Exception

Upgrading

To install the beta, just run sudo gem install koala –pre.  (This seems to work for both 0.10 and 1.0.0.beta1.)

To 1.0

In the next few weeks, we’ll be adding native Typhoeus file upload support and working through the fork and pull queues, which are filled with great ideas.  We’ll probably release one more beta to let you all play with Typhoeus uploads, and once that dust settles we’ll release the final version.

As always, please send us any feedback, comments, and questions!  We’re happy to hear from you.

Best,

The Koala Team
(Alex, Chris, Rafi, and the folks at Context Optional)

Koala 1.0 beta!

Hey everyone,

We’re very excited to announce the beta release of Koala 1.0!  This is a huge release, well deserving of the version bump.  With this update, we’ve expanded Koala to support the entire current Facebook platform and have made improvements throughout the library to make Koala faster, easier, and more stable.

Photo Uploads

You read that right — Koala now supports photo uploads!  We’ve integrated Nick Sieger’s multipart-post gem to provide support through Net::HTTP.  Koala’s Graph API now offers a #put_picture method as well as support for posting file to Facebook through any Graph or REST API method.

# put_picture requires a hash containing info about the photo to upload
file_hash = {
  "path" => 'path/to/some-image-file.jpg',
  "content_type" => 'image/jpeg'
}

@graph.put_picture(file_hash, :message => "I've uploaded a photo!")
# => { "id" => FACEBOOK_UID_FOR_THE_PHOTO }

You can learn more about photo uploads here on the Uploading Photos wiki page.

Photos are in beta

During this beta period, we’ll be working hard to make photo uploads as simple as the rest of Koala.  By the time we officially launch 1.0, you’ll be able to easily upload photos using File objects, temporary uploads to Rails or Sinatra, or from any other source using the same hash system we have now.  We’ll also incorporate native support for Typhoeus file uploads as soon as that’s released (huge thanks to our friend JT Archie for implementing that feature).

Other Enhancements


API Methods:

  • GraphAPI#delete_like: self-explanatory and useful. (Thanks, waseem!)
  • OAuth#parse_signed_request: updated to support Facebook’s current canvas encryption plans.

Internal improvements:

  • For public requests (e.g. no access token), Koala now uses http instead of https to improve speed; this can be overridden globally or per request.
  • Read-only REST API requests now go through Facebook’s faster api-read server.
  • For consistency, GraphAPI#delete_object will now raise an error if there’s no access token (like #put_object and #delete_like).

Test Suite improvements:

  • We’ve expanded the tests for the HTTP service modules.
  • Live tests now verify that the access token has the necessary permissions before starting.
  • We’ve replaced the 50-person network test, which often took 15+ minutes to run live, with a much faster 5-person test.

Installing 1.0.0.beta

Installing the beta is simple — just run

sudo gem install koala --pre

Download the new version and give it a go.  If you hit any problems with photo uploads, the under-the-hood improvements, or anything else, please open a ticket on Github and we’ll get it fixed.  As always, too, if you have any questions/comments/feedback, just drop us an email.

Happy coding!

The Koala Team
(Alex, Chris, Rafi, and the folks at Context Optional)

Koala 0.9.1 released

Hey everyone,

We’ve just released Koala 0.9.1. This release contains fixes to make the Koala test suite compatible with Ruby 1.9.2 and resolves two gem configuration issues that were reported by developers on Rails 3.

As always, let us know if you find any bugs or have any requests or suggestions for the next release — just open an issue on Github.

Cheers,

Alex
http://github.com/arsduo/koala/

Koala 0.7.0 released!

Hey everyone,

I’m happy to announce that Koala 0.7.0 has been officially released! This version includes two major updates:

  • A new RealtimeUpdates class, which can be used to manage subscriptions for realtime user updates (see http://developers.facebook.com/docs/api/realtime)
  • Added greatly improved testing using mocks rather than live calls to Facebook; these are now the default set of tests.

We also added some minor but useful enhancements:

  • Added Koala::Response class (internally), which encapsulates HTTP results since Facebook sometimes sends data in the status or headers
  • Used that to add a get_picture method to the GraphAPI class, which fetches an object’s picture from the redirect headers
  • Much other internal refactoring
  • Updated readme, documentation, and changelog

Download the latest gem and check it the code at http://github.com/arsduo/koala!

As always, I want to thank my co-contributor Chris Baclig for his invaluable work, which has made this project so much better.  I also want to thank Jeremy Dunn for contributing most of the realtime updates code, and Adeel Ahmad for discovering the picture issue and its source.

Finally, if you know what Koala is and you’re not yet part of our Google Group, come join us!  It’s a great place to ask any questions you have about Koala or about the Facebook APIs in general.

Have a great Wednesday,

Alex

The OAuth Playground

Hey everyone,

It’s high time I unveiled the OAuth Playground – a microsite designed to make it dead simple to get valid OAuth codes and access tokens so you can focus on building your apps and libraries.  As I discovered creating Koala (which powers the Playground), working with OAuth requires an incredibly repetitious cycle of generating and regenerating the authentication info for Facebook.  Really, human beings shouldn’t have to spend three minutes in the browser just to test a wall post.  Computers should do that kind of thing for us.  In that spirit, once I was sufficiently fed up, I took a few minutes to learned Sinatra (highly recommended) and then built a site to do all that OAuth ritual for you and for me.

The OAuth Playground lives at http://oauth.twoalex.com, and lets you:

  • Log into Facebook via OAuth and see the OAuth code, access token, and all the other data produced through redirect-based authentication.
  • Log into Facebook via the Javascript SDK (once known as Facebook Connect) and see the cookie data and your access token.
  • Control extended permissions, adding and revoking options at will to produce a token or OAuth URL with the abilities you need.*
  • Copy and paste Koala code samples so you can jump right in with irb.

If you’re playing with OAuth or the Graph API, you should definitely check out the Playground.  I mean, where else are you going to get an OAuth access token with offline_access, user_photo_video_tags, and friends_hometown permissions on a moment’s notice?

Best,

Alex

PS the OAuth Playground is, of course, open source.

* Note: don’t forget to hit the Update Permissions button when changing permissions.  The UI there is awkward, and we’re on it.

Seen elsewhere talking about F8

Earlier this week I wrote a blog post about F8 and the Context Optional Hackathon for the company blog. It’s great to see my thoughts on the big takeaways from F8 and what we learned at the Hackathon published on the company site; it’s even better to have kicked off the engineering category with the very first (of many) posts by a developer.

Check it out:
http://www.contextoptional.com/2010/reflections-on-f8-and-our-first-company-hackathon/

Have a great weekend,

Alex

Introducing Koala: a new gem for Facebook’s new Graph API

Check out Koala’s official documentation on our Github wiki! It has all the same content, but as of version 0.5.0, the wiki is more up-to-date.

I’m excited to announce the first release of Koala (http://github.com/arsduo/koala), a lightweight and flexible Facebook Graph library for Ruby.

Introductions all around

Using Koala, you have complete access to the Facebook Graph API — in a moment, we’ll go through how to use it to read from and write to the social graph.  Before we dig into this very long blog post, though, it’s worth a moment to go over our four goals for the library.

Koala’s goals

  • Lightweight: Koala should be as light and simple as Facebook’s own new libraries, providing API accessors and returning simple JSON.  (We clock in, with comments, just over 300 lines of code.)
  • Fast: Koala should, out of the box, be quick. In addition to supporting the vanilla Ruby networking libraries, it natively supports Typhoeus, our preferred gem for making fast HTTP requests. Of course, That brings us to our next topic:
  • Flexible: Koala should be useful to everyone, regardless of their current configuration.  (We have no dependencies beyond the JSON gem.  Koala also has a built-in mechanism for using whichever HTTP library you prefer to make requests against the graph.)
  • Tested: Koala should have complete test coverage, so you can rely on it.  (By the time you read this the final tests are being written.)

Also, I want Koala to be great Ruby, and to be responsive to your needs and suggestions. This is my first gem, so please, send me any suggestions, feedback, or comments you have.

History for the historically minded (the rest of you can skip to the code)

How Koala came about: I was lucky  to go to Facebook’s F8 conference a week and a half ago, and even luckier to have the chance to meet several Facebook Platform engineers (a big thank-you to Context Optional, my employer, for making both possible).  As you may know, Facebook released their new Graph API at F8 — a much, much, much simpler way of accessing Facebook data.  The Facebook engineers I met there were justifiably proud of the new interface and how its simplicity allowed them to write a complete Python library in just over 200 lines of code.

As we were talking, those engineers offhandedly suggested someone port their new library to Ruby — a challenge too good to refuse.  The public beta of their new Javascript SDK had already won me over to the simple API philosophy of a generic API accessor providing JSON output, and I jumped at the chance to bring that approach to Ruby.  By the end of the conference, I could fetch data, and by the end of the night, I had read/write access to the entire social graph.  I’ve spent the next week building out the library with Rafi Jacoby at Context Optional, and now the Koala gem is ready for use.

Using Koala

Playing with Koala is every bit as warm and cuddly as the real animal would be in a perfect world.

Getting the Code

Let’s start by installing the gem:

gem install koala # sudo if needed

Once that’s done, using Koala is simple:

require 'rubygems'
require 'koala'
#
# initialize a Graph API connection
@graph = Koala::Facebook::GraphAPI.new

A note on namespaces

To avoid conflict with anyone else’s Facebook class or module, I’ve namespaced everything inside the Koala module. I highly recommend you add ‘include Koala’ (or even ‘include Koala::Facebook’) to skip all that wordiness if your environment doesn’t already have a Facebook class.

Graph API: now in your browser!

Important side note: did you know you can play with the Graph API in your browser? It’s one of my favorite aspects of the new API. For each example coming up, I include a link to the equivalent query. If you haven’t been to graph.facebook.com, you should definitely click through and play with the results. (Try your own nickname!) Since I’m abbreviating the API results for space, I strongly encourage you to check it out.

Getting public data

Let’s first get some data from Facebook.  To learn about an object, just use the get_object method.  For instance, you can learn about people:

# http://graph.facebook.com/koppel
@graph.get_object("koppel")
# => {"name"=>"Alex Koppel", "id"=>"2905623", "last_name"=>"Koppel", "link"=>"http://www.facebook.com/koppel", "first_name"=>"Alex"}

And Pages:

# http://graph.facebook.com/contextoptional
@graph.get_object("contextoptional")
# => {"name"=>"Context Optional, Inc.", "id"=>"7204941866", ....}

Even anonymously, you can get certain connections like a Page’s feed:

# http://graph.facebook.com/contextoptional/feed
@graph.get_connections("contextoptional", "feed")
# => {"data"=> array_of_stream stories }

As well as details about individual public stories:

# http://graph.facebook.com/7204941866_117111188317384
@graph.get_object("7204941866_117111188317384")  # remember this ID
# => {"name"=>"Bare Escentuals Cosmetics",
#     "message"=>"We've just launched the Bare Escentuals "Mom & Me" application!",
#     "likes"=>3,
#     ....
#    }

You can also searches public posts for the keyword of your choice:

# http://graph.facebook.com/search?q=koala
@graph.search("koala")
# => {"data"=> [{"from"=>{"name"=>"Amy", ...}, "id"=>....,
#     "message"=>"My apartment is infested with koala bears...."}]}

Getting Private Data

Public data’s cool, but it’s often not enough. You want to know who your users are — their full details, their likes, their feed, their friends. Without an access token, you can’t get that:

@graph.get_connections("koppel", "likes")
# => Koala::Facebook::GraphAPIError: An access token is required to request this resource.

We’ll go over getting an access token in a moment. For now, head over to http://graph.facebook.com — Facebook’s Graph API developer site has a bunch of links, any of which will provide you with an access token. Copy that from the URL, and check out what you can do now:

# first, initialize a Graph API with your token
@graph = Koala::Facebook::GraphAPI.new(your_oauth_token)

# now, try that query again
# http://graph.facebook.com/koppel/likes?access_token=#{your_oauth_token}
@graph.get_connections("koppel", "likes")
# => {"data"=>[{"name"=>"Mechanics' Institute Library", ....}]}

“me” is a very useful shortcut Facebook provides to getting the current user:

# http://graph.facebook.com/me?access_token=#{your_oauth_token}
@graph.get_object("me")
# => {"name"=>"Alex Koppel", ....}

With a user’s access token, you get any public information, plus additional information through extended permissions (see below).

Writing to the Graph

Reading’s all well and good, but no discussion of the graph would be complete without some writing. In order to write to the social graph, you’ll need to prompt your user for the publish_stream extended permission. (We’ll talk about permissions in a bit.)

For the sake of simplicity, let’s assume the token we got above has the right permissions; otherwise, you’ll get an error. (Since writing to the graph involves sending POST requests, the browser follow-along unfortunately has to end.)

Let’s start by posting to our own walls using the put_wall_post method.

@graph.put_wall_post("hey, i'm learning kaola")
# => {"id"=>"2905623_123183957698327"}

Oops — we misspelled Koala! How embarrassing.

@graph.delete_object("2905623_123183957698327")
# => true

Let’s never speak of that again, okay?

You can also write to other people’s walls. For instance, I’ll send a link to a cool (if sappy) comic to my husband.

@graph.put_wall_post("explodingdog!", {:name => "i love loving you", :link => "http://www.explodingdog.com/title/ilovelovingyou.html"}, "tmiley")
=> {"id"=>"83901496_520908898070"}

Speaking of family, Mother’s Day is coming up. Let’s go back to that earlier post about the Mother’s Day app my company just released, and like it.

@graph.put_like("7204941866_117111188317384")
# => true

Now it has 4 likes:

@graph.get_object("7204941866_117111188317384")
# => {"message"=>"We've just launched the Bare Escentuals "Mom & Me" application", "likes"=>4...}

Personal confession: I still haven’t picked out a gift for my mom. Time to talk about how I need to do that.

@graph.put_comment("7204941866_117111188317384", "Can't believe Mother's Day's just a week away!  I'd better get on that gift.")
# => {"id"=>"7204941866_117111188317384_448625"} # ID of the comment

That’s more or less it for the Graph API. All the methods you just saw wrap a generic put_object method, which you can use whenever the convenience methods don’t work for you.

def put_object(parent_object, connection_name, args = {}) .... 

OAuth

Koala also includes an OAuth class, which helps with two common authentication-related tasks: verifying cookies and generates authentication URLs.

OAuth URLs and tokens

In order to use OAuth — a much cleaner way of verifying yourself to Facebook — you have to get tokens for your users. If you’re using the Javascript library, it will provide the OAuth token in the cookies it creates (we’ll talk about verifying those in a moment). If not, don’t worry — there’s a redirect-based method that works too (and can be played with in the browser). To learn more about OAuth, check out Facebook’s page on OAuth authentication at http://developers.facebook.com/docs/api#authorization.

Here’s how to get an OAuth token in two steps:

  1. First, send your users to the OAuth code URL. Facebook verifies that they’re logged in, want to access your app, and are willing to grant you any permissions you request. They are then redirect the user to a callback on your registered site with an OAuth code in the GET parameters.
  2. Now that you have the code, you can get the token. (Don’t confuse one for the other; I’ve made that mistake.) You can now send a request to a second OAuth URL with that code, your application’s super-secret code, and some other parameters. Facebook returns the code to you in the body of the response (you should do this from your server behind-the-scenes).

Let’s walk through it together. Koala makes it easy to generate the URLs you need. All you have to do is create an OAuth helper with information for your app. (callback_url is optional, but if you don’t include it here, you have to include it in later calls.)

@oauth = Facebook::OAuth.new(app_id, code, callback_url)
# => #<Koala::Facebook::OAuth:0x1017177b0 @app_id=#{your_app_id}, @oauth_callback_url=#{your_callback_url}, @app_secret=#{your_secret_code}>

Now we can use @oauth to generate the URL for the authentication code. url_for_oauth_code takes a hash, which can include the :permissions you want (either as an array or a comma-separated string) and a :callback URL (in case you want to point the callback to a specific address in your domain).

@oauth.url_for_oauth_code
# => "https://graph.facebook.com/oauth/authorize?client_id=#{app_id}&redirect_uri=#{callback_url}"
@oauth.url_for_oauth_code(:permissions => "stream_publish")
# => "https://graph.facebook.com/oauth/authorize?client_id=#{app_id}&redirect_uri=#{callback_url}
&scope=stream_publish"

Now that you have the URL, you can send your user there. Once she’s logged into Facebook and granted your permissions (if requested), she’ll be redirected to your callback; the code will be in that request’s GET parameters (under the key, you guessed it, code). Now you can generate the URL that will yield up the access token.

@oauth.url_for_access_token(user_code)
# => "https://graph.facebook.com/oauth/access_token?client_id=#{app_id}&redirect_uri=#{callback_url}&
client_secret=#{app_secret}&code=#{user_code}"

Fire off a request to that address, and you’ll get the access token and how long until it expires.

Note: Koala OAuth currently doesn’t include methods to grab and parse the token directly, but those will be coming in the near future.

Cookie Parsing

The other common OAuth related-task is parsing and validating Facebook’s cookies. The new Javascript library (formerly Facebook Connect) is awesome — small, clean, and very useful for adding social touches to your website. It’ll take care of logging the user in and it handles all the OAuth token craziness behind the scenes. All you have to do is verify the cookies are legit — the user is indeed who his browser says he is.

Let’s test that. I’ve taken some real-live cookies from a website my husband and I are working on, which uses Koala for cookie validation. (Sorry about them breaking the formatting. Some cookies just don’t have good manners.)

{"fbs_190889632882"=>"\"access_token=190889632882|2.U25mFtixF8Pqth45AtnsBQ__.3600.1272909600-2905623|DNjswq9Q-fKDrP60TY76Tv8GxCc.&expires=1272909600&secret=QR_id58vqV_qW7MnfJlmLw__&session_key=2.U25mFtixF8Pqth45AtnsBQ__.3600.1272909600-2905623&sig=a76960c0c3669470f7ca53b53e034ac4&uid=2905623\"", [other cookies]...}

The important cookie is the fbs_#{app_id} cookie, which contains a string (complete with inner quotes) containing all the information you need to verify Facebook has, indeed, confirmed this user. To verify the cookies, just instantiate an OAuth instance like you did above (no callback URL needed) and run:

@oauth.get_user_from_cookie(cookies)
# => {"session_key"=>"2.U25mFtixF8Pqth45AtnsBQ__.3600.1272909600-2905623", "expires"=>"1272909600", "uid"=>"2905623", "sig"=>"a76960c0c3669470f7ca53b53e034ac4", "secret"=>"QR_id58vqV_qW7MnfJlmLw__", "access_token"=>"190889632882|2.U25mFtixF8Pqth45AtnsBQ__.3600.1272909600-2905623|DNjswq9Q-fKDrP60TY76Tv8GxCc."

There you go — you have a validated user ID and an access token to boot. Of course, if the cookies aren’t valid (expired, falsified, etc.) the method will simply return nil.

Koala and Other Libraries

One of my goals in writing Koala is to make a library anyone can use. In particular, I didn’t want to tie the library to a particular mechanism for making network requests to Facebook. Typhoeus may be our library of choice at Context Optional, but Koala doesn’t really care if you’d rather use Curb or HTTParty or just plain old Net::HTTP.

Using Koala with another HTTP library is simple — just write a really quick module defining one class method called make_request:

def self.make_request(path, args, verb)
  # make the request
  # return the body of the result as a string for JSON parsing
end

When Koala is loaded, it checks to see if Typhoeus is installed; if not, it silently falls back to Net::HTTP for requests. To use your module instead, just call

Koala.http_service = YourModule

The http_service= method will include your module, overwriting the existing make_request method. Voila! You’re done.

(You can check out lib/http_services.rb to see how the built-in HTTP modules are designed.)

This works because all the methods we just saw are wrappers for a method named api, which makes and parses the request. In everyday life you probably won’t need to access the api method directly, but it’s important to know in case you want to extend Koala to use a different HTTP library.

def api(path, args = {}, verb = "get")
  # other code....
  # make the request via the provided module's make_request method
  result = Koala.make_request(path, args, verb)
  # other code....
end

Request logging and the like

You can also use the same mechanism to implement request logging. Just stick some logging inside the make_request method — you can even call super to actually send the request.

Koala inside other libraries

Since Koala just implements a basic wrapper for the Graph API, there’s no reason Koala couldn’t be used inside any other systems, including other Facebook libraries that provide higher-level data encapsulation and convenience methods. Just sayin’.

Making sure Koala works

Koala’s going to have full test coverage. Right now, Koala::Facebook::GraphAPI has two test suites — one with and one without an access token — which put it through its paces. I’m still working on the OAuth test suite and plan to have that update out within a week.

The tests are written in RSpec and can be run by calling

spec koala_tests.rb

from the test directory. (I hear it’s proper form to include a Rake task that runs the tests. Stay tuned.)

Test data

Since we’re using the Facebook API, we have to play by the rules of the Facebook API. Unfortunately, that means using cookies and OAuth access codes that expire. (While we could stub the Facebook API, that wouldn’t get us much by way of testing, given how simple Koala is.) So, you’ll need to supply your own information in tests/facebook_data.yml. Sorry! Let me know if you have a better idea.

Tests and Graph nodes

When you run the tests with an access token, the put_object tests will create and then immediately delete several wall posts on your own wall. As Koala cleans up after itself, it also outputs (via puts) the IDs of each node created, in case anything goes wrong.

Wrapup

Well, that’s about it — thanks for making it all the way through this very long blog post! I’m very excited about the launch of Koala (and a bit nervous – it’s my first gem, after all). I hope you’ll find the Koala library useful as you implement Facebook’s new Graph API.

Stay tuned for more updates on Github — there’ll be more tests, new OAuth methods, and no doubt further changes on the way in the next week or two.

If you have any questions/comments/bug reports, feel free to drop me a message on Github. I’d love to hear from you.

Cheers!

Alex
http://github.com/arsduo/koala

« Previous Page
koppel badge miley badge