如何将一个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?