【问题标题】:Amazon Lex Facebook integration using Node.js request module使用 Node.js 请求模块的 Amazon Lex Facebook 集成
【发布时间】:2018-02-04 06:09:12
【问题描述】:

我的 Lex 机器人配置了 Lambda 函数并与 Facebook Messenger 集成。这一切都很好。 现在我正在尝试获取 Facebook 用户信息,以便使用用户名创建个性化的欢迎响应。

我可以获取用户信息,所以效果很好。这是我的 Lambda 代码:

exports.handler = (event, context, callback) => {
console.log("EVENT= "+ JSON.stringify(event));
var start = new Date().getTime();

if (event.sessionAttributes == null){ event.sessionAttributes = {}; } 
if (event.requestAttributes == null){ event.requestAttributes = {}; }

// get messenger platform type that user used to access this Lex bot
if (event.requestAttributes['x-amz-lex:channel-type']){
    var accessType = event.requestAttributes['x-amz-lex:channel-type']; // 'Facebook' or 'Twilio-SMS'
} else {
    var accessType = "other";
}
if (!event.sessionAttributes['userInfo']) {

    if (accessType == "Facebook"){
        var pageAccessToken = event.requestAttributes['x-amz-lex:facebook-page-id'];
        var PSID = event.requestAttributes['x-amz-lex:user-id'];
    request({
                uri: 'https://graph.facebook.com/v2.6/'+PSID+'?fields=first_name,last_name,gender&access_token='+pageAccessToken
            },
            function (error, response, body){
                var end = new Date().getTime();
                console.log(end - start);

                body = JSON.parse(body);

                if (!error && response.statusCode == 200) {
                    event.sessionAttributes['userInfo'] = {
                        "first_name": body['first_name'],
                        "last_name": body['last_name'],
                        "gender": body['gender'],
                        "id": body['id']
                    };

                    console.log("FB USERINFO:"+ body);
                } else {
                    console.log("FB ERROR: "+error+" +++++++RESPONSE: "+response);
                }
            }
        );
    try {
            intentProcessor(event,
                (response) => {
                    console.log("RESPONSE= "+ JSON.stringify(response));
                    callback(null, response);
                });
        } catch (err) {
            callback(err);
        }
} else {
    try {
        intentProcessor(event,
            (response) => {
                console.log("RESPONSE= "+ JSON.stringify(response));
                callback(null, response);
            });
    } catch (err) {
        callback(err);
    }
}
};

在上面的代码中,我正在同步执行try,Lex 在callback(无名称函数)甚至开始之前响应 facebook,因此 sessionAttributes 永远不会使用userInfo 设置。

但如果我异步执行此操作,并在回调函数中接收和处理用户信息时将 try 放入 callback 中,Facebook 会超时并且响应永远不会返回给用户。

为什么异步方式在 Facebook 中超时? 这种方法有问题吗? 有没有办法通过“请稍等”消息来阻止 Facebook,直到回调返回?

【问题讨论】:

  • 这个机器人是否响应 Facebook 的 webhook 消息事件?我知道他们对响应有 20 秒的要求,并且对用户信息请求的冷启动 + 往返可能足够长以超时。此外,如果您正在响应 webhook,您应该简单地传递您的数据以进行处理,并立即发送您正在处理的 webhook 的 200 响应(避免在响应 webhook 请求之前尝试执行其他操作,如 HTTP 请求) .
  • @mootrichard 听起来很棒。您能否通过发送 200 响应的实现提供答案?
  • 我试过res.sendStatus(200);res.status(200).send('OK'); 都出现“...不是函数”的错误
  • 我已经安装了 Express,所以 res.status(200).send('OK'); 不再出错。但结果与原始问题相同。即使响应在 20 秒内生成,Facebook 也无法收到响应。
  • 您能否确认您正在使用 Amazon API Gateway 处理请求?您应该能够使用lambda-proxy 发送您的回复,并将您的回复设置为callback(null, response) 以拥有statusCode: 200。如果您可以确认,我可以写一个应该有效的示例的答案。

标签: node.js facebook-graph-api chatbot facebook-messenger amazon-lex


【解决方案1】:

显然你是not the only one with this problem。问题就在这里:

event.sessionAttributes['userInfo'] = {
                    "first_name": body['first_name'],
                    "last_name": body['last_name'],
                    "gender": body['gender'],
                    "id": body['id']
                };

Lex 不支持 sessionAttributes 值中的多深度数组/对象。删除 ['userInfo'] 级别(当然,在此处和任何引用代码中),一切都应该正常。

来源:https://docs.aws.amazon.com/lex/latest/dg/context-mgmt.html#context-mgmt-complex-attributes

免责声明:我本人认识@Jay,今晚我们就这个问题进行了几个小时的视频聊天以调试它。 That doesn't appear to be against the rules,但我听从模组/管理员如何处理声誉。

【讨论】:

  • 附带说明:您可以将会话属性 userInfo 作为字符串传递,然后将其转换回 json 以克服多深度问题。
  • 是的,或者您可以使用分隔符(例如:-)来“分组”您的对象。例如:"userInfo-first_name": body['first_name']。很多变通方法(我在最初的回复中只提供了最简单的一种),但根本问题是对象的深度超过了一层。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-08
相关资源
最近更新 更多