Giter Club home page Giter Club logo

fbgraph's Introduction

Stay Classy, Facebook

FBgraph is a nodejs module that provides easy access to the facebook graph api

npm downloads

Oh nooooooesss - MOAR facebook

I created this because I wanted to access FB's graph from node. The libraries I found, felt clunky to me, and I needed an excuse to create a node module.

All calls will return json. Facebook sometimes (on friend requests, deleting test users, access token request) decides to just return a string or true or redirects directly to the image. I say nay-nay! Let's make it Disney, and keep things consistent!

Installation via npm

$ npm install fbgraph

var graph = require('fbgraph');

Authentication

If you get an accesstoken via some other Oauth module like everyauth , connect-auth or node-oauth you can just set the access token directly. Most get calls, and pretty much all post calls will require an access_token

Static access token (used on all calls)

    graph.setAccessToken(access_token);

To use a specific access token for a particular request

    // pass it in as part of the url
    graph.post(userId + "/feed?access_token=007", wallPost, function(err, res) {
        // returns the post id
        console.log(res); // { id: xxxxx}
    });

This is how you would get authenticated using only the fbgraph module. More details below on the express app section

    // get authorization url
    var authUrl = graph.getOauthUrl({
        "client_id":     conf.client_id
      , "redirect_uri":  conf.redirect_uri
    });

    // shows dialog
    res.redirect(authUrl);

    // after user click, auth `code` will be set
    // we'll send that and get the access token
    graph.authorize({
        "client_id":      conf.client_id
      , "redirect_uri":   conf.redirect_uri
      , "client_secret":  conf.client_secret
      , "code":           req.query.code
    }, function (err, facebookRes) {
      res.redirect('/loggedIn');
    });

Securing API calls

Facebook recommends adding the appsecret_proof parameter to all API calls to verify that the access tokens are coming from a valid app. You can make this happen automatically by calling graph.setAppSecret(app_secret), which will be used on all calls to generate the appsecret_proof hash that is sent to Facebook. Make sure you also set the access token for the user via graph.setAccessToken.

Extending access token expiration time

If you want to extend the expiration time of your short-living access token, you may use extendAccessToken method as it is shown below:

    // extending static access token
    graph.extendAccessToken({
        "client_id":      conf.client_id
      , "client_secret":  conf.client_secret
    }, function (err, facebookRes) {
       console.log(facebookRes);
    });

    // extending specific access token
    graph.extendAccessToken({
        "access_token":    client_access_token
      , "client_id":      conf.client_id
      , "client_secret":  conf.client_secret
    }, function (err, facebookRes) {
       console.log(facebookRes);
    });

How requests are made

All calls are made using the request nodejs module Why? something to do with wheels and re-invention.

Request options are directly mapped and can be set like so:

var options = {
    timeout:  3000
  , pool:     { maxSockets:  Infinity }
  , headers:  { connection:  "keep-alive" }
};

graph
  .setOptions(options)
  .get("zuck", function(err, res) {
    console.log(res); // { id: '4', name: 'Mark Zuckerberg'... }
  });

Possible options can be found on the request github page

followRedirect cannot be overriden and has a default value of false encoding will have utf-8 as default if nothing is set

Request Object

The request object is exposed as a property on graph object. So that all the request api can be accessed.

var graphObject = graph
  .get("zuck", function(err, res) {
    console.log(res); // { id: '4', name: 'Mark Zuckerberg'... }
  });

// abort the request.
graphObject.request.abort();

Pagination

Pagination in Facebook is done either with a cursor or a next url to call. To simplify the fbgraph API, it's possible to use a fully constructed URL in order to get the next page. See the following example:

// note: you might want to prevent the callback hell :)
graph.get('likes', {limit: 2, access_token: "foobar"}, function(err, res) {
  if(res.paging && res.paging.next) {
    graph.get(res.paging.next, function(err, res) {
      // page 2
    });
  }
});

Setting the version of the Graph Api

graph.setVersion("2.8");

See Facebook API changelog for available versions.

Read data from the Graph Api

graph.get("zuck", function(err, res) {
  console.log(res); // { id: '4', name: 'Mark Zuckerberg'... }
});

params in the url

graph.get("zuck?fields=picture", function(err, res) {
  console.log(res); // { picture: 'http://profile.ak.fbcdn.net/'... }
});

params as an object

var params = { fields: "picture" };

graph.get("zuck", params,  function(err, res) {
  console.log(res); // { picture: "http://profile.ak.fbcdn.net/..." }
});

GraphApi calls that redirect directly to an image will return a json response with relevant fields

graph.get("/zuck/picture", function(err, res) {
  console.log(res); // { image: true, location: "http://profile.ak.fb..." }
});

Search data from the Graph Api

Search for public posts that contain brogramming

var searchOptions = {
    q:     "brogramming"
  , type:  "post"
};

graph.search(searchOptions, function(err, res) {
  console.log(res); // {data: [{id: xxx, from: ...}, {id: xxx, from: ...}]}
});

Publish data to the Graph Api

All publish requests will require an access token

only needs to be set once

graph.setAccessToken(accessToken);

Post a message on the user's wall

var wallPost = {
  message: "I'm gonna come at you like a spider monkey, chip!"
};

graph.post("/feed", wallPost, function(err, res) {
  // returns the post id
  console.log(res); // { id: xxxxx}
});

Delete a Graph object

To delete a graph object, provide an object id and the response will return {data: true} or {data:false}

graph.del(postID, function(err, res) {
  console.log(res); // {data:true}/{data:false}
});

Performing a batch request

Batching allows you to pass instructions for several operations in a single HTTP request.

graph.batch([
  {
    method: "GET",
    relative_url: "me" // Get the current user's profile information
  },
  {
    method: "GET",
    relative_url: "me/friends?limit=50" // Get the first 50 friends of the current user
  }
], function(err, res) {
  console.log(res);
  // [
  //   {
  //     "code": 200, 
  //     "headers":[
  //       {"name": "Content-Type", "value": "text/javascript; charset=UTF-8"}
  //     ],
  //     "body": "{\"id\":\"…\"}"
  //   },
  //   {
  //     "code": 200,
  //     "headers":[
  //       {"name": "Content-Type", "value": "text/javascript; charset=UTF-8"}
  //     ],
  //     "body":"{\"data\": [{…}]}"
  //   }
  // ]
});

Performing a FQL query

A single FQL query is done by sending a query as a string

var query = "SELECT name FROM user WHERE uid = me()";

graph.fql(query, function(err, res) {
  console.log(res); // { data: [ { name: 'Ricky Bobby' } ] }
});

You can specify additional options by adding a JSON object

var query = "SELECT name FROM user WHERE uid = me()";
var options = {access_token: "foobar"};

graph.fql(query, options, function(err, res) {
  console.log(res); // { data: [ { name: 'Ricky Bobby' } ] }
});

Performing a FQL Multi-Query

FQL Multi-Queries are done by sending in an object containing the separate queries

var query = {
    name:         "SELECT name FROM user WHERE uid = me()"
  , permissions:  "SELECT email, user_about_me, user_birthday FROM permissions WHERE uid = me()"
};

graph.fql(query, function(err, res) {
  console.log(res);
  // { data: [
  //   { name: 'name', fql_result_set: [{name: 'Ricky Bobby'}] },
  //   { name: 'permissions', fql_result_set: [{email: 1, user_about_me: 1...}] }
  // ]}
});

Rockin' it on an Express App

This example assumes that you have a link on the main page / that points to /auth/facebook. The user will click this link and get into the facebook authorization flow ( if the user hasn't already connected) After authorizing the app the user will be redirected to /UserHasLoggedIn

npm install --save express fbgraph method-override body-parser errorhandler pug
/**
 * Module dependencies.
 */

var express   = require('express')
  , graph     = require('fbgraph');
var app = express(); 
var server = require("http").createServer(app);


// this should really be in a config file!
var conf = {
    client_id:      'APP-PUBLIC-ID'
  , client_secret:  'APP-SECRET-ID'
  , scope:          'email, user_about_me, user_birthday, user_location, publish_actions'
  // You have to set http://localhost:3000/ as your website
  // using Settings -> Add platform -> Website
  , redirect_uri:   'http://localhost:3000/auth'
};


// Configuration
var methodOverride = require('method-override');
var bodyParser = require('body-parser');
var errorHandler = require('errorhandler');

app.set('views', __dirname + '/views');
// Jade was renamed to pug
app.set('view engine', 'pug');
app.use(bodyParser.urlencoded({
  extended: true
}));
app.use(methodOverride());

var path = require ('path');
app.use(express.static(path.join(__dirname, '/public')));

var env = process.env.NODE_ENV || 'development';
if ('development' == env) {
   app.use(errorHandler({ dumpExceptions: true, showStack: true }));
}

// Routes

app.get('/', function(req, res){
  res.render("index", { title: "click link to connect" });
});

app.get('/auth', function(req, res) {

  // we don't have a code yet
  // so we'll redirect to the oauth dialog
  if (!req.query.code) {
    console.log("Performing oauth for some user right now.");
  
    var authUrl = graph.getOauthUrl({
        "client_id":     conf.client_id
      , "redirect_uri":  conf.redirect_uri
      , "scope":         conf.scope
    });

    if (!req.query.error) { //checks whether a user denied the app facebook login/permissions
      res.redirect(authUrl);
    } else {  //req.query.error == 'access_denied'
      res.send('access denied');
    }
  }
  // If this branch executes user is already being redirected back with 
  // code (whatever that is)
  else {
    console.log("Oauth successful, the code (whatever it is) is: ", req.query.code);
    // code is set
    // we'll send that and get the access token
    graph.authorize({
        "client_id":      conf.client_id
      , "redirect_uri":   conf.redirect_uri
      , "client_secret":  conf.client_secret
      , "code":           req.query.code
    }, function (err, facebookRes) {
      res.redirect('/UserHasLoggedIn');
    });
  }
});


// user gets sent here after being authorized
app.get('/UserHasLoggedIn', function(req, res) {
  res.render("index", { 
      title: "Logged In" 
  });
});


var port = process.env.PORT || 3000;
app.listen(port, function() {
  console.log("Express server listening on port %d", port);
});

Running tests

Before running the test suite, add your Facebook appId and appSecret to tests/config.js This is needed to create test users and to get a test access_token

$ npm install
$ make test

Tests might fail if the Facebook api has an issue.

License

(The MIT License)

Copyright (c) 2011 Cristiano Oliveira <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

fbgraph's People

Contributors

apostopher avatar bergman avatar chrisjhoughton avatar cimnine avatar criso avatar darker avatar davidgruebl avatar devongovett avatar draz avatar emersion avatar etx avatar ivanseidel avatar jminuscula avatar josser avatar kanakiyajay avatar michalw avatar mikechun avatar mweibel avatar pdehaan avatar simison avatar simllll avatar timisbusy avatar tjmcewan avatar trakout avatar zavg 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  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

fbgraph's Issues

Extend long-term token

Hey,

Is it possible to extend the long-term token?

When I use the extendAccessToken method, the expires response decreases. Does that mean that even the new token won't work after some time?

Thanks,
Philmod

Do not force to use require() to create a new fbgraph instance

Hello and thank you for the good work on this module.

A suggestion : it would be nice if we could require the module once at the beginning of our scripts instead of everytime we to open a connection to Facebook.

Unless I missed something, right now we have to write :

// somewhere deep down in my script
$.each(contacts, function(i, contact)){
    // create a dedicated instance of fbgraph (we don't want only one instance which would get a different access token every now and then)
    var graph = require('fbgraph');
    graph.setAccessToken(token);
    graph.someMethodWithAuth({
        "client_id": conf.client_id,
        "client_secret": conf.client_secret
    };
    graph.doSomething()...
}

I'd rather do something like

// at the top of my file with all the others, for clarity.
// double underscores are my own convention to show that the variable is a module in the "global" scope
var __fbgraph = require('fbgraph');
// global default config
__fbgraph.config({
        "client_id": conf.client_id,
        "client_secret": conf.client_secret
    };

// later, deep down in my script
$.each(contacts, function(i, contact)){
    var graph = new __fbgraph();
    graph.doSomething()...
}

Also, I see no support of the batch get requests, which is going to be a deal breaker for me. Thanks anyway :)

Bug in Graph.prototype.end(body) (graph.js line 83)

Hello,

When body is an object (try get 'me/picture') this function returns null.
The reason for this is typeof(body === 'string) is a boolean since body==='string' and typeof(true) is boolean.

The statement needs to be:

var json = typeof body === 'string' ? null : body

Nitzan Bar

decode signed_request for "Deauthorize Callback URL"

The Facebook documentation lacks a lot when it comes to details for the "Deauthorize Callback URL" or the signed_request parameter.

Using requestb.in I was able to find out that Facebook calls the URL when a user revokes access and passes a signed_request POST parameter along. Now the question is, how do I decode it and more importantly, should fbgraph offer a helper method do to so?

Access token is set to the whole app !

i'm working on multi sessions app (user login/logout) so when when set_accessToken is triggered the access_token of current user is set to all online users so any user of those can post under the name of last user !!!

store access_token in session

Hi,

Love the work you've done here, but it's a bit tricky because we have to store the access_token in a session:

req.session.access_token = graph.getAccessToken();

And everytime the browser does some action, we have to pull the access_token from the session and set

graph.setAccessToken(req.session.access_token);

Could you add an option to the graph.get function so that we can pass the access_token directly. eg:

graph.get("/me", req.session.access_token, function(err, data) {
    console.log(data);
});

Thx

Edit: fyi, I'm using Express.js session support: http://expressjs.com/guide.html#session-support

App with api Fb

Hello,
I would like to configure my app with the its key and the relative secret key... how can I do ?

Once configured I would to send a message...

Thanks for your help.
-A

[Feature] FB App on Page Tab

Hey,

Like I read here on the Page Tab Tutorial apps that are integrated on pages have additional information (pageid, admin of page and if page got liked by the user). These things are stored on the signed_request parameter with the additional parameter page. Also there is a string parameter called app_data.

As far as I understand this isn't implemented in fbgraph. Do you might consider supporting querying information about apps on page tabs within fbgraph?

Thanks in advance!

Posting Custom Open Graph Object

I am having trouble figuring out how to use fbgraph to post a custom Open Graph object, or figuring out if it is actually possible using fbgraph.

The example code that FB gives me for creating an object is:

FB.api(
  'me/objects/[app]:[obj_type]',
  'post',
  {
    app_id: [app_id],
    type: "[app]:[obj_type]",
    url: "[sample_url]",
    title: "[sample_title]",
    image: "[link_to_img]",
    description: ""
  },
  function(response) {
    // handle the response
  }
);

and to post the action it gives me:

FB.api(
  'me/app:create',
  'post',
  {
    [obj_type]: "[sample_url]"
  },
  function(response) {
    // handle the response
  }
);

Is this possible to recreate with fbgraph? If so, would it be possible to include instructions and examples for how to do this in the Readme?

Thank you very much!

  • Evan

batch request?

Hi, I love this module only thing missing so far is batch request. Good job guys.

Susb

With this lib Its possible get the "wall comments feed" like Twitter Stream APi ?

Ask permissions every time on auth request

Hi. How can I make facebook ask for granting permissions every time user tries to authorize, like twitter does. Now it just does all needed redirects at once without anything.
Thanks.

Javascript SDK

Hey,

I love what you've done here, i've spent the last day trying out almost every single node Facebook wrapper and they are all SO clunky! The only thing i'd really like your library to have is support for getting the access token via the "fbsr_APPID" cookie, for when I'm using the Facebook javacript SDK.

Thanks, and great work!

tests fail

When accessing the graphApi with no Access Token* and performing a public search
✗ should return valid data
» expected undefined to be an Array // graph.test.js:133

res is:
{ error:
{ message: '(#200) Permissions error',
type: 'OAuthException',
code: 200 } }

fbgraph.get() showing https error

 fbgraph.get('/me',{access_key: res_accesskey}, function(error, data) {
    console.log(error);
 })

when i call the above function i get the below given error:

{ message: 'Error processing https request',
exception: 
[Error: 3086730960:error:0607907F:digital envelope       routines:EVP_PKEY_get1_RSA:expecting an rsa key:../deps/openssl/openssl/crypto/evp/p_lib.c:288:
 ] }

I have the updated version of node and even checked by setting "strictSSL" to false.
please guide me regarding this.

Test Code.

Can you provide the html files for the example you give under the "Rockin' it on an Express App" title

Using access Token

In your example for express , where do i insert the code

graph.setAccessToken(req.session.access_token);

getLogoutUrl

hey,
How I can get logOutUrl for my user? there is seems no such functions for graph object

graph api only accepts username but should accept userId also

line 215 of your code

if (typeof url !== 'string') {
  return callback({ message: 'Graph api url must be a string' }, null);
}

not sure how you want to handle this.. whether to use an option to say its a userid and then ignore the check or just remove this check altogether.

Publish update to NPM

Hi! Awesome job at this library...

But I guess it's not in npm yet, the last commit regarding batch creations... Took me one our to figure that out...

Thanks

Help in index template

Hello. I am new to facebook apps. I loved this library. But I'm confused when you create the index template. Might help me find some basics to create a template that shows the friends of a given user instance.

Greetings.

permission manage_notifications?

I want to get notification of fb like that:
graph.get("/me/notifications", function(err, q) {
res.send(q);
});

But when I run, I'm received a error:
{
"error": {
"message": "(#200) Requires extended permission: manage_notifications",
"type": "OAuthException",
"code": 200
}
}
How can i set permission for my request?
Thanks

timeout option not working

I tried passing the timeout option to the fbgraph object and looks like it is not being passed to the request object.
And that makes the request not to timeout if the request takes more time that the set by setOptions parameter.

Found the reason looks like due to following line of code:
https://github.com/criso/fbgraph/blob/master/lib/graph.js#L222
Where it is assumped that Graph object will get the same this as the current object, which is not true.

The solution for this is to passing options as parameter to Graph function.

Auth redirects in a canvas app

When using the sample authentication code in a Fb canvas app, doing res.redirect(authUrl) results in this:

Refused to display 'https://www.facebook.com/dialog/oauth?...' in a frame because it set 'X-Frame-Options' to 'DENY'. about:blank:1

In various posts it looks like we need to redirect the browser top to the oauth, we can't do it within an iframe loaded from Facebook.

Has anyone else run into this?

how to post as page itself?

I set

graph.setAccessToken(access_token);
graph.setAppSecret(app_secret);

but always get error

{ error: 
   { message: '(#200) Unpublished posts must be posted to a page as the page itself.',
     type: 'OAuthException',
     code: 200 } }

what is the correct way do it?

How to get all friends details since its blocked in version 2.0??

how i can get all my friends details since its blocked in version 2.0?
When i am using me/friends in version 1.0 its giving all my friends details but in version 2.0 i am getting only few names.How i can do this in version 2.0.
how i can use graph targeting option using graph.search()??

Bug when I try to use graph.fql

When I try :

var graph = require('fbgraph');
var fqlRequester = graph.fql;
fqlRequester('SELECT [...]', function(err,rep) {
console.log(rep);
});

I get :

TypeError: Object #<Object> has no method 'get'
    at exports.fql (./node_modules/fbgraph/lib/graph.js:340:15)

It's true, it cannot work ! Isn't it ?
On line 340, if i replace "this.get" by "exports.get(", it works like a charm.

Does I make a bad usage of the lib ?

Thanks !

How do you check if it's already logged in?

Is there any way to store that in a session, or there is a function like "graph.isLoggedIn() " that would make it easier to know if it's already logged in on another page?

Facebook Event Images

I was wondering if anyone had a sample of how to post an image with a facebook event using this module? I have tried it every way that I can think of, and I can not get any of them to work at all. I can get the event to create on facebook just fine, but I can not get an image to attach to it on creation. I have to go to facebook and add the image that way.

Question about Custom Actions

Hi There,

I have a question about using custom facebook actions with this API. I'm trying to post an action as per the "Open Graph Mechanics" section of this page: https://developers.facebook.com/docs/opengraph/keyconcepts/.

Essentially, I want to make a call as follows: POST https://graph.facebook.com/me/appname:actiontype?objecttype=Object_URL&accessToken=accesstoken

If I make a call as follows:

            graph.setAccessToken(user.accessToken)
                .post("/me/appname:actiontype", {objecttype:Object_URL}, function(err,data){
                    if(err) console.log(err)
                    else console.log(data)
                });

will both the objectURL/type and accessToken make it through to facebook? I've been looking through the code you've written and I can't tell what exactly will happen.

could i just remove the "setAccessToken()" clause and add the accessToken info into the "postData" parameter object, or would that break something in your code?

I'm currently developing on a local computer - otherwise I would test this myself.

Best,
Sami

Wall post with privacy settings don't work

Hi, here the example:

fbgraph.setAccessToken(object._user.auth.facebook.access_token);

fbgraph.post(
"/me/feed",
{
message: 'Someone commented your post: ' + object.comments[0].message,
privacy: {
value: 'CUSTOM',
friends: 'SELF'
}
}, function(err, res){
if (err) {
console.log(err);
}
});

I see message on the wall but privacy settings doesn't applied.

I made some investigation and found that problem is in querystring:

Graph.prototype.post = function() {
var self = this
, postData = querystring.stringify(this.postData); // Querystring don't like nested objects.
this.options.body = postData;

Here REPL session example:

t = {message: "123", smth: { subprop: "123"}};
{ message: '123', smth: { subprop: '123' } }
qs = require("querystring");
{ unescapeBuffer: [Function],
unescape: [Function],
escape: [Function],
encode: [Function],
stringify: [Function],
decode: [Function],
parse: [Function] }
qs.stringify(t)
'message=123&smth='

Here the issue (I'm curious why it closed): nodejs/node-v0.x-archive#1665

No node specified

Hi and thanks for this stuff! 👍

I'm trying to work with pagination but as your example is wrote, there is no specification about the node in which you want to know the "likes".
Indeed it returns:

{ error:
{ message: 'No node specified',
type: 'GraphMethodException',
code: 100
}
}

Any thought on that?

Graph API 2.0

This is more of a discussion opener than a direct issue at this stage, but if you haven't seen - Facebook's just announced a ton of new changes to their API. Most notably for this module, they'll be versioning the API moving forwards.

They've now introduced v2.0, with a number of little tweaks and changes. It would be great to hear what your thoughts are on things. I'd definitely recommend some kind of version global parameter, but to allow for flexibility it should be possible to specify this on the request level as well.

Thoughts?

Global access tokens

Hi Cristiano,

This is more of a question than an "issue" as such, but I thought it was worth querying the fundamentals of how access tokens are set within the fbgraph module. Correct me if I'm wrong, but it looks like they're being set on a global application level rather than a user level. As a result, issues can be caused when:

  • User A logs in, we set their access token, and the /me endpoint is queried
  • User B logs in, we set their access token (which is different to user A), and the /me endpoint is queried
  • User A now wants to get a list of all their friends, so the /me/friends endpoint is queried
  • Oh no! User A has actually got back user B's friends, because the access token for user B is still assigned to the graph object.

The way I've got round this issue so far is by always calling graph.setAccessToken directly before any queries. Another way of handling this would be to require the module within individual queries, but I've never seen this done in node, there must be a reason for this...

So I guess my question is - was this by design? Am I missing or not considering something?

Extend Access Token (Due to deprecation of offline_access scope)

graph = require("fbgraph");

extendAccessToken = function (accessToken, callback) {
    var uri = "oauth/access_token?client_id=" + process.env.FACEBOOK_APP_ID + "&client_secret=" + process.env.FACEBOOK_APP_SECRET + "&grant_type=fb_exchange_token&fb_exchange_token=" + accessToken;
    graph.get(uri, function (err, res) {
      process.nextTick(function () {
        typeof callback === "function" ? callback(res.access_token) : void 0;
      });
    });
}

Consider adding this on fbgraph :)

Outdated API call example in README.md

Posting a message on a friend's wall in the way as it is described in README.md is not possible any more. I'd suggest changing the example to only post on the users wall:

graph.post("/feed", wallPost, function(err, res) {
  // returns the post id
  console.log(res); // { id: xxxxx}
}); 

Removing the ability to post to friends' timelines via API
We have found that posting content via API (stream.publish) on a friend's wall lead to a high incidence of user dissatisfaction (hiding content, blocking the app). After the migration period, posting content to friends' timelines via stream.publish will no longer be allowed. Please use the Feed Dialog for posting.

source: https://developers.facebook.com/blog/post/2013/06/26/october-2013-platform-changes/

How to get Facebook login popup

Hi,

The current faceboook authorization opens entire page for fb login instead of showing a login popup window.Help appreciated on how to do tht using fbgraph

Response code?

Is it possible to retrieve the status code of the request to know when we're hitting the Facebook rate limit?

Duplicate message

Hi, i've this code:

    // Set index route
    app.get('/', utils.accesslog, function(req, res){
        //Get token from session to allow post
        graph.setAccessToken(req.session.fb_token);
        console.log(req.session.fb_token); 
        var wallPost = {
          message: "Hello!"
        };
        // To post you need to authorize the applicationt to public_stream: http://facebook.com/authorize.php?api_key=MYAPPAPIKEY&v=1.0&ext_perm=publish_stream
        graph.post(req.session.fb_userId + "/feed", wallPost, function(err, results) {
          // returns the post id
              if (err){
              console.log(JSON.stringify(err)); // { id: xxxxx}
              }else {console.log(JSON.stringify(results));}
        });
        res.render('index', {connected: req.session.connected, title: configuration.Params.title, message: [{msg: "Hello" + req.session.fb_userId}]});

    });


    // Set facebook login path. On Facebook main parameter page set url as: mysite.tld/fblogin
    app.get('/fblogin', utils.accesslog, function(req, res){
        // we don't have a code yet
        // so we'll redirect to the oauth dialog
        if (!req.query.code) {
            var authUrl = graph.getOauthUrl({
                "client_id":     configuration.Params.facebook_appId,
                "redirect_uri":  configuration.Params.facebook_redirect_uri
            });

            if (!req.query.error) { //checks whether a user denied the app facebook login/permissions
                res.redirect(authUrl);
            } else {  //req.query.error == 'access_denied'
                res.send('access denied');
            }
            return;
        }

        // code is set
        // we'll send that and get the access token
        graph.authorize({
            "client_id":      configuration.Params.facebook_appId,
            "redirect_uri":   configuration.Params.facebook_redirect_uri,
            "client_secret":  configuration.Params.facebook_secret,
            "code":           req.query.code
        }, function (err, facebookRes) {
            console.log(facebookRes); 
            req.session.fb_token = facebookRes.access_token;  
          // Get user information and put them into session
            graph.get("me", function(err, user) {
                req.session.fb_userId = user.id;
                console.log(user); // { id: '4', name: 'Mark Zuckerberg'... }

                res.redirect('/');
            });
        });
    });```

I have two duplicate message to facebook:
{"id":"1657787844_3625402647858"}
{"message":"(#506) Duplicate status message","type":"OAuthException","code":506,"error_data":{"kError":1455006}}
It seems that pages is refreshed twice, probably i wrote something bad.

Had someone the same problem?

Thanks for your time.
Best regards.

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.