单个AWS Lambda函数可响应Alexa技能请求并返回JSON对象,具体取决于调用方式

时间:2018-09-01 22:21:45

标签: aws-lambda nodes aws-api-gateway alexa-skills-kit

我正在尝试使用相同的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函数而言,每个Amazon资源号而言)必须只有一个条目文件,即我无法使Lambda以index_Alexa.js开头,而以{ {1}}。

关于如何获取相同的Lambda函数(就相同的JS文件或文件包而言),我建议任何人都可以做。

1 个答案:

答案 0 :(得分:1)

我在某种程度上质疑该方法的实用性,以下内容还有一些优化的余地,但是一种实现方法是将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表示该值将始终存在。