koala 1.6.0 → 1.7.0rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +2 -5
- data/Gemfile +1 -2
- data/changelog.md +107 -4
- data/koala.gemspec +5 -5
- data/lib/koala.rb +13 -4
- data/lib/koala/api.rb +28 -3
- data/lib/koala/api/graph_api.rb +33 -3
- data/lib/koala/api/graph_collection.rb +20 -20
- data/lib/koala/api/rest_api.rb +1 -3
- data/lib/koala/http_service.rb +21 -16
- data/lib/koala/oauth.rb +15 -11
- data/lib/koala/version.rb +1 -1
- data/readme.md +34 -7
- data/spec/cases/api_spec.rb +21 -1
- data/spec/cases/graph_api_batch_spec.rb +38 -16
- data/spec/cases/graph_api_spec.rb +13 -20
- data/spec/cases/http_service_spec.rb +39 -9
- data/spec/cases/koala_spec.rb +34 -22
- data/spec/cases/oauth_spec.rb +16 -12
- data/spec/cases/test_users_spec.rb +5 -1
- data/spec/fixtures/mock_facebook_responses.yml +14 -6
- data/spec/spec_helper.rb +19 -35
- data/spec/support/graph_api_shared_examples.rb +34 -17
- data/spec/support/koala_test.rb +10 -1
- data/spec/support/mock_http_service.rb +77 -33
- metadata +27 -32
- data/spec/support/json_testing_fix.rb +0 -42
data/lib/koala/api.rb
CHANGED
@@ -41,8 +41,13 @@ module Koala
|
|
41
41
|
#
|
42
42
|
# @return the body of the response from Facebook (unless another http_component is requested)
|
43
43
|
def api(path, args = {}, verb = "get", options = {}, &error_checking_block)
|
44
|
-
#
|
45
|
-
|
44
|
+
# If a access token is explicitly provided, use that
|
45
|
+
# This is explicitly needed in batch requests so GraphCollection
|
46
|
+
# results preserve any specific access tokens provided
|
47
|
+
args["access_token"] ||= @access_token || @app_access_token if @access_token || @app_access_token
|
48
|
+
|
49
|
+
# Translate any arrays in the params into comma-separated strings
|
50
|
+
args = sanitize_request_parameters(args)
|
46
51
|
|
47
52
|
# add a leading /
|
48
53
|
path = "/#{path}" unless path =~ /^\//
|
@@ -53,7 +58,7 @@ module Koala
|
|
53
58
|
if result.status.to_i >= 500
|
54
59
|
raise Koala::Facebook::ServerError.new(result.status.to_i, result.body)
|
55
60
|
end
|
56
|
-
|
61
|
+
|
57
62
|
yield result if error_checking_block
|
58
63
|
|
59
64
|
# if we want a component other than the body (e.g. redirect header for images), return that
|
@@ -66,6 +71,26 @@ module Koala
|
|
66
71
|
MultiJson.load("[#{result.body.to_s}]")[0]
|
67
72
|
end
|
68
73
|
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
# Sanitizes Ruby objects into Facebook-compatible string values.
|
78
|
+
#
|
79
|
+
# @param parameters a hash of parameters.
|
80
|
+
#
|
81
|
+
# Returns a hash in which values that are arrays of non-enumerable values
|
82
|
+
# (Strings, Symbols, Numbers, etc.) are turned into comma-separated strings.
|
83
|
+
def sanitize_request_parameters(parameters)
|
84
|
+
parameters.reduce({}) do |result, (key, value)|
|
85
|
+
# if the parameter is an array that contains non-enumerable values,
|
86
|
+
# turn it into a comma-separated list
|
87
|
+
# in Ruby 1.8.7, strings are enumerable, but we don't care
|
88
|
+
if value.is_a?(Array) && value.none? {|entry| entry.is_a?(Enumerable) && !entry.is_a?(String)}
|
89
|
+
value = value.join(",")
|
90
|
+
end
|
91
|
+
result.merge(key => value)
|
92
|
+
end
|
93
|
+
end
|
69
94
|
end
|
70
95
|
end
|
71
96
|
end
|
data/lib/koala/api/graph_api.rb
CHANGED
@@ -5,8 +5,6 @@ require 'koala/http_service/uploadable_io'
|
|
5
5
|
|
6
6
|
module Koala
|
7
7
|
module Facebook
|
8
|
-
GRAPH_SERVER = "graph.facebook.com"
|
9
|
-
|
10
8
|
# Methods used to interact with the Facebook Graph API.
|
11
9
|
#
|
12
10
|
# See https://github.com/arsduo/koala/wiki/Graph-API for a general introduction to Koala
|
@@ -144,6 +142,7 @@ module Koala
|
|
144
142
|
def put_connections(id, connection_name, args = {}, options = {}, &block)
|
145
143
|
# Posts a certain connection
|
146
144
|
raise AuthenticationError.new(nil, nil, "Write operations require an access token") unless @access_token
|
145
|
+
|
147
146
|
graph_call("#{id}/#{connection_name}", args, "post", options, &block)
|
148
147
|
end
|
149
148
|
|
@@ -178,7 +177,7 @@ module Koala
|
|
178
177
|
def get_picture(object, args = {}, options = {}, &block)
|
179
178
|
# Gets a picture object, returning the URL (which Facebook sends as a header)
|
180
179
|
resolved_result = graph_call("#{object}/picture", args, "get", options.merge(:http_component => :headers)) do |result|
|
181
|
-
result["Location"]
|
180
|
+
result ? result["Location"] : nil
|
182
181
|
end
|
183
182
|
block ? block.call(resolved_result) : resolved_result
|
184
183
|
end
|
@@ -228,6 +227,9 @@ module Koala
|
|
228
227
|
# @param message the message to write for the wall
|
229
228
|
# @param attachment a hash describing the wall post
|
230
229
|
# (see the {https://developers.facebook.com/docs/guides/attachments/ stream attachments} documentation.)
|
230
|
+
# If attachment contains a properties key, this will be turned to
|
231
|
+
# JSON (if it's a hash) since Facebook's API, oddly, requires
|
232
|
+
# this.
|
231
233
|
# @param target_id the target wall
|
232
234
|
# @param options (see #get_object)
|
233
235
|
# @param block (see Koala::Facebook::API#api)
|
@@ -244,6 +246,10 @@ module Koala
|
|
244
246
|
# @see #put_connections
|
245
247
|
# @return (see #put_connections)
|
246
248
|
def put_wall_post(message, attachment = {}, target_id = "me", options = {}, &block)
|
249
|
+
if properties = attachment.delete(:properties) || attachment.delete("properties")
|
250
|
+
properties = MultiJson.dump(properties) if properties.is_a?(Hash) || properties.is_a?(Array)
|
251
|
+
attachment["properties"] = properties
|
252
|
+
end
|
247
253
|
put_connections(target_id, "feed", attachment.merge({:message => message}), options, &block)
|
248
254
|
end
|
249
255
|
|
@@ -368,6 +374,21 @@ module Koala
|
|
368
374
|
block ? block.call(access_token) : access_token
|
369
375
|
end
|
370
376
|
|
377
|
+
# Get an access token information
|
378
|
+
# The access token used to instantiate the API object needs to be
|
379
|
+
# the app access token or a valid User Access Token from a developer of the app.
|
380
|
+
# See https://developers.facebook.com/docs/howtos/login/debugging-access-tokens/#step1
|
381
|
+
#
|
382
|
+
# @param input_token the access token you want to inspect
|
383
|
+
# @param block (see Koala::Facebook::API#api)
|
384
|
+
#
|
385
|
+
# @return a JSON array containing data and a map of fields
|
386
|
+
def debug_token(input_token, &block)
|
387
|
+
access_token_info = graph_call("debug_token", {:input_token => input_token})
|
388
|
+
|
389
|
+
block ? block.call(access_token_info) : access_token_info
|
390
|
+
end
|
391
|
+
|
371
392
|
# Fetches the comments from fb:comments widgets for a given set of URLs (array or comma-separated string).
|
372
393
|
# See https://developers.facebook.com/blog/post/490.
|
373
394
|
#
|
@@ -383,6 +404,15 @@ module Koala
|
|
383
404
|
get_object("comments", args, options, &block)
|
384
405
|
end
|
385
406
|
|
407
|
+
# App restrictions require you to JSON-encode the restriction value. This
|
408
|
+
# is neither obvious nor intuitive, so this convenience method is
|
409
|
+
# provided.
|
410
|
+
#
|
411
|
+
# @params app_id the application to apply the restrictions to
|
412
|
+
# @params restrictions_hash the restrictions to apply
|
413
|
+
# @param args (see #get_object)
|
414
|
+
# @param options (see #get_object)
|
415
|
+
# @param block (see Koala::Facebook::API#api)
|
386
416
|
def set_app_restrictions(app_id, restrictions_hash, args = {}, options = {}, &block)
|
387
417
|
graph_call(app_id, args.merge(:restrictions => MultiJson.dump(restrictions_hash)), "post", options, &block)
|
388
418
|
end
|
@@ -6,22 +6,22 @@ module Koala
|
|
6
6
|
# A light wrapper for collections returned from the Graph API.
|
7
7
|
# It extends Array to allow you to page backward and forward through
|
8
8
|
# result sets, and providing easy access to paging information.
|
9
|
-
class GraphCollection < Array
|
10
|
-
|
9
|
+
class GraphCollection < Array
|
10
|
+
|
11
11
|
# The raw paging information from Facebook (next/previous URLs).
|
12
12
|
attr_reader :paging
|
13
13
|
# @return [Koala::Facebook::GraphAPI] the api used to make requests.
|
14
14
|
attr_reader :api
|
15
15
|
# The entire raw response from Facebook.
|
16
16
|
attr_reader :raw_response
|
17
|
-
|
17
|
+
|
18
18
|
# Initialize the array of results and store various additional paging-related information.
|
19
|
-
#
|
19
|
+
#
|
20
20
|
# @param response the response from Facebook (a hash whose "data" key is an array)
|
21
21
|
# @param api the Graph {Koala::Facebook::API API} instance to use to make calls
|
22
22
|
# (usually the API that made the original call).
|
23
23
|
#
|
24
|
-
# @return [Koala::Facebook::GraphCollection] an initialized GraphCollection
|
24
|
+
# @return [Koala::Facebook::GraphCollection] an initialized GraphCollection
|
25
25
|
# whose paging, raw_response, and api attributes are populated.
|
26
26
|
def initialize(response, api)
|
27
27
|
super response["data"]
|
@@ -31,32 +31,32 @@ module Koala
|
|
31
31
|
end
|
32
32
|
|
33
33
|
# @private
|
34
|
-
# Turn the response into a GraphCollection if they're pageable;
|
34
|
+
# Turn the response into a GraphCollection if they're pageable;
|
35
35
|
# if not, return the original response.
|
36
36
|
# The Ads API (uniquely so far) returns a hash rather than an array when queried
|
37
|
-
# with get_connections.
|
37
|
+
# with get_connections.
|
38
38
|
def self.evaluate(response, api)
|
39
39
|
response.is_a?(Hash) && response["data"].is_a?(Array) ? self.new(response, api) : response
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
# Retrieve the next page of results.
|
43
|
-
#
|
43
|
+
#
|
44
44
|
# @return a GraphCollection array of additional results (an empty array if there are no more results)
|
45
45
|
def next_page
|
46
46
|
base, args = next_page_params
|
47
47
|
base ? @api.get_page([base, args]) : nil
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
# Retrieve the previous page of results.
|
51
|
-
#
|
51
|
+
#
|
52
52
|
# @return a GraphCollection array of additional results (an empty array if there are no earlier results)
|
53
53
|
def previous_page
|
54
54
|
base, args = previous_page_params
|
55
55
|
base ? @api.get_page([base, args]) : nil
|
56
56
|
end
|
57
|
-
|
58
|
-
# Arguments that can be sent to {Koala::Facebook::API#graph_call} to retrieve the next page of results.
|
59
|
-
#
|
57
|
+
|
58
|
+
# Arguments that can be sent to {Koala::Facebook::API#graph_call} to retrieve the next page of results.
|
59
|
+
#
|
60
60
|
# @example
|
61
61
|
# @api.graph_call(*collection.next_page_params)
|
62
62
|
#
|
@@ -64,9 +64,9 @@ module Koala
|
|
64
64
|
def next_page_params
|
65
65
|
@paging && @paging["next"] ? parse_page_url(@paging["next"]) : nil
|
66
66
|
end
|
67
|
-
|
68
|
-
# Arguments that can be sent to {Koala::Facebook::API#graph_call} to retrieve the previous page of results.
|
69
|
-
#
|
67
|
+
|
68
|
+
# Arguments that can be sent to {Koala::Facebook::API#graph_call} to retrieve the previous page of results.
|
69
|
+
#
|
70
70
|
# @example
|
71
71
|
# @api.graph_call(*collection.previous_page_params)
|
72
72
|
#
|
@@ -74,7 +74,7 @@ module Koala
|
|
74
74
|
def previous_page_params
|
75
75
|
@paging && @paging["previous"] ? parse_page_url(@paging["previous"]) : nil
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
# @private
|
79
79
|
def parse_page_url(url)
|
80
80
|
GraphCollection.parse_page_url(url)
|
@@ -102,9 +102,9 @@ module Koala
|
|
102
102
|
end
|
103
103
|
end
|
104
104
|
end
|
105
|
-
|
105
|
+
|
106
106
|
# @private
|
107
|
-
# legacy support for when GraphCollection lived directly under Koala::Facebook
|
107
|
+
# legacy support for when GraphCollection lived directly under Koala::Facebook
|
108
108
|
GraphCollection = API::GraphCollection
|
109
109
|
end
|
110
110
|
end
|
data/lib/koala/api/rest_api.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
module Koala
|
2
2
|
module Facebook
|
3
|
-
|
4
|
-
|
5
|
-
# Methods used to interact with Facebook's legacy REST API.
|
3
|
+
# Methods used to interact with Facebook's legacy REST API.
|
6
4
|
# Where possible, you should use the newer, faster Graph API to interact with Facebook;
|
7
5
|
# in the future, the REST API will be deprecated.
|
8
6
|
# For now, though, there are a few methods that can't be done through the Graph API.
|
data/lib/koala/http_service.rb
CHANGED
@@ -23,6 +23,23 @@ module Koala
|
|
23
23
|
builder.adapter Faraday.default_adapter
|
24
24
|
end
|
25
25
|
|
26
|
+
# Default servers for Facebook. These are read into the config OpenStruct,
|
27
|
+
# and can be overridden via Koala.config.
|
28
|
+
DEFAULT_SERVERS = {
|
29
|
+
:graph_server => 'graph.facebook.com',
|
30
|
+
:dialog_host => 'www.facebook.com',
|
31
|
+
:rest_server => 'api.facebook.com',
|
32
|
+
# certain Facebook services (beta, video) require you to access different
|
33
|
+
# servers. If you're using your own servers, for instance, for a proxy,
|
34
|
+
# you can change both the matcher and the replacement values.
|
35
|
+
# So for instance, if you're talking to fbproxy.mycompany.com, you could
|
36
|
+
# set up beta.fbproxy.mycompany.com for FB's beta tier, and set the
|
37
|
+
# matcher to /\.fbproxy/ and the beta_replace to '.beta.fbproxy'.
|
38
|
+
:host_path_matcher => /\.facebook/,
|
39
|
+
:video_replace => '-video.facebook',
|
40
|
+
:beta_replace => '.beta.facebook'
|
41
|
+
}
|
42
|
+
|
26
43
|
# The address of the appropriate Facebook server.
|
27
44
|
#
|
28
45
|
# @param options various flags to indicate which server to use.
|
@@ -33,9 +50,9 @@ module Koala
|
|
33
50
|
#
|
34
51
|
# @return a complete server address with protocol
|
35
52
|
def self.server(options = {})
|
36
|
-
server = "#{options[:rest_api] ?
|
37
|
-
server.gsub!(
|
38
|
-
server.gsub!(
|
53
|
+
server = "#{options[:rest_api] ? Koala.config.rest_server : Koala.config.graph_server}"
|
54
|
+
server.gsub!(Koala.config.host_path_matcher, Koala.config.video_replace) if options[:video]
|
55
|
+
server.gsub!(Koala.config.host_path_matcher, Koala.config.beta_replace) if options[:beta]
|
39
56
|
"#{options[:use_ssl] ? "https" : "http"}://#{server}"
|
40
57
|
end
|
41
58
|
|
@@ -126,18 +143,6 @@ module Koala
|
|
126
143
|
http_options[:timeout] = value
|
127
144
|
end
|
128
145
|
|
129
|
-
# @private
|
130
|
-
def self.timeout
|
131
|
-
Koala::Utils.deprecate("HTTPService.timeout is now HTTPService.http_options[:timeout]; .timeout will be removed in a future version.")
|
132
|
-
http_options[:timeout]
|
133
|
-
end
|
134
|
-
|
135
|
-
# @private
|
136
|
-
def self.timeout=(value)
|
137
|
-
Koala::Utils.deprecate("HTTPService.timeout is now HTTPService.http_options[:timeout]; .timeout will be removed in a future version.")
|
138
|
-
http_options[:timeout] = value
|
139
|
-
end
|
140
|
-
|
141
146
|
# @private
|
142
147
|
def self.proxy
|
143
148
|
Koala::Utils.deprecate("HTTPService.proxy is now HTTPService.http_options[:proxy]; .proxy will be removed in a future version.")
|
@@ -230,4 +235,4 @@ module Koala
|
|
230
235
|
Faraday.default_adapter = :net_http
|
231
236
|
end
|
232
237
|
end
|
233
|
-
end
|
238
|
+
end
|
data/lib/koala/oauth.rb
CHANGED
@@ -4,9 +4,6 @@ require 'base64'
|
|
4
4
|
|
5
5
|
module Koala
|
6
6
|
module Facebook
|
7
|
-
|
8
|
-
DIALOG_HOST = "www.facebook.com"
|
9
|
-
|
10
7
|
class OAuth
|
11
8
|
attr_reader :app_id, :app_secret, :oauth_callback_url
|
12
9
|
|
@@ -23,9 +20,12 @@ module Koala
|
|
23
20
|
|
24
21
|
# Parses the cookie set Facebook's JavaScript SDK.
|
25
22
|
#
|
26
|
-
# @note
|
27
|
-
#
|
28
|
-
#
|
23
|
+
# @note this method can only be called once per session, as the OAuth code
|
24
|
+
# Facebook supplies can only be redeemed once. Your application
|
25
|
+
# must handle cross-request storage of this information; you can no
|
26
|
+
# longer call this method multiple times. (This works out, as the
|
27
|
+
# method has to make a call to FB's servers anyway, which you don't
|
28
|
+
# want on every call.)
|
29
29
|
#
|
30
30
|
# @param cookie_hash a set of cookies that includes the Facebook cookie.
|
31
31
|
# You can pass Rack/Rails/Sinatra's cookie hash directly to this method.
|
@@ -48,6 +48,7 @@ module Koala
|
|
48
48
|
#
|
49
49
|
# @return the authenticated user's Facebook ID, or nil.
|
50
50
|
def get_user_from_cookies(cookies)
|
51
|
+
Koala::Utils.deprecate("Due to Facebook changes, you can only redeem an OAuth code once; it is therefore recommended not to use this method, as it will consume the code without providing you the access token. See https://developers.facebook.com/roadmap/completed-changes/#december-2012.")
|
51
52
|
if signed_cookie = cookies["fbsr_#{@app_id}"]
|
52
53
|
if components = parse_signed_request(signed_cookie)
|
53
54
|
components["user_id"]
|
@@ -74,6 +75,9 @@ module Koala
|
|
74
75
|
#
|
75
76
|
# @param options any query values to add to the URL, as well as any special/required values listed below.
|
76
77
|
# @option options permissions an array or comma-separated string of desired permissions
|
78
|
+
# @option options state a unique string to serve as a CSRF (cross-site request
|
79
|
+
# forgery) token -- highly recommended for security. See
|
80
|
+
# https://developers.facebook.com/docs/howtos/login/server-side-login/
|
77
81
|
#
|
78
82
|
# @raise ArgumentError if no OAuth callback was specified in OAuth#new or in options as :redirect_uri
|
79
83
|
#
|
@@ -86,7 +90,7 @@ module Koala
|
|
86
90
|
url_options = {:client_id => @app_id}.merge(options)
|
87
91
|
|
88
92
|
# Creates the URL for oauth authorization for a given callback and optional set of permissions
|
89
|
-
build_url("https://#{
|
93
|
+
build_url("https://#{Koala.config.dialog_host}/dialog/oauth", true, url_options)
|
90
94
|
end
|
91
95
|
|
92
96
|
# Once you receive an OAuth code, you need to redeem it from Facebook using an appropriate URL.
|
@@ -110,7 +114,7 @@ module Koala
|
|
110
114
|
:code => code,
|
111
115
|
:client_secret => @app_secret
|
112
116
|
}.merge(options)
|
113
|
-
build_url("https://#{
|
117
|
+
build_url("https://#{Koala.config.graph_server}/oauth/access_token", true, url_options)
|
114
118
|
end
|
115
119
|
|
116
120
|
# Builds a URL for a given dialog (feed, friends, OAuth, pay, send, etc.)
|
@@ -125,7 +129,7 @@ module Koala
|
|
125
129
|
def url_for_dialog(dialog_type, options = {})
|
126
130
|
# some endpoints require app_id, some client_id, supply both doesn't seem to hurt
|
127
131
|
url_options = {:app_id => @app_id, :client_id => @app_id}.merge(options)
|
128
|
-
build_url("http://#{
|
132
|
+
build_url("http://#{Koala.config.dialog_host}/dialog/#{dialog_type}", true, url_options)
|
129
133
|
end
|
130
134
|
|
131
135
|
# access tokens
|
@@ -175,7 +179,7 @@ module Koala
|
|
175
179
|
# @return the application access token and other information (expiration, etc.)
|
176
180
|
def get_app_access_token_info(options = {})
|
177
181
|
# convenience method to get a the application's sessionless access token
|
178
|
-
get_token_from_server({:
|
182
|
+
get_token_from_server({:grant_type => 'client_credentials'}, true, options)
|
179
183
|
end
|
180
184
|
|
181
185
|
# Fetches the application's access token (ignoring expiration and other info).
|
@@ -346,7 +350,7 @@ module Koala
|
|
346
350
|
|
347
351
|
def build_url(base, require_redirect_uri = false, url_options = {})
|
348
352
|
if require_redirect_uri && !(url_options[:redirect_uri] ||= url_options.delete(:callback) || @oauth_callback_url)
|
349
|
-
raise ArgumentError, "
|
353
|
+
raise ArgumentError, "build_url must get a callback either from the OAuth object or in the parameters!"
|
350
354
|
end
|
351
355
|
|
352
356
|
"#{base}?#{Koala::HTTPService.encode_params(url_options)}"
|
data/lib/koala/version.rb
CHANGED
data/readme.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
[![Build Status](https://secure.travis-ci.org/arsduo/koala.png)](http://travis-ci.org/arsduo/koala)
|
2
2
|
|
3
|
+
**Note**: a recent Facebook change will cause apps that parse the cookies every
|
4
|
+
request to fail with the error "OAuthException: This authorization code has
|
5
|
+
been used." If you're seeing this, please read the note in the [OAuth
|
6
|
+
wiki](https://github.com/arsduo/koala/wiki/OAuth) for more information.
|
7
|
+
|
3
8
|
Koala
|
4
9
|
====
|
5
10
|
[Koala](http://github.com/arsduo/koala) is a Facebook library for Ruby, supporting the Graph API (including the batch requests and photo uploads), the REST API, realtime updates, test users, and OAuth validation. We wrote Koala with four goals:
|
@@ -7,7 +12,7 @@ Koala
|
|
7
12
|
* Lightweight: Koala should be as light and simple as Facebook’s own libraries, providing API accessors and returning simple JSON.
|
8
13
|
* 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:
|
9
14
|
* Flexible: Koala should be useful to everyone, regardless of their current configuration. We support JRuby, Rubinius, and REE as well as vanilla Ruby (1.8.7, 1.9.2, and 1.9.3), and use the Faraday library to provide complete flexibility over how HTTP requests are made.
|
10
|
-
* 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](travis-ci.org/arsduo/koala/).
|
15
|
+
* 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](http://travis-ci.org/arsduo/koala/).
|
11
16
|
|
12
17
|
Installation
|
13
18
|
---
|
@@ -24,9 +29,9 @@ gem "koala"
|
|
24
29
|
|
25
30
|
Graph API
|
26
31
|
----
|
27
|
-
The Graph API is the simple, slick new interface to Facebook's data.
|
28
|
-
Using it with Koala is quite straightforward. First, you'll need an access token, which you can get through
|
29
|
-
Facebook's [Graph API Explorer](https://developers.facebook.com/tools/explorer) (click on 'Get Access Token').
|
32
|
+
The Graph API is the simple, slick new interface to Facebook's data.
|
33
|
+
Using it with Koala is quite straightforward. First, you'll need an access token, which you can get through
|
34
|
+
Facebook's [Graph API Explorer](https://developers.facebook.com/tools/explorer) (click on 'Get Access Token').
|
30
35
|
Then, go exploring:
|
31
36
|
|
32
37
|
```ruby
|
@@ -110,6 +115,23 @@ fql = @api.fql_query(my_fql_query)
|
|
110
115
|
@api.put_wall_post(process_result(fql))
|
111
116
|
```
|
112
117
|
|
118
|
+
Configuration
|
119
|
+
----
|
120
|
+
You can change the host that koala makes requests to (point to a mock server, apigee, runscope etc..)
|
121
|
+
```ruby
|
122
|
+
# config/initializers/koala.rb
|
123
|
+
require 'koala'
|
124
|
+
|
125
|
+
Koala.configure do |config|
|
126
|
+
config.graph_server = 'my-graph-mock.mysite.com'
|
127
|
+
# other common options are `rest_server` and `dialog_host`
|
128
|
+
# see lib/koala/http_service.rb
|
129
|
+
end
|
130
|
+
```
|
131
|
+
|
132
|
+
Of course the defaults are the facebook endpoints and you can additionally configure the beta
|
133
|
+
tier and video upload matching and replacement strings.
|
134
|
+
|
113
135
|
OAuth
|
114
136
|
-----
|
115
137
|
You can use the Graph and REST APIs without an OAuth access token, but the real magic happens when you provide Facebook an OAuth token to prove you're authenticated. Koala provides an OAuth class to make that process easy:
|
@@ -119,10 +141,15 @@ You can use the Graph and REST APIs without an OAuth access token, but the real
|
|
119
141
|
|
120
142
|
If your application uses Koala and the Facebook [JavaScript SDK](http://github.com/facebook/facebook-js-sdk) (formerly Facebook Connect), you can use the OAuth class to parse the cookies:
|
121
143
|
```ruby
|
122
|
-
|
123
|
-
|
144
|
+
# parses and returns a hash including the token and the user id
|
145
|
+
# NOTE: this method can only be called once per session, as the OAuth code
|
146
|
+
# Facebook supplies can only be redeemed once. Your application must handle
|
147
|
+
# cross-request storage of this information; you can no longer call this method
|
148
|
+
# multiple times.
|
149
|
+
@oauth.get_user_info_from_cookies(cookies)
|
124
150
|
```
|
125
151
|
And if you have to use the more complicated [redirect-based OAuth process](http://developers.facebook.com/docs/authentication/), Koala helps out there, too:
|
152
|
+
|
126
153
|
```ruby
|
127
154
|
# generate authenticating URL
|
128
155
|
@oauth.url_for_oauth_code
|
@@ -223,4 +250,4 @@ LIVE=true bundle exec rake spec
|
|
223
250
|
# you can also test against Facebook's beta tier
|
224
251
|
LIVE=true BETA=true bundle exec rake spec
|
225
252
|
```
|
226
|
-
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.
|
253
|
+
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.
|