AWS Lambda cannot make a REST call to an external API

I am using nodeJS code to call rest using request module. I also used a callback function, but the request function fails.

My thread goes to the searchTSTData function, but the request method fails.

From the callback function I only get responseString = 'More for the request request, which I initialized in the searchTSTData function. It is not updated based on the response returned by the API, which should either be an error or a success response string.

I have included modules in the zip as the lambda does not throw an error and passes the test. Also I'm pretty sure the request module is not working like in the Cloudwatch logs. I don't see any console files that I wrote inside the request.

Please suggest where I went wrong. I am new to NodeJS.

Here is the code -

'use strict';
const request = require('request');
const Alexa = require('alexa-sdk');
const APP_ID = 'amzn1.ask.skill.80a49cf5-254c-123a-a456-98745asd21456';  

const languageStrings = {
    'en': {
        translation: {
            TST: [
                'A year on Mercury is just 88 days long.',
            ],
            SKILL_NAME: 'TEST',
            GET_TST_MESSAGE: "Here your TST: You searched for ",
            HELP_MESSAGE: 'You can say get me a TST, or, you can say exit... What can I help you with?',
            HELP_REPROMPT: 'What can I help you with?',
            STOP_MESSAGE: 'Goodbye!',
        },
    },
};

const handlers = {
    'LaunchRequest': function () {
        this.emit('GetTST');
    },
    'GetNewTSTIntent': function () {
        this.emit('GetTST');
    },
    'GetTST': function () {
        // Get a random space fact from the space facts list
        // Use this.t() to get corresponding language data
        const inputValue = this.event.request.intent.slots.Search.value;
        var finalResponse = "Some error occurred in code. Please try again later.";
        console.log('Input recieved as '+inputValue);

        searchTSTData(inputValue, function (response){
        console.log('trying to call');
                        finalResponse = response;                                                    
         });

         console.log("after function call");

        // Create speech output
        const speechOutput = this.t('GET_TST_MESSAGE')  + inputValue+". Here are the results " +finalResponse;
        this.emit(':tellWithCard', speechOutput, this.t('SKILL_NAME'), speechOutput);
    },
    'AMAZON.HelpIntent': function () {
        const speechOutput = this.t('HELP_MESSAGE');
        const reprompt = this.t('HELP_MESSAGE');
        this.emit(':ask', speechOutput, reprompt);
    },
    'AMAZON.CancelIntent': function () {
        this.emit(':tell', this.t('STOP_MESSAGE'));
    },
    'AMAZON.StopIntent': function () {
        this.emit(':tell', this.t('STOP_MESSAGE'));
    },
};

exports.handler = function (event, context) {
    const alexa = Alexa.handler(event, context);
    alexa.APP_ID = APP_ID;
    // To enable string internationalization (i18n) features, set a resources object.
    alexa.resources = languageStrings;
    alexa.registerHandlers(handlers);
    alexa.execute();
};


function searchTSTData(searchString,callback){
    var responseString = 'Yet to make query rest';

    request({
    url: 'https://api.google.com/getresultsInJson',
    method: 'GET'
    }, function (error, response, body) {
            if (error) {
                responseString = 'Error received from rest api. Please try again after some time.';
                } else if(response.statusCode===200){
                responseString = 'Sucess Success';
                }else{
                responseString = 'Nothing is working'; 
                }
            });
            callback(responseString);
           }

      

0


source to share


2 answers


is your lambda method inside the VPC? check http://docs.aws.amazon.com/lambda/latest/dg/vpc.html you need to give external access to it



+2


source


The Alexa-SDK ends the lambda event loop when you call this.emit()

.

In your example, you are calling request()

, which runs asynchronously. Immediately after the call request()

(through searchTSTData()

) you emit this.emit()

which ends the event loop and leaves the response unhandled.

To process your response, you want to hold the call this.emit()

:



const handlers = {
  'GetTST': function () {
    searchTSTData(inputValue, (response) => {
      const speechOutput = response;
      this.emit(':tell', speechOutput);
    });
  }
};

      

Read here about the programming model for lambda functions in nodes: http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html

0


source







All Articles