2017-03-09 19 views
1

我发现了很多有关此主题的评论,但没有一篇适合我。我正在构建一个Facebook机器人。现在说我只想将文本回显给调用者。我有一个使用ec2的例子。移到lambda时,它不起作用。这里是我的代码:在lambda处理程序中使用请求承诺将放弃调用

exports.handler = (event, context, callback) => { 
... 
} else if (event.httpMethod == 'POST') { 
    var data = JSON.parse(event.body); 
    if (data.object == 'page') { 
     data.entry.forEach(function(pageEntry) { 
      // Iterate over each messaging event 
      pageEntry.messaging.forEach(function(messagingEvent) { 
       if (messagingEvent.message) { 
        receivedMessage(messagingEvent); 
       } 
      }); 
     }); 
    } 
    //if I only use callback like the documentation states, gateway always says 502, regardless of the message content in second param, or even using no params 
    //callback(null, JSON.stringify({"statusCode": 200, "headers": {"content-type":"application.json"}, "body": ""})); 
    //if i answer using succeed, gateway says 200 ok, bot never gets post 
    context.succeed({"statusCode": 200, "headers": {"content-type":"application.json"}, "body": ""}); 
} 

function receivedMessage(event) { 
var senderID = event.sender.id; 
var messageText = message.text; 
if (messageText) { 
    var messageData = { 
     recipient: { 
      id: senderID 
     }, 
     message: { 
      text: messageText, 
      metadata: "DEVELOPER_DEFINED_METADATA" 
     } 
     }; 
    callSendAPI(messageData); 
} 

}

function callSendAPI(messageData) { 
request({ 
    uri: 'https://graph.facebook.com/v2.8/me/messages', 
    qs: { access_token: PAGE_ACCESS_TOKEN }, 
    method: 'POST', 
    json: messageData 
}).then(function(body) { 
    console.log('success'); 
}).catch(function(err) { 
    console.error("Failed calling Send API", err); 
}); 

}

我试图在部分。然后移动context.succeed但网关得到502。如果我打的“测试”按钮在aws lambda控制台中,messenger获取消息。看起来这个承诺存在于通话中,但并未触发。

我阅读了很多关于这个主题的文章,并尝试了很多答案,但没有成功。我读过其他人有同样的问题使用claudiajs,有或没有克劳迪娅的承诺。

现在我正在考虑搬回ec2。任何帮助赞赏。

回答

0

使用callback(...)context.succeed(...)之间的差异,是context.succeed(...)调用将使Lambda等待一个空的事件循环。请参阅此链接以了解更多详细信息:http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html

在您的代码示例中,当您调用callback(...)时,事件循环中仍有来自receivedMessage和callSendAPI的事件。该代码不会链接所产生的承诺,并在致电callback(...)之前“等待”完成。你也可以建立一个响应,并在两种方法中的每一种中调用回调。

我建议从receivedMessage返回承诺& callSendAPI,并在处理完所有消息后调用回调。

像这样的东西可能会奏效:

/* This goes inside your handler */ 
//using Bluebird promises 
Promise.all(Promise.map(data.entry, pageEntry => { 
    // Iterate over each messaging event 
    return Promise.all(
      pageEntry.messaging 
        .filter(e => e.message) 
        .map(messagingEvent => 
        receivedMessage(messagingEvent))); 
})).then(res => callback(null, res)) 
    .catch(err => callback(err)); 
/* The code above goes in your handler */ 

function receivedMessage(event) { 
    var senderID = event.sender.id; 
    var messageText = message.text; 
    if (messageText) { 
     var messageData = { 
       recipient: { 
        id: senderID 
       }, 
       message: { 
        text: messageText, 
        metadata: "DEVELOPER_DEFINED_METADATA" 
       } 
       }; 
     return callSendAPI(messageData); 
    } else { 
     return Promise.resolve({}); 
    } 
} 

function callSendAPI(messageData) { 
     return request({ 
       uri: 'https://graph.facebook.com/v2.8/me/messages', 
       qs: { access_token: PAGE_ACCESS_TOKEN }, 
       method: 'POST', 
       json: messageData 
      }); 
} 
+0

本文档指出必须设置上下文:https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-simple- proxy-for-lambda-output-format –

+0

'context.succeed(...)'结果必须采用指定的JSON格式才能与API网关集成。对于我提供的示例代码,这可能是'context.succeed(JSON.stringify({statusCode:200,body:res}))''而不是'callback(null,res)'。 –

+0

如果您只使用Lambda,则仍然可以在原始代码中使用回调解决方案和结果。 –

相关问题