Node.js Lambda 函数 returns "The response is invalid" 从 REST 调用返回到 Alexa 服务模拟器
Node.js Lambda function returns "The response is invalid" back to Alexa Service Simulator from REST call
在 node.js Lambda 函数和 Alexa 之间对 API 进行 REST 调用时出现问题。我正在使用 request 库通过帐户链接技能进行调用。我只为意图设置了一个样本话语,模拟器可以看到这一点。
此外,cloudwatch 日志显示来自 api 端点的 200 响应代码以及从 console.logs 到 CW 的 API 返回的任何数据。
'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.
}
};
我猜这与我要求 Alexa 提供的 speechOutput 格式有关 "emit/tell"?
不是,与speechOutput的格式无关。问题是当执行 request
方法的回调时,对 this
的引用丢失了。要解决这个问题,请在调用 request
之前保留对 this
的引用(例如,将 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');
}
});
}
在 node.js Lambda 函数和 Alexa 之间对 API 进行 REST 调用时出现问题。我正在使用 request 库通过帐户链接技能进行调用。我只为意图设置了一个样本话语,模拟器可以看到这一点。
此外,cloudwatch 日志显示来自 api 端点的 200 响应代码以及从 console.logs 到 CW 的 API 返回的任何数据。
'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.
}
};
我猜这与我要求 Alexa 提供的 speechOutput 格式有关 "emit/tell"?
不是,与speechOutput的格式无关。问题是当执行 request
方法的回调时,对 this
的引用丢失了。要解决这个问题,请在调用 request
之前保留对 this
的引用(例如,将 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');
}
});
}