AWS Lambda 中的 HTTP 请求不起作用/NodeJS
HTTP Request in AWS Lambda is not working / NodeJS
我知道,这个话题经常被讨论。但是这些 post 要么很旧,要么不能解决我的问题。所以我尝试打开一个新的(其他)。
我最近开始制作 Alexa Skills。所以现在我设法在(也是旧的)教程的帮助下设置我的 AWS Lambda 函数。第一步一切正常。
所以现在我想向网站发送 GET 请求,只是为了获取状态代码。在下一步中,Alexa 应该会告诉我这段代码——但那是另一回事了。
所以我试图用许多不同的代码片段来完成请求——但没有任何效果。阅读各种 post 后,我了解到代码运行速度比请求执行速度快。所以请求的答案永远不会出现在日志中。也就是说,我不能使用它。
这是我当前的代码:
exports.handler = async (event, context, callback) => {
try {
console.log(event)
if (event.session.new) {
console.log("new session");
}
switch (event.request.type) {
case "LaunchRequest":
console.log("LAUNCH REQUEST");
context.succeed(
generateResponse(
buildSpeechletResponse("This is a launch request", true), {}
)
)
break;
case "IntentRequest":
console.log("INTENT REQUEST")
switch (event.request.intent.name) {
case "checkConnection":
console.log("INTENT CHECK CONNECTION")
const https = require('https')
let url = "xxx/xxx/bc/alexa"
exports.handler = async function(event) {
console.log("async function")
const promise = new Promise(function(resolve, reject) {
https.get(url, (res) => {
resolve(res.statusCode)
}).on('error', (e) => {
reject(Error(e))
})
})
return promise
}
context.succeed(null, generateResponse(
buildSpeechletResponse("server answered with code " + this.statusCode, true), {}));
break;
}
case ("SessionEndedRequest"):
console.log("SESSION ENEDED REQUEST")
break;
default:
context.fail(`INVALID REQUEST TYPE: ${event.request.type}`);
break;
}
}
catch (error) { context.fail(`Exception: ${error}`) }
}
// Helpers
buildSpeechletResponse = (outputText, shouldEndSession) => {
console.log("buildSpeechletResponse");
return {
outputSpeech: {
type: "PlainText",
text: outputText
},
shouldEndSession: shouldEndSession
}
};
generateResponse = (speechletResponse, sessionAttributes) => {
console.log("generateResponse")
return {
version: "1.0",
sessionAttributes: sessionAttributes,
response: speechletResponse
}
};
如果我通过 lambda 测试测试代码(包括来自 Alexa 的 JSON 来检查连接),日志如下所示。
- 14:48:14 开始 RequestId:c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 版本:$LATEST
- 14:48:14 2020-02-13T14:48:14.802Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 INFO { version: '1.0', session: { new: true, sessionId: 'amzn1.echo-api.session.0a26e495-1085-44e0-83f3-13937d026c1b', 应用程序: { applicationId: 'amzn1.ask.skill.42b0dea7-952e-4695-a3d2-ab951c98ac9c' }, 用户: { userId: 'amzn1.ask.account.AHKG3FP33CDNS5PBKQESKQ73PAWMYTB7PRL4A2UGJTG77NOGSKKQBG5QNKVZ
- 14:48:14 2020-02-13T14:48:14.802Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 信息新会话
- 14:48:14 2020-02-13T14:48:14.802Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 信息意图请求
- 14:48:14 2020-02-13T14:48:14.802Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 信息意图检查连接
- 14:48:14 2020-02-13T14:48:14.964Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 INFO buildSpeechletResponse
- 14:48:14 2020-02-13T14:48:14.964Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 信息生成响应
- 14:48:15 2020-02-13T14:48:15.042Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 信息会话已请求
据我所知,代码运行到 "INTENT CHECK CONNECTION",但日志 "async function" 从未出现。那么这里发生了什么?代码是否被跳过?我如何设法获得最先进的工作 http 请求? (对不起,如果我的post不是"common way"。这也是我的第一个post)
In your code exports.handler = async function(event) {} is the cause
exports.handler 始终在 AWS lambda 的入口函数中
我只是删除了这段代码
exports.handler = async (event, context, callback) => {
try {
console.log(event)
if (event.session.new) {
console.log("new session");
}
switch (event.request.type) {
case "LaunchRequest":
console.log("LAUNCH REQUEST");
context.succeed(
generateResponse(
buildSpeechletResponse("This is a launch request", true), {}
)
)
break;
case "IntentRequest":
console.log("INTENT REQUEST")
switch (event.request.intent.name) {
case "checkConnection":
console.log("INTENT CHECK CONNECTION")
const https = require('https')
let url = "xxx/xxx/bc/alexa"
https.get(url, (res) => {
context.succeed(null, generateResponse(
buildSpeechletResponse("server answered with code " + res.statusCode, true), {}));
}).on('error', (e) => {
// handle error here
reject(Error(e))
})
})
break;
}
case ("SessionEndedRequest"):
console.log("SESSION ENEDED REQUEST")
break;
default:
context.fail(`INVALID REQUEST TYPE: ${event.request.type}`);
break;
}
}
catch (error) { context.fail(`Exception: ${error}`) }
}
// Helpers
buildSpeechletResponse = (outputText, shouldEndSession) => {
console.log("buildSpeechletResponse");
return {
outputSpeech: {
type: "PlainText",
text: outputText
},
shouldEndSession: shouldEndSession
}
};
generateResponse = (speechletResponse, sessionAttributes) => {
console.log("generateResponse")
return {
version: "1.0",
sessionAttributes: sessionAttributes,
response: speechletResponse
}
};
所以我想通了。我提供的代码几乎是正确的。请求函数需要封装到另一个函数中。通过微小的调整,它适用于以下代码:
// HTTP Request Function
function httpGet(options) {
const https = require('https');
return new Promise(((resolve, reject) => {
const request = https.request(options, (response) => {
response.setEncoding('utf8');
let returnData = '';
if (response.statusCode < 200 || response.statusCode >= 300) {
return reject(new Error(`${response.statusCode}: ${response.req.getHeader('host')} ${response.req.path}`));
}
response.on('data', (chunk) => {
returnData += chunk;
});
response.on('end', () => {
resolve(response.statusCode); //Fill response with status code
});
response.on('error', (error) => {
reject(error);
});
});
request.end();
}));
}
我知道,这个话题经常被讨论。但是这些 post 要么很旧,要么不能解决我的问题。所以我尝试打开一个新的(其他)。 我最近开始制作 Alexa Skills。所以现在我设法在(也是旧的)教程的帮助下设置我的 AWS Lambda 函数。第一步一切正常。 所以现在我想向网站发送 GET 请求,只是为了获取状态代码。在下一步中,Alexa 应该会告诉我这段代码——但那是另一回事了。 所以我试图用许多不同的代码片段来完成请求——但没有任何效果。阅读各种 post 后,我了解到代码运行速度比请求执行速度快。所以请求的答案永远不会出现在日志中。也就是说,我不能使用它。
这是我当前的代码:
exports.handler = async (event, context, callback) => {
try {
console.log(event)
if (event.session.new) {
console.log("new session");
}
switch (event.request.type) {
case "LaunchRequest":
console.log("LAUNCH REQUEST");
context.succeed(
generateResponse(
buildSpeechletResponse("This is a launch request", true), {}
)
)
break;
case "IntentRequest":
console.log("INTENT REQUEST")
switch (event.request.intent.name) {
case "checkConnection":
console.log("INTENT CHECK CONNECTION")
const https = require('https')
let url = "xxx/xxx/bc/alexa"
exports.handler = async function(event) {
console.log("async function")
const promise = new Promise(function(resolve, reject) {
https.get(url, (res) => {
resolve(res.statusCode)
}).on('error', (e) => {
reject(Error(e))
})
})
return promise
}
context.succeed(null, generateResponse(
buildSpeechletResponse("server answered with code " + this.statusCode, true), {}));
break;
}
case ("SessionEndedRequest"):
console.log("SESSION ENEDED REQUEST")
break;
default:
context.fail(`INVALID REQUEST TYPE: ${event.request.type}`);
break;
}
}
catch (error) { context.fail(`Exception: ${error}`) }
}
// Helpers
buildSpeechletResponse = (outputText, shouldEndSession) => {
console.log("buildSpeechletResponse");
return {
outputSpeech: {
type: "PlainText",
text: outputText
},
shouldEndSession: shouldEndSession
}
};
generateResponse = (speechletResponse, sessionAttributes) => {
console.log("generateResponse")
return {
version: "1.0",
sessionAttributes: sessionAttributes,
response: speechletResponse
}
};
如果我通过 lambda 测试测试代码(包括来自 Alexa 的 JSON 来检查连接),日志如下所示。
- 14:48:14 开始 RequestId:c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 版本:$LATEST
- 14:48:14 2020-02-13T14:48:14.802Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 INFO { version: '1.0', session: { new: true, sessionId: 'amzn1.echo-api.session.0a26e495-1085-44e0-83f3-13937d026c1b', 应用程序: { applicationId: 'amzn1.ask.skill.42b0dea7-952e-4695-a3d2-ab951c98ac9c' }, 用户: { userId: 'amzn1.ask.account.AHKG3FP33CDNS5PBKQESKQ73PAWMYTB7PRL4A2UGJTG77NOGSKKQBG5QNKVZ
- 14:48:14 2020-02-13T14:48:14.802Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 信息新会话
- 14:48:14 2020-02-13T14:48:14.802Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 信息意图请求
- 14:48:14 2020-02-13T14:48:14.802Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 信息意图检查连接
- 14:48:14 2020-02-13T14:48:14.964Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 INFO buildSpeechletResponse
- 14:48:14 2020-02-13T14:48:14.964Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 信息生成响应
- 14:48:15 2020-02-13T14:48:15.042Z c8790cd2-81c9-4b8e-98ac-91b2ae6493f6 信息会话已请求
据我所知,代码运行到 "INTENT CHECK CONNECTION",但日志 "async function" 从未出现。那么这里发生了什么?代码是否被跳过?我如何设法获得最先进的工作 http 请求? (对不起,如果我的post不是"common way"。这也是我的第一个post)
In your code exports.handler = async function(event) {} is the cause
exports.handler 始终在 AWS lambda 的入口函数中
我只是删除了这段代码
exports.handler = async (event, context, callback) => {
try {
console.log(event)
if (event.session.new) {
console.log("new session");
}
switch (event.request.type) {
case "LaunchRequest":
console.log("LAUNCH REQUEST");
context.succeed(
generateResponse(
buildSpeechletResponse("This is a launch request", true), {}
)
)
break;
case "IntentRequest":
console.log("INTENT REQUEST")
switch (event.request.intent.name) {
case "checkConnection":
console.log("INTENT CHECK CONNECTION")
const https = require('https')
let url = "xxx/xxx/bc/alexa"
https.get(url, (res) => {
context.succeed(null, generateResponse(
buildSpeechletResponse("server answered with code " + res.statusCode, true), {}));
}).on('error', (e) => {
// handle error here
reject(Error(e))
})
})
break;
}
case ("SessionEndedRequest"):
console.log("SESSION ENEDED REQUEST")
break;
default:
context.fail(`INVALID REQUEST TYPE: ${event.request.type}`);
break;
}
}
catch (error) { context.fail(`Exception: ${error}`) }
}
// Helpers
buildSpeechletResponse = (outputText, shouldEndSession) => {
console.log("buildSpeechletResponse");
return {
outputSpeech: {
type: "PlainText",
text: outputText
},
shouldEndSession: shouldEndSession
}
};
generateResponse = (speechletResponse, sessionAttributes) => {
console.log("generateResponse")
return {
version: "1.0",
sessionAttributes: sessionAttributes,
response: speechletResponse
}
};
所以我想通了。我提供的代码几乎是正确的。请求函数需要封装到另一个函数中。通过微小的调整,它适用于以下代码:
// HTTP Request Function
function httpGet(options) {
const https = require('https');
return new Promise(((resolve, reject) => {
const request = https.request(options, (response) => {
response.setEncoding('utf8');
let returnData = '';
if (response.statusCode < 200 || response.statusCode >= 300) {
return reject(new Error(`${response.statusCode}: ${response.req.getHeader('host')} ${response.req.path}`));
}
response.on('data', (chunk) => {
returnData += chunk;
});
response.on('end', () => {
resolve(response.statusCode); //Fill response with status code
});
response.on('error', (error) => {
reject(error);
});
});
request.end();
}));
}