如何将一个AWS Lambda用于Alexa Skills Kit和API.AI?

过去,我已经设置了两个单独的用Java编写的AWS lambda。 一个用于Alexa,另一个用于Api.ai. 他们只是将“Hello world”返回给每个助手api。 所以虽然他们很简单,但他们工作。 当我开始为每个代码编写越来越多的代码时,我开始看到我的java代码有多类似,而我只是重复了两次单独的lambda表达式。

快进到今天。

什么我现在工作的是具有单一 AWS的λ,可以从两个 Alexa和Api.ai处理输入,但我遇到了一些麻烦。 目前,我的想法是,当lambda运行时,会有一个简单的if语句,如下所示:

以下是不是真正的代码,正如我想我可以在我的脑海中所做的那样

if (figureOutIfInputType.equals("alexa")){
runAlexaCode();
} else if (figureOutIfInputType.equals("api.ai")){
runApiAiCode();
}

事情现在我需要以某种方式告诉该功能是否被alexa或api.ai所调用。

这是我现在的实际Java:

public class App implements RequestHandler<Object, String> {

  @Override
  public String handleRequest(Object input, Context context) {
    System.out.println("myLog: " + input.toString());

      return "Hello from AWS";
  }

然后我运行Alexa和Api.ai中的lambda来查看在java中生成的对象输入。

API.ai

{id=asdf-6801-4a9b-a7cd-asdffdsa, timestamp=2017-07-
28T02:21:15.337Z, lang=en, result={source=agent, resolvedQuery=hi how 
are you, action=, actionIncomplete=false, parameters={}, contexts=[], 
metadata={intentId=asdf-3a2a-49b6-8a45-97e97243b1d7, 
webhookUsed=true, webhookForSlotFillingUsed=false, 
webhookResponseTime=182, intentName=myIntent}, fulfillment=
{messages=[{type=0, speech=I have failed}]}, score=1}, status=
{code=200, errorType=success}, sessionId=asdf-a7ac-43c8-8ae8-
bc1bf5ecaad0}

Alexa的

{version=1.0, session={new=true, sessionId=amzn1.echo-api.session.asdf-
7e03-4c35-9d98-d416eefc5b23, application=    
{applicationId=amzn1.ask.skill.asdf-a02e-4938-a747-109ea09539aa}, user=        
{userId=amzn1.ask.account.asdf}}, context={AudioPlayer=
{playerActivity=IDLE}, System={application=
{applicationId=amzn1.ask.skill.07c854eb-a02e-4938-a747-109ea09539aa}, 
user={userId=amzn1.ask.account.asdf}, device=
{deviceId=amzn1.ask.device.asdf, supportedInterfaces={AudioPlayer={}}}, 
apiEndpoint=https://api.amazonalexa.com}}, request={type=IntentRequest, 
requestId=amzn1.echo-api.request.asdf-5de5-4930-8f04-9acf2130e6b8, 
timestamp=2017-07-28T05:07:30Z, locale=en-US, intent=
{name=HelloWorldIntent, confirmationStatus=NONE}}}

所以现在我有我的Alexa和Api.ai输出,他们是不同的。 这很好。 我可以告诉哪一个是哪个。 但我卡住了。 我不确定是否应该尝试创建一个AlexaInput对象和一个ApiAIinput对象。

我做这一切都错了吗? 试图让一个lambda满足来自多个服务(Alexa和ApiAI)的“助理”请求我错了吗?

任何帮助,将不胜感激。 当然,其他人必须在AWS中编写他们的助手功能,并且希望将他们的代码用于“助理”平台。


我有同样的问题和相同的想法,但随着我越来越深入的实施,我意识到这不是很实际的一个重要原因:

虽然我的很多逻辑需要相同 - 结果的格式不同。 有时,即使结果的细节或格式也会不同。

我所做的是回到网络编程中熟悉的一些概念,将其分为两部分:

  • 后端系统负责采用参数并应用业务逻辑来生成结果。 这些结果将是相当低级别的,而不是整个短语,但更多的是一组键/值对,它们表明要给出什么样的结果以及在该结果中需要哪些值。

  • 负责处理Alexa / Assistant特定事务的前端系统。 所以它会接受请求,提取参数和状态,用这些信息调用后端系统,得到一个返回结果,包括发送什么类型的回复和需要的值,然后格式化确切的短语(以及任何其他支持信息,如卡片或其他),并将其放入正确格式的响应中。

  • 前端组件对于每种代理类型都是不同的lambda函数,主要是为了使逻辑更清晰。 后端组件既可以是库函数,也可以是其他lambda函数,无论对于任务最有意义,但与前端实现无关。

    我想也可以通过拥有一个抽象的父类来实现后端逻辑,并将前端逻辑作为其子类。 我不会这样做,因为它没有在两者之间提供清晰的界面边界,但它并非不合理。


    你可以用不同的方式实现结果(代码重用)。

    首先,使用aws-lambda-java-events库为每种类型的事件(Alexa,API网关等)创建一个方法。 以下是一些信息:http://docs.aws.amazon.com/lambda/latest/dg/java-programming-model-handler-types.html

    每个入口点方法都应该处理触发它的事件(API网关)的语义并调用通用代码来为您提供代码重用。

    其次,将您的JAR / ZIP上传到S3存储桶。

    第三,对于您要处理的每个事件 - 创建一个Lambda函数,引用S3存储桶中相同的ZIP / JAR并指定相关入口点。

    通过这种方式,您将获得代码重用,而无需在AWS上同时处理多个代码副本,尽管需要定义多个Lambda。

    有一个很好的工具可以支持这种叫做无服务器框架的方式,我强烈建议你看看:https://serverless.com/framework/docs/providers/aws/


    我一直使用单个Lambda来处理Alexa ASK和Microsoft Luis.ai响应。 我使用的是Python而不是Java,但这个想法是相同的,我相信使用AlexaInput和ApiAIinput对象,都应该是扩展相同的接口。

    我首先使用上下文信息来确定请求来自哪里,并将其解析为适当的对象(我使用简单的嵌套字典)。 然后将其传递给我的主要处理函数,最后再根据上下文将输出传递给格式化程序。 格式化程序会知道你需要返回什么。 唯一需要注意的是处理会话信息; 在我的情况下,我无论如何都序列化到我自己的DynamoDB表。

    链接地址: http://www.djcxy.com/p/40147.html

    上一篇: How to use a single AWS Lambda for both Alexa Skills Kit and API.AI?

    下一篇: Chrome storage quota reporting lower than expected