fb_util 0.0.7
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/lib/fb_util.rb +199 -0
- metadata +62 -0
data/lib/fb_util.rb
ADDED
@@ -0,0 +1,199 @@
|
|
1
|
+
require 'mechanize'
|
2
|
+
|
3
|
+
class FBUtil
|
4
|
+
@graph_url = nil
|
5
|
+
@access_token = nil
|
6
|
+
@feed = nil
|
7
|
+
@account_info = nil
|
8
|
+
@debug = nil
|
9
|
+
|
10
|
+
def initialize(access_token, debug = false)
|
11
|
+
@debug = debug
|
12
|
+
@graph_url = 'https://graph.facebook.com'
|
13
|
+
@access_token = access_token
|
14
|
+
if @access_token.blank? && !Rails.nil?
|
15
|
+
Rails.logger.info 'An access token is required for this class to work'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Get the basic account information from facebook
|
20
|
+
def get_account_info
|
21
|
+
@account_info ||= get_request('/me')
|
22
|
+
end
|
23
|
+
|
24
|
+
# Get the users feed
|
25
|
+
def get_feed
|
26
|
+
@feed ||= get_request('/me/feed')
|
27
|
+
# I have no idea why sometimes it uses the data index and sometimes it doesn't....
|
28
|
+
begin
|
29
|
+
return @feed['data']
|
30
|
+
rescue
|
31
|
+
return @feed
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Post a message to the users wall
|
36
|
+
# message: text of the message to be posted. Links will not be converted to click able links. Use post_link to post a clickable link (including video)
|
37
|
+
def post_status(message)
|
38
|
+
post_request('/me/feed', {message: message})
|
39
|
+
end
|
40
|
+
|
41
|
+
# Post a picture to the users wall
|
42
|
+
# picture_path: the actual file path to the image (no urls)
|
43
|
+
# message: the message to be attached to the image if any. Can be null or empty.
|
44
|
+
# post_to_feed: true (by default) if you want the picture to be posted to the users wall, false if you want it hidden. This isn't 100% tested.
|
45
|
+
def post_picture(picture_path, message, post_to_feed=true)
|
46
|
+
File.open(picture_path.to_s.gsub('%20', '\ ').gsub('(', '\(').gsub(')', '\)'), 'rb') do |binary_image|
|
47
|
+
if post_to_feed
|
48
|
+
post_request('/me/photos', {source: binary_image, message: message})
|
49
|
+
else
|
50
|
+
post_request('/me/photos', {source: binary_image, message: message, no_story: 'true'})
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Set an already existing image to be the users cover image
|
56
|
+
# picture_id: the facebook id of the image to use as the users cover image. This currently doesn't allow for an offset, but this will be available in the next version.
|
57
|
+
def set_as_cover_image(picture_id)
|
58
|
+
post_request('/me', {cover: picture_id, no_feed_story: 'true'})
|
59
|
+
end
|
60
|
+
|
61
|
+
# Post a clickable link to a users feed (works for youtube videos as well)
|
62
|
+
# link: the link (beginning with http:// or https://) that will be displayed in the users feed
|
63
|
+
# message: the message to be posted with the link on the feed page
|
64
|
+
def post_link(link, message)
|
65
|
+
post_request('/me/feed', {link: link, message: message})
|
66
|
+
end
|
67
|
+
|
68
|
+
# Post a reply to a status that is already existing on facebook
|
69
|
+
# status_id: the facebook id of the status to reply to
|
70
|
+
# message: the message to use in the reply
|
71
|
+
def reply_to_status(status_id, message)
|
72
|
+
post_request('/' + status_id + '/comments', {message: message})
|
73
|
+
end
|
74
|
+
|
75
|
+
# Delete a status
|
76
|
+
# status_id: the facebook id of the status to delete
|
77
|
+
def delete_status(status_id)
|
78
|
+
delete_request('/' + status_id)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Get statuses from facebook page/account
|
82
|
+
def get_statuses
|
83
|
+
@statuses ||= get_request('/me/statuses')
|
84
|
+
# I have no idea why sometimes it uses the data index and sometimes it doesn't....
|
85
|
+
begin
|
86
|
+
return @statuses['data']
|
87
|
+
rescue
|
88
|
+
return @statuses
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Get the insights of a page (**this doesn't work for profiles**)
|
93
|
+
def get_insights
|
94
|
+
@insights ||= get_request('/me/insights')
|
95
|
+
begin
|
96
|
+
return @insights['data']
|
97
|
+
rescue
|
98
|
+
return @insights
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Get any fql request
|
103
|
+
# Fql cannot be cached since it might be used more than once to gather different data without creating a new facebook api class
|
104
|
+
def get_fql(fql)
|
105
|
+
get_request('/fql?q=' + CGI.escape(fql))['data']
|
106
|
+
end
|
107
|
+
|
108
|
+
# Get pages associated with the account
|
109
|
+
def get_pages
|
110
|
+
@page ||= get_request('/me/accounts')['data']
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
# Execute a get request against the facebook endpoint requested
|
115
|
+
# end_point: anything in the url after the graph.facebook.com i.e. /me/accounts
|
116
|
+
def get_request(end_point)
|
117
|
+
execute_request(end_point, 'get')
|
118
|
+
end
|
119
|
+
|
120
|
+
# Send data to the facebook endpoint requested
|
121
|
+
# end_point: anything in the url after the graph.facebook.com i.e. /me/accounts
|
122
|
+
# parameters: the information to be sent to facebook in a hash
|
123
|
+
def post_request(end_point, parameters)
|
124
|
+
execute_request(end_point, 'post', parameters)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Delete end point from facebook
|
128
|
+
def delete_request(end_point)
|
129
|
+
execute_request(end_point, 'delete')
|
130
|
+
end
|
131
|
+
|
132
|
+
# The actual request send to facebook
|
133
|
+
# end_point: anything in the url after the graph.facebook.com i.e. /me/accounts
|
134
|
+
# method: the HTTP method used to send or receive information from facebook
|
135
|
+
# parameters: the information to be send to facebook in a hash
|
136
|
+
def execute_request(end_point, method, parameters = {})
|
137
|
+
agent = Mechanize.new
|
138
|
+
response = nil
|
139
|
+
begin
|
140
|
+
if end_point.include? '?'
|
141
|
+
url = @graph_url + end_point + '&access_token=' + @access_token
|
142
|
+
else
|
143
|
+
url = @graph_url + end_point + '?access_token=' + @access_token
|
144
|
+
end
|
145
|
+
if method == 'get'
|
146
|
+
response = agent.get(url)
|
147
|
+
elsif method == 'delete'
|
148
|
+
response = agent.get(url + '&method=delete')
|
149
|
+
elsif method == 'post'
|
150
|
+
response = agent.post(url, parameters)
|
151
|
+
end
|
152
|
+
if @debug && !Rails.nil?
|
153
|
+
# Echo the response if we are in development mode
|
154
|
+
if Rails.env.development?
|
155
|
+
Rails.logger.info 'FB: ' + method.capitalize + end_point
|
156
|
+
# Rails.logger.info 'FB Response: ' + response.body
|
157
|
+
end
|
158
|
+
end
|
159
|
+
return (JSON.parse response.body)
|
160
|
+
rescue Exception => e
|
161
|
+
if !Rails.nil?
|
162
|
+
Rails.logger.info e.page.body
|
163
|
+
Rails.logger.info 'Raw exception: ' + e.message
|
164
|
+
if @debug
|
165
|
+
if !(method == 'post')
|
166
|
+
Rails.logger.info 'FB: Error executing ' + method + ' request for "' + end_point + '"'
|
167
|
+
else
|
168
|
+
Rails.logger.info 'FB: Error executing ' + method + ' request for "' + end_point + '" with parameters: ' + parameters.inspect
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
return []
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# These are the methods that don't need to be called with an instanciated class because they don't need an access token
|
177
|
+
class << self
|
178
|
+
def base64_url_decode(encoded_url)
|
179
|
+
encoded_url += '=' * (4 - encoded_url.length.modulo(4))
|
180
|
+
Base64.decode64(encoded_url.gsub('-', '+').gsub('_', '/'))
|
181
|
+
end
|
182
|
+
|
183
|
+
def parse_signed_request(signed_request, application_secret, max_age = 3600)
|
184
|
+
encoded_signature, encoded_json = signed_request.split('.', 2)
|
185
|
+
json = JSON.parse(base64_url_decode(encoded_json))
|
186
|
+
encryption_algorithm = json['algorithm']
|
187
|
+
|
188
|
+
if encryption_algorithm != 'HMAC-SHA256'
|
189
|
+
raise 'Unsupported encryption algorithm.'
|
190
|
+
elsif json['issued_at'] < Time.now.to_i - max_age
|
191
|
+
raise 'Signed request too old.'
|
192
|
+
elsif base64_url_decode(encoded_signature) != OpenSSL::HMAC.hexdigest('sha256', application_secret, encoded_json).split.pack('H*')
|
193
|
+
raise 'Invalid signature.'
|
194
|
+
end
|
195
|
+
|
196
|
+
return json
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fb_util
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.7
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Brennon Loveless
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-06-18 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: mechanize
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.3'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.3'
|
30
|
+
description: A quick utility class to work with the facebook graph api and misc facebook
|
31
|
+
functions
|
32
|
+
email: brennon@fritzandandre.com
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- lib/fb_util.rb
|
38
|
+
homepage: http://rubygems.org/gems/fb_util
|
39
|
+
licenses: []
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options: []
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
requirements: []
|
57
|
+
rubyforge_project:
|
58
|
+
rubygems_version: 1.8.24
|
59
|
+
signing_key:
|
60
|
+
specification_version: 3
|
61
|
+
summary: Oh my simple facebook util
|
62
|
+
test_files: []
|