lib/koala.rb in koala-0.6.0 vs lib/koala.rb in koala-0.7.0

- old
+ new

@@ -12,10 +12,12 @@ require 'graph_api' # add REST API methods require 'rest_api' +require 'realtime_updates' + module Koala module Facebook # Ruby client library for the Facebook Platform. # Copyright 2010 Facebook @@ -42,23 +44,30 @@ # initialize with an access token def initialize(access_token = nil) @access_token = access_token end - def api(path, args = {}, verb = "get", options = {}) + def api(path, args = {}, verb = "get", options = {}, &error_checking_block) # Fetches the given path in the Graph API. - args["access_token"] = @access_token if @access_token - + args["access_token"] = @access_token || @app_access_token if @access_token || @app_access_token # make the request via the provided service result = Koala.make_request(path, args, verb, options) - - # Facebook sometimes sends results like "true" and "false", which aren't strictly object - # and cause JSON.parse to fail - # so we account for that - response = JSON.parse("[#{result}]")[0] - response + # Parse the body as JSON and check for errors if provided a mechanism to do so + # Note: Facebook sometimes sends results like "true" and "false", which aren't strictly objects + # and cause JSON.parse to fail -- so we account for that by wrapping the result in [] + body = response = JSON.parse("[#{result.body.to_s}]")[0] + if error_checking_block + yield(body) + end + + # now return the desired information + if options[:http_component] + result.send(options[:http_component]) + else + body + end end end class GraphAPI < API include GraphAPIMethods @@ -71,21 +80,25 @@ class GraphAndRestAPI < API include GraphAPIMethods include RestAPIMethods end + class RealtimeUpdates < API + include RealtimeUpdateMethods + end + class APIError < Exception attr_accessor :fb_error_type def initialize(details = {}) self.fb_error_type = details["type"] super("#{fb_error_type}: #{details["message"]}") end end class OAuth - attr_accessor :app_id, :app_secret, :oauth_callback_url + attr_reader :app_id, :app_secret, :oauth_callback_url def initialize(app_id, app_secret, oauth_callback_url = nil) @app_id = app_id @app_secret = app_secret @oauth_callback_url = oauth_callback_url end @@ -142,33 +155,46 @@ callback = options[:callback] || @oauth_callback_url raise ArgumentError, "url_for_access_token must get a callback either from the OAuth object or in the parameters!" unless callback "https://#{GRAPH_SERVER}/oauth/access_token?client_id=#{@app_id}&redirect_uri=#{callback}&client_secret=#{@app_secret}&code=#{code}" end + def get_access_token(code) + # convenience method to get a parsed token from Facebook for a given code + # should this require an OAuth callback URL? + get_token_from_server(:code => code, :redirect_uri => @oauth_callback_url) + end + + def get_app_access_token + # convenience method to get a the application's sessionless access token + get_token_from_server({:type => 'client_cred'}, true) + end + + protected + + def get_token_from_server(args, post = false) + # fetch the result from Facebook's servers + result = fetch_token_string(args, post) + + # if we have an error, parse the error JSON and raise an error + raise APIError.new((JSON.parse(result)["error"] rescue nil) || {}) if result =~ /error/ + + # otherwise, parse the access token + parse_access_token(result) + end + def parse_access_token(response_text) components = response_text.split("&").inject({}) do |hash, bit| key, value = bit.split("=") hash.merge!(key => value) end components end - def fetch_token_string(code) + def fetch_token_string(args, post = false) Koala.make_request("oauth/access_token", { :client_id => @app_id, - :redirect_uri => @oauth_callback_url, - :client_secret => @app_secret, - :code => code - }, "get") - end - - def get_access_token(code) - result = fetch_token_string(code) - - # if we have an error, parse the error JSON and raise an error - raise APIError.new((JSON.parse(result)["error"] rescue nil) || {}) if result =~ /error/ - # otherwise, parse the access token - parse_access_token(result) + :client_secret => @app_secret + }.merge!(args), post ? "post" : "get").body end end end # finally, set up the http service Koala methods used to make requests