Coder Social home page Coder Social logo

mini_fb's Introduction

MiniFB - the simple miniature facebook library

MiniFB is a small, lightweight Ruby library for interacting with the Facebook API.

Brought to you by: Appoxy

Support

Join our Discussion Group at: http://groups.google.com/group/mini_fb

Demo Rails Application

There is a demo Rails app that uses mini_fb graph api at: http://github.com/appoxy/mini_fb_demo

Installation

gem install mini_fb

Facebook Graph API

For an overview of what this is all about, see http://developers.facebook.com/docs/api.

Authentication

Facebook now uses Oauth 2 for authentication, but don't worry, this part is easy.

# Get your oauth url
@oauth_url = MiniFB.oauth_url(FB_APP_ID, # your Facebook App ID (NOT API_KEY)
                              "http://www.yoursite.com/sessions/create", # redirect url
                              :scope=>MiniFB.scopes.join(",")) # This asks for all permissions
# Have your users click on a link to @oauth_url
.....
# Then in your /sessions/create
access_token_hash = MiniFB.oauth_access_token(FB_APP_ID, "http://www.yoursite.com/sessions/create", FB_SECRET, params[:code])
@access_token = access_token_hash["access_token"]
# TODO: This is where you'd want to store the token in your database
# but for now, we'll just keep it in the cookie so we don't need a database
cookies[:access_token] = @access_token

That's it. You now need to hold onto this access_token. We've put it in a cookie for now, but you probably want to store it in your database or something.

General Use

@response_hash = MiniFB.get(@access_token, @id, @options = {})

It's very simple:

@id = {some ID of something in facebook} || "me"
@options:
  type = {some facebook type like feed, friends, or photos}
  version = {version of the graph api}. Example: "2.5"
  fields = {array of fields to explicit fetch}
  params = {optional params}

# @response_hash is a hash, but also allows object like syntax for instance, the following is true:
@response_hash["user"] == @response_hash.user

See http://developers.facebook.com/docs/api for the available types.

Posting Data to Facebook

Also pretty simple:

@id = {some ID of something in facebook}
@type = {some type of post like comments, likes, feed} # required here
@response_hash = MiniFB.post(@access_token, @id, :type=>@type)

FQL

my_query = "select uid,a,b,c from users where ...."
@res = MiniFB.fql(@access_token, my_query)

Logging

To enabled logging:

MiniFB.enable_logging

Original Facebook API

This API will probably go away at some point, so you should use the Graph API above in most cases.

General Usage

The most general case is to use MiniFB.call method:

user_hash = MiniFB.call(FB_API_KEY, FB_SECRET, "Users.getInfo", "session_key"=>@session_key, "uids"=>@uid, "fields"=>User.all_fields)

Which simply returns the parsed json response from Facebook.

Oauth 2.0 Authentication and Original Rest Api

You can use the Graph api Oauth 2.0 token with original api methods. BEWARE: This has only been tested against stream.publish at present.

MiniFB.rest(@access_token, "rest.api.method", options)

eg:

response = MiniFB.rest(@access_token, "stream.publish", :params => {
  :uid => @user_id, :target_id => @target_user_id,
  :message => "Hello other user!"
})

all responses will be json. In the instance of 'bad json' methods, the response will formatted {'response': '#{bad_response_string}'}

Some Higher Level Objects for Common Uses

Get a MiniFB::Session:

@fb = MiniFB::Session.new(FB_API_KEY, FB_SECRET, @fb_session, @fb_uid)

Then it makes it a bit easier to use call for a particular user/session.

response = @fb.call("stream.get")

With the session, you can then get the user information for the session/uid.

user = @fb.user

Then get info from the user:

first_name = user["first_name"]

Or profile photos:

photos = user.profile_photos

Or if you want other photos, try:

photos = @fb.photos("pids"=>[12343243,920382343,9208348])

Higher Level Objects with OAuth2

Get a MiniFB::OAuthSession with a Spanish locale:

@fb = MiniFB::OAuthSession.new(access_token, 'es_ES')

Using the session object to make requests:

@fb.get('117199051648010')
@fb.post('me', :type => :feed, :params => {
  :message => "This is me from MiniFB"
})
@fb.fql('SELECT id FROM object_url WHERE url="http://www.imdb.com/title/tt1250777/"')
@fb.rest('notes.create', :params => {
  :title => "ToDo", :content => "Try MiniFB"
})

Getting graph objects through the session:

@fb.me
@fb.me.name
@fb.me.connections
@fb.me.feed

@ssp = @fb.graph_object('117199051648010')
@ssp.mission
@ssp.photos

Facebook Connect

This is actually very easy, first follow these instructions: http://wiki.developers.facebook.com/index.php/Connect/Setting_Up_Your_Site

Then add the following script to the page where you put the login button so it looks like this:

<script>
    function facebook_onlogin(){
        document.location.href = "<%= url_for :action=>"fb_connect" %>";
    }
</script>
<fb:login-button onlogin="facebook_onlogin();"></fb:login-button>

Define an fb_connect method in your login/sessions controller like so:

 def fb_connect
    @fb_info = MiniFB.parse_cookie_information(FB_APP_ID, cookies) # some users may have to use their API rather than the app. ID.
    puts "uid=#{@fb_info['uid']}"
    puts "session=#{@fb_info['session_key']}"

    if MiniFB.verify_cookie_signature(FB_APP_ID, FB_SECRET, cookies)
      # And here you would create the user if it doesn't already exist, then redirect them to wherever you want.
    else
      # The cookies may have been modified as the signature does not match
    end

end

Photo Uploads

This is as simple as calling:

@fb.call("photos.upload", "filename"=>"<full path to file>")

The file_name parameter will be used as the file data.

mini_fb's People

Contributors

aprimadi avatar ayrat555 avatar blanchma avatar bowsersenior avatar dpogue avatar foreverman avatar hfwang avatar isuda avatar jjanauskas avatar krokodaxl avatar mfo avatar mmozuras avatar myxaluch avatar oleriesenberg avatar ramin avatar rbshubbard avatar rgabo avatar scsmith avatar thoughtless avatar treeder avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mini_fb's Issues

Fix authenticate_as_app with logging enabled

NoMethodError: undefined method body' for {"access_token"=>"1426088894273662|dJE00nxA_buHZHdFLOWMtkYTHXA"}:Hash from /Users/blanchma/.rvm/gems/ruby-2.0.0-p247@moms_day/gems/mini_fb-2.0.0/lib/mini_fb.rb:565:inauthenticate_as_app'
from (irb):2

It only happens with logging enabled. Fix with #47

New format of returned data in fb_exchange_token

Hello!

Cool library, thank you! But last time, when I want to exchange my short-lived token to long-lived, I faced with problem - incorrect parsing of response data:

[11] pry(#<Authentication::Facebook>)> MiniFB.fb_exchange_token(app_id, app_secret, token)
=> {"{\"access_token\":\"***",\"token_type\":\"bearer\",\"expires_in\":5038422}"=>
  nil}

I guess, FB change the format of data on fb_exchange_token

screen shot 2017-07-12 at 13 33 48

So, I try to fix it by myself and create a PR during the week, I think

Friends.getAppUsers Bug (REST)

On line 660 of mini_fb.rb (v1.1.5), within the MiniFB::fetch method, you check if the result is an array and immediately attempt to utilize Hashie to convert its structure. Unfortunately, the REST call to friends.getAppUsers returns an array of Facebook user ID's, which this method incorrectly attempts to convert (and ultimately has an error occur in Hashie). Instead, the raw array data provided by friends.getAppUsers should be returned to the calling method.

if res_hash.is_a? Array # fql  return this
    res_hash.collect! { |x| Hashie::Mash.new(x) }
else
    res_hash = Hashie::Mash.new(res_hash)
end

Batch Publishing

Please direct me to another forum and close this if it's not the right place to post this.

Facebook supports batched posting for posting/getting multiple actions (bulk publishing or posts for example).
https://developers.facebook.com/docs/api/batch/

Can we support that or is it possible thru MiniFB?

Problem with religion

MiniFB.get(u.oauth2_token, 'me') doesn't bring Religion and Polical but from Graph API in developer.facebook.com I can see. I have requested all the permission. If I ask explicitly the field => ['religion'], I only get Hashie::Mash with an attribute id. What can be happen ?

verify_signed_request error due SHA256 usage of OpenSSL

Hello,

While using MiniFB to verify the signed_request received as part of App Deauthorization, we found that with latest Ruby 1.8.7 (patchlevel 334) it fails with the following exception:

>> MiniFB.verify_signed_request(secret, req)
TypeError: wrong argument (String)! (Expected kind of OpenSSL::Digest::Digest)
  from /home/dev/myapp/shared/bundle/ruby/1.8/gems/mini_fb-1.1.7/lib/mini_fb.rb:320:in `digest'
  from /home/dev/myapp/shared/bundle/ruby/1.8/gems/mini_fb-1.1.7/lib/mini_fb.rb:320:in `verify_signed_request'

Investigation of this turns out that 'SHA256' should be replaced with OpenSSL::Digest::SHA256.new instead, like this:

sha256 = OpenSSL::Digest::SHA256.new
expected_sig = OpenSSL::HMAC.digest(sha256, secret, p.tr("-_", "+/"))

get( :type=>:picture) fails

I bypassed it - in line 551 of mini_fb.rb - in the exception handling clause, I changed to simply return resp and not make a JSON out of it.
this way binary stuff can be fetched.

VERSION = "2.2.1" -> bug, body.split

Hi Guys, first of all great job for this gem, I've been using it for years : always worked smoothly.

Unfortunately the 2.2.1.gem from rubygems.org is missing the following commit that fixes the body.split instead of body.to_s.split

You can validate this issue by downloading the gem, unpacking it and finding greping the code :

wget https://rubygems.org/downloads/mini_fb-2.2.1.gem
gem unpack mini_fb-2.2.1.gem
cat lib/mini_fb.rb | grep 'resp.split'

Can you release a 2.2.2 with this bugfix ?

Problem with login_url

I believe there is a problem with the login_url method. Perhaps its possible that this wasn't meant to be used with canvas/iframe applications?

The login url facebook says to use is apps.facebook.com/login.php?v=1.0&....... The login url is generating api.facebook.com (and without the v=1.0). This causes FB to throw an error when trying to have a user authorize an application.

I know they have the oauth specification, but that seems to use a facebook connect url as its request_uri, which doesn't seem like the correct approach for a canvas/iframe application.

Puts in mini_fb 1.0.6

Hey guys, great library!

There is a puts at line 535 of mini_fb 1.0.6 which is dumping trace to our log files every time a POST action is made out to facebook. This should probably not be enabled by default.

Thanks

Just want to thank you for this gem! :)

REST Issue

Hi appoxy!

Thanks for developing this lightweight mini_fb. However, I came up with this problem when I was searching for my friends who are app users too. Here is the code I created:

@fb = MiniFB::OAuthSession.new(access_token, 'es_ES')
@fb.rest('friends.getAppUsers')
NoMethodError Exception: undefined method `each_pair' for XXXXXX:Fixnum

Thanks again and hoping for a quick response.

OpenSSL::SSL::SSLError

OpenSSL::SSL::SSLError SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

This happen after allow access.

rest client does not connect to graph api using SSLv3

require 'mini_fb'
access_token = "that_crazy long string"
MiniFB.get access_token, 'me'
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server hello A: sslv3 alert handshake failure
from /Users/rafaelsantos/.rbenv/versions/2.1.3/lib/ruby/2.1.0/net/http.rb:920:in `connect'

It seems the POODLE is annoying here, too.

bug when using split('&') for params_array

Hi,

HTTPClient get returns a HTTPMessage object:

params_array = resp.split("&")

should be changed to

params_array = resp.body.to_s.split("&")

on line 515 & 531 in mini_fb.rb

cheers

Thanks, using it, license

Thanks for this gem, currently used in Diaspora project!

I presume that this is free to use? From a more formal viewpoint, is there any license describing on what conditions, if any, one can use this gem?

thanks & rest-client issues

Hi!

Thanks for mini_fb! I'm really enjoying using this lightweight fb utility. I wanted to drop a note and ask if you had experienced any problems with rest-client. I recently deployed an app to Heroku using mini_fb and received the following error:

Error Message:


NoMethodError: undefined method `body' for #RestClient::Response:0x2ac99823d188

Where:


facebook#login
[GEM_ROOT]/gems/mini_fb-1.0.4/lib/mini_fb.rb, line 366

I get the same error with mini_fb-1.0.5. I think the problem is rest-client with versions lower that 1.5.0. http://github.com/archiloque/rest-client/blob/1.5.1/history.md. Should mini_fb require rest-client 1.5 or higher as a dependency?

Thanks again!

Release 2.0.1

@treeder What about releasing a new version of mini_fb, which would include the latest three small fixes? ๐Ÿ˜„

Possible signed_request signature validation error

I was implementing my own signed_request system for a project, and came across an inconsistency in how MiniFB does signature validation.

https://github.com/appoxy/mini_fb/blob/master/lib/mini_fb.rb#L320
This uses the base64 of the payload to build the signature.

Facebook's PHP example and almost every other example in other languages that I've seen uses the url-encoded base64 of the payload.

This would only cause problems if the signature happened to contain the + / (or - _) characters, which doesn't seem to be very often. However I did encounter an instance in my application where the MiniFB code believed the signature to be invalid due to the url-encoded base64.

JSON.parse does not work on valid JSON

When calling Facebook's auth.revokeAuthorization (see code below), Facebook simply returns "true". This is valid JSON, but the call to JSON.parse on line 203 of mini_fb.rb throws an exception, claiming that it is not valid JSON. As a workaround, I had to wrap my call with a rescue.

fb = MiniFB::Session.new(FACEBOOK_CONNECT_CONFIG['api_key'], FACEBOOK_CONNECT_CONFIG['secret_key'], current_user.facebook_session_key, current_user.facebook_uid)
fb.call('auth.revokeAuthorization', {:uid => current_user.facebook_uid})

Get user photos without limitations

Hi mini_fb,

Good Day,

Using mini_fb used i got user's photos, but i can get only 25 photos.
How can i remove the limitations. I need to get all photos.

Please advise.

Thank you

mini_fb fails if behind proxy

If behind proxy, net_http library will fails with `initialize': Connection refused - connect(2) (Errno::ECONNREFUSED) error, thus mini_fb fails.
It would be nice to handle this case also.

Stream.publish and attachments

Hi there,

I'm having some trouble using the REST API and publishing attachments with a href, titl, description and status message. Whenever I do it, it posts the message, but not any of the attachment details.

Do you know anything I may be doing wrong?

The call i'm making logs as...
https://api.facebook.com/method/stream.publish?format=JSON&message=RAMM&uid=[[PAGE_ID]]&access_token=[[ACCESS_TOKEN]]&attachment=%7B%22media%22:[%7B%22href%22:%22http:%5C/%5C/en.wikipedia.org%5C/wiki%5C/Kool_%2526_the_Gang%22,%22src%22:%22http:%5C/%5C/upload.wikimedia.org%5C/wikipedia%5C/en%5C/thumb%5C/4%5C/48%5C/KoolAndTheGangCollage-1000.jpg%5C/200px-KoolAndTheGangCollage-1000.jpg%22,%22type%22:%22image%22%7D],%22href%22:%22http:%5C/%5C/en.wikipedia.org%5C/wiki%5C/Kool_%2526_the_Gang%22,%22name%22:%22Kool%20&%20the%20Gang%20%20Wikipedia,%20the%20free%20encyclopedia%22,%22description%22:%22%22%7D

and the response is the uid to the created status.

Thanks in advance,

Andy.

oauth_url should not be nil without :scope

Right now oauth_url will return nil if :scope is not defined

MiniFB.oauth_url(FB_APP_ID, 'http://myurl') # Returns nil
MiniFB.oauth_url(FB_APP_ID, 'http://myurl', :scope => '' ) # Returns properly (for public access only)

oauth_url is just missing one line (basically making it match login_url):

in mini_fb.rb line 307

def self.oauth_url(app_id, redirect_uri, options={})
  oauth_url = "#{graph_base}oauth/authorize"
  oauth_url << "?client_id=#{app_id}"
  oauth_url << "&redirect_uri=#{URI.escape(redirect_uri)}"
  oauth_url << "&scope=#{options[:scope]}" if options[:scope]
end

should be:

def self.oauth_url(app_id, redirect_uri, options={})
  oauth_url = "#{graph_base}oauth/authorize"
  oauth_url << "?client_id=#{app_id}"
  oauth_url << "&redirect_uri=#{URI.escape(redirect_uri)}"
  oauth_url << "&scope=#{options[:scope]}" if options[:scope]
  oauth_url
end

Publishing checkins

Hi all. Great gem! I am trying to publish checkins and am almost there, but I am stumped, having read the gem docs and the Facebook API docs, about the right format for the coordinates. I tried:

MiniFB.post(checkin.user.facebook_auth.token, 'me', :type => 'checkins', :message => text, :place => checkin.producer.name, :coordinates => {'latitude' => '51.0000', 'longitude' => '-7.0011'}, :application => FACEBOOK_APP_ID)

...and I get an OAuth error saying latitude and longitude are missing. I have also tried using an array. Anyone know how to send the coordinates?

better way to handle facebook allow access?

in the example app, first time user is presented with a login page (welcomes_controller#index), user then has to click on the login link to see the allow access page. is there anyway to skip the index page and directly go to the allow access page? the good old facebooker has the desired behavior. my attempt of using redirect_to :auth_url in welcomes_controller#index fails.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.