koala 1.2.0beta1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +12 -2
- data/koala.gemspec +7 -8
- data/lib/koala/graph_api.rb +11 -22
- data/lib/koala/graph_batch_api.rb +11 -1
- data/lib/koala/graph_collection.rb +7 -2
- data/lib/koala/http_service.rb +0 -1
- data/lib/koala/oauth.rb +32 -22
- data/lib/koala/realtime_updates.rb +1 -1
- data/lib/koala/test_users.rb +1 -2
- data/lib/koala/uploadable_io.rb +2 -1
- data/lib/koala/version.rb +3 -0
- data/lib/koala.rb +7 -2
- data/readme.md +27 -7
- data/spec/cases/{api_base_spec.rb → api_spec.rb} +25 -0
- data/spec/cases/graph_and_rest_api_spec.rb +0 -26
- data/spec/cases/graph_api_batch_spec.rb +12 -30
- data/spec/cases/graph_api_spec.rb +0 -20
- data/spec/cases/graph_collection_spec.rb +116 -0
- data/spec/cases/koala_spec.rb +7 -3
- data/spec/cases/oauth_spec.rb +130 -43
- data/spec/cases/test_users_spec.rb +11 -23
- data/spec/cases/uploadable_io_spec.rb +28 -0
- data/spec/fixtures/facebook_data.yml +3 -2
- data/spec/fixtures/mock_facebook_responses.yml +5 -5
- data/spec/support/graph_api_shared_examples.rb +23 -70
- data/spec/support/koala_test.rb +30 -6
- data/spec/support/mock_http_service.rb +2 -1
- metadata +19 -29
data/CHANGELOG
CHANGED
|
@@ -4,8 +4,16 @@ New methods:
|
|
|
4
4
|
-- Old classes are aliased with deprecation warnings (non-breaking change)
|
|
5
5
|
-- TestUsers#update lets you update the name or password of an existing test user
|
|
6
6
|
-- API.get_page_access_token lets you easily fetch the access token for a page you manage (thanks, marcgg!)
|
|
7
|
+
-- Added version.rb (Koala::VERSION)
|
|
7
8
|
Updated methods:
|
|
9
|
+
-- OAuth now parses Facebook's new signed cookie format
|
|
8
10
|
-- API.put_picture now accepts URLs to images (thanks, marcgg!)
|
|
11
|
+
-- Bug fixes to put_picture, parse_signed_request, and the test suite (thanks, johnbhall and Will S.!)
|
|
12
|
+
-- Smarter GraphCollection use
|
|
13
|
+
-- Any pageable result will now become a GraphCollection
|
|
14
|
+
-- Non-pageable results from get_connections no longer error
|
|
15
|
+
-- GraphCollection.raw_results allows access to original result data
|
|
16
|
+
-- Koala no longer enforces any limits on the number of test users you create at once
|
|
9
17
|
Internal improvements:
|
|
10
18
|
-- Koala now uses Faraday to make requests, replacing the HTTPServices (see wiki)
|
|
11
19
|
-- Koala::HTTPService.http_options allows specification of default Faraday connection options
|
|
@@ -15,13 +23,15 @@ Internal improvements:
|
|
|
15
23
|
-- Koala no longer automatically switches to Net::HTTP when uploading IO objects to Facebook
|
|
16
24
|
-- RealTimeUpdates and TestUsers are no longer subclasses of API, but have their own .api objects
|
|
17
25
|
-- The old .graph_api accessor is aliases to .api with a deprecation warning
|
|
26
|
+
-- Removed deprecation warnings for pre-1.1 batch interface
|
|
18
27
|
Testing improvements:
|
|
19
28
|
-- Live test suites now run against test users by default
|
|
20
29
|
-- Test suite can be repeatedly run live without having to update facebook_data.yml
|
|
21
30
|
-- OAuth code and session key tests cannot be run against test users
|
|
22
|
-
-- Faraday adapter for live tests can be specified with ADAPTER=[your adapter] in the
|
|
31
|
+
-- Faraday adapter for live tests can be specified with ADAPTER=[your adapter] in the rspec command
|
|
32
|
+
-- Live tests can be run against the beta server by specifying BETA=true in the rspec command
|
|
23
33
|
-- Tests now pass against all rubies on Travis CI
|
|
24
|
-
-- Expanded test coverage
|
|
34
|
+
-- Expanded and refactored test coverage
|
|
25
35
|
-- Fixed bug with YAML parsing in Ruby 1.9
|
|
26
36
|
|
|
27
37
|
v1.1
|
data/koala.gemspec
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
|
3
|
+
require 'koala/version'
|
|
2
4
|
|
|
3
5
|
Gem::Specification.new do |s|
|
|
4
6
|
s.name = %q{koala}
|
|
5
|
-
s.version =
|
|
6
|
-
s.date = %q{2011-
|
|
7
|
+
s.version = Koala::VERSION
|
|
8
|
+
s.date = %q{2011-09-27}
|
|
7
9
|
|
|
8
10
|
s.summary = %q{A lightweight, flexible library for Facebook with support for the Graph API, the REST API, realtime updates, and OAuth authentication.}
|
|
9
11
|
s.description = %q{Koala is a lightweight, flexible Ruby SDK for Facebook. It allows read/write access to the social graph via the Graph and REST APIs, as well as support for realtime updates and OAuth and Facebook Connect authentication. Koala is fully tested and supports Net::HTTP and Typhoeus connections out of the box and can accept custom modules for other services.}
|
|
@@ -29,22 +31,19 @@ Gem::Specification.new do |s|
|
|
|
29
31
|
|
|
30
32
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
31
33
|
s.add_runtime_dependency(%q<multi_json>, ["~> 1.0"])
|
|
32
|
-
s.add_runtime_dependency(%q<faraday>, ["~> 0.7.
|
|
33
|
-
s.add_runtime_dependency(%q<faraday-stack>, ["~> 0.1.3"])
|
|
34
|
+
s.add_runtime_dependency(%q<faraday>, ["~> 0.7.0"])
|
|
34
35
|
s.add_development_dependency(%q<rspec>, ["~> 2.5"])
|
|
35
36
|
s.add_development_dependency(%q<rake>, ["~> 0.8.7"])
|
|
36
37
|
else
|
|
37
38
|
s.add_dependency(%q<multi_json>, ["~> 1.0"])
|
|
38
39
|
s.add_dependency(%q<rspec>, ["~> 2.5"])
|
|
39
40
|
s.add_dependency(%q<rake>, ["~> 0.8.7"])
|
|
40
|
-
s.add_dependency(%q<faraday>, ["~> 0.7.
|
|
41
|
-
s.add_dependency(%q<faraday-stack>, ["~> 0.1.3"])
|
|
41
|
+
s.add_dependency(%q<faraday>, ["~> 0.7.0"])
|
|
42
42
|
end
|
|
43
43
|
else
|
|
44
44
|
s.add_dependency(%q<multi_json>, ["~> 1.0"])
|
|
45
45
|
s.add_dependency(%q<rspec>, ["~> 2.5"])
|
|
46
46
|
s.add_dependency(%q<rake>, ["~> 0.8.7"])
|
|
47
|
-
s.add_dependency(%q<faraday>, ["~> 0.7.
|
|
48
|
-
s.add_dependency(%q<faraday-stack>, ["~> 0.1.3"])
|
|
47
|
+
s.add_dependency(%q<faraday>, ["~> 0.7.0"])
|
|
49
48
|
end
|
|
50
49
|
end
|
data/lib/koala/graph_api.rb
CHANGED
|
@@ -71,9 +71,7 @@ module Koala
|
|
|
71
71
|
|
|
72
72
|
def get_connections(id, connection_name, args = {}, options = {})
|
|
73
73
|
# Fetchs the connections for given object.
|
|
74
|
-
graph_call("#{id}/#{connection_name}", args, "get", options)
|
|
75
|
-
result ? GraphCollection.new(result, self) : nil # when facebook is down nil can be returned
|
|
76
|
-
end
|
|
74
|
+
graph_call("#{id}/#{connection_name}", args, "get", options)
|
|
77
75
|
end
|
|
78
76
|
|
|
79
77
|
def put_connections(id, connection_name, args = {}, options = {})
|
|
@@ -174,9 +172,7 @@ module Koala
|
|
|
174
172
|
|
|
175
173
|
def search(search_terms, args = {}, options = {})
|
|
176
174
|
args.merge!({:q => search_terms}) unless search_terms.nil?
|
|
177
|
-
graph_call("search", args, "get", options)
|
|
178
|
-
result ? GraphCollection.new(result, self) : nil # when facebook is down nil can be returned
|
|
179
|
-
end
|
|
175
|
+
graph_call("search", args, "get", options)
|
|
180
176
|
end
|
|
181
177
|
|
|
182
178
|
# Convenience Methods
|
|
@@ -199,14 +195,12 @@ module Koala
|
|
|
199
195
|
def get_page(params)
|
|
200
196
|
# Pages through a set of results stored in a GraphCollection
|
|
201
197
|
# Used for connections and search results
|
|
202
|
-
graph_call(*params)
|
|
203
|
-
result ? GraphCollection.new(result, self) : nil # when facebook is down nil can be returned
|
|
204
|
-
end
|
|
198
|
+
graph_call(*params)
|
|
205
199
|
end
|
|
206
200
|
|
|
207
201
|
# Batch API
|
|
208
202
|
def batch(http_options = {}, &block)
|
|
209
|
-
batch_client = GraphBatchAPI.new(access_token)
|
|
203
|
+
batch_client = GraphBatchAPI.new(access_token, self)
|
|
210
204
|
if block
|
|
211
205
|
yield batch_client
|
|
212
206
|
batch_client.execute(http_options)
|
|
@@ -214,15 +208,7 @@ module Koala
|
|
|
214
208
|
batch_client
|
|
215
209
|
end
|
|
216
210
|
end
|
|
217
|
-
|
|
218
|
-
def self.included(base)
|
|
219
|
-
base.class_eval do
|
|
220
|
-
def self.batch
|
|
221
|
-
raise NoMethodError, "The BatchAPI signature has changed (the original implementation was not thread-safe). Please see https://github.com/arsduo/koala/wiki/Batch-requests. (This message will be removed in the final 1.1 release.)"
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
end
|
|
225
|
-
|
|
211
|
+
|
|
226
212
|
# Direct access to the Facebook API
|
|
227
213
|
# see any of the above methods for example invocations
|
|
228
214
|
def graph_call(path, args = {}, verb = "get", options = {}, &post_processing)
|
|
@@ -231,10 +217,15 @@ module Koala
|
|
|
231
217
|
raise error if error
|
|
232
218
|
end
|
|
233
219
|
|
|
234
|
-
#
|
|
220
|
+
# turn this into a GraphCollection if it's pageable
|
|
221
|
+
result = GraphCollection.evaluate(result, self)
|
|
222
|
+
|
|
223
|
+
# now process as appropriate for the given call (get picture header, etc.)
|
|
235
224
|
post_processing ? post_processing.call(result) : result
|
|
236
225
|
end
|
|
237
226
|
|
|
227
|
+
private
|
|
228
|
+
|
|
238
229
|
def check_response(response)
|
|
239
230
|
# check for Graph API-specific errors
|
|
240
231
|
# this returns an error, which is immediately raised (non-batch)
|
|
@@ -244,8 +235,6 @@ module Koala
|
|
|
244
235
|
end
|
|
245
236
|
end
|
|
246
237
|
|
|
247
|
-
private
|
|
248
|
-
|
|
249
238
|
def parse_media_args(media_args, method)
|
|
250
239
|
# photo and video uploads can accept different types of arguments (see above)
|
|
251
240
|
# so here, we parse the arguments into a form directly usable in put_object
|
|
@@ -4,6 +4,13 @@ module Koala
|
|
|
4
4
|
|
|
5
5
|
def self.included(base)
|
|
6
6
|
base.class_eval do
|
|
7
|
+
attr_reader :original_api
|
|
8
|
+
|
|
9
|
+
def initialize(access_token, api)
|
|
10
|
+
super(access_token)
|
|
11
|
+
@original_api = api
|
|
12
|
+
end
|
|
13
|
+
|
|
7
14
|
alias_method :graph_call_outside_batch, :graph_call
|
|
8
15
|
alias_method :graph_call, :graph_call_in_batch
|
|
9
16
|
|
|
@@ -46,7 +53,7 @@ module Koala
|
|
|
46
53
|
batch_op.to_batch_params(access_token)
|
|
47
54
|
})
|
|
48
55
|
|
|
49
|
-
graph_call_outside_batch('/', args, 'post', http_options) do |response|
|
|
56
|
+
batch_result = graph_call_outside_batch('/', args, 'post', http_options) do |response|
|
|
50
57
|
# map the results with post-processing included
|
|
51
58
|
index = 0 # keep compat with ruby 1.8 - no with_index for map
|
|
52
59
|
response.map do |call_result|
|
|
@@ -80,6 +87,9 @@ module Koala
|
|
|
80
87
|
end
|
|
81
88
|
end
|
|
82
89
|
end
|
|
90
|
+
|
|
91
|
+
# turn any results that are pageable into GraphCollections
|
|
92
|
+
batch_result.inject([]) {|processed_results, raw| processed_results << GraphCollection.evaluate(raw, @original_api)}
|
|
83
93
|
end
|
|
84
94
|
|
|
85
95
|
end
|
|
@@ -10,12 +10,17 @@ module Koala
|
|
|
10
10
|
# It also allows access to paging information and the
|
|
11
11
|
# ability to get the next/previous page in the collection
|
|
12
12
|
# by calling next_page or previous_page.
|
|
13
|
-
attr_reader :paging
|
|
14
|
-
attr_reader :api
|
|
13
|
+
attr_reader :paging, :api, :raw_response
|
|
15
14
|
|
|
15
|
+
def self.evaluate(response, api)
|
|
16
|
+
# turn the response into a GraphCollection if it's pageable; if not, return the original response
|
|
17
|
+
response.is_a?(Hash) && response["data"].is_a?(Array) ? self.new(response, api) : response
|
|
18
|
+
end
|
|
19
|
+
|
|
16
20
|
def initialize(response, api)
|
|
17
21
|
super response["data"]
|
|
18
22
|
@paging = response["paging"]
|
|
23
|
+
@raw_response = response
|
|
19
24
|
@api = api
|
|
20
25
|
end
|
|
21
26
|
|
data/lib/koala/http_service.rb
CHANGED
data/lib/koala/oauth.rb
CHANGED
|
@@ -9,31 +9,18 @@ module Koala
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def get_user_info_from_cookie(cookie_hash)
|
|
12
|
-
# Parses the cookie set
|
|
13
|
-
#
|
|
14
|
-
# cookies should be a Hash, like the one Rails provides
|
|
12
|
+
# Parses the cookie set Facebook's JavaScript SDK.
|
|
13
|
+
# You can pass Rack/Rails/Sinatra's cookie hash directly to this method.
|
|
15
14
|
#
|
|
16
15
|
# If the user is logged in via Facebook, we return a dictionary with the
|
|
17
16
|
# keys "uid" and "access_token". The former is the user's Facebook ID,
|
|
18
17
|
# and the latter can be used to make authenticated requests to the Graph API.
|
|
19
18
|
# If the user is not logged in, we return None.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if fb_cookie = cookie_hash["fbs_" + @app_id.to_s]
|
|
26
|
-
# remove the opening/closing quote
|
|
27
|
-
fb_cookie = fb_cookie.gsub(/\"/, "")
|
|
28
|
-
|
|
29
|
-
# since we no longer get individual cookies, we have to separate out the components ourselves
|
|
30
|
-
components = {}
|
|
31
|
-
fb_cookie.split("&").map {|param| param = param.split("="); components[param[0]] = param[1]}
|
|
32
|
-
|
|
33
|
-
# generate the signature and make sure it matches what we expect
|
|
34
|
-
auth_string = components.keys.sort.collect {|a| a == "sig" ? nil : "#{a}=#{components[a]}"}.reject {|a| a.nil?}.join("")
|
|
35
|
-
sig = Digest::MD5.hexdigest(auth_string + @app_secret)
|
|
36
|
-
sig == components["sig"] && (components["expires"] == "0" || Time.now.to_i < components["expires"].to_i) ? components : nil
|
|
19
|
+
|
|
20
|
+
if signed_cookie = cookie_hash["fbsr_#{@app_id}"]
|
|
21
|
+
parse_signed_cookie(signed_cookie)
|
|
22
|
+
elsif unsigned_cookie = cookie_hash["fbs_#{@app_id}"]
|
|
23
|
+
parse_unsigned_cookie(unsigned_cookie)
|
|
37
24
|
end
|
|
38
25
|
end
|
|
39
26
|
alias_method :get_user_info_from_cookies, :get_user_info_from_cookie
|
|
@@ -70,7 +57,7 @@ module Koala
|
|
|
70
57
|
def get_access_token_info(code, options = {})
|
|
71
58
|
# convenience method to get a parsed token from Facebook for a given code
|
|
72
59
|
# should this require an OAuth callback URL?
|
|
73
|
-
get_token_from_server({:code => code, :redirect_uri => @oauth_callback_url}, false, options)
|
|
60
|
+
get_token_from_server({:code => code, :redirect_uri => options[:redirect_uri] || @oauth_callback_url}, false, options)
|
|
74
61
|
end
|
|
75
62
|
|
|
76
63
|
def get_access_token(code, options = {})
|
|
@@ -104,7 +91,7 @@ module Koala
|
|
|
104
91
|
raise "SignedRequest: Unsupported algorithm #{envelope['algorithm']}" if envelope['algorithm'] != 'HMAC-SHA256'
|
|
105
92
|
|
|
106
93
|
# now see if the signature is valid (digest, key, data)
|
|
107
|
-
hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, @app_secret, encoded_envelope
|
|
94
|
+
hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, @app_secret, encoded_envelope)
|
|
108
95
|
raise 'SignedRequest: Invalid signature' if (signature != hmac)
|
|
109
96
|
|
|
110
97
|
return envelope
|
|
@@ -162,6 +149,29 @@ module Koala
|
|
|
162
149
|
end
|
|
163
150
|
components
|
|
164
151
|
end
|
|
152
|
+
|
|
153
|
+
def parse_unsigned_cookie(fb_cookie)
|
|
154
|
+
# remove the opening/closing quote
|
|
155
|
+
fb_cookie = fb_cookie.gsub(/\"/, "")
|
|
156
|
+
|
|
157
|
+
# since we no longer get individual cookies, we have to separate out the components ourselves
|
|
158
|
+
components = {}
|
|
159
|
+
fb_cookie.split("&").map {|param| param = param.split("="); components[param[0]] = param[1]}
|
|
160
|
+
|
|
161
|
+
# generate the signature and make sure it matches what we expect
|
|
162
|
+
auth_string = components.keys.sort.collect {|a| a == "sig" ? nil : "#{a}=#{components[a]}"}.reject {|a| a.nil?}.join("")
|
|
163
|
+
sig = Digest::MD5.hexdigest(auth_string + @app_secret)
|
|
164
|
+
sig == components["sig"] && (components["expires"] == "0" || Time.now.to_i < components["expires"].to_i) ? components : nil
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def parse_signed_cookie(fb_cookie)
|
|
168
|
+
components = parse_signed_request(fb_cookie)
|
|
169
|
+
if (code = components["code"]) && token_info = get_access_token_info(code, :redirect_uri => '')
|
|
170
|
+
components.merge(token_info)
|
|
171
|
+
else
|
|
172
|
+
nil
|
|
173
|
+
end
|
|
174
|
+
end
|
|
165
175
|
|
|
166
176
|
def fetch_token_string(args, post = false, endpoint = "access_token", options = {})
|
|
167
177
|
Koala.make_request("/oauth/#{endpoint}", {
|
data/lib/koala/test_users.rb
CHANGED
|
@@ -35,7 +35,7 @@ module Koala
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def list
|
|
38
|
-
@api.graph_call(accounts_path)
|
|
38
|
+
@api.graph_call(accounts_path)
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def delete(test_user)
|
|
@@ -72,7 +72,6 @@ module Koala
|
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
def create_network(network_size, installed = true, permissions = '')
|
|
75
|
-
network_size = 50 if network_size > 50 # FB's max is 50
|
|
76
75
|
users = (0...network_size).collect { create(installed, permissions) }
|
|
77
76
|
friends = users.clone
|
|
78
77
|
users.each do |user|
|
data/lib/koala/uploadable_io.rb
CHANGED
data/lib/koala.rb
CHANGED
|
@@ -8,7 +8,6 @@ require 'openssl'
|
|
|
8
8
|
require 'base64'
|
|
9
9
|
|
|
10
10
|
# include koala modules
|
|
11
|
-
require 'koala/http_service'
|
|
12
11
|
require 'koala/oauth'
|
|
13
12
|
require 'koala/graph_api'
|
|
14
13
|
require 'koala/graph_batch_api'
|
|
@@ -17,11 +16,17 @@ require 'koala/graph_collection'
|
|
|
17
16
|
require 'koala/rest_api'
|
|
18
17
|
require 'koala/realtime_updates'
|
|
19
18
|
require 'koala/test_users'
|
|
20
|
-
|
|
19
|
+
|
|
20
|
+
# HTTP module so we can communicate with Facebook
|
|
21
|
+
require 'koala/http_service'
|
|
21
22
|
|
|
22
23
|
# add KoalaIO class
|
|
23
24
|
require 'koala/uploadable_io'
|
|
24
25
|
|
|
26
|
+
# miscellaneous
|
|
27
|
+
require 'koala/utils'
|
|
28
|
+
require 'koala/version'
|
|
29
|
+
|
|
25
30
|
module Koala
|
|
26
31
|
|
|
27
32
|
module Facebook
|
data/readme.md
CHANGED
|
@@ -9,28 +9,41 @@ Koala
|
|
|
9
9
|
* Flexible: Koala should be useful to everyone, regardless of their current configuration. (We support JRuby, Rubinius, and REE as well as vanilla Ruby, and use the Faraday library to provide complete flexibility over how HTTP requests are made.)
|
|
10
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.)
|
|
11
11
|
|
|
12
|
+
Facebook Changes on October 1, 2011
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
**Koala 1.2 supports all of Facebook's new authentication schemes**, which will be introduced on October 1, 2011; the old Javascript library and older authentication schemes will be deprecated at the same time.
|
|
16
|
+
|
|
17
|
+
To test your application, upgrade to the latest version of Koala (see below) and configure your application according to Facebook's [OAuth 2.0 and HTTPS Migration](https://developers.facebook.com/docs/oauth2-https-migration/) guide. If you have the appropriate calls to get_user_info_from_cookies (apps using the Javascript SDK) and/or parse_signed_params (for Canvas and tab apps), your application should work without a hitch.
|
|
18
|
+
|
|
19
|
+
_Note_: in their new secure cookie format, Facebook provides an OAuth code, which Koala automatically exchanges for an access token. Because this involves a call to Facebook's servers, you should consider storing the user's access token in their session and only calling get_user_info_from_cookies when necessary (access_token not present, you discover it's expired, etc.). Otherwise, you'll be calling out to Facebook each time the user loads a page, slowing down your site. (As we figure out best practices for this, we'll update the wiki.)
|
|
20
|
+
|
|
12
21
|
Installation
|
|
13
22
|
---
|
|
14
23
|
|
|
15
24
|
Easy:
|
|
16
25
|
|
|
17
|
-
[sudo|rvm] gem install koala
|
|
18
|
-
[sudo|rvm] gem install koala # for 1.1
|
|
26
|
+
[sudo|rvm] gem install koala
|
|
19
27
|
|
|
20
28
|
Or in Bundler:
|
|
21
29
|
|
|
22
|
-
gem "koala"
|
|
23
|
-
gem "koala" # for 1.1
|
|
30
|
+
gem "koala"
|
|
24
31
|
|
|
25
32
|
Graph API
|
|
26
33
|
----
|
|
27
34
|
The Graph API is the simple, slick new interface to Facebook's data. Using it with Koala is quite straightforward:
|
|
28
|
-
|
|
35
|
+
|
|
29
36
|
@graph = Koala::Facebook::API.new(oauth_access_token)
|
|
37
|
+
# in 1.1 or earlier, use GraphAPI instead of API
|
|
38
|
+
|
|
30
39
|
profile = @graph.get_object("me")
|
|
31
40
|
friends = @graph.get_connections("me", "friends")
|
|
32
41
|
@graph.put_object("me", "feed", :message => "I am writing on my wall!")
|
|
33
42
|
|
|
43
|
+
# you can even use the new Timeline API
|
|
44
|
+
# see https://developers.facebook.com/docs/beta/opengraph/tutorial/
|
|
45
|
+
@graph.put_connections("me", "namespace:action", :object => object_url)
|
|
46
|
+
|
|
34
47
|
The response of most requests is the JSON data returned from the Facebook servers as a Hash.
|
|
35
48
|
|
|
36
49
|
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:
|
|
@@ -61,13 +74,18 @@ Where the Graph API and the old REST API overlap, you should choose the Graph AP
|
|
|
61
74
|
|
|
62
75
|
Fortunately, Koala supports the REST API using the very same interface; to use this, instantiate an API:
|
|
63
76
|
|
|
64
|
-
|
|
77
|
+
@rest = Koala::Facebook::API.new(oauth_access_token)
|
|
78
|
+
# in 1.1 or earlier, use RestAPI instead of API
|
|
79
|
+
|
|
65
80
|
@rest.fql_query(my_fql_query) # convenience method
|
|
66
81
|
@rest.fql_multiquery(fql_query_hash) # convenience method
|
|
67
82
|
@rest.rest_call("stream.publish", arguments_hash) # generic version
|
|
68
83
|
|
|
69
84
|
Of course, you can use the Graph API methods on the same object -- the power of two APIs right in the palm of your hand.
|
|
70
85
|
|
|
86
|
+
@api = Koala::Facebook::API.new(oauth_access_token)
|
|
87
|
+
# in 1.1 or earlier, use GraphAndRestAPI instead of API
|
|
88
|
+
|
|
71
89
|
@api = Koala::Facebook::API.new(oauth_access_token)
|
|
72
90
|
fql = @api.fql_query(my_fql_query)
|
|
73
91
|
@api.put_wall_post(process_result(fql))
|
|
@@ -92,7 +110,7 @@ You can also get your application's own access token, which can be used without
|
|
|
92
110
|
@oauth.get_app_access_token
|
|
93
111
|
|
|
94
112
|
For those building apps on Facebook, parsing signed requests is simple:
|
|
95
|
-
@oauth.parse_signed_request(
|
|
113
|
+
@oauth.parse_signed_request(signed_request_string)
|
|
96
114
|
|
|
97
115
|
Or, if for some horrible reason, you're still using session keys, despair not! It's easy to turn them into shiny, modern OAuth tokens:
|
|
98
116
|
@oauth.get_token_from_session_key(session_key)
|
|
@@ -158,5 +176,7 @@ You can also run live tests against Facebook's servers:
|
|
|
158
176
|
|
|
159
177
|
# Again from anywhere in the project directory:
|
|
160
178
|
LIVE=true bundle exec rake spec
|
|
179
|
+
# you can also test against Facebook's beta tier
|
|
180
|
+
LIVE=true BETA=true bundle exec rake spec
|
|
161
181
|
|
|
162
182
|
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.
|
|
@@ -98,4 +98,29 @@ describe "Koala::Facebook::API" do
|
|
|
98
98
|
end
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
+
describe "with an access token" do
|
|
102
|
+
before(:each) do
|
|
103
|
+
@api = Koala::Facebook::API.new(@token)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it_should_behave_like "Koala RestAPI"
|
|
107
|
+
it_should_behave_like "Koala RestAPI with an access token"
|
|
108
|
+
|
|
109
|
+
it_should_behave_like "Koala GraphAPI"
|
|
110
|
+
it_should_behave_like "Koala GraphAPI with an access token"
|
|
111
|
+
it_should_behave_like "Koala GraphAPI with GraphCollection"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
describe "without an access token" do
|
|
115
|
+
before(:each) do
|
|
116
|
+
@api = Koala::Facebook::API.new
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it_should_behave_like "Koala RestAPI"
|
|
120
|
+
it_should_behave_like "Koala RestAPI without an access token"
|
|
121
|
+
|
|
122
|
+
it_should_behave_like "Koala GraphAPI"
|
|
123
|
+
it_should_behave_like "Koala GraphAPI without an access token"
|
|
124
|
+
it_should_behave_like "Koala GraphAPI with GraphCollection"
|
|
125
|
+
end
|
|
101
126
|
end
|
|
@@ -19,30 +19,4 @@ describe "Koala::Facebook::GraphAndRestAPI" do
|
|
|
19
19
|
api = Koala::Facebook::GraphAndRestAPI.new("token")
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
|
-
|
|
23
|
-
describe "with an access token" do
|
|
24
|
-
before(:each) do
|
|
25
|
-
@api = Koala::Facebook::API.new(@token)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it_should_behave_like "Koala RestAPI"
|
|
29
|
-
it_should_behave_like "Koala RestAPI with an access token"
|
|
30
|
-
|
|
31
|
-
it_should_behave_like "Koala GraphAPI"
|
|
32
|
-
it_should_behave_like "Koala GraphAPI with an access token"
|
|
33
|
-
it_should_behave_like "Koala GraphAPI with GraphCollection"
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
describe "without an access token" do
|
|
37
|
-
before(:each) do
|
|
38
|
-
@api = Koala::Facebook::API.new
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
it_should_behave_like "Koala RestAPI"
|
|
42
|
-
it_should_behave_like "Koala RestAPI without an access token"
|
|
43
|
-
|
|
44
|
-
it_should_behave_like "Koala GraphAPI"
|
|
45
|
-
it_should_behave_like "Koala GraphAPI without an access token"
|
|
46
|
-
it_should_behave_like "Koala GraphAPI with GraphCollection"
|
|
47
|
-
end
|
|
48
22
|
end
|
|
@@ -430,7 +430,7 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
|
430
430
|
end
|
|
431
431
|
|
|
432
432
|
describe "usage tests" do
|
|
433
|
-
it "
|
|
433
|
+
it "gets two results at once" do
|
|
434
434
|
me, koppel = @api.batch do |batch_api|
|
|
435
435
|
batch_api.get_object('me')
|
|
436
436
|
batch_api.get_object(KoalaTest.user1)
|
|
@@ -439,7 +439,15 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
|
439
439
|
koppel['id'].should_not be_nil
|
|
440
440
|
end
|
|
441
441
|
|
|
442
|
-
it '
|
|
442
|
+
it 'makes mixed calls inside of a batch' do
|
|
443
|
+
me, friends = @api.batch do |batch_api|
|
|
444
|
+
batch_api.get_object('me')
|
|
445
|
+
batch_api.get_connections('me', 'friends')
|
|
446
|
+
end
|
|
447
|
+
friends.should be_a(Koala::Facebook::GraphCollection)
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
it 'turns pageable results into GraphCollections' do
|
|
443
451
|
me, friends = @api.batch do |batch_api|
|
|
444
452
|
batch_api.get_object('me')
|
|
445
453
|
batch_api.get_connections('me', 'friends')
|
|
@@ -448,14 +456,14 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
|
448
456
|
friends.should be_an(Array)
|
|
449
457
|
end
|
|
450
458
|
|
|
451
|
-
it '
|
|
459
|
+
it 'makes a get_picture call inside of a batch' do
|
|
452
460
|
pictures = @api.batch do |batch_api|
|
|
453
461
|
batch_api.get_picture('me')
|
|
454
462
|
end
|
|
455
463
|
pictures.first.should_not be_empty
|
|
456
464
|
end
|
|
457
465
|
|
|
458
|
-
it "
|
|
466
|
+
it "handles requests for two different tokens" do
|
|
459
467
|
me, insights = @api.batch do |batch_api|
|
|
460
468
|
batch_api.get_object('me')
|
|
461
469
|
batch_api.get_connections(@app_id, 'insights', {}, {"access_token" => @app_api.access_token})
|
|
@@ -571,30 +579,4 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
|
571
579
|
end
|
|
572
580
|
end
|
|
573
581
|
end
|
|
574
|
-
|
|
575
|
-
describe "new interface" do
|
|
576
|
-
it "includes a deprecation warning on GraphAPI" do
|
|
577
|
-
begin
|
|
578
|
-
Koala::Facebook::GraphAPI.batch do
|
|
579
|
-
end
|
|
580
|
-
rescue NoMethodError => @err
|
|
581
|
-
end
|
|
582
|
-
|
|
583
|
-
# verify the message points people to the wiki page
|
|
584
|
-
@err.should
|
|
585
|
-
@err.message.should =~ /https\:\/\/github.com\/arsduo\/koala\/wiki\/Batch-requests/
|
|
586
|
-
end
|
|
587
|
-
|
|
588
|
-
it "includes a deprecation warning on GraphAndRESTAPI" do
|
|
589
|
-
begin
|
|
590
|
-
Koala::Facebook::GraphAndRestAPI.batch do
|
|
591
|
-
end
|
|
592
|
-
rescue NoMethodError => @err
|
|
593
|
-
end
|
|
594
|
-
|
|
595
|
-
# verify the message points people to the wiki page
|
|
596
|
-
@err.should
|
|
597
|
-
@err.message.should =~ /https\:\/\/github.com\/arsduo\/koala\/wiki\/Batch-requests/
|
|
598
|
-
end
|
|
599
|
-
end
|
|
600
582
|
end
|
|
@@ -19,24 +19,4 @@ describe "Koala::Facebook::GraphAPI" do
|
|
|
19
19
|
api = Koala::Facebook::GraphAPI.new("token")
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
|
-
|
|
23
|
-
context "with an access token" do
|
|
24
|
-
before :each do
|
|
25
|
-
@api = Koala::Facebook::API.new(@token)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it_should_behave_like "Koala GraphAPI"
|
|
29
|
-
it_should_behave_like "Koala GraphAPI with an access token"
|
|
30
|
-
it_should_behave_like "Koala GraphAPI with GraphCollection"
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
context "without an access token" do
|
|
34
|
-
before :each do
|
|
35
|
-
@api = Koala::Facebook::API.new
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
it_should_behave_like "Koala GraphAPI"
|
|
39
|
-
it_should_behave_like "Koala GraphAPI without an access token"
|
|
40
|
-
it_should_behave_like "Koala GraphAPI with GraphCollection"
|
|
41
|
-
end
|
|
42
22
|
end
|