使用 Actions Builder 构建适用于 Google 助理的 Interactive Canvas Action

Google 助理是 Google 虚拟智能个人助理,借助 Actions on Google 开发者平台,您可以打造软件,从而为超过 10 亿台设备(包括智能音箱、手机、汽车、电视、头戴式耳机等)扩展 Google 助理的功能。用户可通过对话与 Google 助理互动,以这种方式处理各种事务,例如购买日用品或约车(若要了解现在可以实现的全部功能,请参阅 Action 目录)。作为开发者,您可以使用 Actions on Google 在用户和您自己的第三方服务之间轻松打造并管理愉悦、实用的对话体验。

本 Codelab 属于高级学习单元,适合在构建适用于 Google 助理的 Action 方面具备一些经验的用户。如果您之前没有任何 Actions on Google 开发经验,我们强烈建议您先学习我们的入门级 Codelab(第 1 级第 2 级),以熟悉该平台。这些单元会逐步指导您学习一系列的功能,从而帮助您扩展 Action 的功能并扩大自己的受众群体。

在本 Codelab 中,您将利用 Interactive Canvas 这个基于 Google 助理构建的框架,向对话型 Action 添加一款全屏游戏。该游戏是一种互动式 Web 应用,Google 助理在对话中将其作为回应发送给用户。然后,用户可以在智能显示屏和 Android 移动设备上可以通过语音或文字输入玩游戏。

您并不需要自行构建整个游戏,而只需部署一个已完成部分构建名为“Snow Pal”的游戏,并在 Codelab 的学习进程中添加游戏逻辑。Snow Pal 是传统猜单词游戏的一种变体;此游戏会显示一些空格,代表一个单词的字母,您需要猜出这个单词可能包含的字母。每猜错一次,Snow Pal 会多融化一点。如果能在 Snow Pal 完全融化前猜出单词,你就赢了。

af9931bb4d507e39.png

图 1. 已完成一部分的 Snow Pal 游戏。

构建内容

在本 Codelab 中,您将构建一个使用 Interactive Canvas 的 Action。您的 Action 将具有以下功能:

  • 用户可以通过语音玩的全屏猜词游戏
  • 用户点按后可开始游戏的按钮
  • 用户点按后可重玩游戏的按钮

完成本 Codelab 的学习后,您构建的 Action 将具有以下对话流:

Google 助理Welcome to Snow Pal! Would you like to start playing the game?

用户Yes

Google 助理Try guessing a letter in the word or guessing the word.

用户I guess the letter E

Google 助理Let's see if your guess is there...E is right. Right on! Good guess.

用户继续猜字母或者直接猜这个未知的单词,直到游戏结束。

学习内容

  • 如何构建和部署 Interactive Canvas Action
  • 如何根据用户的语音和触控输入更新猜词游戏
  • 如何使用不同方法向 Web 应用传递数据
  • 如何调试 Interactive Canvas Action

所需条件

学习本 Codelab 前,您需要做好以下准备:

  • 网络浏览器,例如 Chrome
  • 选择一种 IDE/文本编辑器
  • 在您的设备上安装 NodeJSnpmgit

我们强烈建议您熟悉 JavaScript (ES6),以便理解本 Codelab 中使用的代码。

可选:获取完整的示例代码

在本 Codelab 中,您将基于不完整版的代码逐步构建示例。如果您愿意,也可以从 GitHub 代码库获取完整版示例。

Interactive Canvas 是一种基于 Google 助理构建的框架,支持向对话型 Action 添加全屏视觉元素和动画。

使用 Interactive Canvas 的 Action 与常规对话型 Action 工作原理类似。不同的是,Interactive Canvas Action 具有的一项额外功能,可以向用于打开全屏 Web 应用的设备发送回应。

用户通过语音或触摸向 Web 应用提供输入,直到对话结束。

fa63a599f215aa81.gif

图 2. 使用 Interactive Canvas 构建的 Action。

在本 Codelab 中,您的项目分为以下三个主要部分:

  • Web 应用:Web 应用文件包含 Web 应用视觉元素和动画的代码,以及用于根据用户输入来更新 Web 应用的逻辑。
  • 对话型 Action:对话型 Action 包含您的对话逻辑,该逻辑可用于识别、处理和响应用户输入。
  • 网络钩子:网络钩子用于处理游戏的逻辑。在本 Codelab 中,您可以将网络钩子视为您的游戏服务器。

在本 Codelab 的各个部分中,您将修改 Web 应用、对话型 Action 和网络钩子,从而向您的 Interactive Canvas Action 添加功能。

概括来讲,Snow Pal Action 中的对话型 Action、网络钩子和 Web 应用的运行方式如下:

  1. 对话型 Action 提示用户猜测单词中的某个字母或者直接猜测整个单词。
  2. 用户对智能显示屏上的 Snow Pal Web 应用说“I guess the letter i”
  3. 系统将用户的输入传递到您在 Actions Builder 和/或 Actions SDK 项目中定义的对话型 Action 中。
  4. 对话型 Action 会处理用户输入,并根据输入内容来决定是触发网络钩子中的逻辑来更新 Web 应用,还是发送元数据来直接更新 Web 应用。
  5. Web 应用进行更新,以显示字母在单词中出现的位置,并提示用户再接着猜。

在“了解 Interactive Canvas 基础架构”部分,您可以详细了解 Interactive Canvas 的工作原理。现在,您已掌握了基础知识,可以开始为本 Codelab 设置您的环境了。

检查您的 Google 权限设置

如需测试您在本 Codelab 中构建的 Action,您需要启用必要的权限,以便 Actions 控制台模拟器能够访问您的 Action。如需启用权限,请按以下步骤操作:

  1. 转到活动控件页面。
  2. 使用您的 Google 帐号登录(如果系统要求登录)。
  3. 启用以下权限:
  • 网络与应用活动记录
  • 网络与应用活动记录下,选中包括 Chrome 历史记录和使用 Google 服务的网站、应用和设备上的活动记录旁边的复选框。

安装 gactions 命令行界面

在本 Codelab 中,您可以使用 gactions 命令行界面 (CLI) 工具,在 Actions 控制台和本地文件系统之间同步您的 Actions 项目。

如需安装 gactions CLI,请按照安装 gactions 命令行工具部分中的说明操作。

安装 Firebase 命令行界面

借助 Firebase 命令行界面 (CLI),您可以将 Actions 项目部署到 Cloud Functions 并托管您的 Web 应用。

本 Codelab 使用 npm 安装 Firebase CLI。请务必安装 npm(通常随 Node.js 一起安装)。

如需安装或升级 CLI,请打开终端并运行以下 npm 命令:

npm install -g firebase-tools

如需验证 CLI 是否已正确安装,请运行以下命令:

firebase --version

确保 Firebase CLI 的版本为 8 或更高版本,这样它才具备 Cloud Functions 所需的全部最新功能。否则,请运行 npm install -g firebase-tools 进行升级。

如需登录 Firebase,请运行以下命令:

firebase login

登录 Firebase 时,请务必使用您创建 Actions 项目时所用的 Google 帐号。

克隆代码库

在本部分中,您将克隆本 Codelab 所需的文件。如需获取这些文件,请按以下步骤操作:

  1. 打开一个终端,然后转到您通常用来存储编码项目的目录。如果没有此目录,请切换到主目录。
  2. 如需克隆此代码库,请在终端运行以下命令:
git clone https://github.com/actions-on-google/actions-builder-canvas-codelab-nodejs

打开 start/ 目录。该代码库包含以下您会用到的重要目录:

  • public/ - 此目录包含 Web 应用的 HTML、CSS 和 JavaScript 代码。
  • sdk/custom/ - 此目录包含对话型 Action(场景、intent 和类型)的逻辑。
  • sdk/webhooks/ - 此目录是网络钩子,包含游戏逻辑。

4864e8047bb2c8f6.png

图 3. start 目录代码的结构。

在本部分中,您将创建并配置 Actions 项目、使用 gactions CLI 将克隆代码库中的代码推送到 Actions 控制台,并部署 Web 应用和网络钩子。

创建 Actions 项目

您的 Actions 项目是 Action 的容器。如需为本 Codelab 创建 Actions 项目,请按以下步骤操作:

  1. 打开 Actions 控制台
  2. 点击 New project
  3. 输入 Project name,例如 canvas-codelab。该名称供内部参考。之后您还可以为项目设置外部名称。

7ea69f1990c14ed1.png

  1. 点击 Create project
  2. What kind of Action do you want to build? 屏幕中,选择 Game 卡片。
  3. 点击 Next
  4. 选择 Blank project 卡片,然后点击 Start building

保存您的 Action 的项目 ID

项目 ID 是您的 Action 的唯一标识符。在本 Codelab 中,您在多个步骤中需要用到项目 ID。

如需检索您的项目 ID,请按以下步骤操作:

  1. 在 Actions 控制台中,点击右上角的三个垂直点。
  2. 点击 Project settings

6f59050b85943073.png

  1. 复制 Project ID

关联结算帐号

如果您需要以后使用 Cloud Functions 在本 Codelab 中部署执行方式,则必须为 Google Cloud 中的项目关联结算帐号。如果您已有结算帐号,可以忽略以下步骤。

如需为您的项目关联结算帐号,请按以下步骤操作:

  1. 转到 Google Cloud Platform 结算页面
  2. 点击添加结算帐号
  3. 填写付款信息,然后点击开始免费试用提交并启用结算功能
  4. 点击页面顶部的我的项目标签页。
  5. Actions 下,点击本 Codelab 的 Actions 项目旁边的三点状图标。
  6. 点击更改结算信息
  7. 在下拉菜单中,选择您配置的结算帐号。点击设置帐号

为避免产生费用,请按照本 Codelab 末尾的“后续步骤”页面中“清理项目”部分所述的步骤操作。

部署 Web 应用

在本部分中,您将使用 Firebase CLI 部署 Web 应用(Snow Pal 游戏)。部署后,您可以检索 Web 应用的网址,并查看游戏在浏览器中的显示效果。

如需部署 Web 应用,请按以下步骤操作:

  1. 在终端中,转到 start/ 目录。
  2. 运行以下命令,将 {PROJECT_ID} 替换为您的项目 ID:
firebase deploy --project {PROJECT_ID} --only hosting

几分钟后,您应该会看到“Deploy complete!”,这表示您已成功将 Snow Pal Web 应用部署到 Firebase。

如需在浏览器中查看 Snow Pal 游戏,请按以下步骤操作:

  1. 检索终端输出中提供的托管网址。网址应为以下格式:https://{PROJECT_ID}.web.app
  1. 将此网址粘贴到浏览器中。您应该会看到包含 Start Game 按钮的 Snow Pal 游戏开始屏幕:

68429faae5141ed0.png

向 Actions 项目中添加 Web 应用网址和项目 ID

接下来,将您的 Web 应用网址和项目 ID 添加到 actions.intent.MAIN.yaml 文件中。添加 Web 应用网址后,对话型 Action 就会知道要将数据发送到什么网址,而在 settings.yaml 中添加项目 ID 后,您就可以在 Actions 控制台中将下载的文件推送到正确的项目。

如需添加您的 Web 应用网址和项目 ID,请按以下步骤操作:

  1. 在文本编辑器中打开 start/sdk/custom/global/actions.intent.MAIN.yaml 文件。
  2. url 字段中,将占位符字符串替换为您的 Web 应用网址。
  3. 在文本编辑器中打开 start/sdk/settings/settings.yaml 文件。
  4. projectId 字段中,将占位符字符串替换为您的项目 ID。

将项目推送到 Actions 控制台

如需使用本地项目更新 Actions 控制台,您需要将 Actions 项目推送到 Actions 控制台。为此,请按以下步骤操作:

  1. 切换到 sdk 目录:
cd sdk/
  1. 如需将本地文件系统的配置复制到 Actions 控制台,请运行以下命令:
gactions push

部署网络钩子

当您运行 gactions push 时,网络钩子起始代码就会导入 Actions 控制台中。在本 Codelab 的剩余部分中,您可以在 Actions 控制台中修改网络钩子代码。此时,您可以从 Actions 控制台部署网络钩子。

如需部署网络钩子,请按照以下步骤操作:

  1. 在 Actions 控制台中,点击导航栏中的 Develop
  2. 点击导航栏中的 Webhook 标签页。
  3. 点击 Deploy Fulfillment

Cloud Functions 配置并部署您的执行方式可能需要几分钟的时间。您应该会在代码编辑器上方看到 Cloud Function deployment in progress... 消息。代码部署成功后,该消息会更新为 Your Cloud Function deployment is up to date

在模拟器中测试

此时,您的 Action 与 Web 应用已建立关联。您可以使用 Actions 控制台模拟器进行测试,确保在您调用 Action 时会显示该 Web 应用。

如需测试您的 Action,请按以下步骤操作:

  1. 在 Actions 控制台导航栏中,点击 Test
  2. Input 字段中输入 Talk to Snow Pal sample,然后按 Enter
  3. Input 字段中输入 Yes,然后按 Enter。或者,您也可以点击页面中间的 Start Game 按钮。

37f7bc4e550d817c.png

您尚未配置用于猜字母或猜单词的逻辑,因此,如果这时猜单词或猜字母,则会收到如下回应:“...Incorrect. Keep on trying! It looks like we need to add more functionality to have this work properly.”

在本项目中,功能分为三个主要组件:对话型 Action、Web 应用和网络钩子。请注意,这是介绍如何设置 Action 的一个模板,这样安排的目的是突出显示 Interactive Canvas 的核心功能。

以下部分将详细介绍对话型 Action、网络钩子和 Web 应用如何协同工作,以及其他重要的 Interactive Canvas 元素。

对话型 Action

您的 Action 的对话型 Action 组件会识别和处理用户的输入,并将其发送至相应的场景,从而形成给用户的回应。例如,如果用户在 Snow Pal 游戏中说“I guess the letter e”,对话型 Action 会将该字母作为一个 intent 参数加以提取,并将其传递给相应的游戏逻辑,进而确定猜测是否正确,并对 Web 应用进行相应的更新。Actions Builder 是 Actions 控制台中基于网络的 IDE,您可以从中查看和修改此对话逻辑。以下屏幕截图显示了 Actions Builder 中对话型 Action 的一部分:

91d1c5300f015ff9.png

图 4. Action Builder 中 Main invocation 的可视化。

此屏幕截图显示了您的 Action 的 Main invocation,在用户说出类似于“Ok Google, talk to Snow Pal sample”的指令后,就会触发该 Action。当用户调用您的 Action 时,Main invocation 会发送一条包含 canvas 响应的提示,其中包含您的 Web 应用的网址。

您 Action 中的第一个 canvas 响应必须包含 Web 应用网址。此响应指示 Google 助理在用户的设备上呈现该地址的 Web 应用。Actions Builder 中的其他 canvas 响应可以包含一个设置为 true 的字段 send_state_data_to_canvas_app。此字段在 intent 得到匹配时向 Web 应用发送 intent 名称和任何参数值,Web 应用则根据这种用户输入的数据进行更新。

网络钩子

在本 Codelab 中,网络钩子包含游戏逻辑(您可以将网络钩子视为游戏服务器)。游戏逻辑包括多种元素,例如确定用户猜测是否正确或用户是否赢得游戏,以及基于结果构建响应。您可以在 Actions Builder 中修改网络钩子。

当您的 Action 需要执行游戏逻辑时,Actions Builder 会调用网络钩子。例如,Game 场景中的 guess intent 会对 guess 处理脚本执行网络钩子调用,然后该处理脚本会执行逻辑,以确定用户的猜测是否正确。网络钩子可以在该处理脚本中包含 Canvas 响应,该响应映射到 Web 应用并对 Web 应用进行相应的更新。

Web 应用

ca564ef59e1003d4.png

图 5. Interactive Canvas Action 中对话型 Action、网络钩子和 Web 应用之间互动的直观呈现。

Web 应用文件包含 Web 应用的视觉元素和动画的代码,以及用于根据用户输入更新 Web 应用的逻辑。您可以在文本编辑器中修改 Web 应用文件,并使用 Firebase CLI 部署这些更改。

对话型 Action 和 Web 应用之间的通信

您需要启用对话型 Action 和 Web 应用之间的通信,以便您的 Web 应用可以根据用户输入进行更新。例如,如果用户说“I guess the letter f”,

对话型 Action 需要为 Web 应用提供字母“f”,以便 Web 应用可以进行相应更新。如需将用户输入从对话型 Action 传递到 Web 应用,您必须载入 Interactive Canvas API。

该 API 的脚本包含在 /public/index.html 中,后者是 Snow Pal 游戏的主 HTML 文件。此文件定义了您的界面在多个脚本中的外观和载入方式:

index.html

<!-- Load Assistant Interactive Canvas API -->
 <script type="text/javascript" src="https://www.gstatic.com/assistant/interactivecanvas/api/interactive_canvas.min.js"></script>

如需根据用户输入更新 Web 应用,您还必须在 Web 应用文件中注册并配置回调。回调可让 Web 应用响应对话型 Action 中的信息或请求。

/public/js/action.js 中,有一个名为 Action 的预配置类,用于声明和注册回调。Action 类是 Interactive Canvas API 的封装容器。使用 scene.js 中的 create() 函数创建 Web 应用时,系统会创建一个新的 Action 实例并调用 setCallbacks(),如以下代码段所示:

scene.js

// Set assistant at game level.
this.assistant = new Action(this);
// Call setCallbacks to register assistant action callbacks.
this.assistant.setCallbacks();

setCallbacks() 函数在 /public/js/action.jsAction 类中作了定义。此函数在创建游戏时通过 Interactive Canvas API 声明并注册回调:

  setCallbacks() {
    // Declare the Interactive Canvas action callbacks.
    const callbacks = {
      onUpdate: (data) => {
     ...
    // Called by the Interactive Canvas web app once web app has loaded to
    // register callbacks.
    this.canvas.ready(callbacks);
  }

setCallbacks() 函数声明了 onUpdate() 回调,在您每次发送 Canvas 响应时,系统都会调用该回调。

下一部分将介绍如何配置此项目的具体代码,从而将对话型 Action 中的数据传递到 Web 应用。

根据用户的输入更新 Web 应用

在本 Codelab 中,您可以使用命令映射,以根据用户的输入来更新 Web 应用。例如,当 start_game 意图在 Welcome 场景中得到匹配时,系统会将提示中包含的 canvas 响应发送至 Web 应用。onUpdate() 解析 canvas 响应中的元数据并调用 START_GAME 命令,该命令随后会调用 scene.js 中的 start() 函数并更新 Web 应用,以开始新的游戏会话。

scene.js 中的 start() 函数还会调用 updateCanvasState() 函数,后者使用名为 setCanvasState() 的方法添加网络钩子可以访问的状态数据。

每条命令结束时,系统会调用 updateCanvasState() 方法(您将在学习本 Codelab 的过程中添加这些命令),用于更新 Web 应用的状态。每次调用 updateCanvasState() 时,displayedWordincorrectGuesses 的值都会根据当前状态进行更新:

scene.js

...
  updateCanvasState() {
    window.interactiveCanvas.setCanvasState({
      correctWord: this.word.text,
      displayedWord: this.word.displayText.text,
      incorrectGuesses: this.incorrectGuesses,
    });

更新后的状态随后可用于下一轮对话。您可以通过 conv.context.canvas.state 在网络钩子中访问此状态,如以下代码段所示:

index.js

...
  let displayedWord = conv.context.canvas.state.displayedWord;
...

在本部分中,您将向 Action 添加 guess 功能,可以让用户猜测单词包含的字母或直接猜测单词。

对话型 Action

在模拟器部分的“Test”中,您收到了一个回应,其中包含:“It looks like we need to add more functionality to have this work properly.”现在,您可以在 Actions 控制台中删除该提示,这样您只会调用网络钩子(在 Game 场景中,guess intent 经过配置,可在它得到匹配时执行网络钩子调用)。

如需移除在 guess 意图得到匹配时出现的静态提示,请按以下步骤操作:

  1. 在 Actions 控制台中,点击导航栏中的 Scenes
  2. 点击 Game以转到 Game 场景。
  3. 点击 Custom intent handling 下的 When guess is matched。清除 Send prompts,即可移除该提示。
  4. 点击 Save

网络钩子

在本部分中,您将更新网络钩子以包含一个逻辑,该逻辑会将用户正确或不正确的猜测映射到 Web 应用文件中的逻辑,后者随后对 Web 应用进行相应的更新。系统已在网络钩子中配置了 guess intent 处理脚本,因此,您只需向此 intent 添加 Canvas 响应,即可触发用于更新 Web 应用的逻辑。

如需更新网络钩子,请执行以下步骤:

  1. 在 Actions 控制台中,点击导航中的 Webhook
  2. 将以下代码添加到 index.js 中的 guess 处理脚本下方:

index.js(字母 A 部分):

// Add SECTION A `conv.add(new Canvas({` content here
conv.add(new Canvas({
  data: {
    command: 'CORRECT_ANSWER',
    displayedWord: displayedWord
  },
}));

index.js(字母 B 部分):

// Add SECTION B `conv.add(new Canvas({` content here
conv.add(new Canvas({
  data: {
    command: 'INCORRECT_ANSWER',
  },
}));
  1. 点击 Save Fulfillment
  2. 点击 Deploy Fulfillment。部署完成后,编辑器上方会显示以下消息:Your Cloud Function deployment is up to date.

Web 应用

现在,您可以配置 Web 应用,以处理 CORRECT_ANSWERINCORRECT_ANSWER 命令。

  1. 在文本编辑器中打开 public/js/action.js
  2. 更新 Web 应用以处理 CORRECT_ANSWERINCORRECT_ANSWER 命令:

action.js(字母 C 部分):

// Add SECTION C `CORRECT_ANSWER: (params) => {` content here
      CORRECT_ANSWER: (params) => {
        this.gameScene.correctAnswer(params);
      },
      INCORRECT_ANSWER: (params) => {
        this.gameScene.incorrectAnswer();
      },
  1. 运行以下命令来更新 Web 应用:
firebase deploy --project {PROJECT_ID} --only hosting

在模拟器中测试您的 Action

此时,您的 Action 可以判断猜测是否正确,并对 Web 应用进行相应的更新。

如需测试您的 Action,请按以下步骤操作:

  1. 在导航栏中,点击 Test
  2. Input 字段中输入 Talk to Snow Pal sample,然后按 Enter
  3. Input 字段中输入 Yes,然后按 Enter。或者,点击 Yes 按钮。
  4. 在输入字段中键入您猜到的字母,然后按 Enter 键。

1c2c2d59a418642b.png

了解代码

在上一部分中,您添加了代码,让用户能够在游戏中猜字母,并看到这些猜测反映到单词或 Snow Pal 上。大体上讲,当 guess intent 得到匹配时,您在 Actions Builder 中执行网络钩子调用,这会将数据传递到您的 Web 应用,以便对该应用进行相应的更新。例如,如果用户在 Snow Pal 游戏中猜到了单词中包含的一个字母,Web 应用就会进行更新,在单词中的正确位置显示该字母。

在使用 Interactive Canvas 的 Action 中,数据从网络钩子传递到 Web 应用的一般流程如下所示:

  1. 用户的输入与一个包含 Canvas 响应的 intent 匹配。
  2. 对话型 Action 或网络钩子发送 Canvas 响应,这将触发 onUpdate() 回调。
  3. onUpdate() 回调映射到自定义逻辑,该逻辑对 Web 应用进行相应的更新。

对于这个特定项目,代码的运行方式如下:

  1. 当用户的输入与 guess intent 匹配时,Action Builder 从用户的输入中提取字母作为参数。
  2. Actions Builder 调用网络钩子中的 guess 处理脚本,其中包含的逻辑可确定用户猜测的字母是否存在于单词中。
  3. guess 处理脚本包含两个 Canvas 响应:一个在猜对字母时执行,另一个在猜错字母时执行。每个 Canvas 响应将相应的数据(CORRECT_ANSWERINCORRECT_ANSWER 命令)传递给 Web 应用。
  4. Canvas 响应的 data 字段中所包含的数据会传递到 action.jsonUpdate() 方法。onUpdate() 调用 scene.js 的命令映射中的相应命令。
  5. 命令映射将映射到 scene.js 中的 correctAnswer()incorrectAnswer() 函数。这些函数相应地更新 Web 应用以反映用户的猜测,并调用 setCanvasState() 以将状态数据从 Web 应用发送到网络钩子。

在本部分中,您将向 Action 添加输赢功能,其中包括用于确定用户输赢的逻辑,以及根据用户的游戏结果来更新 Web 应用图像的逻辑。

对话型 Action

用于处理用户游戏输赢情况的功能将在 guess intent 中进行配置,因此,您不必在 Actions Builder 中执行任何其他配置。

网络钩子

在本部分中,您将更新网络钩子以包含一个逻辑,该逻辑会处理用户赢得或输掉游戏的情况,并映射到相应 Web 应用逻辑,后者则用相应的输赢屏幕更新游戏。

如需更新网络钩子,请执行以下步骤:

  1. 在 Actions 控制台中,点击导航中的 Webhook
  2. 将以下代码添加到 index.js 中的 guess 处理脚本下方:

index.js(字母 D 部分):

// Add SECTION D `if (userHasWon)` content here
    if (userHasWon) {
      conv.add(`<speak>Let's see if your guess is there...<break
        time='2500ms'/> ${guess} is right. That spells ${correctWord}!
        ${randomArrayItem(WIN_RESPONSES)}</speak>`);
      conv.add(new Canvas({
        data: {
          command: 'WIN_GAME',
          displayedWord: displayedWord
        },
      }));
      conv.add(`<speak>${PLAY_AGAIN_INSTRUCTIONS}</speak>`);
    } else {

index.js(字母 E 部分):

// Add SECTION E `}` here
}

index.js(字母 F 部分):

// Add SECTION F `Check if the user has exceeded the maximum` content here
// Check if the user has exceeded the maximum amount of max guesses allowed.
    const userHasLost = conv.context.canvas.state.incorrectGuesses + 1 >= MAX_INCORRECT_GUESSES;
    if (userHasLost) {
      conv.add(`<speak>Let's see if your guess is there...<break
      time='2500ms'/> ${guess} is wrong. Sorry you lost. The word is ${correctWord}!</speak>`);
      conv.add(new Canvas({
        data: {
          command: 'LOSE_GAME',
        },
      }));
      conv.add(`<speak>${PLAY_AGAIN_INSTRUCTIONS}</speak>`);
    } else {

index.js(字母 G 部分):

// Add SECTION G `}` here
}
  1. 点击 Save Fulfillment
  2. 点击 Deploy Fulfillment。部署完成后,编辑器上方会显示以下消息:Your Cloud Function deployment is up to date.

在这里,您添加了两个 Canvas 包含 WIN_GAMELOSE_GAME 命令的响应,用于处理用户赢得或输掉游戏的情况。在下一部分中,您将添加一项功能,用于根据用户输赢情况来更新 Web 应用。

Web 应用

现在,您可以对 Web 应用进行配置,以便根据用户输赢情况进行更新。如需更新 Web 应用,请按以下步骤操作:

  1. 在文本编辑器中打开 public/js/action.js
  2. 更新您的 Web 应用以处理 WIN_GAMELOSE_GAME 命令:

action.js(字母 H 部分):

// Add SECTION H `WIN_GAME: (params) => {` content here
      WIN_GAME: (params) => {
        this.gameScene.winGame(params);
      },
      LOSE_GAME: (params) => {
        this.gameScene.loseGame();
      },
  1. 运行以下命令来更新 Web 应用:
firebase deploy --project {PROJECT_ID} --only hosting

在模拟器中测试您的 Action

此时,您的 Action 可以处理用户赢得或输掉游戏的情况,并为每个结果显示相应的屏幕。

如需测试您的 Action,请按以下步骤操作:

  1. 在 Actions 控制台导航栏中,点击 Test
  2. Input 字段中输入 Talk to Snow Pal sample,然后按 Enter
  3. Input 字段中输入 Yes,然后按 Enter。或者,您也可以点击 Start Game 按钮。
  4. 猜字母和单词,直至赢得或输掉游戏。

ee572870f9a7df36.png

如果您请求再玩一次,则会收到一条消息,提示您尚未添加必需的重玩功能。您将在下一部分中添加此功能。

了解代码

游戏输赢功能的运行方式与猜测功能相同 - 当用户输入与 guess intent 匹配时,您的网络钩子对用户的猜测进行评估。如果用户猜测正确,代码会检查用户是否获胜;如果获胜,系统则会将 WIN_GAME 命令发送至 Web 应用。如果猜测错误,代码会检查用户是否失败;如果失败,系统则会将 LOSE_GAME 命令发送至 Web 应用。这些命令会触发 scene.js 中的 winGame()loseGame() 函数,这两个函数会更新 Web 应用,以呈现输赢屏幕并更新游戏状态。

在本部分中,您将添加一项功能,让用户可以通过说出“Play again”或点击 Web 应用中的 Play Again 按钮开始一局新游戏。您可以在 Actions Builder 中修改 play_again intent,以发送可对 Web 应用进行相应更新的 canvas 响应,并添加可在用户点击 Play Again 按钮时触发 play_again intent 的逻辑。

对话型 Action

在上一部分测试 Action 时,您尝试重玩游戏,收到了以下提示:“That would be great, but we will build this functionality in a later section. For now, just reset the Action.”现在,您可以删除此提示并替换为新提示,新提示会在用户请求重玩游戏时显示(例如,“Okay, here's another game!”),并包含一个 canvas 响应,可触发 Web 应用开始一局新游戏。

如需更新用户要求重玩游戏时显示的提示,请按以下步骤操作:

  1. 在 Actions 控制台中,点击 Scene 下拉菜单。
  2. 点击 Game 场景。
  3. 点击 Custom intent handling 下的 When play_again is matched
  4. 将提示替换为以下内容:
candidates:
  - first_simple:
      variants:
        - speech: 'Okay, here's another game!'
    canvas:
      sendStateDataToCanvasApp: true
  1. 点击 Save

网络钩子

在本 Codelab 中,网络钩子用于管理游戏逻辑。由于“重玩”功能不需要任何类型的逻辑验证,因此无需调用网络钩子;您可以直接从 Actions Builder 发送 canvas 响应,以将必要数据传递到 Web 应用(您在上一部分中已对此作了配置)。

Web 应用

现在,您可以修改 Web 应用文件,以便在用户要求重玩时进行相应更新。如需添加此功能,请按以下步骤操作:

  1. 在文本编辑器中打开 public/js/action.js
  2. 更新 Web 应用以处理 PLAY_AGAIN 命令:

action.js(字母 I 部分):

// Add SECTION I `PLAY_AGAIN: (params) => {` content here
      PLAY_AGAIN: (params) => {
        this.gameScene.start();
      },
  1. 在文本编辑器中打开 public/js/scene.js
  2. 更新 Web 应用,以在用户点击“Play Again”按钮时开启新游戏会话:

scene.js(字母 J 部分):

// Add SECTION J `sendTextQuery` content here
     window.interactiveCanvas.sendTextQuery('Play again');
  1. 运行以下命令来更新 Web 应用:
firebase deploy --project {PROJECT_ID} --only hosting

在模拟器中测试您的 Action

现在,当用户说出“Play again”或点按“Play again”按钮时,您的 Action 将开启一个新游戏会话。

如需测试您的 Action,请按以下步骤操作:

  1. 在导航栏中,点击 Test
  2. Input 字段中输入 Talk to Snow Pal sample,然后按 Enter
  3. Input 字段中输入 Yes,然后按 Enter。或者,您也可以点击 Start Game 按钮。
  4. 猜字母和单词,直至赢得或输掉游戏。
  5. Input 字段中输入 Play Again,然后按 Enter 键。或者,您也可以点击 Play Again 按钮。

1fbc7193f7a9d0f5.png

了解代码

测试您的 Action 时,您可以通过语音输入(说出“Play again”)或触控输入(点击“Play Again”按钮)来开启一局新游戏。

对于语音输入选项,就是当用户说出“Play again”或某些类似指令时,就会触发 play_again intent,并向提示队列添加提示(“Okay, here's another game!”)。提示中包含的 canvas 响应会将 intent 名称和其他元数据发送给 Web 应用。系统会将 intent 名称传递给 onUpdate() 回调,该回调将相应的命令 PLAY_AGAIN 映射到 action.js 中的命令映射。PLAY_AGAIN 命令会触发 scene.jsstart() 函数,并使用新游戏会话更新 Web 应用。

对于触控输入选项,您可以使用名为 sendTextQuery(), 的 Interactive Canvas API,从而通过触控输入触发 intent,让按钮发挥作用。

在本 Codelab 中,当用户点击“Play Again”按钮时,您将使用 sendTextQuery() 调用 play_again intent。Play again 参数与 play_again intent 中的训练短语匹配,并触发该 intent,触发方式与用户说“Play again”相同。然后,play_again intent 触发用于更新 Web 应用并开启新游戏会话的逻辑。

在本部分中,您将更新 PLAY_GAME 隐式调用

借助 PLAY_GAME 隐式调用,用户可以在发出笼统请求(例如“I want to play a game”)时调用您的 Action。

源代码包含位于 /sdk/custom/global/actions.intent.PLAY_GAME.yamlPLAY_GAME 全局 intent。这会作为 PLAY_GAME 显示在控制台的 Invocation 中,如以下屏幕截图所示:

b4a73c0ddd88f6d5.png

如需让用户能够通过此隐式调用来调用您的 Action,您需要在 PLAY_GAME 隐式调用中添加包含 Web 应用网址的 canvas 响应。为此,请按以下步骤操作:

  1. 在 Actions 控制台中,点击导航栏中的 PLAY_GAME
  2. 更新提示以添加您的 Web 应用网址,如以下代码段所示:
candidates:
  - canvas:
      url: 'https://<PROJECT_ID>.web.app'
  1. 点击 Save

在模拟器中测试您的 Action

您的 Action 现在支持 PLAY_GAME 隐式调用。

如需测试您的 Action,请按以下步骤操作:

  1. 在导航栏中,点击 Test
  2. 点击 Test fulfillment for system intents
  3. 点击 Invoke Action

1a4f647e17ebab53.png

系统应当会在模拟器中调用您的 Action。

在本部分中,您将了解如何对无法正常运行的 Interactive Canvas Action 进行调试。Snow Pal 项目带有预封装的调试界面,您可以启用它。调试界面会将所有 console.log()console.error() 输出显示在屏幕的右下角,如以下屏幕截图所示:

4c8531d24366b5df.png

如需启用此调试界面,请打开 /public/css/main.css 文件并添加注释行 display: none !important;,如以下代码段所示:

main.css

.debug {
 display: flex;
 flex-direction: column;

/* Comment below to view debug overlay */
/* display: none !important; */

 width: 500px;
 height: 150px;
 right: 0;
 bottom: 0;
 position: absolute;
}

恭喜您!

您完成了入门级 Interactive Canvas Codelab,并掌握了构建自己的 Interactive Canvas Action 所需的技能。

您学到的内容

  • 如何构建、部署和测试 Interactive Canvas Action
  • 如何使用 Canvas 响应来更新 Web 应用
  • 如何使用不同方法强化 Action 功能,例如 sendTextQuery()setCanvasState()
  • 如何调试 Action

其他学习资源

查看以下资源,详细了解 Interactive Canvas:

清理项目 [推荐]

为避免可能产生的费用,建议您移除不想使用的项目。如需删除您在本 Codelab 中创建的项目,请按以下步骤操作:

  1. 如需删除 Cloud 项目和资源,请完成关停(删除)项目部分中所列的步骤。
  1. 可选:如需立即从 Actions 控制台移除您的项目,请完成删除项目部分中所列的步骤。如果您未完成该步骤,系统会在大约 30 天后自动移除您的项目。

反馈意见调查

在您离开本页面前,请填写简短的调查问卷,与我们分享您的体验。