Node.js Лямбда-функция возвращает "Недопустимый ответ" обратно в Alexa Service Simulator из вызова REST.
Возникли проблемы с выполнением REST-вызова API между лямбда-функцией node.js и Alexa. Я использую библиотеку запросов, чтобы совершать звонки с привязанным аккаунтом. Я установил только один пример высказывания для намерения, и симулятор видит это прекрасно.
Кроме того, в журналах cloudwatch показан код ответа 200 от конечной точки API и любые возвращенные данные из API из console.logs в CW.
'use strict';
var http = require('http');
var request = require('request');
var Alexa = require('alexa-sdk');
var APP_ID = "amzn1.ask.skill.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX";
exports.handler = function(event, context, callback) {
var alexa = Alexa.handler(event, context);
alexa.appId = APP_ID;
alexa.registerHandlers(handlers);
alexa.execute();
};
var handlers = {
'LaunchRequest': function () {
this.emit(':tell', 'Hi!');
},
'ApiWelcomeIntent': function () {
request('https://some.web/api', function (error, response, body) {
if (!error && response.statusCode == 200) {
// from within the callback, write data to response, essentially returning it.
var speechOutput = JSON.stringify(body);
console.log(body + " :Raw output?");
console.log(speechOutput + ' :JSON stringified');
console.log(response.statusCode);
this.emit(':tell', speechOutput);
} else {
console.log(error + ' : ' + response.statusCode);
this.emit(':tell', 'There was an error');
}
});
},
'AMAZON.HelpIntent': function () {} //.........And other built in intents.
}
};
Я предполагаю, что это как-то связано с форматом speechOutput, который я прошу Алексею "испустить / рассказать"?
2 ответа
Нет, это не имеет ничего общего с форматом speechOutput. Проблема в том, что когда обратный вызов request
метод выполняется, ссылка на this
потерян. Чтобы решить эту проблему, сохраните ссылку на this
прежде чем позвонить request
(например, назначить this
к переменной с именем self
):
'use strict';
var http = require('http');
var request = require('request');
var Alexa = require('alexa-sdk');
var APP_ID = "amzn1.ask.skill.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX";
exports.handler = function(event, context, callback) {
var alexa = Alexa.handler(event, context);
alexa.appId = APP_ID;
alexa.registerHandlers(handlers);
alexa.execute();
};
var handlers = {
'LaunchRequest': function () {
this.emit(':tell', 'Hi!');
},
'ApiWelcomeIntent': function () {
self = this
request('https://some.web/api', function (error, response, body) {
if (!error && response.statusCode == 200) {
// from within the callback, write data to response, essentially returning it.
var speechOutput = JSON.stringify(body);
console.log(body + " :Raw output?");
console.log(speechOutput + ' :JSON stringified');
console.log(response.statusCode);
self.emit(':tell', speechOutput); // USE SELF HERE
} else {
console.log(error + ' : ' + response.statusCode);
self.emit(':tell', 'There was an error'); // AND HERE AS WELL
}
});
},
'AMAZON.HelpIntent': function () {} //.........And other built in intents.
}
};
Вы сталкиваетесь с проблемой только из-за асинхронного поведения вызова NodeJS и не имеют ничего общего с запросом вызова. Вы можете решить это либо с помощью обещаний, либо с помощью обратного вызова из метода. Ниже приведен фрагмент.
'use strict';
var http = require('http');
var request = require('request');
var Alexa = require('alexa-sdk');
var APP_ID = "amzn1.ask.skill.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX";
exports.handler = function(event, context, callback) {
var alexa = Alexa.handler(event, context);
alexa.appId = APP_ID;
alexa.registerHandlers(handlers);
alexa.execute();
};
var handlers = {
'LaunchRequest': function () {
this.emit(':tell', 'Hi!');
},
'ApiWelcomeIntent': function () {
requestAPI( (message) => {
this.emit(':tell', message);
});
},
'AMAZON.HelpIntent': function () {} //.........And other built in intents.
}
};
function requestAPI(callback) {
request('https://some.web/api', function (error, response, body) {
if (!error && response.statusCode == 200) {
// from within the callback, write data to response, essentially returning it.
var speechOutput = JSON.stringify(body);
console.log(body + " :Raw output?");
console.log(speechOutput + ' :JSON stringified');
console.log(response.statusCode);
callback(speechOutput);
} else {
console.log(error + ' : ' + response.statusCode);
callback('There was an error');
}
});
}