Search code examples
node.jsamazon-web-servicesaws-lambdagetalexa-skills-kit

HTTP Request in AWS Lambda is not working / NodeJS


i know, this topic was discussed very often. But these posts are either very old, or do not fix my problem. So i try it with opening a new (other) one. I recently started making Alexa Skills. So now i managed to set up my AWS Lambda function with the help of (an also old) Tutorial. Everything worked fine in the first step. So now i want to sent a GET Request to a website, just to get the status code. In the next step, Alexa should tell me this code- but thats a diffrent story. So i tried to get the request done with many different code snippets- but nothing worked. After reading various posts, i understand that the code runs faster then the request can be executed. So the answer of the request does never show up in the logs. Which means, i cannot make use of it.

This is my current code:

exports.handler = async (event, context, callback) => {
  try {
    console.log(event)
    if (event.session.new) {
      console.log("new session");
    }
    switch (event.request.type) {
      case "LaunchRequest":
        console.log("LAUNCH REQUEST");
        context.succeed(
          generateResponse(
            buildSpeechletResponse("This is a launch request", true), {}
          )
        )
        break;
      case "IntentRequest":
        console.log("INTENT REQUEST")
        switch (event.request.intent.name) {
          case "checkConnection":
            console.log("INTENT CHECK CONNECTION")
            const https = require('https')
            let url = "xxx/xxx/bc/alexa"
            exports.handler = async function(event) {
              console.log("async function")
              const promise = new Promise(function(resolve, reject) {
                https.get(url, (res) => {
                  resolve(res.statusCode)
                }).on('error', (e) => {
                  reject(Error(e))
                })
              })
              return promise
            }
            context.succeed(null, generateResponse(
              buildSpeechletResponse("server answered with code " + this.statusCode, true), {}));
            break;
        }
      case ("SessionEndedRequest"):
        console.log("SESSION ENEDED REQUEST")
        break;
      default:
        context.fail(`INVALID REQUEST TYPE: ${event.request.type}`);
        break;
    }
  }
  catch (error) { context.fail(`Exception: ${error}`) }
}
// Helpers
buildSpeechletResponse = (outputText, shouldEndSession) => {
  console.log("buildSpeechletResponse");
  return {
    outputSpeech: {
      type: "PlainText",
      text: outputText
    },
    shouldEndSession: shouldEndSession
  }
};
generateResponse = (speechletResponse, sessionAttributes) => {
  console.log("generateResponse")
  return {
    version: "1.0",
    sessionAttributes: sessionAttributes,
    response: speechletResponse
  }
};

If i test the code via the lambda test (including the JSON from Alexa to check connection), the log look like this.

  • 14:48:14 START RequestId: c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 Version: $LATEST
  • 14:48:14 2020-02-13T14:48:14.802Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 INFO { version: '1.0', session: { new: true, sessionId: 'amzn1.echo-api.session.0a26e495-1085-44e0-83f3-13937d026c1b', application: { applicationId: 'amzn1.ask.skill.42b0dea7-952e-4695-a3d2-ab951c98ac9c' }, user: { userId: 'amzn1.ask.account.AHKG3FP33CDNS5PBKQESKQ73PAWMYTB7PRL4A2UGJTG77NOGSKKQBG5QNKVZ
  • 14:48:14 2020-02-13T14:48:14.802Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 INFO new session
  • 14:48:14 2020-02-13T14:48:14.802Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 INFO INTENT REQUEST
  • 14:48:14 2020-02-13T14:48:14.802Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 INFO INTENT CHECK CONNECTION
  • 14:48:14 2020-02-13T14:48:14.964Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 INFO buildSpeechletResponse
  • 14:48:14 2020-02-13T14:48:14.964Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 INFO generateResponse
  • 14:48:15 2020-02-13T14:48:15.042Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 INFO SESSION ENEDED REQUEST

So as far as i see, th code runs to "INTENT CHECK CONNECTION", but the log "async function" never shows up. So what happens here? Is the code skipped? How do i manage to get a working http request state of the art? (Sorry, if my post is not the "common way". It is also my first post)


Solution

  • So i figured it out. The code i provided was nearly correct. The request function needed to be capsuled into another function. With minor adjustments, it worked with this code:

        // HTTP Request Function
    function httpGet(options) {
      const https = require('https');
      return new Promise(((resolve, reject) => {
        const request = https.request(options, (response) => {
          response.setEncoding('utf8');
          let returnData = '';
          if (response.statusCode < 200 || response.statusCode >= 300) {
            return reject(new Error(`${response.statusCode}: ${response.req.getHeader('host')} ${response.req.path}`));
          }
          response.on('data', (chunk) => {
            returnData += chunk;
          });
          response.on('end', () => {
            resolve(response.statusCode); //Fill response with status code
          });
          response.on('error', (error) => {
            reject(error);
          });
        });
        request.end();
      }));
    }