Reputation: 1
the following lamdba code works perfectly fine when testing locally using Alex-app-server but when published and tested on AWS Lambda, it gets within the else statement and prints the console.log('OUT PUBLISH') But it doesn't publish the 'lambda/channelnumber' nor does it send the correct response back to me or print 'IN PUBLISH'
Any ideas why its just completing the bottom half of the else statement and not touching the publish function?
Code Snippet where I believe the problem lies
function (request, response) {
var channelNumber = request.slot('CHANNELNUMBER');
if (_.isEmpty(channelNumber)) {
var prompt = 'I didn\'t hear a channel code. Tell me a channel code.';
response.say(prompt).shouldEndSession(true);
return true;
} else {
//Doesn't publish any of this?????
thingShadows.publish('lambda/channelNumber', channelNumber, function () {
var prompt1 = 'Okay.';
response.say(prompt1).shouldEndSession(true);
console.log('in publish');
});
////But prints this??
console.log('out publish');
return true;
}
}
Full Code
'use strict';
module.change_code = 1;
var Alexa = require('alexa-app');
var skill = new Alexa.app('smartmote');
var awsIot = require('aws-iot-device-sdk');
var deviceName = "tv";
var _ = require('lodash');
var path = require('path');
var host = "XXXXXXXXXXXXXXXXXXXX.iot.us-east-1.amazonaws.com";
//App id is the skill being used.
var app_id = "amzn1.ask.skill.YYYYYYYYYYYYYYYYYYYYY";
var thingShadows = awsIot.thingShadow({
keyPath: path.join(__dirname, '/Raspi.private.key'),
certPath: path.join(__dirname, '/Raspi.cert.pem'),
caPath: path.join(__dirname, '/root-CA.crt'),
clientId: deviceName,
region: "us-east-1",
});
var reprompt = 'I didn\'t hear a channel, tell me a channel number or name to change to that channel';
skill.launch(function (request, response) {
var prompt = 'To change channel, tell me a channel number.';
response.say(prompt).reprompt(reprompt).shouldEndSession(true);
});
skill.intent('ChannelNumberIntent', {
'slots': {
'CHANNELNUMBER': 'CHANNELID'
},
'utterances': ['{|Change|put} {|the|on} {|channel} {|to} {-|CHANNELNUMBER}']
},
function (request, response) {
var channelNumber = request.slot('CHANNELNUMBER');
if (_.isEmpty(channelNumber)) {
var prompt = 'I didn\'t hear a channel code. Tell me a channel code.';
response.say(prompt).shouldEndSession(true);
return true;
} else {
thingShadows.publish('lambda/channelNumber', channelNumber, function () {
console.log('in pub');
var prompt1 = 'Okay.';
response.say(prompt1).shouldEndSession(true);
callback();
});
console.log('out pub');
return true;
}
}
);
module.exports = skill;
Upvotes: 0
Views: 2373
Reputation: 11431
This is most likely because of the asynchronous nature of your code.
You haven't told us what thingShadows.publish()
does, but it appears to take a callback function as its second argument. Presumably this function will be called when publish()
has finished doing whatever it does.
When running locally I would imagine that the output you see is (in this order):
out publish
in publish
Notice that out publish
gets called before in publish
. This is because the publish
method is asynchronous, so execution will continue as soon as it is called. In your case, you are calling return
immediately after calling publish
, which probably means your lambda job is ending before it has a chance to log in publish
.
You haven't provided enough information about the rest of your lambda code/setup to provide a full answer, but you need to make sure that you are waiting for your publish method to have finished before continuing. One way to achieve this is to use the callback object that is passed to your lambda handler:
exports.myHandler = function(event, context, callback) {
// Other code
thingShadows.publish('lambda/channelNumber', channelNumber, function () {
var prompt1 = 'Okay.';
response.say(prompt1).shouldEndSession(true);
console.log('in publish');
// When the publish method is complete, we can call `callback`
// to tell lambda we are done
callback();
});
}
Upvotes: 3