Search code examples
lambdarequestbotsgateway

using request promise in lambda handler will abandon call


I have found quite a few comments around this topic, but none that actually work for me. I am building a facebook bot. Say for now I only want to echo the text back to the caller. I have a working example of this using ec2. When moving to lambda, it does not work. Here is my code:

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

}

I tried moving the context.succeed in the .then part but gateway gets 502. If I hit the 'test' button in the aws lambda console, messenger gets the message. It seems that the promise exists with the call but it is not triggered.

I read many posts on the subject and tried many of the answers, with no success. I read others had same issue using claudiajs, with or without claudia promises.

For now I am considering moving back to ec2. Any help appreciated.


Solution

  • This documentation states that context must be set in the case of a API Gateway lambda proxy: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-simple-proxy-for-lambda-output-format

    The problem I was having is that upon error on catch, I was not calling context.fail, which ended in a 502 bad gateway and calls would not be received after. All paths must have context set.