在DialogFlow中访问Facebook Messenger用户配置文件API

时间:2018-08-22 10:11:10

标签: dialogflow facebook-messenger facebook-messenger-bot

我正在Google的DialogFlow中建立一个跨平台的聊天机器人。我想访问Facebook用户个人资料API以了解用户的名字。

我正在努力寻求有关如何(或是否)实现此目标的建议。

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

这里有人实现了吗?

2 个答案:

答案 0 :(得分:2)

我昨天为我的一个机器人做了这件事,您需要两件事,首先是页面令牌,其次是psid,即页面范围用户ID。

在dialogflow上,您将收到带有psid作为发件人ID的请求块。您可以在以下位置找到它:

agent.originalRequest.payload.data.sender.id

此psid需要在处传递给api get请求 /$psid?fields=first_name,您的网页令牌为accessToken,以获取响应的名字。

答案 1 :(得分:1)

您需要致电Facebook Graph API才能获取用户的个人资料。

Facebook为此提供了一些SDK,但是它们的官方JavaScript SDK更适合用于Web客户端,而不是服务器。他们在该链接上提到了一些第三方Node.js库。我特别使用fbgraph(在撰写本文时,它似乎是唯一被“保留”的一种)。

因此,您需要页面令牌才能进行调用。在开发过程中,您可以从这里获得一个: https://developers.facebook.com/apps/<your app id>/messenger/settings/

下面是一些示例代码:

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;
}

请注意,您并非总是可以访问发件人ID,如果您确实可以访问,则您也不一定总是可以访问个人资料。对于email之类的某些字段,您需要请求特殊权限。如果用户是发起对话的人,则通常会使用诸如姓名和个人资料图片之类的常规字段。更多信息here

希望有帮助。

修改

承诺而不是异步:

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 );
      });
  });
}