通过适用于 Google 助理的 Action 吸引用户

1. 概览

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

这是一个高级 Codelab 模块,面向已有一些构建 Google 助理 Action 经验的读者。如果您之前没有任何 Actions on Google 开发经验,我们强烈建议您先学习我们的入门级 Codelab(第 1 级第 2 级第 3 级),熟悉此平台。这些高级模块将指导您使用一系列功能,帮助您扩展 Action 的功能并扩大您的受众群体。

衡量 Action 成效的一个重要方法是衡量用户互动度,或者 Action 在首次互动后再次吸引用户的效果。为简化操作,您可以在 Action 中实现多项功能,为用户提供返回对话的路径。

本 Codelab 介绍了 Actions on Google 用户互动功能和最佳做法。

a3fc0061bd01a75.png 961ef6e27dc73da2.png

构建内容

您可以通过增强以下功能来增强已经构建的功能:

  • 向用户发送每日动态,供用户点按以与您的 Action 对话
  • 向用户发送链接,提醒你的 Action 返回 Action
  • 创建从移动网络浏览器将用户转到 Action 的链接

学习内容

  • 什么是用户互动,以及为什么 Action 对 Action 的成功很重要
  • 如何修改 Action 以提升用户互动度
  • 要在不同类型的 Action 中使用哪些用户互动功能
  • 如何使用 Actions API 通过 Google 助理发送通知

您需要满足的条件

您必须拥有以下工具:

  • 选择一种 IDE/文本编辑器,例如 WebStormAtomSublime
  • 已安装 Node.js、npm 和 git 的 shell 命令的终端
  • 网络浏览器,例如 Google Chrome
  • 具有 Firebase 命令行界面的本地开发环境
  • 一部搭载 Google 助理的移动设备(Android 或 iOS 设备)(您必须使用用于构建此项目的 Google 帐号登录 Google 助理。)

我们强烈建议(但不强制要求)您熟悉 JavaScript (ES6),以便理解网络钩子代码。

2. 设置项目

本部分将介绍如何向之前的完整 Action 添加用户互动功能。

了解示例

此 Codelab 中的示例是一个针对虚构健身房“Action Gym”的简单 Action。此 Action 提供健身房的相关信息,包括每天轮换的课程列表。此类信息丰富的 Action 非常适合使用所有用户互动功能,因为轮替类列表每天提供不同的实用信息。

下图显示了操作健身房示例的对话流程:

e2d6e4ad98948cf3.png

您可以对对话框稍作修改,以便更好地适应您添加的互动功能。不过,对话的常规设计不会发生太大变化。

下载基础文件

运行以下命令,为 Codelab 克隆 GitHub 代码库:

git clone https://github.com/actions-on-google/user-engagement-codelab-nodejs

设置项目和代理

如需设置您的 Actions 项目和 Dialogflow 代理,请完成以下步骤:

  1. 打开 Actions 控制台
  2. 点击新项目
  3. 输入项目名称,例如 engagement-codelab
  4. 点击创建项目
  5. 请向下滚动至更多选项部分,然后点击对话卡片,而不是选择类别。
  6. 点击 Build your Action 以展开选项,然后选择 Add Action(s)
  7. 点击添加您的首个操作
  8. Create Action 对话框中,选择 Custom Intent,然后点击 Build 以启动 Dialogflow 控制台。
  9. 在 Dialogflow 控制台的代理创建页面中,点击创建
  10. 点击左侧导航栏中的 6bf56243a8a11a3b.png(齿轮图标)。
  11. 点击导出和导入 (Export and Import),然后点击从 Zip 文件恢复 (Restore from Zip)。
  12. 从您之前下载的 /user-engagement-codelab-nodejs/start/ 目录中上传 agent.zip 文件。
  13. 输入 RESTORE,然后点击恢复
  14. 点击完成

部署您的执行方式

现在,您的 Actions 项目和 Dialogflow 代理已准备就绪,您可以使用 Firebase Functions CLI 部署本地 index.js 文件。

从基础克隆的 /user-engagement-codelab-nodejs/start/functions/ 目录中,运行以下命令:

firebase use <PROJECT_ID>
npm install
firebase deploy

几分钟后,您应该会看到“Deploy Deploy!”,这表示您已成功将网络钩子部署到 Firebase。

检索部署网址

您需要向 Dialogflow 提供 Cloud Functions 函数的网址。如需检索此网址,请按以下步骤操作:

  1. 打开 Firebase 控制台
  2. 从选项列表中选择您的 Actions 项目。
  3. 导航到左侧导航栏上的开发 > 函数。如果系统提示您“选择数据共享设置”,您可以点击以后再说来忽略此选项。
  4. 信息中心标签页下,您应该会在触发器下看到一个网址“fulfillment”及其网址。保存此网址;在下一部分中,您需要将其复制到 Dialogflow 中。

1741a329947975db.png

在 Dialogflow 中设置网络钩子网址

现在,您需要更新 Dialogflow 代理以使用网络钩子执行。请按以下步骤进行此操作:

  1. 打开 Dialogflow 控制台(如果您愿意,可以关闭 Firebase 控制台)。
  2. 点击左侧导航栏中的 Fulfillment
  3. 启用网络钩子
  4. 粘贴您从 Firebase 信息中心复制的网址(如果尚未显示)。
  5. 点击保存

验证项目设置是否正确

用户应该能够调用您的 Action,获取有关 Action Gym 的信息,包括硬编码的营业时间(包含营业时间)和文本回复(列出课程每天的课程安排)。

如需在 Actions 模拟器中测试您的 Action,请按以下步骤操作:

  1. 在 Dialogflow 控制台的左侧导航栏中,依次点击 Integrations(集成)和 Google Assistant
  2. 确保已启用自动预览更改,然后点击测试以更新您的 Actions 项目。
  3. Actions 模拟器会加载您的 Actions 项目。如需测试您的 Action,请在 Input 字段中输入 Talk to my test app,然后按 Enter 键。
  4. 您应该会看到一条欢迎光临行动健身房。请尝试按照提示继续对话,同时确保你的执行方式为每个输入都提供响应。

60acf1ff87b1a87f.png

3.添加每日更新订阅

常见的互动方式是在关键时刻为用户提供信息。这是通过向用户提供订阅某个 intent 的每日更新选项实现的,该功能会向用户发送一个直接链接到该 intent 执行方式的 Google 助理通知。

在此步骤中,您将了解每日更新订阅,并将其添加到 Action 的 Class List intent。按照这些说明操作之后,您的 Action 对话将如下图所示:

f48891c8118f7436.png

这会如何吸引用户?

智能手机用户很可能熟悉推送通知,这类通知可以提供应用专属的信息和最新动态。每日更新订阅是一种在 Google 助理之外访问移动设备的用户的简单方法,前提是您要发送最新动态的 intent 能继续每天为用户提供价值。

每日更新可以成为一种有效的互动工具,但不一定适用于所有 Action。在决定是否为 Action 添加每日更新订阅时,请考虑以下提示:

  • 确保每日更新会让用户每天看到不同的实用信息。如果每天点按更新导致系统每次都显示相同的提示,用户可能在几天后就会退订。
  • 确保用户直接跳转到您的每日更新意图,以便理解您的对话框。用户不必从对话的开头开始,因此预计他们不会有太多相关背景信息。
  • 先提示用户您的 Action 的优势,然后再提示用户订阅每日动态。您的用户在看到订阅选项时,会想到“我每天都想要这款内容”。
  • 不要不断向用户重复提供订阅建议。在向用户展示他们所订阅的内容后立即提供每日更新订阅,并避免在别处向订阅者发布此类订阅。
  • 触发更新 intent 后使对话保持简短。大多数每日更新应只包含一个响应,然后无需用户输入即可关闭。

开启每日动态

每日更新订阅可添加到欢迎 intent 中,以将用户转到对话的开头部分,或更具体的 intent,以深层链接到对话中的某处。在本 Codelab 中,类列表 intent 是最合理的做法,因为对话每天都在发生变化,而用户可能会发现,提醒自己可以使用哪些类很有用。

请按照以下步骤为 Class List intent 启用每日更新:

  1. 在 Actions 控制台中,点击 Develop 标签页,然后在左侧导航栏中选择 Actions
  2. 点击 Actions 列表下的 Class List
  3. 用户互动部分下方,切换是否要向用户提供每日动态选项。
  4. 设置描述每日更新的内容标题。具体情境是“您希望我把每天的安排在什么时间发送?”,因此请确保您的标题描述准确且大声读出来。在此示例中,请将内容标题设置为 list of upcoming Action Gym classes
  5. 点击页面顶部的保存

c00885cc30e14d68.png

设置 Dialogflow

在 Dialogflow 控制台中按照以下步骤创建每日更新订阅流程的 intent:

提示用户订阅

  1. 设置一个新的 intent 来处理请求订阅每日更新的用户。在 Dialogflow 控制台中,点击左侧导航栏中意图 (Intents) 旁边的 + 按钮以创建新意图。
  2. 将此新 intent 命名为 Setup Updates
  3. 训练短语部分下,添加以下用户表达式
  • Send daily reminders
  • Reminder
  • Remind me
  • Updates
  • Upcoming classes
  1. Fulfillment 部分下,切换为此意图启用网络钩子调用选项。
  2. 点击页面顶部的保存

5c70faa02151da0.png

处理用户的决定

  1. 设置一个新的 intent 来处理用户对每日更新订阅提示的响应。点击左侧导航栏中的 Intents 旁边的 + 按钮以创建新 intent。
  2. 将此新 intent 命名为 Confirm Updates
  3. 事件部分下,添加 actions_intent_REGISTER_UPDATE。完成每日更新订阅流程后,无论用户是否订阅,都会触发此 Dialogflow 事件。
  4. Fulfillment 部分下,切换为此意图启用网络钩子调用选项。
  5. 点击页面顶部的保存

b871c2bdadac8abc.png

实现 fulfillment

如需在网络钩子中实现 fulfillment,请完成以下步骤:

加载依赖项

b2f84ff91b0e1396.pngindex.js 文件中,更新 require() 函数以添加 actions-on-google 软件包中的 RegisterUpdate 软件包,因此导入将如下所示:

index.js

const {
  dialogflow,
  Suggestions,
  RegisterUpdate,
} = require('actions-on-google');

更新建议内容信息卡

b2f84ff91b0e1396.pngindex.js 文件中,将 DAILY 条目添加到建议内容信息卡列表,使 Suggestion 定义如下所示:

index.js

// Suggestion chip titles
const Suggestion = {
  HOURS: 'Ask about hours',
  CLASSES: 'Learn about classes',
  DAILY: 'Send daily reminders',
};

为新 intent 添加执行方式

当用户说出他们想要订阅时,通过调用包含更新目标 intent 的 RegisterUpdate 帮助程序(类列表)和类型 (DAILY) 来启动每日更新订阅流程。订阅流程完成后,Google 助理会使用 status 参数触发 actions_intent_REGISTER_UPDATE 事件,以描述订阅是否成功。向用户提供根据订阅状态发生变化的后续提示。

b2f84ff91b0e1396.pngindex.js 文件中,添加以下代码:

index.js

// Start opt-in flow for daily updates
app.intent('Setup Updates', (conv) => {
  conv.ask(new RegisterUpdate({
    intent: 'Class List',
    frequency: 'DAILY',
  }));
});

// Confirm outcome of opt-in for daily updates
app.intent('Confirm Updates', (conv, params, registered) => {
  if (registered && registered.status === 'OK') {
     conv.ask(`Gotcha, I'll send you an update everyday with the ` +
     'list of classes. Can I help you with anything else?');
  } else {
    conv.ask(` I won't send you daily reminders. Can I help you with anything else?`);
  }
  if (conv.screen) {
    conv.ask(new Suggestions([Suggestion.HOURS, Suggestion.CLASSES]));
  }
});

为用户提供备选提示

Class List 响应会在结束时提供每日更新订阅,但这样会引发问题。因为当用户点按每日更新通知时,系统会触发相同的响应,所以系统仍会提醒他们订阅每日更新,即使他们刚刚收到每日更新通知也是如此。您如何避免用户认为他们需要重新订阅?

幸运的是,您的 conv 对象的参数包含有关用户开始对话位置的信息。您可以检查 conv 参数,看看它们是否包含 UPDATES 部分(表明用户是通过每日更新通知发起对话),然后相应地更改响应的。您也可以在提供类列表后立即使用此对话分支关闭对话框,这遵循了我们尽量保持每日更新的最佳做法。

b2f84ff91b0e1396.pngindex.js 文件中,替换以下代码:

index.js

// Class list intent handler
app.intent('Class List', (conv, {day}) => {
  if (!day) {
    day = DAYS[new Date().getDay()];
  }
  const classes =
  [...new Set(schedule.days[day].map((d) => `${d.name} at ${d.startTime}`))]
  .join(', ');
  const classesMessage =
  `On ${day} we offer the following classes: ${classes}. ` +
  `Can I help you with anything else?`;
  conv.ask(classesMessage);
  if (conv.screen) {
    conv.ask(new Suggestions([Suggestion.HOURS]));
  }
});

替换为:

index.js

// Class list intent handler
app.intent('Class List', (conv, {day}) => {
  if (!day) {
    day = DAYS[new Date().getDay()];
  }
  const classes =
  [...new Set(schedule.days[day].map((d) => `${d.name} at ${d.startTime}`))]
  .join(', ');
  let classesMessage = `On ${day} we offer the following classes: ${classes}. `;
  // If the user started the conversation from the context of a daily update,
  // the conv's arguments will contain an 'UPDATES' section.
  let engagement = conv.arguments.get('UPDATES');
  // Check the conv arguments to tailor the conversation based on the context.
  if (engagement) {
    classesMessage += `Hope to see you soon at Action Gym!`;
    conv.close(classesMessage);
  } else {
    classesMessage += `Would you like me to send you daily reminders of upcoming classes, or can I help you with anything else?`;
    conv.ask(classesMessage);
    if (conv.screen) {
      conv.ask(new Suggestions([Suggestion.DAILY, Suggestion.HOURS]));
    };
  };
});

测试每日动态

在终端中,运行以下命令以将更新后的网络钩子代码部署到 Firebase:

firebase deploy

如需在 Actions 模拟器中测试系统给出的提示,请按以下步骤操作:

  1. 在 Actions 控制台中,转到 Test
  2. Input 字段中输入 Talk to my test app,然后按 Enter 键。
  3. 输入 Learn about classes,然后按 Enter 键。您的 Action 回复现在应该会显示以发送每日提醒。
  4. 输入 Send daily reminders,然后按 Enter 键。
  5. 输入您想要查看更新的时间,然后按 Enter 键。为了进行测试,请比当前时间晚 3-5 分钟。

83a15ecac8c71787.png

在移动设备上,你应该会在你指定的更新时间前后收到 Google 助理发送的通知。请注意,该通知可能需要几分钟才会显示。点按通知后,通知应该直接深层链接到 Google 助理中的 Class List intent,从而为您提供即将开始的课程的列表:

8582482eafc67d5b.png

4.添加推送通知

作为吸引 Action 之外的用户的其他方法,您可以调用 Actions API 向用户发送推送通知。与每日更新不同,Google 助理不会自动安排这些通知的发送时间,因此您可以按需发送。

在这一步中,您将学习如何通过添加一个新的 Class Canceld intent 并向用户发送有关课程取消的通知,从而在 Action 中实现推送通知。您还需要设置发送通知所需的以下三个组件:

  • Actions API 帐号 - 您要通过向 API 发送 POST 请求向用户发送通知,因此您需要设置一个服务帐号和凭据,以便与此 API 进行交互。
  • 权限帮助程序 - 您需要获得用户权限才能访问向用户发送推送通知所需的用户 ID。在此示例中,您将使用客户端库函数调用权限帮助程序并请求此 ID。
  • 存储 - 要在对话外向用户发送推送通知,您需要将用户 ID 存储在可随意召回的位置。在此示例中,您将设置一个 Firestore 数据库来存储每个用户的信息。

按照以下说明操作后,您可以将以下对话框添加到 Action 的对话中:

7c9d4b633c547823.png

这会如何吸引用户?

智能手机用户很可能熟悉推送通知,这类通知可以提供应用专属的信息和最新动态。推送通知是访问 Google 助理以外的移动设备用户的灵活方式,前提是有充分理由允许用户启用通知功能。通过每日更新,用户已经知道他们每天都会收到通知。然而,使用推送通知时,用户不知道是选择接收不常收到的通知,还是希望每天收到多条通知。

推送通知是一款实用的互动工具,但不一定要与每项 Action 都集成在一起。在决定是否向 Action 添加推送通知时,请参考以下提示:

  • 规划推送通知的一些示例时间表。如果您计划每天只发送一条推送通知,请考虑改用每日更新。
  • 确保每次收到通知时,您的推送通知都是有用的信息。通知还可以深层链接到您的 Action 的某个 intent,因此请确保该 intent 实用且具有相关性。
  • 在要求用户订阅推送通知时明确说明这一点。他们应该了解每次推送通知会发生什么情况,并大致了解通知的发送频率。

启用 Actions API

  1. 打开 Google Cloud Console,从下拉菜单中选择您的 Actions 项目名称。

d015c1515b99e3db.png

  1. 在导航菜单 (☰) 中,转到 API & Services > Library
  2. 搜索 Actions API,然后点击启用

6d464f49c88e70b4.png

创建服务帐号

Actions API 要求进行身份验证,因此您需要创建一个服务帐号来发送请求。请按照以下步骤为 Actions API 创建并安装服务帐号密钥:

  1. 在 Google Cloud Console 的导航菜单 (☰) 中,转到 API 和 Service > 凭据
  2. 点击创建凭据 &gt 服务帐号密钥
  3. 服务帐号下拉菜单中,选择新建服务帐号
  4. 填写以下信息:
  • 服务帐号名称service-account
  • 角色:Project > Owner
  • 服务帐号 IDservice-account(始终后接 @<project_id>.iam.gserviceaccount.com)
  • 密钥类型:JSON
  1. 点击创建
  2. 将下载的 JSON 文件移至项目的 /user-engagement-codelab/start/functions/ 目录。
  3. 将 JSON 文件重命名为 service-account.json

d9bd79d35691de3a.png

启用 Firestore

要在对话之外发送通知,您需要一种方法来存储可从通知代码引用的用户 ID。在本示例中,我们使用 Firestore 数据库来存储订阅用户的用户 ID。

请按照以下步骤为您的 Action 创建 Firestore 数据库:

  1. Firebase 控制台中,选择您的 Actions 项目名称。
  2. 在左侧导航栏中,转到开发 &gt 数据库,然后点击创建数据库
  3. 选择以测试模式开始
  4. 点击启用

6dfc386413954caa.png

设置 Dialogflow

在 Dialogflow 控制台中按照以下步骤创建推送通知选择启用流程:

提示用户订阅

  1. 设置一个新的 intent,用于处理用户要求订阅有关已取消的课程的推送通知。在 Dialogflow 控制台中,点击左侧导航栏中意图 (Intents) 旁边的 + 按钮以创建新意图。
  2. 将此新 intent 命名为 Setup Push Notifications
  3. 训练短语部分下,添加以下用户表达式
  • Subscribe to notifications
  • Send notification
  • Notify me
  • Send class notifications
  • Cancelled notifications
  1. Fulfillment 部分下,切换为此意图启用网络钩子调用选项。
  2. 点击页面顶部的保存

3d99bc41d0492552.png

处理用户的决定

  1. 设置一个新的 intent 来处理用户对推送通知订阅提示的响应。点击左侧导航栏中的 Intents 旁边的 + 按钮以创建新 intent。
  2. 将此新 intent 命名为 Confirm Push Notifications
  3. 事件部分下,添加 actions_intent_PERMISSION。用户完成推送通知订阅流程会触发此 Dialogflow 事件,无论他们最终是否订阅。
  4. Fulfillment 部分下,切换为此意图启用网络钩子调用选项。
  5. 点击页面顶部的保存

d37f550c5e07cb73.png

处理推送通知

您可以将推送通知与特定 intent 关联,这样,点按推送通知的用户便可深层链接到您的 Action 中的相应 intent。在此示例中,为推送通知添加一个新 intent,提供有关已取消类的详细信息。

请按照以下步骤添加一个 intent,以便在用户点按推送通知时触发:

  1. 在 Dialogflow 控制台中,点击左侧导航栏中意图 (Intents) 旁边的 + 按钮以创建新意图。
  2. 将此新 intent 命名为 Class Canceled
  3. 训练短语部分下,将 Cancelations 添加为用户表达式
  4. Fulfillment 部分下,切换为此意图启用网络钩子调用选项。
  5. 点击页面顶部的保存

940379556f559631.png

在对话过程中发送测试通知

在生产环境中,您应将一个脚本与发送推送通知的 Action 执行代码分开。在本示例中,创建一个 intent,您可以在调用 Action 时调用该 intent 以发送推送通知。此 intent 仅用于调试目的;实际上,推送通知不应由你的执行方式进行处理,也不会以其他方式作为 Action 对话的一部分触发。

按以下步骤创建用于测试推送通知的 intent:

  1. 为便于测试和调试,请设置一个新 intent,允许您向已订阅的用户发送推送通知。在 Dialogflow 控制台中,点击左侧导航栏中意图 (Intents) 旁边的 + 按钮以创建新意图。
  2. 将此新 intent 命名为 Test Notification
  3. 训练短语部分下,将 Test notification 添加为用户表达式
  4. Fulfillment 部分下,切换为此意图启用网络钩子调用选项。
  5. 点击页面顶部的保存

6967f5a997643eb8.png

开启推送通知

如需为 Class Canceled intent 启用推送通知,请按以下步骤操作:

  1. 在 Dialogflow 控制台中,转到导航栏中的集成 (Integrations)。
  2. Google 助理卡片上,点击集成设置
  3. 类已取消作为隐式调用 intent 添加。必须执行此步骤,Dialogflow 才能识别用户能否通过课程取消 intent 发起对话(通过点按推送通知)。
  4. 点击关闭

1ac725231ed279a1.png

  1. 在 Actions 控制台中,点击 Develop 标签页,然后在左侧导航栏中选择 Actions
  2. 点击 Actions 列表下的 Class Canceld
  3. 用户互动度部分,切换要发送推送通知吗?选项。
  4. 设置描述推送通知的内容标题。上下文是“我可以发送推送通知吗?”,因此请确保您的标题具有描述性,并且大声读出标题时听起来正确。在此示例中,请将内容标题设置为 class cancelations
  5. 点击页面顶部的保存

4304c7cd575f6de3.png

实现 fulfillment

如需在网络钩子中实现 fulfillment,请完成以下步骤:

加载依赖项

b2f84ff91b0e1396.pngindex.js 文件中,更新 require() 函数以添加 actions-on-google 软件包中的 UpdatePermission 软件包,因此导入将如下所示:

index.js

const {
  dialogflow,
  Suggestions,
  RegisterUpdate,
  UpdatePermission,
} = require('actions-on-google');

更新建议内容信息卡

b2f84ff91b0e1396.pngindex.js 文件中,将 NOTIFICATIONS 条目添加到建议内容信息卡列表,使 Suggestion 定义如下所示:

index.js

// Suggestion chip titles
const Suggestion = {
  HOURS: 'Ask about hours',
  CLASSES: 'Learn about classes',
  DAILY: 'Send daily reminders',
  NOTIFICATIONS: 'Get notifications',
};

设置新的导入作业

为了连接到 Firestore 数据库,请添加 firebase-admin 软件包,并为数据库中存储的字段添加常量。此外,导入 google-auth-libraryrequest 软件包以处理与 Actions API 的身份验证和请求。

b2f84ff91b0e1396.pngindex.js 文件中,将以下代码添加到 import 中:

index.js

// Firebase admin import
const admin = require('firebase-admin');

// Initialize Firestore
admin.initializeApp();
const db = admin.firestore();

// Firestore constants
const FirestoreNames = {
 INTENT: 'intent',
 USER_ID: 'userId',
 USERS: 'users',
};

// Actions API authentication imports
const {auth} = require('google-auth-library');
const request = require('request');

提示设置课程取消通知

b2f84ff91b0e1396.pngindex.js 文件中,替换以下代码:

index.js

// Class list intent handler
app.intent('Class List', (conv, {day}) => {
  if (!day) {
    day = DAYS[new Date().getDay()];
  }
  const classes =
  [...new Set(schedule.days[day].map((d) => `${d.name} at ${d.startTime}`))]
  .join(', ');
  let classesMessage = `On ${day} we offer the following classes: ${classes}. `;
  // If the user started the conversation from the context of a daily update,
  // the conv's arguments will contain an 'UPDATES' section.
  let engagement = conv.arguments.get('UPDATES');
  // Check the conv arguments to tailor the conversation based on the context.
  if (engagement) {
    classesMessage += `Hope to see you soon at Action Gym!`;
    conv.close(classesMessage);
  } else {
    classesMessage += `Would you like me to send you daily reminders of upcoming classes, or can I help you with anything else?`;
    conv.ask(classesMessage);
    if (conv.screen) {
      conv.ask(new Suggestions([Suggestion.DAILY, Suggestion.HOURS]));
    };
  };
});

替换为:

index.js

// Class list intent handler
app.intent('Class List', (conv, {day}) => {
  if (!day) {
    day = DAYS[new Date().getDay()];
  }
  const classes =
  [...new Set(schedule.days[day].map((d) => `${d.name} at ${d.startTime}`))]
  .join(', ');
  let classesMessage = `On ${day} we offer the following classes: ${classes}. `;
  // If the user started the conversation from the context of a daily update,
  // the conv's arguments will contain an 'UPDATES' section.
  let engagement = conv.arguments.get('UPDATES');
  // Check the conv arguments to tailor the conversation based on the context.
  if (engagement) {
    classesMessage += `Hope to see you soon at Action Gym!`;
    conv.close(classesMessage);
  } else {
    classesMessage += `Would you like to receive daily reminders of upcoming classes, subscribe to notifications about cancelations, or can I help you with anything else?`;
    conv.ask(classesMessage);
    if (conv.screen) {
      conv.ask(new Suggestions([Suggestion.DAILY, Suggestion.NOTIFICATIONS,
Suggestion.HOURS]));
    };
  };
});

为新 intent 添加执行方式

当用户说出他们想要订阅推送通知时,调用 UpdatePermission 帮助程序以请求用户权限。如果成功,PERMISSION 参数将添加到 conv 对象的参数中,您可以检查该参数以透视对话。

获得用户权限后,从 conv 对象的参数中获取用户 ID,并将其保存在数据库中。您稍后需要将此用户 ID 发送给 Actions API,以供 Google 助理决定接收通知的人员。

最后,为点按推送通知触发的 Class Canceled intent 添加 fulfillment。在此示例中,您的响应是一个占位符字符串,但在 Action 就绪的正式版中,您的通知脚本会提供关于已取消的类的更多动态信息。

b2f84ff91b0e1396.pngindex.js 文件中,添加以下代码:

index.js

// Call the User Information helper for permission to send push notifications
app.intent('Setup Push Notifications', (conv) => {
 conv.ask('Update permission for setting up push notifications');
 conv.ask(new UpdatePermission({intent: 'Class Canceled'}));
});

// Handle opt-in or rejection of push notifications
app.intent('Confirm Push Notifications', (conv) => {
 if (conv.arguments.get('PERMISSION')) {
   let userId = conv.arguments.get('UPDATES_USER_ID');
   if (!userId) {
     userId = conv.request.conversation.conversationId;
   }
   // Add the current conversation ID and the notification's
   // target intent to the Firestore database.
   return db.collection(FirestoreNames.USERS)
   .add({
     [FirestoreNames.INTENT]: 'Class Canceled',
     [FirestoreNames.USER_ID]: userId,
   })
   .then(() => {
     conv.ask(`Great, I'll notify you whenever there's a class cancelation. ` +
     'Can I help you with anything else?');
   });
 } else {
   conv.ask(`Okay, I won't send you notifications about class cancelations. ` +
     'Can I help you with anything else?');
 }
 if (conv.screen) {
    conv.ask(new Suggestions([Suggestion.CLASSES, Suggestion.HOURS]));
  }
});

// Intent triggered by tapping the push notification
app.intent('Class Canceled', (conv) => {
 conv.ask('Classname at classtime has been canceled.');
});

添加测试通知

如需向用户发送推送通知,请向 Actions API 发送 POST 请求并提供用户 ID、通知标题和目标 intent。在此示例中,触发测试通知 intent 将遍历您的 Firestore 数据库,并向订阅了通知的所有用户发送推送通知。

请注意,在此示例中,您需要在网络钩子执行方式中添加用于发送推送通知的代码,并通过在对话中调用测试 intent 来触发该代码。在您打算发布的 Action 中,推送通知代码应存在于与您的执行方式不同的脚本中。

b2f84ff91b0e1396.pngindex.js 文件中,添加以下代码:

index.js

// Debug intent to trigger a test push notification
app.intent('Test Notification', (conv) => {
 // Use the Actions API to send a Google Assistant push notification.
 let client = auth.fromJSON(require('./service-account.json'));
 client.scopes = ['https://www.googleapis.com/auth/actions.fulfillment.conversation'];
 let notification = {
   userNotification: {
     title: 'Test Notification from Action Gym',
   },
   target: {},
 };
 client.authorize((err, tokens) => {
   if (err) {
     throw new Error(`Auth error: ${err}`);
   }
   // Iterate through Firestore and send push notifications to every user
   // who's currently opted in to canceled class notifications.
   db.collection(FirestoreNames.USERS)
       .where(FirestoreNames.INTENT, '==', 'Class Canceled')
       .get()
       .then((querySnapshot) => {
         querySnapshot.forEach((user) => {
           notification.target = {
             userId: user.get(FirestoreNames.USER_ID),
             intent: user.get(FirestoreNames.INTENT),
           };
           request.post('https://actions.googleapis.com/v2/conversations:send', {
             'auth': {
               'bearer': tokens.access_token,
             },
             'json': true,
             'body': {'customPushMessage': notification, 'isInSandbox': true},
           }, (err, httpResponse, body) => {
             if (err) {
               throw new Error(`API request error: ${err}`);
             }
             console.log(`${httpResponse.statusCode}: ` +
               `${httpResponse.statusMessage}`);
             console.log(JSON.stringify(body));
           });
         });
       })
       .catch((error) => {
         throw new Error(`Firestore query error: ${error}`);
       });
 });
 conv.ask('A notification has been sent to all subscribed users.');
});

测试推送通知

在终端中,运行以下命令以将更新后的网络钩子代码部署到 Firebase:

firebase deploy

如需在 Actions 模拟器中测试通知,请按以下步骤操作:

  1. 在 Actions 控制台中,转到 Test 标签页。
  2. Input 字段中输入 Talk to my test app,然后按 Enter 键。
  3. 输入 Learn about classes,然后按 Enter 键。
  4. 输入 Get notifications,然后按 Enter 键。
  5. 如果您尚未授予 Action 向您发送推送通知的权限,请输入 yes 并按 Enter 键。
  6. 输入 yes,然后按 Enter 键。现在,您的 Google 帐号应该已订阅有关此操作的推送通知。

3a8704bdc0bcbb17.png

  1. 输入 no,然后按 Enter 键即可退出。
  2. 输入 Talk to my test app 并按 Enter 键即可发起新对话。
  3. 输入 Test notification,然后按 Enter 键。

634dfcb0be8dfdec.png

您应该会在几分钟内在移动设备上收到“来自 Action Gym 的测试通知”。点按此通知会将您深层链接到 Action 的 Class Canceld intent。

33cbde513c10122e.png

5. 创建 Google 助理链接

到目前为止,我们讨论了您可以实现的用户互动功能,以吸引用户再次访问您的 Action,但这些互动功能是以用户发现和使用您的 Action 为依托的。

你可以创建 Google 助理链接,以便将移动设备用户直接链接到你的 Google 助理 Action。由于 Google 助理链接是标准的超链接,因此您可以将其添加到网站或任何网络营销材料(如博客或社交媒体帖子)中。

在这一步中,您将了解什么是 Google 助理链接、如何为 Action 创建欢迎 intent,以及如何将其添加到简单网站以进行测试。

这会如何吸引用户?

首次将用户吸引到你的 Action 可能很困难,特别是当他们需要显式调用 Google 助理上的 Action 时。Google 助理链接可以为用户提供指向你的 Action 的直接链接,从而减轻这种阻碍。当用户在内置 Google 助理的设备上点击您的 Google 助理链接后,系统会直接将其转到您的 Action。当用户在非移动设备或不支持 Google 助理的其他任何设备上打开您的链接时,他们仍会转到您的 Actions 目录列表(如果已发布),让该链接仍然可以向这些用户推广您的 Action。

Google 助理链接是一款实用的互动工具,因此,如果您计划通过网站或社交媒体宣传自己的 Action,建议您创建一个。在创建和分发 Google 助理链接之前,请留意以下提示:

  • 你的 Action 发布后,Google 助理链接才有效。当项目处于草稿状态时,该链接将只能在您自己的设备上生效。其他任何人都将转到 Actions 目录下的 404 页面。
  • 你可以通过在 Alpha 版或 Beta 版环境中发布 Action,让用户在发布之前测试 Google 助理链接。请注意,只有参与 Alpha 版或 Beta 版测试的用户才能测试您的 Google 助理链接。
  • 确保 Google 助理链接的目标 intent 能给新用户留下良好的第一印象。欢迎欢迎 intent 是 Google 助理链接的默认目标位置,因为它应该已经很好地引入了你的 Action

要为欢迎 intent 创建 Google 助理链接,请按以下步骤操作:

  1. 在 Actions 控制台中,点击 Develop 标签页,然后在左侧导航栏中选择 Actions
  2. 点击 Actions 列表下的 actions.intent.MAIN
  3. 链接部分下,切换您是否希望为此操作启用网址选项。
  4. 设置描述 Action 的描述性 Link title。使用简单的动词-名词对来描述用户可通过 Action 完成的操作。在此示例中,请将链接标题设置为 learn about Action Gym
  5. 请复制本页底部的 HTML 代码段,并保存以备后用。
  6. 点击页面顶部的保存

55341b8102b71eab.png

部署测试网站

如需测试您的 Google 助理链接,您可以使用 Firebase 工具随您的 fulfillment 一起部署测试网站。我们已经针对此示例构建了一个简单的测试网站,您只需添加 Google 助理链接即可。

转到 fulfillment 的 /user-engagement-codelab-nodejs/start/public/ 目录,并在文本编辑器中打开 index.html 文件。

b2f84ff91b0e1396.pngindex.html 文件中,将 Google 助理链接的 HTML 代码段粘贴到正文元素中。该文件最终应类似于以下代码段:

index.html

<body>
    <p>
     <a href="https://assistant.google.com/services/invoke/uid/000000efb5f2fd97">🅖 Ask my test app to learn about Action Gym
     </a>
    </p>
</body>

在终端中,运行以下命令以将测试网站部署到 Firebase:

firebase deploy

部署命令运行完毕后,记下输出中的 Hosting 网址

b01e8d322fb5d623.png

在移动设备的网络浏览器中转到此网址,您应该会在测试网站上看到 Google 助理链接。在移动设备上点击此链接,您应该会转到 Google 助理中的 Action 欢迎欢迎 intent。

599845d647f5b624.png

您还可以尝试在桌面浏览器中转到 Hosting 网址,因为 Action 未发布,所以您会转到 Assistant 目录中的 404 页面。

6. 后续步骤

恭喜!

现在,您已了解开发 Action 时用户互动的重要性、平台上可用的用户互动功能,以及如何向 Action 添加各项功能。

其他学习资源

请浏览以下资源,详细了解您的 Action 用户互动情况:

欢迎关注我们的 Twitter 帐号 @ActionsOnGoogle,及时了解我们的最新公告,还可以使用标签 #AoGDevs 发布 Twitter 微博,分享您构建的成果!

反馈意见调查

离开之前,请填写此表单告诉我们您的体验。