亚马逊官网Alexa技能初级入门-05

模块5:通过持久属性帮助您的技能记忆
Help Your Skill Remember with Persistent Attributes

欢迎来到我们的入门教程第5单元,该模块介绍了如何构建引人入胜的Alexa技能。在本模块中,我们将学习如何帮助您的技能记住具有持久属性的信息。

您将学到的内容:

如何使用持久属性记住信息
如何使用S3PersistenceAdapter轻松保存信息以备后用
如何使用RequestInterceptor使您的技能后端更高效
在本模块结束时,您的Cake Time技能将能够保存用户的生日,并记住该生日,以避免再次询问相同的问题。毕竟,如果技能不记得信息,那么收集信息的意义何在?

为此模块使用 Alexa开发人员控制台。登录到控制台并打开Cake Time技能。

步骤1:使用Amazon S3保存和读取数据

现在,代码中包含 birthday, month, 和year 。问题在于,当代码运行结束时,技能会忘记这些值。要解决该问题,您将把这些值保存到Amazon S3。这样,该技能可以在会话之间读取它们。

SDK提供了一种用于跨会话保存信息的有用机制:AttributesManager。使用管理器,即使您以后更改数据存储位置,您的读/写代码也可以保持不变。

Alexa技能的后端代码可以存在于任何HTTPS服务器上。大多数时候,Alexa开发人员使用AWS编写并托管其后端代码。在构建Cake Time时,您一直在使用Alexa托管的技能在开发人员控制台中编写代码。该代码在具有限制的AWS Free Tier上运行。Alexa托管的技能非常适合学习构建,甚至在拥有大量观众之前发布简单的技能。但是,如果您的技能开始流行,您可能需要考虑将后端代码移至您自己的AWS资源中。

这与增加记忆力有什么关系?在后端代码中使用Alexa托管的技能时,它将存储在Amazon S3中。如果您选择在自己的AWS资源上构建代码,则使用Amazon DynamoDB可能更有意义。如果您不知道两者之间的区别,请不要担心。要知道的重要一点是,您现在正在编写的后端代码将与Amazon S3一起使用,并且如果您以后决定迁移到自己的AWS资源,则仅需要进行少量更改即可与DynamoDB一起使用。

首先使用AttributesManager在Cake Time”中保存用户的生日。

a。 在开发人员控制台中,单击“ Code ” 选项卡。

b。 在左侧窗格中 双击 package.json文件。该文件在编辑器中打开。

C。 请注意 ,第2行上的 “name”是 “ hello-world”。将其更改为 “ cake-time”。

在这里插入图片描述
找到 “dependencies” 部分。您将添加一个依赖项。将新的依赖项放在现有列表的底部是最简单的。

d。 找到以“ aws-sdk”开头的行 。在它下面创建一个新行,然后复制并粘贴以下代码:

"ask-sdk-s3-persistence-adapter": "^2.0.0"

在这里插入图片描述

该 的package.json 文件看起来应该像现在如下:

在这里插入图片描述
e。 点击 保存。

F。 单击index.js 选项卡切换回另一个文件 。

新的依赖项使您可以使用AttributesManager来使用Amazon S3保存和读取用户数据。现在,您需要将该依赖项导入到代码中。为此,您需要让代码知道依赖关系的存在。

G。 在 index.js 文件中,找到以const Alexa开头的行 。在 其下方创建一个新行 ,然后复制并粘贴以下代码:

const persistenceAdapter = require(‘ask-sdk-s3-persistence-adapter’);
现在的代码应如下所示:
在这里插入图片描述

程式码片段
H。 向下滚动代码,直到找到开始export.handler的行 。在其下方创建一个新行,然后复制并粘贴以下代码:

.withPersistenceAdapter(
new persistenceAdapter.S3PersistenceAdapter({bucketName:process.env.S3_PERSISTENCE_BUCKET})
)

添加后,此部分代码应如下所示:

在这里插入图片描述
保存

现在,您已设置为使用AttributesManager来保存数据并将数据读取到Amazon S3。稍后,如果您决定将技能的后端代码移至您自己的AWS资源中,则将撤消在此步骤中所做的更改。

步骤2:制作异步代码

现在,您将修改代码以保存用户的生日。在“ Code ” 选项卡上的 index.js 文件中,找到 CaptureBirthdayIntentHandler。这是您在上一节中创建的处理程序。在对其进行更改之前,让我们回顾一下异步代码的概念。如果您很熟悉,请随时跳过。

运行代码时,它通常会逐行快速运行。这是太棒了。一台计算机可以执行许多计算,并且运算速度比人类快得多。但是,当一部分代码需要做一些花费时间才能移至下一行的操作时,该操作可能会暂停。如果花时间的代码部分可以启动并运行而不停止其余代码继续下去,那将更好。这称为异步代码。在这里很重要的原因是因为保存和读取用户数据比其余的技能代码花了更多时间。幸运的是,使代码块异步非常简单。

一个。 找到 CaptureBirthdayIntentHandler。有一个 canHandle() function和 handle() function。在handle() function前面 ,键入 async, 后跟一个空格。

async handle(handlerInput) {

该部分代码现在应如下所示:

在这里插入图片描述
b。 接下来,您将使用AttributesManager保存用户的生日。在 CaptureBirthdayIntentHandler内的 handle() function中,找到以const day开头的行 。在 其下方创建一个新行 ,然后复制并粘贴以下代码:

const attributesManager = handlerInput.attributesManager;

Cake Time技能代码接收year,month和day。您需要告诉Amazon S3保存这些值。该代码告诉AttributesManager数据是什么,然后管理器将其发送到Amazon S3。

C。 在 CaptureBirthdayIntentHandler内,找到刚刚添加的行(它以const attributesManager开头 )。在 其下方创建一个新行 ,然后复制并粘贴以下代码:

const birthdayAttributes = {
"year" : year,
"month" : month,
"day" : day
};

这段代码将代码中已经声明的变量映射到代码运行时将在Amazon S3中创建的相应变量。

这些变量现在被声明为持久变量 (它们在声明 它们的函数中是局部的,但是它们的值在两次调用之间保留在内存中)。现在,您可以将用户的数据保存到他们。首先,使用 AttributesManager 设置数据以保存到Amazon S3。

该部分代码现在应如下所示:

在这里插入图片描述
d。 在CaptureBirthdayIntentHandler内的 handle() function中,找到以const sayOutput开头的行。在其上方创建一个新行。复制并粘贴以下代码:

attributesManager.setPersistentAttributes(birthdayAttributes);

该部分代码现在应如下所示:

const CaptureBirthdayIntentHandler = {

    canHandle(handlerInput) {

        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'

            && Alexa.getIntentName(handlerInput.requestEnvelope) === 'CaptureBirthdayIntent';

    },

    async handle(handlerInput) {

        const year = handlerInput.requestEnvelope.request.intent.slots.year.value;

        const month = handlerInput.requestEnvelope.request.intent.slots.month.value;

        const day = handlerInput.requestEnvelope.request.intent.slots.day.value;

        

        const attributesManager = handlerInput.attributesManager;

        

        const birthdayAttributes = {

            "year": year,

            "month": month,

            "day": day

            

        };

        attributesManager.setPersistentAttributes(birthdayAttributes);

        await attributesManager.savePersistentAttributes();    

        

        const speakOutput = `Thanks, I'll remember that you were born ${month} ${day} ${year}.`;

在用户信息保存到Amazon S3之后,“ await”关键字告诉代码暂停并继续。如果您不包括关键字,则无论数据是否成功保存到Amazon S3,代码都将继续运行。这可能导致数据无法保存,Alexa每次启动该技能时都会提示用户生日。

F。 点击 保存。

步骤3:读取储存的资料

太好了,现在用户的生日已保存到Amazon S3。但是,现在需要更新此技能,以便下次用户opens Cake Time时,Alexa知道用户的生日信息已存储,并且她无需询问。为此,您将修改代码以在要求用户生日之前读取存储在Amazon S3中的数据。如果数据存在,则Alexa不需要询问。如果数据不存在,Alexa将要求您提供信息。

Amazon S3存储桶是公共云存储资源。存储桶类似于用于存储对象的文件夹,该文件夹由数据和描述性元数据组成。

需要一个新的处理程序来读取存储的数据。新处理程序中的 canHandle()和handle()functions 将与Amazon S3通信。但是,这些功能会做同样的事情,这很浪费。要合并,请使用拦截器。拦截器拦截请求以读取存储在Amazon S3中的生日信息。

一个。在以// 开始的代码中查找注释 // The SkillBuilder acts as the entry point. 。在此注释上方创建一个新行。复制并粘贴以下代码:

const LoadBirthdayInterceptor = {
    async process(handlerInput) {
        const attributesManager = handlerInput.attributesManager;
        const sessionAttributes = await attributesManager.getPersistentAttributes() || {};

        const year = sessionAttributes.hasOwnProperty('year') ? sessionAttributes.year : 0;
        const month = sessionAttributes.hasOwnProperty('month') ? sessionAttributes.month : 0;
        const day = sessionAttributes.hasOwnProperty('day') ? sessionAttributes.day : 0;

        if (year && month && day) {
            attributesManager.setSessionAttributes(sessionAttributes);
        }
    }
};

该部分代码现在应如下所示:

在这里插入图片描述
现在添加一段代码来注册拦截器,以使SDK知道它的存在。

b。 内 exports.handler 朝着代码的底部,找到开头的行 IntentReflectorHandler)//确保。在它下面创建一个新行。复制并粘贴以下代码:

.addRequestInterceptors(
    LoadBirthdayInterceptor
)

该部分代码现在应如下所示:

在这里插入图片描述
最后,添加新的处理程序。您将其添加到LaunchRequestHandler和CaptureBirthdayIntentHandler之间。

C。找到以const CaptureBirthdayIntentHandler开头的行。在上方创建新行,然后为新处理程序复制并粘贴以下代码:

const HasBirthdayLaunchRequestHandler = {
    canHandle(handlerInput) {

        const attributesManager = handlerInput.attributesManager;
        const sessionAttributes = attributesManager.getSessionAttributes() || {};

        const year = sessionAttributes.hasOwnProperty('year') ? sessionAttributes.year : 0;
        const month = sessionAttributes.hasOwnProperty('month') ? sessionAttributes.month : 0;
        const day = sessionAttributes.hasOwnProperty('day') ? sessionAttributes.day : 0;

        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest'

            && year

            && month

            && day;
    },
    handle(handlerInput) {

        const attributesManager = handlerInput.attributesManager;
        const sessionAttributes = attributesManager.getSessionAttributes() || {};

        const year = sessionAttributes.hasOwnProperty('year') ? sessionAttributes.year : 0;
        const month = sessionAttributes.hasOwnProperty('month') ? sessionAttributes.month : 0;
        const day = sessionAttributes.hasOwnProperty('day') ? sessionAttributes.day : 0;

        // TODO:: Use the settings API to get current date and then compute how many days until user's birthday
        // TODO:: Say Happy birthday on the user's birthday

        const speakOutput = `Welcome back. It looks like there are X more days until your y-th birthday.`;

        return handlerInput.responseBuilder
            .speak(speakOutput)
            .getResponse();
    }
};

新的处理程序具有canHandle()和handle() functions。该canHandle() functions检查用户的生日信息被保存在 Amazon S3。如果是这样,则处理程序将使SDK知道它可以执行此工作(它具有用户的生日信息,并且可以执行接下来的操作)。在()处理函数告诉Alexa的说,“Welcome back. It looks like there are x more days until your y-th birthday.”

在上一节中更改处理程序的名称时,还必须在代码底部的处理程序列表中更改名称。因为添加了新的处理程序,所以必须将新的处理程序添加到此列表中。

d。在代码底部,找到.addRequestHandlers() functions,以及以LaunchRequestHandler开头的行。在其上方创建一个新行。将以下代码复制并粘贴到新行中:

HasBirthdayLaunchRequestHandler,

该部分代码现在应如下所示:

exports.handler = Alexa.SkillBuilders.custom()

    .withPersistenceAdapter(

        new persistenceAdapter.S3PersistenceAdapter({bucketName:process.env.S3_PERSISTENCE_BUCKET})

    )

    .addRequestHandlers(

        HasBirthdayLaunchRequestHandler,

        LaunchRequestHandler,

        CaptureBirthdayIntentHandler,

        HelpIntentHandler,

        CancelAndStopIntentHandler,

        SessionEndedRequestHandler,

        IntentReflectorHandler) // make sure IntentReflectorHandler is last so it doesn't override your custom intent handlers

    .addRequestInterceptors(

        LoadBirthdayInterceptor

    )

    .addErrorHandlers(

        ErrorHandler)

    .lambda();

e. 点击保存

f.点击发布

如何删除或重置用户的生日

测试时,您可能需要删除或重置用户的生日。有两种方法可以做到这一点。

在Alexa开发人员控制台的“ 测试”选项卡上的模拟器中使用第一种方法 。输入或说:“Alexa, tell Cake Time I was born on {month} {day} {year}.”
tell cake time i was born on july twelve two thousand and twenty

第二种方法是使用以下步骤从Amazon S3删除保存的信息:

一个。 在“ Code ” 选项卡上,单击 屏幕左下角的“ Media storage ”。将打开 S3 Management Console
在这里插入图片描述
b。 在页面顶部,找到breadcrumbs。单击启动 amzn-1-ask-skill.

在这里插入图片描述
C。 单击以amzn1.ask.account.开头的文件旁边的复选框 。

在这里插入图片描述
d。 单击 操作。

e。 点击 删除。

F。 点击 删除。用户的生日被删除。

Wrap-up

这是您在本节中所做的摘要。首先,您调整了Cake Time技能,以使用AttributesManager将用户信息保存并读取到Amazon S3。然后,将代码添加到 CaptureBirthdayIntentHandler 以保存用户的生日。最后,您创建了一个新的处理程序(HasBirthdayLaunchRequestHandler),因此Alexa不会重复询问同一位用户的生日。

现在该进行测试了,因此请单击“ 测试” 选项卡,然后执行以下步骤。

步骤1:启动技能
说“open Cake Time”。

Alexa应该回答:“Hello! Welcome to Cake Time. When is your birthday?”

Tell Alexa your birthday
随时尝试向Alexa提供部分信息,并确保她要求并收集缺失的信息。

有了您的出生月份,日期和年份后,Alexa应该回答: “Thanks, I’ll remember that your birthday is {month} {day} {year}.”

会话结束。此时,如果没有在本节中添加的代码,则下次调用该技能时,Alexa会再次要求您生日。现在,Alexa存储此信息。

Launch the skill a second time
说“open Cake Time”。

Alexa应该回答:“欢迎回来。看来您的第y个生日还有X天了。”

您可能已经注意到,随着代码现在的工作方式,Alexa会说“ X”和“ YT H”。不用担心 在下一部分中,您将使用代码来计算距用户下一个生日为止的天数,以便Alexa可以使用该信息进行响应。

Code
如果您的技能不起作用或遇到某种语法错误,请从下面的链接下载Node.js或Python中的代码示例。然后,转到Alexa开发人员控制台中的“代码”选项卡,然后将代码复制并粘贴到index.js文件(Node.js)或lambda_function.py文件(Python)中。在测试之前,请确保保存并部署代码。

Node.js Github Code Sample, Module 3: Add Memory to Your Skill

Python Github Code Sample, Module 3: Add Memory to Your Skill

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页