I'm working on a Claudia.js bot that can be reached through Slack, FB messenger, and as an Alexa skill. Supposedly in claudia, you can return plain text and the framework will give it back to the "frontend" correctly... What I have currently have here works fine with FB and Slack, but when I access it through the Alexa "Service Simulator" I always get "The response is invalid." Here is the lambda that uses Claudia.js. Basically it gets messages from the client and then shunts them to another Lambda that is the "AI". Alexa seems to be choking on line 67. Ideas?
const promiseDelay = require('promise-delay');
// const aws = require('aws-sdk');
// const lambda = new aws.Lambda();
const lambda = require('aws-lambda-invoke');
const botBuilder = require('claudia-bot-builder');
const stackTrace = require('stack-trace');
//const slackDelayedReply = botBuilder.slackDelayedReply;
const getIntentName = alexaPayload =>
alexaPayload &&
alexaPayload.request &&
alexaPayload.request.type === 'IntentRequest' &&
alexaPayload.request.intent &&
alexaPayload.request.intent.name;
const api = botBuilder((message, apiRequest) => {
console.log = console.log.bind(null, '[LOG]');
console.info = console.info.bind(null, '[INFO]');
console.error = console.error.bind(null, '[ERROR]');
console.warn = console.warn.bind(null, '[WARN]');
console.info(message, apiRequest);
console.log(apiRequest.body);
const requestData = {
'user-id': {
type: message.type,
ID: message.sender
},
epoch: 1484771343.01,
'payload-type': 'luis',
facets: {},
utterance: 'Seek Showtimes',
payload: {
query: 'Seek Showtime',
topScoringIntent: {
intent: 'SeekShowtime',
score: 1.0
},
intents: [{
intent: 'SeekShowtime',
score: 1
}],
entities: []
}
};
if (message.text) {
return new Promise((resolve, reject) => {
lambda.raw.invoke({
FunctionName: 'ca2',
Payload: JSON.stringify(requestData),
}, (err, done) => {
if (err) {
const trace = stackTrace.parse(err);
console.warn(err);
console.error(trace);
return reject(err);
}
resolve(done);
});
}).then((result) => { // the initial response
const payload = JSON.parse(result.Payload);
console.log(payload.utterance);
return payload.utterance;
}).catch((error) => {
const trace = stackTrace.parse(error);
console.warn(error);
console.error(trace);
return 'Could not setup';
});
} else if (getIntentName(apiRequest.body) === 'ExitApp') {
return {
response: {
outputSpeech: {
type: 'PlainText',
text: 'Bye from Bot!'
},
shouldEndSession: true
}
};
} else {
return {};
}
},
{ platforms: ['facebook', 'slackSlashCommand', 'alexa'] }
);
module.exports = api;
Update -- even if I hardcode a plain text string response or use Alexa Message Builder I still get "The response is invalid." as the Service Response is coming back "undefined."
Looking at logs, as soon as the response is returned (for parsing by botBuilder and a pass to Alexa) this error occurs [TypeError: Cannot read property 'replace' of undefined]
Another update:
If I replace return payload.utterance
with something like
if (type === 'alexa-skill') {
Console.warn('trying to contact alexa');
return "Hi from Alexa";
}
The problem persists.
Here is where the Json Request comes in, no problem:
2017-04-27T18:06:30.552Z 3d70c273-2b74-11e7-a1c8-bf3fec00cbff STORE Map { "user-id": Map { "type": "alexa-skill", "ID": "amzn1.ask.account.AF6FUNJDSHGCXPVSAO5HUSRYFBD3SPCJJLILC4HLPS3K3L4AOWIMXPS4ZDDCXQ3ZVIV5L4FOMYD23PWZXEIAKYQBVXIQTPE2WW2PMBIXQIY3TUATXADCVNYO7NYUR2B45EU5GRIWBFHQIPLQVDQZMXD7IYVGTKAV3OWPHROCPR7XIUGNSJEAGQZJOMULSKT5HYSNUNJONASE34Y" }, "epoch": 1484771343.01, "payload-type": "luis", "utterance": "when is Logan playing", "payload": Map { "query": "when is Logan playing" } }
Here is the response I get back from the other lambda (the payload):
017-04-27T18:06:32.513Z 3d70c273-2b74-11e7-a1c8-bf3fec00cbff [LOG] mnlpData { StatusCode: 200,
Payload: '{"utterance": "To find movies playing near you, I need to know where you are. Please tell me your zip code.", "AskLocation": 1, "context": {"updated": 1493316392.162429, "user_id": "TEST_ID_TUES_14", "sessions": [{"intents": ["SeekShowtime", "SeekShowtime"], "facet-delta": {}, "facets": {"ity.location": {"ity.zip": "", "ity.code": "", "ity.theatre-name": ""}, "ity.movie": {"ity.title": "", "ity.code": ""}, "ity.time": [], "ity.date": []}, "modes": ["", "SHOWTIME_SWITCH", "AskLocation", "SHOWTIME_SWITCH", "AskLocation"]}], "created": 1493316379.950335, "mode_process_count": 2, "user-id": {"type": "alexa-skill", "ID": "amzn1.ask.account.AF6FUNJDSHGCXPVSAO5HUSRYFBD3SPCJJLILC4HLPS3K3L4AOWIMXPS4ZDDCXQ3ZVIV5L4FOMYD23PWZXEIAKYQBVXIQTPE2WW2PMBIXQIY3TUATXADCVNYO7NYUR2B45EU5GRIWBFHQIPLQVDQZMXD7IYVGTKAV3OWPHROCPR7XIUGNSJEAGQZJOMULSKT5HYSNUNJONASE34Y"}, "utterance": ["To find movies playing near you, I need to know where you are. Please tell me your zip code."]}}' }
then:
2017-04-27T18:06:32.514Z 3d70c273-2b74-11e7-a1c8-bf3fec00cbff [WARN] trying to contact alexa
and then the error:
2017-04-27T18:06:32.514Z 3d70c273-2b74-11e7-a1c8-bf3fec00cbff [TypeError: Cannot read property 'replace' of undefined]