1

I'm new to Dialogflow and I wanted to integrate it to Facebook Messenger using webhooks. Problem is that I don't know how GRAPH API works. I already created my chatbot and tested it on the console. It works like this:

User: book appointment
Bot: Ask for credentials (username, password, etc.)

After validation it then saves it to my database. The problem with this is that the chatbot will ask the user password when asking an update for appointment status.

I wanted to integrate to Facebook Messenger because the chatbot won't be constantly asking for the user password as it will use the FB:ID to verify the user account.

Any idea how to translate it to code? I'm using nodejs to write my code?

Wytrzymały Wiktor
  • 11,492
  • 5
  • 29
  • 37
Lorenzo Yu
  • 21
  • 4
  • Hi, have you tried to use the answer on [this question](https://stackoverflow.com/questions/51964566/access-facebook-messenger-user-profile-api-in-dialogflow) ? There is a description on how to get it via graph api. – ewertonvsilva Mar 01 '22 at 09:27
  • @ewertonvsilva sorry for the really late reply. I've checked it and it worked. Thanks! – Lorenzo Yu Mar 07 '22 at 13:56

1 Answers1

1

Post an answer as community wiki, as this solution has solved the issue. The solution based on Graph Api posted on this answer:


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.

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 );
      });
  });
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
ewertonvsilva
  • 1,795
  • 1
  • 5
  • 15