使用 Node.js 请求模块的 Amazon Lex Facebook 集成

Amazon Lex Facebook integration using Node.js request module

我已经为我的 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 14=].

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

Facebook异步方式为什么会超时? 这种方法有问题吗? 有没有办法在回调 returns 之前使用 "one moment please" 消息来阻止 Facebook?

显然你是 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 值中的多深度 arrays/objects。删除 ['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,但我遵从 mods/admins 如何处理声誉。