fb_util 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/fb_util.rb +199 -0
  2. 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: []