skip to Main Content

I’m building a cross-platform chatbot in Google’s DialogFlow. I’d like to access the Facebook User Profile API to learn the user’s first name.

I’m struggling to find advice on how (or if) I can make this happen.

https://developers.facebook.com/docs/messenger-platform/identity/user-profile/

Has anybody here achieved this?

2

Answers


  1. I did that for one of my bots yesterday, you need 2 things, first the Page Token and second is the psid which is Page scope user ID.

    On dialogflow, you will receive the request block with psid as sender id. You can find it at:

    agent.originalRequest.payload.data.sender.id

    This psid needs to be passed to api get request at
    /$psid?fields=first_name with your page Token as accessToken to get the first name in response.

    Login or Signup to reply.
  2. You need to make a call to Facebook Graph API in order to get user’s profile.

    Facebook offers some SDKs for this, but their official JavaScript SDK is more intended to be on a web client, not on a server. They mention some 3rd party Node.js libraries on that link. I’m particularly using fbgraph (at the time of writing, it’s the only one that seems to be “kind of” maintained).

    So, you need a Page Token to make the calls. While developing, you can get one from here:
    https://developers.facebook.com/apps/<your app id>/messenger/settings/

    Here’s some example code:

    const { promisify } = require('util');
    let graph = require('fbgraph'); // facebook graph library
    
    const fbGraph = {
      get: promisify(graph.get)
    }
    
    graph.setAccessToken(FACEBOOK_PAGE_TOKEN);  // <--- your facebook page token
    graph.setVersion("3.2");
    
    // gets profile from facebook
    // user must have initiated contact for sender id to be available
    // returns: facebook profile object, if any
    async function getFacebookProfile(agent) {
      let ctx = agent.context.get('generic');
      let fbSenderID = ctx ? ctx.parameters.facebook_sender_id : undefined;
      let payload;
    
      console.log('FACEBOOK SENDER ID: ' + fbSenderID);
    
      if ( fbSenderID ) {
        try { payload = await fbGraph.get(fbSenderID) }
        catch (err) { console.warn( err ) }
      }
    
      return payload;
    }
    

    Notice you don’t always have access to the sender id, and in case you do, you don’t always have access to the profile. For some fields like email, you need to request special permissions. Regular fields like name and profile picture are usually available if the user is the one who initiates the conversation. More info here.

    Hope it helps.

    Edit

    Promise instead of async:

    function getFacebookProfile(agent) {
      return new Promise( (resolve, reject) => {
        let ctx = agent.context.get('generic');
        let fbSenderID = ctx ? ctx.parameters.facebook_sender_id : undefined;
    
        console.log('FACEBOOK SENDER ID: ' + fbSenderID);
    
        fbGraph.get( fbSenderID )
          .then( payload => {
            console.log('all fine: ' + payload);
            resolve( payload );
          })
          .catch( err => {
            console.warn( err );
            reject( err );
          });
      });
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search