单个 AWS Lambda 函数响应 Alexa 技能请求,return 一个 JSON 对象,具体取决于它的调用方式

Single AWS Lambda function to respond to Alexa skill requests, and return a JSON object, depending on how it is called

我正在尝试使用同一个 AWS Lambda 函数对同一个 DynamoDB 数据集做两件事。

(a) 提供 Alexa 技能响应

我已经实现了,技能运行正常。我正在使用 NodeJS 和 Amazon Skills Kit 版本 2。我的 index.js 最后几行如下:

const skillBuilder = Alexa.SkillBuilders.standard();
exports.handler = skillBuilder
  .addRequestHandlers(
    LaunchRequest,
    HelpIntent,
    // .... various other intents
    UnhandledIntent
  )
  .addErrorHandlers(ErrorHandler)
  .lambda();

(b) 提供一个 JSON 对象总结一些数据库内容

我为 Alexa 技能设置的 NodeJS 代码处理 DynamoDB 数据以提供技能响应。为了我自己的利益,我想使用相同的代码库(即相同的 Lambda 函数)来生成摘要。我不想将 Lambda 函数的片段复制粘贴到一个单独的函数中。我宁愿用相同的代码来完成这两项任务,以使一切步调一致。

我的问题是返回此 JSON 对我请求的响应的 Lambda 代码结构如下,来自 https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html:

 'use strict';
 console.log('Loading hello world function');

 exports.handler = function(event, context, callback) {
    let name = "you";
    let city = 'World';
    // etc ... more code ...
    callback(null, response);
 };

这两段代码都为`exports.handler`

分配了一个函数

我想我要达到这样的效果:

if ( /* test whether being called by Alexa or by API Gateway */ )
  { /* Make the Alexa Response */ }
else
  { /* Construct the JSON data summary response  */ }

据我所知,每个 Lambda 函数(在 Lambda 函数的每个亚马逊资源编号的意义上)必须只有一个入口文件,即我无法启动 Lambda index_Alexa.js对比 index_JSON.js

我愿意接受任何关于如何让相同的 Lambda 函数(在相同的 JS 文件或文件包的意义上)做这两件事的建议。

我有点怀疑这种方法的用处,下面还有一些优化的潜力,但实现这一点的一种方法是将 exports.handler 声明为一个简单的包装器,它调用正确的先前声明的处理程序功能基于您可以在请求中测试的条件。

// set up handler for alexa

const skillBuilder = Alexa.SkillBuilders.standard();
const alexa_handler = skillBuilder
  .addRequestHandlers(
    LaunchRequest,
    HelpIntent,
    // .... various other intents
    UnhandledIntent
  )
  .addErrorHandlers(ErrorHandler)
  .lambda();

// set up handler for API Gateway

const api_gateway_handler = function(event, context, callback) {
    let name = "you";
    let city = 'World';
    // etc ... more code ...
    callback(null, response);
 };

// for each invocation, choose which of the above to invoke

exports.handler = function(event, context, callback) {
    if(/* some test that is true only for API Gateway */)
    {
        api_gateway_handler(event, context, callback);
    }
    else
    {
        alexa_handler(event, context, callback);
    }
};

if(/* some test that is true only for API Gateway */) 行是您需要解决的问题,但我怀疑这样的事情可能会奏效:

if(event.input && event.input.requestContext && event.input.requestContext.apiId)

API 网关文档suggest,该值将始终存在。