Koala
Koala is a Facebook library for Ruby, supporting the Graph API (including the batch requests and photo uploads), the Marketing API, the Atlas API, realtime updates, test users, and OAuth validation. We wrote Koala with four goals:
- Lightweight: Koala should be as light and simple as Facebook’s own libraries, providing API accessors and returning simple JSON.
- Fast: Koala should, out of the box, be quick. Out of the box, we use Facebook's faster read-only servers when possible and if available, the Typhoeus gem to make snappy Facebook requests. Of course, that brings us to our next topic:
- Flexible: Koala should be useful to everyone, regardless of their current configuration. We support all currently-supported Ruby versions (MRI 2.1-2.4) and Koala should work on JRuby and Rubinius.
- Tested: Koala should have complete test coverage, so you can rely on it. Our test coverage is complete and can be run against either mocked responses or the live Facebook servers; we're also on Travis CI.
Found a bug? Interested in contributing? Check out the Maintenance section below!
Installation
Koala 3.0 is out! There should be no significant changes for most users. If you encounter any
problems, please file an issue and I'll take a look.
In Bundler:
gem "koala"
Otherwise:
[sudo|rvm] gem install koala
Configuration
Most applications will only use one application configuration. Rather than having to provide that
value every time, you can configure Koala to use global settings:
Koala.configure do |config|
config.access_token = MY_TOKEN
config.app_access_token = MY_APP_ACCESS_TOKEN
config.app_id = MY_APP_ID
config.app_secret = MY_APP_SECRET
end
Note: this is not currently threadsafe. (PRs welcome as long as they support both threaded and
non-threaded configuration.)
Graph API
The Graph API is the interface to Facebook's data. Using it with Koala is quite straightforward.
First, you'll need an access token, which you can get through Facebook's Graph API
Explorer (click on 'Get Access Token').
Then, go exploring:
require 'koala'
@graph = Koala::Facebook::API.new(access_token)
profile = @graph.get_object("me")
friends = @graph.get_connections("me", "friends")
@graph.put_connections("me", "feed", message: "I am writing on my wall!")
@graph.get_connections("me", "mutualfriends/#{friend_id}")
@graph.put_connections("me", "namespace:action", object: object_url)
@graph = Koala::Facebook::API.new(access_token, app_secret)
Koala.config.api_version = "v2.0"
@graph.get_object("me", {}, api_version: "v2.0")
The response of most requests is the JSON data returned from the Facebook servers as a Hash.
When retrieving data that returns an array of results (for example, when calling API#get_connections
or API#search
)
a GraphCollection object will be returned, which makes it easy to page through the results:
feed = @graph.get_connections("me", "feed")
feed.each {|f| do_something_with_item(f) }
next_feed = feed.next_page
next_page_params = feed.next_page_params
page = @graph.get_page(next_page_params)
You can also make multiple calls at once using Facebook's batch API:
@graph.batch do |batch_api|
batch_api.get_object('me')
batch_api.put_wall_post('Making a post in a batch.')
end
You can pass a "post-processing" block to each of Koala's Graph API methods. This is handy for two reasons:
-
You can modify the result returned by the Graph API method:
education = @graph.get_object("me") { |data| data['education'] }
# returned value only contains the "education" portion of the profile
-
You can consume the data in place which is particularly useful in the batch case, so you don't have to pull
the results apart from a long list of array entries:
@graph.batch do |batch_api|
# Assuming you have database fields "about_me" and "photos"
batch_api.get_object('me') {|me| self.about_me = me }
batch_api.get_connections('me', 'photos') {|photos| self.photos = photos }
end
Check out the wiki for more details and examples.
App Access Tokens
You get your application's own access token, which can be used without a user session for subscriptions and certain other requests:
@oauth = Koala::Facebook::OAuth.new(app_id, app_secret, callback_url)
@oauth.get_app_access_token
For those building apps on Facebook, parsing signed requests is simple:
@oauth.parse_signed_request(signed_request_string)
The OAuth class has additional methods that may occasionally be useful.
Real-time Updates
Sometimes, reaching out to Facebook is a pain -- let it reach out to you instead. The Graph API allows your application to subscribe to real-time updates for certain objects in the graph; check the official Facebook documentation for more details on what objects you can subscribe to and what limitations may apply.
Koala makes it easy to interact with your applications using the RealtimeUpdates class:
@updates = Koala::Facebook::RealtimeUpdates.new(app_id: app_id, secret: secret)
You can do just about anything with your real-time update subscriptions using the RealtimeUpdates class:
@updates.subscribe("user", "first_name, last_name", callback_url, verify_token)
@updates.list_subscriptions
@updates.unsubscribe("user")
And to top it all off, RealtimeUpdates provides a static method to respond to Facebook servers' verification of your callback URLs:
Koala::Facebook::RealtimeUpdates.meet_challenge(params, your_verify_token)
For more information about meet_challenge and the RealtimeUpdates class, check out the Real-Time Updates page on the wiki.
Rate limits
We support Facebook rate limit informations as defined here: https://developers.facebook.com/docs/graph-api/overview/rate-limiting/
The information is available either via the Facebook::APIError
:
error.fb_buc_usage
error.fb_ada_usage
error.fb_app_usage
Or with the rate_limit_hook:
Koala.configure do |config|
config.rate_limit_hook = ->(limits) {
limits["x-app-usage"]
limits["x-ad-account-usage"]
limits["x-business-use-case-usage"]
}
end
Koala::Facebook::API.new('', '', ->(limits) {})
Test Users
We also support the test users API, allowing you to conjure up fake users and command them to do your bidding using the Graph API:
@test_users = Koala::Facebook::TestUsers.new(app_id: id, secret: secret)
user = @test_users.create(is_app_installed, desired_permissions)
user_graph_api = Koala::Facebook::API.new(user["access_token"])
@test_users.create_network(network_size, is_app_installed, common_permissions)
Talking to Facebook
Koala uses Faraday to make HTTP requests, which means you have complete control over how your app makes HTTP requests to Facebook. You can set Faraday options globally or pass them in on a per-request (or both):
Koala.http_service.http_options = {
ssl: { ca_path: "/etc/ssl/certs" }
}
@api.get_object(id, args_hash, { request: { timeout: 10 } })
The HTTP Services wiki page has more information on what options are available, as well as on how to configure your own Faraday middleware stack (for instance, to implement request logging).
See examples, ask questions
Some resources to help you as you play with Koala and the Graph API:
- Complete Koala documentation on the wiki
- Facebook's Stack Overflow site is a stupendous place to ask questions, filled with people who will help you figure out what's up with the Facebook API.
- Facebook's Graph API Explorer, where you can play with the Graph API in your browser
Testing
Unit tests are provided for all of Koala's methods. By default, these tests run against mock responses and hence are ready out of the box:
bundle exec rake spec
You can also run live tests against Facebook's servers:
LIVE=true bundle exec rake spec
LIVE=true BETA=true bundle exec rake spec
By default, the live tests are run against test users, so you can run them as frequently as you want. If you want to run them against a real user, however, you can fill in the OAuth token, code, and access_token values in spec/fixtures/facebook_data.yml. See the wiki for more details.
Maintenance
Pull requests: Koala exists as it does thanks to the amazing support and work of community members of all
backgrounds and levels of experience. Pull requests are very welcome!
Issues: If you have any questions about the gem, found an issue in the Ruby code or
documentation, or have another question that isn't right for StackOverflow, just open an issue and fill out the template.
Please note that this project is released with a Contributor Code of Conduct. By participating in
this project you agree to abide by its terms. See
code_of_conduct.md for more information.