Проблемы с текстовыми ответами Claudia.js и Alexa
Я работаю над ботом Claudia.js, с которым можно связаться через Slack, FB messenger, и в качестве навыка Alexa. Предположительно в клаве вы можете вернуть простой текст, и фреймворк вернет его "внешнему интерфейсу" правильно... То, что у меня сейчас есть, прекрасно работает с FB и Slack, но когда я получаю к нему доступ через Alexa "Service Simulator" Alexa Я всегда получаю "Ответ недействителен". Вот лямбда, которая использует Claudia.js. По сути, он получает сообщения от клиента, а затем передает их другой лямбде, которая называется "ИИ". Алекса, кажется, задыхается на линии 67. Идеи?
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;
Обновление - даже если я жестко закодирую ответ в виде простой текстовой строки или использую Alexa Message Builder, я все равно получаю "Ответ недействителен". поскольку ответ службы возвращается "неопределенный".
Глядя на логи, как только возвращается ответ (для парсинга botBuilder и передачи в Alexa) возникает эта ошибка [TypeError: Cannot read property 'replace' of undefined]
Еще одно обновление:
Если я заменю return payload.utterance
с чем-то вроде
if (type === 'alexa-skill') {
Console.warn('trying to contact alexa');
return "Hi from Alexa";
}
Проблема сохраняется.
Вот где приходит запрос Json, нет проблем:
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" } }
Вот ответ, который я получаю от другой лямбды (полезной нагрузки):
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."]}}' }
затем:
2017-04-27T18:06:32.514Z 3d70c273-2b74-11e7-a1c8-bf3fec00cbff [WARN] trying to contact alexa
а потом ошибка:
2017-04-27T18:06:32.514Z 3d70c273-2b74-11e7-a1c8-bf3fec00cbff [TypeError: Cannot read property 'replace' of undefined]
2 ответа
Во-первых, если вы заметили полезную нагрузку, отправленную вам с другой лямбды, вы можете увидеть utterance
является массивом, поэтому вам может потребоваться передать первый элемент, если он есть.
Взглянув на код разработчика ботов, я могу поспорить, что полученная вами ошибка связана с тем, что alexaAppName
не определено, и при передаче его респонденту, который закодирован в base64, невозможно выполнить замену этой переменной.
Я хотел бы убедиться, что имя моего приложения правильно настроено, и что указана правильная строка, как показано в примере с alexa claudia.
Если вы еще не сделали, запустите claudia update --configure-alexa-skill
и введите имя своего бота, затем используйте URL, который он дает в настройке вашего Алекса скилла. Выберите HTTPS вместо лямбда-арн.
В настоящее время, message.text
передается как пустая строка, что означает, что ни один из ваших блоков журнала не запускается, и вы возвращаете пустой объект в самом низу вашего кода. Попробуйте сами, заменив этот пустой объект строкой, тестер alexa больше не жалуется.
Так почему message.text пустая строка? Клаудия js заполняет текстовое поле, объединяя все слоты, которые были заполнены для вашего намерения. Если у вашего намерения нет слотов, то клава передает пустую строку.
Добавьте слоты в ваше намерение, убедитесь, что навык настроен, и устраните проблемы логического оператора.