alexa implement CanFulfillIntentRequest in node.js - alexa-skill

Alexa has released CanFulfillIntentRequest feature or Name-free Interaction for custom skills recently. I am trying to implement it in my existing skill which uses alexa-sdk. Please find my code below:
'use strict';
const Alexa = require('alexa-sdk');
var handlers = {
'LaunchRequest': function() {
var speechOutput = "You can ask me to read out quotes from Steve Jobs";
var repromptText = "Sorry I didnt understand";
this.emit(':tell', speechOutput, repromptText);
},
'RandomQuote': function() {
let data = getQuoteFunction();
const author = data[0];
const quote = data[1];
let cardTitle = "Quotation from author";
let cardContent = "Actual quote";
let speechOutput = "Actual quote";
// Speak out the output along with card information
this.emit(':tellWithCard', speechOutput, cardTitle, cardContent);
}
}
exports.handler = function (event, context, callback) {
const alexa = Alexa.handler(event, context, callback);
alexa.registerHandlers(handlers);
alexa.execute();
};
Do we need to add handler for CanFulfillIntentRequest, the way I did for other handlers ? for example:
var handlers = {
'LaunchRequest': function() {
},
'RandomQuote': function() {
},
'CanFulfillIntentRequest': function() {
//code to handle
}
}
Is this feature only available in ASK SDK v2 for Node.js ? Can we implement it in skill developed using alexa-sdk. Could anyone please let me know ?
Thanks

Related

Getting timestamp of individual alexa responses in dynamodb

I am creating an Alexa factskill that asks the user for some information on their health, and users respond with a score from 1-10 depending on the level of pain in different areas. I then input the data into a DynamoDB table, which stores the information(score out of 10) for the four health questions (swelling, feeling, sleeping, breathing) and the user ID. However, the entries are not giving a timestamp for when they were created. I was wondering if there was a way to make a timestamp for preferably every health question response, but also a timestamp for the entire entry would help. Would I have to use any external SDKs, as I was looking up DynamoDB documentations and didn't find out any way to add a timestamp.
Below is my index.js code for my Lambda function that is used for my Alexa skill.
'use strict';
const Alexa = require('alexa-sdk');
const SKILL_NAME = 'Home Assist';
const HELP_MESSAGE = 'You can say I want to input my data';
const HELP_REPROMPT = 'What can I help you with?';
const STOP_MESSAGE = 'Goodbye!';
const handlers = {
'LaunchRequest': function () {
this.emit('HomeAssistQuestions');
},
'HomeAssistQuestions': function () {
this.attributes.healthscores = {
'patientID' : 0,
'scores': {
'feeling': {
'score': 0
},
'sleeping': {
'score': 0
},
'breathing': {
'score': 0
},
'swollen': {
'score': 0
}
}
};
if(this.event.request.dialogState !== 'COMPLETED'){
this.emit(':delegate');
}
else{
const feelingScore = this.event.request.intent.slots.feelingRating.value;
const sleepingScore = this.event.request.intent.slots.sleepingRating.value;
const breathingScore = this.event.request.intent.slots.breathingRating.value;
const swollenScore = this.event.request.intent.slots.SwollenRating.value;
const id = this.event.request.intent.slots.id.value;
this.attributes.healthscores.patientID = id;
this.attributes.healthscores.scores['feeling'].score = feelingScore;
this.attributes.healthscores.scores['sleeping'].score = sleepingScore;
this.attributes.healthscores.scores['breathing'].score = breathingScore;
this.attributes.healthscores.scores['swollen'].score = swollenScore;
this.response.speak("Health Scores Recorded");
this.emit(':responseReady');
}
},
'AMAZON.HelpIntent': function () {
const speechOutput = HELP_MESSAGE;
const reprompt = HELP_REPROMPT;
this.response.speak(speechOutput).listen(reprompt);
this.emit(':responseReady');
},
'AMAZON.CancelIntent': function () {
this.response.speak(STOP_MESSAGE);
this.emit(':responseReady');
},
'AMAZON.StopIntent': function () {
this.response.speak(STOP_MESSAGE);
this.emit(':responseReady');
},
'SessionEndedRequest': function(){
this.emit('saveState', true);
}
};
exports.handler = function (event, context, callback) {
const alexa = Alexa.handler(event, context, callback);
alexa.dynamoDBTableName = 'HealthScores';
alexa.APP_ID = "amzn1.ask.skill.d5b8d597-eb50-41c6-a22d-b0f18c23b544";
alexa.registerHandlers(handlers);
alexa.execute();
};
You can try something like this:
...
this.attributes.healthscores.scores['swollen'].score = swollenScore;
this.attributes.healthscores.timestamp = Date.now();
this.response.speak("Health Scores Recorded");
...

AWS Lambda cannot publish to IoT topic properly

I have written Lambda function using JavaScript, which responses to my voice and turns on the LED on my Raspberry.
But I have a problem with publishing its state to my thing topic. While Alexa responses correct ("Turning on" if Im asking to turn it on and "Turning off" if asking to off), my topic doesn't always get the state changes. Some times it gets data and sometime it doesn't and after few more invocations it gets data in bulk, and I cant even get the logic of creating a sequence of data in that bulk.
var AWS = require('aws-sdk');
var config = {};
config.IOT_BROKER_ENDPOINT = "xxxxxx.iot.us-east-1.amazonaws.com";
config.IOT_BROKER_REGION = "us-east-1";
config.IOT_THING_NAME = "raspberry";
var iotData = new AWS.IotData({endpoint: config.IOT_BROKER_ENDPOINT});
var topic = 'LED';
exports.handler = function (event, context) {
...
...
function updatePowerState (intent, session, callback) {
var speechOutput = '';
var newValue = '';
var repromptText = '';
const cardTitle = 'Power';
var sessionAttributes = {};
const shouldEndSession = true;
var value = intent.slots.PowerState.value;
if(value == 'on' || value == 'off') {
newValue = value.toUpperCase();
speechOutput = 'Turning your lamp ' + value;
updateShadow(newValue);
} else {
speechOutput = 'I didnt understand you. Please, repeat your request.';
}
callback(sessionAttributes, buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}
function updateShadow(newValue) {
let payload = {
state: {
desired: {
power_state: newValue
}
}
};
var JSON_payload = JSON.stringify(payload);
var updates = {
topic: topic,
payload: JSON_payload,
qos: 0
};
iotData.publish(updates, (err, data) => {
if(err) {
console.log(err);
}
else {
console.log('Success!');
}
});
}
Do you have any ideas about its causes? Thank you!
Async methods like iotData.publish cause problems into AWS Lambda, because you request a execution and the lambda function ends soon without waiting for the response and processing the request.
Another problem could be your permissions.
var AWS = require('aws-sdk');
var iotdata = new AWS.IotData({endpoint: 'iotCoreEndpoint.iot.us-east-1.amazonaws.com'});
exports.handler = async (event) => {
var params = {
topic: 'topic/topicName',
payload: JSON.stringify(event.body),
qos: 0
};
await iotdata.publish(params).promise()
};
Just make sure to add the required permissions or you can attach the following policy to your lambda role: AWSIoTWirelessFullPublishAccess

Alexa-App creating intents in seperate files and import and using them in index.js

I am trying to make my file management a bit easier and make each intent in its own file. How do I include that so my index.js uses that intent. Heres and example of what I have tried.
var alexa = require('alexa-app');
var app = new alexa.app();
var GetLunchSuggestions = require('./Intents/GetLunchSuggestions');
app.launch(function(request, response) {
response.say('Welcome I am built to handle your lunch requests');
response.shouldEndSession(false);
});
app.use(GetLunchSuggestions);
// Connect to lambda
exports.handler = app.lambda();
if (process.argv.length === 3 && process.argv[2] === 'schema') {
console.log(app.schema());
console.log(app.utterances());
}
I want use lunch suggestions intent in this file. How do you do this?
In your ./Intents/GetLunchSuggestions.js
module.exports = {
'AMAZON.HelpIntent': function () {
const speechOutput = 'I'm a handler from different file.';
this.response.speak(speechOutput).shouldEndSession(isLaunched);
this.emit(':responseReady');
}
}
then in your index.js
const GetLaunchSuggestions = require('./Intents/GetLunchSuggestions');
exports.handler = function (event, context, callback) {
const alexa = Alexa.handler(event, context, callback);
alexa.appId = APP_ID; // APP_ID is your skill id which can be found in the Amazon developer console where you create the skill.
alexa.registerHandlers(
handlers, // this where some of your handlers being defined. You can remove this if it was not define it your code.
GetLaunchSuggestions // this is your handler from different file.
);
alexa.execute();
};

Alexa skill which can read Facebook posts using AWS Lambda, Node.js and the Alexa Skills Kit

I am developing an Alexa skill using AWS Lambda, Node.js and the Alexa Skills Kit.I am using a forked from skill-sample-nodejs-fact project & successfully deployed & tested the sample fact project .Now I am trying to modify that code to read posts on some Facebook feeds.First I tried to develop some node application which can read posts & it was successful.Please find below code for your reference.I used fb module -
https://www.npmjs.com/package/fb
const FB = require('fb');
FB.setAccessToken('abc');
const query='cnninternational/posts';
FB.api(query, function (res) {
if(!res || res.error) {
console.log(!res ? 'error occurred' : res.error);
return;
}
console.log(res);
});
Next, I tried to integrate above code block into the lambda function.Unfortunately, I was unable, to read Facebook posts using these codes.Please find those code blocks in the below panel .Also, I checked cloudwatch logs as well.I can see the "GetNewsIntent", but I didn't see "fb-init" , "fb-error" or "fb-exit"entries in logs.Surprisingly, no error in logs as well.I would much appreciate it if someone can help to solve that issue.
'use strict';
const Alexa = require('alexa-sdk');
const FB = require('fb');
const APP_ID = 'abc';
const SKILL_NAME = 'test';
const GET_FACT_MESSAGE = "Here's your news: ";
const STOP_MESSAGE = 'Goodbye!';
exports.handler = function(event, context, callback) {
var alexa = Alexa.handler(event, context);
alexa.appId = APP_ID;
alexa.registerHandlers(handlers);
alexa.execute();
};
const handlers = {
'LaunchRequest': function () {
this.emit('GetNewsIntent');
},
'GetNewsIntent': function () {
console.log('GetNewsIntent');
const speechOutput = GET_FACT_MESSAGE;
const query='cnninternational/posts';
FB.setAccessToken('abc');
FB.api(query, function (res) {
console.log('fb-init');
if(!res || res.error) {
console.log(!res ? 'error occurred' : res.error);
console.log('fb-error');
return;
}
console.log(res);
speechOutput = speechOutput + res;
console.log('fb-exit');
});
this.response.cardRenderer(SKILL_NAME, speechOutput);
this.response.speak(speechOutput);
this.emit(':responseReady');
},
'AMAZON.StopIntent': function () {
this.response.speak(STOP_MESSAGE);
this.emit(':responseReady');
},
};
Have you implemented account linking? You should be using event.session.user.accessToken for the parameter to setAccessToken().
I have removed this.response.cardRenderer , this.response.speak & changed the code bit.It's working fine now.Please find the below code snippet which can be used to read posts on the BBC Facebook page.
var accessToken = '';
exports.handler = function(event, context, callback) {
var alexa = Alexa.handler(event, context);
alexa.appId = APP_ID;
alexa.registerHandlers(handlers);
alexa.execute();
};
const handlers = {
'NewSession': function() {
var welcomeMessage = "Welcome to Athena";
welcomeMessage = welcomeMessage +"<break time=\"1s\"/>"+ "<audio src='https://s3.amazonaws.com/my-ssml-samples/Flourish.mp3' />"+"<break time=\"1s\"/>";
welcomeMessage += HELP_MESSAGE;
accessToken = this.event.session.user.accessToken;
if (accessToken) {
FB.setAccessToken(accessToken);
this.emit(':ask', welcomeMessage, HELP_REPROMPT);
}
else {
// If we don't have an access token, we close down the skill.
this.emit(':tellWithLinkAccountCard', "This skill requires you to link a Facebook account. Seems like you are not linked to a Facebook Account. Please link a valid Facebook account and try again.");
}
},
'LaunchRequest': function () {
this.emit('NewSession');
},
'ReadBbcNewsFacebookPostsIntent': function () {
var alexa = this;
FB.api("bbcnews/posts", function (response) {
if (response && !response.error) {
if (response.data) {
var output = "Here are recent posts" + "<break time=\"1s\"/>";
var max = 5;
for (var i = 0; i < response.data.length; i++) {
if (i < max) {
output += "<break time=\"1s\"/>" + "Post " +
(i + 1) +
response.data[i].message.replace(/(?:https?|ftp):\/\/[\n\S]+/g, '')
+ ". ";
}
}
alexa.emit(':ask', output+ ", What would you like to do next?",HELP_MESSAGE);
} else {
// REPORT PROBLEM WITH PARSING DATA
}
} else {
// Handle errors here.
console.log(response.error);
this.emit(':tell', EMPTY_ACCESS_TOKEN_MESSAGE, TRY_AGAIN_MESSAGE);
}
});
}
};

AWS Lambda unable to call external https endpoint

We are working on an Alexa skill and it will need to reach out to external REST API's to get data. I'm having a really hard time getting this to work in our lambda function for some reason. I'm also having a hard time determining if the problem is in my node.js code not using callback's correctly or if it's in the VPC settings for my function. Here is my code, I've stripped out the non-essential stuff.
/* eslint-disable func-names */
/* eslint quote-props: ["error", "consistent"]*/
/**
* This sample demonstrates a simple skill built with the Amazon Alexa Skills
* nodejs skill development kit.
* This sample supports multiple lauguages. (en-US, en-GB, de-DE).
* The Intent Schema, Custom Slots and Sample Utterances for this skill, as well
* as testing instructions are located at https://github.com/alexa/skill-sample-nodejs-fact
**/
'use strict';
const Alexa = require('alexa-sdk');
const APP_ID = undefined; // TODO replace with your app ID (OPTIONAL).
const https = require('https');
const handlers = {
'LaunchRequest': function () {
this.emit('GetFact');
},
'GetNewFactIntent': function () {
this.emit('GetFact');
},
'maintenanceIntent': function () {
console.log('inside maintenanceIntent');
var options = {
host: 'api.forismatic.com',
path: '/api/1.0/?method=getQuote&lang=en&format=text',
method: 'GET'
};
getQuote(options, function (quote){
if(quote === ''){
console.log("No quote");
//speechOutput = "Please try again later";
}
else{console.log(quote)}
//self.emit(':tellWithCard', speechOutput, SKILL_NAME, text);
});
// Create speech output
// Place holder
var randomFact = 'Test Fact';
const speechOutput = randomFact;
this.emit(':tellWithCard', speechOutput, 'test skill name', randomFact);
},
'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, callback) {
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 getQuote(options, callback){
var text = '';
console.log("in getquote");
https.get(options, function(res) {
console.error("Got response: " + res.statusCode);
res.on("data", function(chunk) {
console.error("BODY: " + chunk);
text = '' + chunk;
return callback(text);
});
}).on('error', function(e) {
text = 'error' + e.message;
console.error("Got error: " + e.message);
});
}
Now when I invoke the maintenanceIntent this is what I see in the logs.
{"timestamp":1508426249817,"message":"START RequestId: 9f66123e-b4e0-11e7-baac-1bfb01d2abc8 Version: $LATEST","logStream":"2017/10/19/[$LATEST]0e048ab2fc5441cda8007e4a1963bf02","logGroup":"/aws/lambda/factDemo","requestID":"9f66123e-b4e0-11e7-baac-1bfb01d2abc8"}
{"timestamp":1508426250256,"message":"Warning: Application ID is not set","logStream":"2017/10/19/[$LATEST]0e048ab2fc5441cda8007e4a1963bf02","logGroup":"/aws/lambda/factDemo","requestID":"9f66123e-b4e0-11e7-baac-1bfb01d2abc8"}
{"timestamp":1508426250256,"message":"inside maintenanceIntent","logStream":"2017/10/19/[$LATEST]0e048ab2fc5441cda8007e4a1963bf02","logGroup":"/aws/lambda/factDemo","requestID":"9f66123e-b4e0-11e7-baac-1bfb01d2abc8"}
{"timestamp":1508426250256,"message":"in getquote","logStream":"2017/10/19/[$LATEST]0e048ab2fc5441cda8007e4a1963bf02","logGroup":"/aws/lambda/factDemo","requestID":"9f66123e-b4e0-11e7-baac-1bfb01d2abc8"}
{"timestamp":1508426250256,"message":"END RequestId: 9f66123e-b4e0-11e7-baac-1bfb01d2abc8","logStream":"2017/10/19/[$LATEST]0e048ab2fc5441cda8007e4a1963bf02","logGroup":"/aws/lambda/factDemo","requestID":"9f66123e-b4e0-11e7-baac-1bfb01d2abc8"}
{"timestamp":1508426250256,"message":"REPORT RequestId: 9f66123e-b4e0-11e7-baac-1bfb01d2abc8\tDuration: 378.28 ms\tBilled Duration: 400 ms \tMemory Size: 128 MB\tMax Memory Used: 33 MB\t","logStream":"2017/10/19/[$LATEST]0e048ab2fc5441cda8007e4a1963bf02","logGroup":"/aws/lambda/factDemo","requestID":"9f66123e-b4e0-11e7-baac-1bfb01d2abc8"}
So I can see it's actually calling the getQuote function. I'm not seeing any errors or success messages at all. I thought maybe I wasn't using callbacks correctly (node isn't my normal development language) but I've actually pulled code straight from an Amazon example on GitHub and I couldn't even get that to work. (This code is very similar to it except it's a little shorter.)
If I strip this down and run it locally through the node, it works fine.
As far as the networking stuff, I followed this guide: https://gist.github.com/reggi/dc5f2620b7b4f515e68e46255ac042a7
. I've also tried Amazon guides but at this point, I'm not even sure how I would check internet connectivity or if this is even the problem.
Any help to get on the right track would be greatly appreciated!
--EDIT--
I've changed my code as so. This comes straight from the alexa-cookbook at https://raw.githubusercontent.com/alexa/alexa-cookbook/master/external-calls/httpsGet/src/index.js
/* eslint-disable func-names */
/* eslint quote-props: ["error", "consistent"]*/
/**
* This sample demonstrates a simple skill built with the Amazon Alexa Skills
* nodejs skill development kit.
* This sample supports multiple lauguages. (en-US, en-GB, de-DE).
* The Intent Schema, Custom Slots and Sample Utterances for this skill, as well
* as testing instructions are located at https://github.com/alexa/skill-sample-nodejs-fact
**/
'use strict';
const Alexa = require('alexa-sdk');
const APP_ID = undefined; // TODO replace with your app ID (OPTIONAL).
const https = require('https');
const handlers = {
'LaunchRequest': function () {
this.emit('GetFact');
},
'GetNewFactIntent': function () {
this.emit('GetFact');
},
'maintenanceIntent': function () {
console.log('inside maintenanceIntent');
var myRequest = 'Florida';
httpsGet(myRequest, (myResult) => {
console.log("sent : " + myRequest);
console.log("received : " + myResult);
this.response.speak('The population of ' + myRequest + ' is ' + myResult);
this.emit(':responseReady');
}
);
// Create speech output
// Place holder
var randomFact = 'Test Fact';
const speechOutput = randomFact;
this.emit(':tellWithCard', speechOutput, 'test skill name', randomFact);
},
'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, callback) {
console.log("exports handler");
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();
console.log("post execute");
};
function httpsGet(myData, callback) {
// GET is a web service request that is fully defined by a URL string
// Try GET in your browser:
// https://cp6gckjt97.execute-api.us-east-1.amazonaws.com/prod/stateresource?usstate=New%20Jersey
console.log("in");
console.log(myData);
// Update these options with the details of the web service you would like to call
var options = {
host: 'cp6gckjt97.execute-api.us-east-1.amazonaws.com',
port: 443,
path: '/prod/stateresource?usstate=' + encodeURIComponent(myData),
method: 'GET',
// if x509 certs are required:
// key: fs.readFileSync('certs/my-key.pem'),
// cert: fs.readFileSync('certs/my-cert.pem')
};
var req = https.request(options, res => {
res.setEncoding('utf8');
var returnData = "";
console.log("request");
res.on('data', chunk => {
console.log("data");
returnData = returnData + chunk;
});
res.on('end', () => {
console.log("end");
// we have now received the raw return data in the returnData variable.
// We can see it in the log output via:
// console.log(JSON.stringify(returnData))
// we may need to parse through it to extract the needed data
var pop = JSON.parse(returnData).population;
callback(pop); // this will execute whatever function the caller defined, with one argument
});
});
console.log("req.end");
req.end();
}
Same idea but slightly different execution of getting the result from the endpoint. This is the log output.
{"timestamp":1508434982754,"message":"START RequestId: f4a39351-b4f4-11e7-a563-fbf7599fa72f Version: $LATEST","logStream":"2017/10/19/[$LATEST]3252e394be9b4a229c3a0d042deffbf8","logGroup":"/aws/lambda/factDemo","requestID":"f4a39351-b4f4-11e7-a563-fbf7599fa72f"}
{"timestamp":1508434982887,"message":"exports handler","logStream":"2017/10/19/[$LATEST]3252e394be9b4a229c3a0d042deffbf8","logGroup":"/aws/lambda/factDemo","requestID":"f4a39351-b4f4-11e7-a563-fbf7599fa72f"}
{"timestamp":1508434982887,"message":"Warning: Application ID is not set","logStream":"2017/10/19/[$LATEST]3252e394be9b4a229c3a0d042deffbf8","logGroup":"/aws/lambda/factDemo","requestID":"f4a39351-b4f4-11e7-a563-fbf7599fa72f"}
{"timestamp":1508434982887,"message":"inside maintenanceIntent","logStream":"2017/10/19/[$LATEST]3252e394be9b4a229c3a0d042deffbf8","logGroup":"/aws/lambda/factDemo","requestID":"f4a39351-b4f4-11e7-a563-fbf7599fa72f"}
{"timestamp":1508434982887,"message":"in","logStream":"2017/10/19/[$LATEST]3252e394be9b4a229c3a0d042deffbf8","logGroup":"/aws/lambda/factDemo","requestID":"f4a39351-b4f4-11e7-a563-fbf7599fa72f"}
{"timestamp":1508434982887,"message":"Florida","logStream":"2017/10/19/[$LATEST]3252e394be9b4a229c3a0d042deffbf8","logGroup":"/aws/lambda/factDemo","requestID":"f4a39351-b4f4-11e7-a563-fbf7599fa72f"}
{"timestamp":1508434983307,"message":"req.end","logStream":"2017/10/19/[$LATEST]3252e394be9b4a229c3a0d042deffbf8","logGroup":"/aws/lambda/factDemo","requestID":"f4a39351-b4f4-11e7-a563-fbf7599fa72f"}
{"timestamp":1508434983309,"message":"post execute","logStream":"2017/10/19/[$LATEST]3252e394be9b4a229c3a0d042deffbf8","logGroup":"/aws/lambda/factDemo","requestID":"f4a39351-b4f4-11e7-a563-fbf7599fa72f"}
{"timestamp":1508434983367,"message":"END RequestId: f4a39351-b4f4-11e7-a563-fbf7599fa72f","logStream":"2017/10/19/[$LATEST]3252e394be9b4a229c3a0d042deffbf8","logGroup":"/aws/lambda/factDemo","requestID":"f4a39351-b4f4-11e7-a563-fbf7599fa72f"}
{"timestamp":1508434983367,"message":"REPORT RequestId: f4a39351-b4f4-11e7-a563-fbf7599fa72f\tDuration: 608.20 ms\tBilled Duration: 700 ms \tMemory Size: 128 MB\tMax Memory Used: 35 MB\t","logStream":"2017/10/19/[$LATEST]3252e394be9b4a229c3a0d042deffbf8","logGroup":"/aws/lambda/factDemo","requestID":"f4a39351-b4f4-11e7-a563-fbf7599fa72f"}
I've tried this in the VPC and out of the VPC with the same result.
So this is solved thanks to this question: Node JS callbacks with Alexa skill
Particurlarly, this line
The :tell function will call the lambda callback and terminate the execution of the lambda function.
Moving the this.emit outside the httpsGet into it like so fixed the issue.
httpsGet(myRequest, (myResult) => {
console.log("sent : " + myRequest);
console.log("received : " + myResult);
this.response.speak('The population of ' + myRequest + ' is ' + myResult);
this.emit(':responseReady');
// Create speech output
// Place holder
var randomFact = 'Test Fact';
const speechOutput = randomFact;
this.emit(':tellWithCard', speechOutput, 'test skill name', randomFact);
}
);

Resources