1
votes

I am using AWS Lambda (Node.js 8.1) for my AWS Lex chatbot which is integrated with facebook and would like to know how to make the bot print out the confirmIntent response (request 1) first and then print the quick replies (request 2).

I have tried a variety of things like adding "request 2" into the same callback as the confirmIntent function, but the quick replies always prints first. I know the issue is because NodeJS is asychronous, but still dont know how to solve it.

function greeting(intentRequest, callback) {
const hello = intentRequest.currentIntent.slots.Hello;
const sessionAttributes = intentRequest.sessionAttributes || {};
const confirmationStatus = intentRequest.currentIntent.confirmationStatus;

var params = null;

var options = {
            uri: 'https://graph.facebook.com/v2.6/'+PSID+'?fields=first_name,last_name,gender&access_token='+process.env.FB_access_token,
            method: 'GET',
            headers: {
                'Content-Type': 'application/json'
            }
        };

var options_2 = {
            uri: 'https://graph.facebook.com/v2.6/me/messages?access_token='+process.env.FB_access_token,
            body: JSON.stringify({
                recipient: {"id":PSID},
                message: {
                    text: "Here is a quick reply!",
                    quick_replies: [
                            {
                                content_type: "text",
                                title: "Search",
                                payload: "yes",
                                image_url: "http://example.com/img/red.png"
                            },
                            {
                                content_type: "location"
                            }
                        ]
                }
            }),
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            }
        };

/*request 1 - Get FB user data*/          
request(options, function (error, response, body) {
    console.log(error,response.body);

    body = JSON.parse(body);

    params = {
        first_name: body['first_name'],
    };
    callback(confirmIntent(sessionAttributes, 'GetStarted', 
        {
            Age: null,
        },
        { contentType: 'PlainText', content: 'Hi ' +params.first_name+ ', I will guide you through a series of questions to select your own customized product. Are you ready to start?' }));
});

/*request 2 - Quick replies*/
request(options_2, function (error, response) {
            console.log(error,response.body);
        });
}

My confirmIntent function

function confirmIntent(sessionAttributes, intentName, slots, message) {
return {
    sessionAttributes,
    dialogAction: {
        type: 'ConfirmIntent',
        intentName,
        slots,
        message,
    },
};
}
1
It depends on your confirmIntent function - where are you getting this from?Faizuddin Mohammed
And as a general rule, callback functions have error first style - which means you should probably be doing something like callback(null, confirmIntent())Faizuddin Mohammed
Also, is confirmIntent() an async function?Faizuddin Mohammed
I have added the confirmIntent function to the main question, and it is not an async function.Rohan Jain

1 Answers

1
votes
/*request 1 - Get FB user data*/

request(options, function(error, response, body) {
  console.log(error, response.body);

  body = JSON.parse(body);

  params = {
    first_name: body["first_name"]
  };

  const confirmation = confirmIntent(
    sessionAttributes,
    "GetStarted",
    {
      Age: null
    },
    {
      contentType: "PlainText",
      content:
        "Hi " +
        params.first_name +
        ", I will guide you through a series of questions to select your own customized product. Are you ready to start?"
    }
  );

  /*request 2 - Quick replies*/
  request(options_2, function(error, response) {
    console.log(error, response.body);
    callback(null, confirmation);
  });
});

You can do this to make sure second request always happens after first request.

If you have Node Carbon, you can also use async await like this:

/*request 1 - Get FB user data*/
const request = require('request-native-promise') //need this for promises (async await are basically promises)
const response1 = await request(options);
const body = JSON.parse(response1.body);

params = {
    first_name: body["first_name"]
};

const confirmation = confirmIntent(
    sessionAttributes,
    "GetStarted", {
        Age: null
    }, {
        contentType: "PlainText",
        content: "Hi " +
            params.first_name +
            ", I will guide you through a series of questions to select your own customized product. Are you ready to start?"
    }
);

callback(null, confirmation);

/*request 2 - Quick replies*/
const response2 = await request(options_2);