Class: FBUtil

Inherits:
Object
  • Object
show all
Defined in:
lib/fb_util.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(access_token, debug = false) ⇒ FBUtil

Returns a new instance of FBUtil.



11
12
13
14
15
16
17
18
# File 'lib/fb_util.rb', line 11

def initialize(access_token, debug = false)
  @debug = debug
  @graph_url = 'https://graph.facebook.com'
  @access_token = access_token
  if @access_token.blank? && !Rails.nil?
    Rails.logger.info 'An access token is required for this class to work'
  end
end

Class Method Details

.generate_oauth_redirect(app_id, redirect_uri, scope) ⇒ Object

This method will generate the appropriate redirect for dialog oauth calls app_id: your app id from the facebook developer application redirect_uri: the uri that you want facebook to redirect to after the user authorizes your app (you can pass get variables in this if you need to pass variables back to your application i.e. example.com/auth?client_id=1) scope: comma seperate list of permissions your application is requesting (developers.facebook.com/docs/authentication/permissions/)



189
190
191
# File 'lib/fb_util.rb', line 189

def generate_oauth_redirect(app_id, redirect_uri, scope)
  return "https://www.facebook.com/dialog/oauth?client_id=" + app_id.to_s + "&redirect_uri=" + CGI.escape(redirect_uri.to_s) + '&scope=' + scope.to_s
end

.get_long_access_token(app_id, app_secret, redirect_uri, code) ⇒ Object

This method will get a long term access token. If you are getting the access_token for a facebook profile this will be valid for 60 days. If you are getting the access_token for a facebook page it be permanent. app_id: your app id assigned from facebook app_secret: your app secret assigned from facebook redirect_uri: A valid redirect uri is required to get access_tokens. You will not be redirected to this uri code: the code sent back from facebook after the user has authorized your application (generate_oauth_redirect will redirect back to your requested uri with the code needed)



198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/fb_util.rb', line 198

def get_long_access_token(app_id, app_secret, redirect_uri, code)
  begin
    agent = Mechanize.new
    short_access_page = agent.get("https://graph.facebook.com/oauth/access_token?client_id=#{app_id}&client_secret=#{app_secret}&redirect_uri=#{redirect_uri}&code=" + code)
    short_access_token = short_access_page.body.split('&')[0].split('=')[1]
    # This is where we convert the short access token into a long access token
    long_token_page = agent.get("https://graph.facebook.com/oauth/access_token?client_id=#{app_id}&client_secret=#{app_secret}&grant_type=fb_exchange_token&fb_exchange_token=#{short_access_token}")
    return {'access_token' => long_token_page.body.split('=')[1]}
  rescue Mechanize::ResponseCodeError => e
    raise FBUtilError.new(e.response_code, e.page.body)
  end
end

.get_long_from_short_access_token(short_access_token, app_id, app_secret) ⇒ Object

If you already have a short term access token this method will exchange that for a long term access token. 60 days for user accounts and indefinitely for profile pages short_access_token: the access token already assigned to the account. It must be a valid, non-expired access token app_id: your app id assigned from facebook app_secret: your app secret assigned from facebook



215
216
217
218
219
220
221
222
223
# File 'lib/fb_util.rb', line 215

def get_long_from_short_access_token(short_access_token, app_id, app_secret)
  begin
    agent = Mechanize.new
    long_token_page = agent.get("https://graph.facebook.com/oauth/access_token?client_id=#{app_id}&client_secret=#{app_secret}&grant_type=fb_exchange_token&fb_exchange_token=#{short_access_token}")
    return {'access_token' => long_token_page.body.split('=')[1]}
  rescue Mechanize::ResponseCodeError => e
    raise FBUtilError.new(e.response_code, e.page.body)
  end
end

.get_short_access_token(app_id, app_secret, redirect_uri, code) ⇒ Object

This method will get a short term access token for your application. Generally (1 - 2 hours) app_id: your app id assigned from facebook app_secret: your app secret assigned from facebook redirect_uri: A valid redirect uri is required to get access_tokens. You will not be redirected to this uri code: the code sent back from facebook after the user has authorized your application (generate_oauth_redirect will redirect back to your requested uri with the code needed)



230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/fb_util.rb', line 230

def get_short_access_token(app_id, app_secret, redirect_uri, code)
  begin
    agent = Mechanize.new
    short_access_page = agent.get("https://graph.facebook.com/oauth/access_token?client_id=#{app_id}&client_secret=#{app_secret}&redirect_uri=#{redirect_uri}&code=" + code)
    if short_access_page.body.include?('expires')
      return {'access_token' => short_access_page.body.split('&')[0].split('=')[1], 'expires' => short_access_page.body.split('&')[1].split('=')[1]}
    else
      return {'access_token' => short_access_page.body.split('=')[1]}
    end
  rescue Mechanize::ResponseCodeError => e
    raise FBUtilError.new(e.response_code, e.page.body)
  end
end

.parse_signed_request(signed_request, application_secret, max_age = 3600) ⇒ Object

This method will parse out a signed request using all the necessary validation required to find out if a facebook request is completely valid signed_request: the signed request passed in by facebook application_secret: the application secret assigned to your application form facebook max_age: the allowed age of the signed request. Defaults to 1 hour



248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# File 'lib/fb_util.rb', line 248

def parse_signed_request(signed_request, application_secret, max_age = 3600)
  encoded_signature, encoded_json = signed_request.split('.', 2)
  json = JSON.parse(base64_url_decode(encoded_json))
  encryption_algorithm = json['algorithm']

  if encryption_algorithm != 'HMAC-SHA256'
    raise 'Unsupported encryption algorithm.'
  elsif json['issued_at'] < Time.now.to_i - max_age
    raise 'Signed request too old.'
  elsif base64_url_decode(encoded_signature) != OpenSSL::HMAC.hexdigest('sha256', application_secret, encoded_json).split.pack('H*')
    raise 'Invalid signature.'
  end

  return json
end

Instance Method Details

#delete_status(status_id) ⇒ Object

Delete a status status_id: the facebook id of the status to delete



79
80
81
# File 'lib/fb_util.rb', line 79

def delete_status(status_id)
  delete_request('/' + status_id)
end

#get_account_infoObject

Get the basic account information from facebook



21
22
23
# File 'lib/fb_util.rb', line 21

def 
  @account_info ||= get_request('/me')
end

#get_feedObject

Get the users feed



26
27
28
29
30
31
32
33
34
# File 'lib/fb_util.rb', line 26

def get_feed
  @feed ||= get_request('/me/feed')
  # I have no idea why sometimes it uses the data index and sometimes it doesn't....
  begin
    return @feed['data']
  rescue
    return @feed
  end
end

#get_fql(fql) ⇒ Object

Get any fql request Fql cannot be cached since it might be used more than once to gather different data without creating a new facebook api class



106
107
108
# File 'lib/fb_util.rb', line 106

def get_fql(fql)
  get_request('/fql?q=' + CGI.escape(fql))['data']
end

#get_insightsObject

Get the insights of a page (**this doesn’t work for profiles**)



95
96
97
98
99
100
101
102
# File 'lib/fb_util.rb', line 95

def get_insights
  @insights ||= get_request('/me/insights')
  begin
    return @insights['data']
  rescue
    return @insights
  end
end

#get_pagesObject

Get pages associated with the account



111
112
113
# File 'lib/fb_util.rb', line 111

def get_pages
  @page ||= get_request('/me/accounts')['data']
end

#get_statusesObject

Get statuses from facebook page/account



84
85
86
87
88
89
90
91
92
# File 'lib/fb_util.rb', line 84

def get_statuses
  @statuses ||= get_request('/me/statuses')
  # I have no idea why sometimes it uses the data index and sometimes it doesn't....
  begin
    return @statuses['data']
  rescue
    return @statuses
  end
end

#post_link(link, message) ⇒ Object

Post a clickable link to a users feed (works for youtube videos as well) link: the link (beginning with http:// or https://) that will be displayed in the users feed message: the message to be posted with the link on the feed page



66
67
68
# File 'lib/fb_util.rb', line 66

def post_link(link, message)
  post_request('/me/feed', {link: link, message: message})
end

#post_picture(picture_path, message, post_to_feed = true) ⇒ Object

Post a picture to the users wall picture_path: the actual file path to the image (no urls) message: the message to be attached to the image if any. Can be null or empty. 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.



46
47
48
49
50
51
52
53
54
# File 'lib/fb_util.rb', line 46

def post_picture(picture_path, message, post_to_feed=true)
  File.open(picture_path.to_s.gsub('%20', '\ ').gsub('(', '\(').gsub(')', '\)'), 'rb') do |binary_image|
    if post_to_feed
      post_request('/me/photos', {source: binary_image, message: message})
    else
      post_request('/me/photos', {source: binary_image, message: message, no_story: 'true'})
    end
  end
end

#post_status(message) ⇒ Object

Post a message to the users wall 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)



38
39
40
# File 'lib/fb_util.rb', line 38

def post_status(message)
  post_request('/me/feed', {message: message})
end

#reply_to_status(status_id, message) ⇒ Object

Post a reply to a status that is already existing on facebook status_id: the facebook id of the status to reply to message: the message to use in the reply



73
74
75
# File 'lib/fb_util.rb', line 73

def reply_to_status(status_id, message)
  post_request('/' + status_id + '/comments', {message: message})
end

#set_as_cover_image(picture_id, offset_y = 50) ⇒ Object

Set an already existing image to be the users cover image picture_id: the facebook id of the image to use as the users cover image. offset_y: the offset that will be used to display the correct portion of the cover image on facebook. Default: 50



59
60
61
# File 'lib/fb_util.rb', line 59

def set_as_cover_image(picture_id, offset_y = 50)
  post_request('/me', {cover: picture_id, offset_y: offset_y.to_i.abs, no_feed_story: 'true'})
end