使用 Google 助理和 Cloud Firestore 进行拼写练习游戏

1. 概览

借助 Google 助理开发者平台,您可以创建软件,在超过 10 亿台设备(包括智能音箱、手机、汽车、电视、头戴式耳机等)上扩展 Google 助理这一虚拟个人助理的功能。用户可通过对话与 Google 助理互动,以处理各种事务,例如购买日用品或约车。作为开发者,您可以使用 Google 助理开发者平台在用户和您自己的第三方执行方式服务之间轻松打造和管理愉悦、有效的对话体验。

此 Codelab 介绍了使用 Google 助理、Cloud Functions 和 Cloud Firestore 进行开发的中级概念。在此 Codelab 中,您将构建一个名为“拼写练习”的游戏,该游戏使用 Google 助理要求用户拼写字词。

构建内容

在此 Codelab 中,您将构建一个具有以下功能的复杂游戏:

  • 接收用户的拼写回复,并根据输入的值修改对话提示
  • 返回与拼写相关的提示,例如词义,或者重复该字词
  • 创建游戏循环,以便用户在拼出单词后能够再次与 Google 助理互动

开始构建之前,您可以在内置 Google 助理的设备上与实时 Action 进行互动,只需说出“Hey Google,跟拼写练习交谈”即可。回访用户通过此操作执行的默认路径如下所示:

完成此 Codelab 后,完成后的 Action 将具有以下对话流:

2e9f94dc0ceafc96.png

学习内容

  • 如何与 Cloud Firestore 交互
  • 如何使用槽向用户收集数据
  • 如何处理用户输入并返回响应
  • 如何使用条件向场景添加逻辑
  • 如何添加游戏循环

所需条件

学习此 Codelab 的前提条件包括:

  • 网络浏览器,例如 Google Chrome
  • 用于编写 Cloud Functions 的 IDE。
  • 付款方式。此 Codelab 使用的是 Cloud Functions for Firebase,因此您的项目必须采用 Firebase Blaze 定价方案(了解详情)。
  • 用于运行 shell 命令的终端
  • Node.js 10 或更高版本

2. 获取函数代码

从命令行克隆 GitHub 代码库

$ git clone https://github.com/FirebaseExtended/codelab-actions-firestore

3. 创建 Firebase 项目并设置您的应用

创建 Firebase 项目

  1. 登录 Firebase
  2. 在 Firebase 控制台中,点击添加项目(或创建项目),然后将您的 Firebase 项目命名为 Spelling-Practice

66ae8d1894f4477

  1. 点击各个项目创建选项。如果系统提示,请接受 Firebase 条款。跳过设置 Google Analytics(分析)的步骤,因为您不会为此应用使用 Google Analytics(分析)。

如需详细了解 Firebase 项目,请参阅了解 Firebase 项目

升级到 Blaze 定价方案

为了使用 Cloud Functions for Firebase,您需要将 Firebase 项目升级到 Blaze 定价方案,这意味着您需要为项目关联一个 Google Cloud Billing 帐号。为此,您需要提供信用卡或其他付款方式。

所有 Firebase 项目(包括采用 Blaze 方案的项目)仍然可以获得 Cloud Functions 的免费用量配额。此 Codelab 中介绍的步骤在免费用量限额内。不过,您会看到 Cloud Storage 收取的小额费用(约 $0.03),该服务用于托管您的 Cloud Functions 构建映像。

4.安装 Firebase CLI

您可以使用 Firebase CLI(命令行界面)部署 Cloud Functions 函数。

根据您的操作系统和使用场景,有多种安装 Firebase CLI 的选项。如果您还使用 Cloud Functions,以下步骤介绍了最常见的方法。

  1. 确保您已安装 Node.js 通常附带的 npm
  2. 通过运行以下 npm 命令安装或升级 CLI:
$ npm -g install firebase-tools
  1. 运行以下命令,验证 CLI 是否已正确安装:
$ firebase --version

确保 Firebase CLI 版本为 9.0.0 或更高版本,以便其具有 Cloud Functions 所需的全部最新功能。如果没有,请运行 npm install -g firebase-tools 进行升级,如上所示。

  1. 运行以下命令向 Firebase CLI 授权:
$ firebase login
  1. 从 scan-functions-start 目录中,设置 Firebase CLI 以使用您的 Firebase 项目。运行以下命令,选择您的项目 ID,然后按照说明操作。出现提示时,您可以选择任何别名,例如 codelab
$ firebase use --add

5. functions 目录

现在,您将使用 Firebase SDK for Cloud Functions 添加功能,为游戏拼写练习构建后端。

借助 Cloud Functions,您无需设置服务器即可在云端运行代码。此 Codelab 将向您展示如何构建响应 Firebase Authentication、Cloud Storage 和 Firebase Realtime Database 事件的函数。我们先从身份验证开始。

使用 Firebase SDK for Cloud Functions 时,您的函数代码将位于 functions 目录下(默认情况下)。为方便您操作,我们已创建了 functions/index.js 文件,供您放置代码。在继续操作之前,您随时可以检查 functions 目录。

$ cd functions
$ ls

您的函数代码也是一个 Node.js 应用,因此需要一个 package.json,用于提供应用的一些相关信息并列出依赖项。

如果您不熟悉 Node.js,进一步了解 Node.js,有助于继续完成此 Codelab。

package.json 文件已列出两个必需的依赖项:Firebase SDK for Cloud FunctionsFirebase Admin SDK。如需在本地安装这些软件包,请从 functions 目录运行 npm install

$ npm install

现在,我们来看一下 index.js 文件:

index.js

/**
 * Copyright 2021 Google Inc. All Rights Reserved.
 * ...
 */
// TODO(DEVELOPER): Import the Cloud Functions for Firebase and Firebase Admin modules here. Also import the Actions SDK here.
// TODO(DEVELOPER): Write the getWordDetailsFromDictionaryAPI function here.
// TODO(DEVELOPER): Write the createSpellingPracticeWord function here.
// TODO(DEVELOPER): Write the app Handle getSpellingWordList function here.
// TODO(DEVELOPER): Write the app Handle getSpellingWord function here.
// TODO(DEVELOPER): Write the app Handle repeatSpellingWord function here.
// TODO(DEVELOPER): Write the app Handle definitionOfSpellingWord function here.
// TODO(DEVELOPER): Write the app Handle verifySpellingWord function here.

您首先应导入所需的模块,然后编写四个函数来代替 TODO。继续执行此 Codelab 的下一步,以导入模块。

6. 导入所需的模块

此 Codelab 需要三个模块。

  • 通过 firebase-functions 模块,我们可以为 Cloud Functions 函数编写触发器
  • firebase-admin 模块允许我们在具有管理员访问权限的服务器上使用 Firebase 平台,例如向 Cloud Firestore 写入数据。
  • Actions SDK Node.js 执行方式库为 Google 助理执行 Actions SDK 处理程序。
  1. 运行以下 npm 命令以安装 Actions SDK:
$ npm install @assistant/conversation
  1. index.js 文件中,将第一个 TODO 替换为以下代码。

这些更改会导入所需的每个模块。

此外,如果将 Firebase Admin SDK 部署在 Cloud Functions 环境或其他 Google Cloud 容器中,系统也可以自动配置 Firebase Admin SDK。当我们在以下更改中调用 admin.initializeApp(); 时,就会发生这种情况。

index.js

/**
 * Copyright 2021 Google Inc. All Rights Reserved.
 * ...
 */

// Import the Actions SDK
const {conversation} = require('@assistant/conversation');
const https = require('https');
const app = conversation();
const cors = require('cors')({origin: true});

// Import the Firebase SDK for Cloud Functions.
const functions = require('firebase-functions');
// Import and initialize the Firebase Admin SDK.
const admin = require('firebase-admin');
admin.initializeApp();
// To access Cloud Firestore
const db = admin.firestore();
// TODO(DEVELOPER): Write the getWordDetailsFromDictionaryAPI function here.
// TODO(DEVELOPER): Write the createSpellingPracticeWord function here.
// TODO(DEVELOPER): Write the shuffleWordList function here.
// TODO(DEVELOPER): Write the app Handle getSpellingWordList function here.
// TODO(DEVELOPER): Write the app Handle getSpellingWord function here.
// TODO(DEVELOPER): Write the app Handle repeatSpellingWord function here.
// TODO(DEVELOPER): Write the app Handle definitionOfSpellingWord function here.
// TODO(DEVELOPER): Write the app Handle verifySpellingWord function here.

现在,我们来使用函数添加业务逻辑,以支持 Google 助理 Action。

7. 创建函数

获取单词定义并将其写入 Cloud Firestore

您将使用 dictionaryapi.dev 公共 API 来获取单词定义。

index.js 文件中,将 getWordDetailsFromDictionaryAPI 的 TODO 替换为以下代码:

index.js

// Retrieves word definition and audio pronunciation from api.dictionaryapi.dev service
// Function uses service provided by https://dictionaryapi.dev/
async function getWordDetailsFromDictionaryAPI(word) {
  let responseData="";
  let req = https.request({
    host: 'api.dictionaryapi.dev',
    port: 443,
    path:'/api/v2/entries/en/' + word,
    method:'GET'
  }, (res) => {
    res.setEncoding('utf8');
    res.on('data', d => {
        responseData+=d;
    })
    res.on('end',function(){
        let object = JSON.parse(responseData)
        const wordListRef = db.collection('wordlist');
        wordListRef.doc(object[0].word).set(
          object[0]
        );
       return responseData;
     });
  });
  req.end();
}

添加 Cloud Firestore 触发器

接下来,您将创建一个 Cloud Functions 函数,每当在 Cloud Firestore 中创建新文档时触发。它将通过我们刚才编写的 getWordDetailsFromDictionaryAPI 函数调用 dictionaryapi.dev API 来获取单词定义。

index.js 文件中,将 createSpellingPracticeWord 的 TODO 替换为以下代码:

index.js

// Firestore 触发器,通过 getWordDetailsFromDictionaryAPI 为每个新的 Firestore 文档提取单词定义

exports.createSpellingPracticeWord = functions.firestore
  .document('wordlist/{word}')
  .onCreate((snap, context) => {
    const newValue = snap.data();
    const word = newValue.word;
    getWordDetailsFromDictionaryAPI(word);
});

获取游戏单词列表

您可以编写一个 Cloud Functions 函数,用于从 Cloud Firestore 中检索 Google 助理的拼写练习字词列表。为此,我们使用应用处理程序。

index.js 文件中,将 getSpellingWordList 的 TODO 替换为以下代码。

将此函数添加到特殊的 app.handle 可以使 Google 助理访问该函数。

index.js

// Store the list of spelling words in Assistant session
app.handle('getSpellingWordList', conv => {
  const wordListRef = db.collection('wordlist').limit(50);
  const snapshot = wordListRef;

  if (snapshot.empty) {
    console.log('No matching documents.');
    return;
  }
  VocabularyList = []

  return snapshot.get().then(snapshot => {
    snapshot.forEach(doc => {
      if (doc.data().word) {
          let definition = 'unknown';
          let audio = 'unknown';
          try {
            if(doc.data().hasOwnProperty('meanings')) {
              if(doc.data().meanings[0].hasOwnProperty('definitions')) {
                  definition = doc.data().meanings[0].definitions[0].definition;
              }
            }
            if(doc.data().hasOwnProperty('phonetics')) {
              if(doc.data().phonetics.length > 0)
                audio = doc.data().phonetics[0].audio;
            }
          } catch (error) {
            console.log(error);
          }

          let obj = {
            word: doc.data().word,
            answer: doc.data().word.split("").join(" "),
            definition: definition,
            audio: audio
          }
          VocabularyList.push(obj);
      }
      // Shuffle the array
      let currentIndex = VocabularyList.length, temporaryValue, randomIndex;
      while (0 !== currentIndex) {
        randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex -= 1;
        temporaryValue = VocabularyList[currentIndex];
        VocabularyList[currentIndex] = VocabularyList[randomIndex];
        VocabularyList[randomIndex] = temporaryValue;
      }
      conv.session.params.vocabWord = VocabularyList;
      conv.session.params.vocabWordIndex = 0;
    });
  });
})

通过 Google 助理会话获取字词

您可以编写一个 Cloud Functions 函数,用于返回字词列表中的下一个拼写单词。

index.js 文件中,将 getSpellingWord 的 TODO 替换为以下代码:

index.js

// Returns a spelling practice word to Google Assistant and uses Speech Synthesis Markup Language (SSML) to format the response
app.handle('getSpellingWord',  conv => {
  if (!conv.session.params.vocabWord.empty) {
    conv.session.params.vocabWordIndex+=1;
    const ssml = '<speak>' +
    '<audio src="'+ conv.session.params.vocabWord[conv.session.params.vocabWordIndex].audio +'">Use phonetics to spell the word.</audio> ' +
    '</speak>';
    conv.add(ssml);
  }
  else
    conv.add('Great job! You completed the Spelling practice');
});

允许游戏重复猜词

您可以编写一个 Cloud Functions 函数来重复游戏的当前单词。

index.js 文件中,将 repeatSpellingWord 的 TODO 替换为以下代码:

index.js

// Returns current spelling word
app.handle('repeatSpellingWord',  conv => {
  if (!conv.session.params.vocabWord.empty) {
    const ssml = '<speak>' +
    '<audio src="'+ conv.session.params.vocabWord[conv.session.params.vocabWordIndex].audio +'">Use phonetics to spell the word. </audio> ' +
    '</speak>';
    conv.add(ssml);
  }
  else
    conv.add('Great job! You completed the Spelling practice');
});

查询字词的定义

您可以编写一个 Cloud Functions 函数来提供游戏当前单词的定义。

index.js 文件中,将 definitionOfSpellingWord 的 TODO 替换为以下代码:

index.js

// Returns spelling word definition from Assistant session parameter
app.handle('definitionOfSpellingWord',  conv => {
  conv.add( 'It means ' + conv.session.params.vocabWord[conv.session.params.vocabWordIndex].definition);
});

检查用户的拼写回复

您可以编写一个 Cloud Functions 函数来验证用户对于如何拼写游戏当前单词的回答。

index.js 文件中,将 verifySpellingWord 的 TODO 替换为以下代码:

index.js

// Verifies user spelling response
app.handle('verifySpellingWord', conv => {
  try {
    userResponse = conv.intent.params.userresponse.resolved.join("");
    if (userResponse.toLowerCase() === conv.session.params.vocabWord[conv.session.params.vocabWordIndex].word.toLowerCase()) {
      conv.add('You are correct. Say next to continue.');
    }
    else {
      conv.add('Sorry, wrong answer. The correct answer is ' + conv.session.params.vocabWord[conv.session.params.vocabWordIndex].answer + ' . Say next to continue.');
    }
  } catch (error) {
    conv.add('Sorry. I did not understand your response' );
  }
});
exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app);

部署所有函数

只有将 Cloud Functions 函数部署到 Firebase 后,这些函数才有效。

spelling-functions-start 目录的根目录运行以下命令:

$ firebase deploy --only functions

您应该会看到以下控制台输出:

i  deploying functions
i  functions: ensuring necessary APIs are enabled...
⚠  functions: missing necessary APIs. Enabling now...
i  env: ensuring necessary APIs are enabled...
⚠  env: missing necessary APIs. Enabling now...
i  functions: waiting for APIs to activate...
i  env: waiting for APIs to activate...
✔  env: all necessary APIs are enabled
✔  functions: all necessary APIs are enabled
i  functions: preparing functions directory for uploading...
i  functions: packaged functions (X.XX KB) for uploading
✔  functions: functions folder uploaded successfully
i  starting release process (may take several minutes)...
i  functions: creating function createSpellingPracticeWord(us-central1)...
✔  functions[createSpellingPracticeWord(us-central1)]: Successful create operation.
i  functions: creating function ActionsOnGoogleFulfillment(us-central1)...
✔  functions[ActionsOnGoogleFulfillment(us-central1)]: Successful create operation.

✔  Deploy complete!
Project Console: https://console.firebase.google.com/project/spelling-practice-1234/overview

记下 ActionsOnGoogleFulfillment 函数 HTTP 端点网址以供日后使用。如需获取端点,请打开 Firebase 控制台,然后点击 spelling-practice 项目。打开 Functions 信息中心以查看函数端点。

332cb0437411a242

您已完成添加所有必需的函数。现在开始设置 Cloud Firestore。

8. 启用 Cloud Firestore

您需要启用 Cloud Firestore。

在 Firebase 控制台的构建部分中,点击 Firestore。然后,点击创建数据库

5c0b4abf4410ffcf.png

对 Cloud Firestore 中数据的访问权限由安全规则控制。首先,您需要对数据设置一些基本规则,然后才能开始操作。点击“Firestore”,然后在 Firebase 控制台的“规则”标签页中添加以下规则,然后点击发布

以下规则将数据访问权限限制为已登录的用户,从而防止未经身份验证的用户执行读取或写入操作。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      //
      // WARNING: These rules are insecure! We will replace them with
      // more secure rules later in the codelab
      //
      allow read, write: if request.auth != null;
    }
  }
}

9. 向 Cloud Firestore 添加字词拼写数据

在此步骤中,您要将拼写字词数据写入 Cloud Firestore,以便您可以为 Google 助理(和游戏)生成字词列表。

Cloud Firestore 数据结构化为集合、文档、字段和子集合。游戏的每个单词都会以自己的文档的形式存储在名为 wordlist 的顶级集合中。对于 Firestore 集合中的每个新文档,系统将触发 createAssigningPracticeWord 函数,以便从 Dictionary API 服务中获取字词详细信息。

创建 Cloud Firestore 集合

  1. 在 Firebase 控制台中,前往 Cloud Firestore 部分。
  2. 点击 + 开始收集
  3. 集合 ID 文本框中,输入 wordlist,然后点击下一步

1b4ccadb90f52f02.png

接下来,我们将为以下字词创建一个文档:agreement

  1. 文档 ID 文本框中,输入 agreement
  2. 字段文本框中输入 word,然后在文本框中输入 agreement
  3. 点击保存

379037e011e8511e

将此文档添加到 Cloud Firestore 后,它会触发您的 createOverrideingPracticeWord 函数来提取该字词的定义详情。通过为每个字词创建新文档来添加更多字词(例如:“敬畏”“汽车”“true”“告诉”“更好”“通勤”...)。

10. 设置 Google 助理

下面几部分将介绍如何设置 Google 助理开发环境和创建 Actions 项目。

检查 Google 权限设置

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

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

c988e1e639e6d6e1.png

创建一个 Actions 项目

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

  1. 打开 Actions 控制台
  2. 点击 New project
  3. 接受服务条款

b174d45710b8086b.png

  1. 输入或选择您使用 Firebase 控制台创建的 spelling-practice-codelab。(此名称供内部参考。稍后,您可以为项目设置外部名称。)

a2951de5d2001fac.png

  1. 点击 Import project
  2. What kind of Action do you want to build? 屏幕中,选择 Custom 卡片。
  3. 点击下一步
  4. 选择 Blank project 卡片。
  5. 点击 Start building
  6. 输入拼写练习作为显示名称,然后点击“保存”。

用户通过调用与您的 Action 开始对话。例如,用户可以通过说出类似于“Hey Google, talk to 拼写练习”这样的指令来调用您的 Action,其中“拼写检查练习”是显示名。

如果您想将 Action 部署到生产环境中,则必须具有显示名。不过,您无需定义显示名即可测试 Action。相反,您可以在模拟器中使用短语“Talk to my test app”来调用您的 Action。

配置 fulfillment

您需要将在本 Codelab 前面部分编写和部署的 Cloud Functions 函数的事件处理程序连接到 Google 助理。

如需配置执行方式,请按以下步骤操作:

  1. 点击侧边导航栏中的 Webhook
  2. 选择 Https 端点作为执行方式选项:

d523bf003e96e66f

  1. HTTPs 端点文本框中输入函数端点的网址,然后点击保存

be53e2cd0d914d54

在下一部分中,您将在 Actions 控制台中自定义主调用的提示。

设置主调用

您必须修改主调用,才能定义在用户调用您的 Action 后会发生的情况。

默认情况下,Actions Builder 会在调用触发时提供通用提示(“Start building your Action by creating main invocation.”)。

如需修改在用户调用您的 Action 时您的 Action 向用户发回的提示,请按以下步骤操作:

  1. 点击导航栏中的 Main invocation

9ff088c04c995cde

  1. 勾选 Call your webhook 并在文本框中添加事件处理脚本名称 getSpellingWordList
  2. 在代码编辑器中,将 speech 字段中的文本替换为以下欢迎辞:Welcome to Spelling Practice

注意:您可以使用 YAMLJSON 格式修改提示。

  1. 点击保存

在模拟器中测试主调用

Actions 控制台提供了一个名为“模拟器”的 Web 工具,用于测试您的 Action。该界面会模拟硬件设备及其设置,因此您可以与您的 Action 对话,就像在智能显示屏、手机、音箱或 KaiOS 上运行一样。

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

  1. 在顶部导航栏中,点击 Test 以转到模拟器。
  2. 如需在模拟器中调用您的 Action,请在左上方的输入字段中输入 Talk to Spelling Practice,然后按键盘上的 Enter 键。

651fc8da1ac9aa0a

触发 Action 的主调用后,Google 助理会使用您的自定义欢迎消息进行响应。此时,对话会在 Google 助理使用问候语做出响应后结束。

查看事件日志

Test 标签页中,右侧面板会显示事件日志,这些日志会将对话记录显示为事件日志。每个事件日志都会显示在这轮对话期间发生的事件。要查看事件日志,请点击事件前面的灰色图标。

您的 Action 目前有一个事件日志,其中既会显示用户的输入(“Talk to 拼写练习”)以及您的 Action 响应,以下屏幕截图显示了该 Action 的事件日志:

a6fb192f94426824

11. 为拼写练习构建对话

现在,您已经定义了用户调用您的 Action 后会发生的情况,接下来可以构建 Action 对话的其余部分了。拼写练习包含 4 个场景,您必须先激活每个场景,然后才能运行该场景。激活场景的最常用方法是配置 Action,以便在用户匹配场景中的用户 intent 时,该 intent 会触发向另一个场景的过渡并激活该场景。

从主调用过渡到起始场景

在本部分中,您将创建一个名为 Start 的新场景,该场景会向用户发送提示,询问他们是否想要开始玩拼写练习。您还可以添加从主调用到新 Start 场景的过渡。

如需创建此场景并为其添加过渡效果,请按以下步骤操作:

  1. 点击顶部导航栏中的 Develop。然后,点击左侧导航栏中的 Main invocation
  2. 在右侧的 Transition 部分中,点击下拉菜单,然后在文本字段中输入 Start

dd4f1807a57f794d.png

  1. 点击 Add(添加)。这会创建一个名为 Start 的场景,并告知 Action 在向用户传递欢迎提示后过渡到 Start 场景。
  2. 点击左侧导航栏中的 Scenes 以显示场景列表。
  3. Scenes 下,点击 Start 以查看 Start 场景。
  4. 点击 Start 场景的 On enter 部分中的 +
  5. 选择 Send prompts
  6. speech 字段中的句子 (Enter the response that users will see or hear...) 替换为向用户询问的问题:Use phonetic alphabet to spell the word. For example alpha for a, bravo for b, charlie for c etc. Do you want to continue?

建议内容信息卡可为用户提供可点击的建议,您的 Action 会将这类建议作为用户输入进行处理。在本部分中,您将添加建议内容信息条,该信息块会显示在您刚刚配置的提示 (Do you want to play) 下方

Spelling Practice

?)以支持使用屏幕设备的用户。

如需将建议内容信息条添加到 Start 场景的提示,请按以下步骤操作:

  1. Start 场景中,点击代码编辑器下方的建议。此操作会添加单个建议内容信息卡。
  2. title 字段中,将 Suggested Response 替换为 'Yes'
  3. 使用相同的格式手动添加标题为“'No'”和“'Help with Phonetics'”的建议条状标签。您的代码应如以下代码段所示:
  4. 点击保存

5ff2ecdc56801b91.png

在模拟器中测试您的 Action

此时,您的 Action 应该从主调用过渡到 Start 场景,并询问用户是否要继续。模拟显示内容中也应该会显示建议内容信息条。

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

  1. 在导航栏中,点击 Test 以转到模拟器。
  2. 如需在模拟器中测试您的 Action,请在“Input”字段中输入 Talk to Spelling Practice
  3. Enter 键。您的 Action 应该会以 Main invocation 提示和添加的 Start 场景提示“Welcome to 拼写练习”使用拼音字母拼写单词。例如,用 alpha 表示 a,用 bravo 表示 b,用 charlie 表示 c,等等。要继续吗?"

以下屏幕截图显示了此互动:

338c9570b02a618e

  1. 点击 YesNoHelp with Phonetics 建议内容信息卡以回应提示。(您也可以说语音留言帮助,或在输入字段中输入 YesNoHelp with Phonetics。)

当您回应提示后,您的 Action 会返回一条消息,指明其无法理解您的输入:“Sorry, I didn't catch that. Can you try again?”由于您尚未配置 Action 使其能够理解和响应“Yes”或“No”输入,因此该 Action 会将您的输入与 NO_MATCH intent 进行匹配。

默认情况下,NO_MATCH 系统 intent 会提供通用响应,但您可以自定义这些响应,向用户表明您无法理解他们的输入。如果无法匹配用户输入的次数达到 3 次,Google 助理就会结束用户与 Action 的对话。

添加“否”意图和拼音 intent

现在,用户可以回复您的 Action 提出的问题了,接下来,您可以配置该 Action,使其能够理解用户的回复(“Yes”或“No”或“Help with Voicetics”)。在以下各部分中,您将创建在用户说出“是”、“否”或“拼音帮助”时匹配的用户 intent,并将这些 intent 添加到 Start 场景中。我们将使用系统 intent yes,并将创建其他 intent。

创建 no intent

现在,您需要创建 no intent,以便在用户不想玩游戏时了解并响应用户。如需创建此 intent,请按以下步骤操作:

  1. 点击导航栏中的开发
  2. 点击导航栏中的 Custom intents 以打开 intent 列表。
  3. 点击 intent 列表末尾的 +(加号)。将新 intent 命名为 no,然后按 Enter 键。
  4. 点击 no 以打开 no intent 页面。
  5. 添加训练短语 (Add training languages) 部分中,点击输入短语 (Enter Phrase) 文本框,然后输入以下短语:
  • No
  • N
  • I don't want
  • nope

98b0c9a7b67ea9b9

  1. 点击保存

Start 场景添加 no intent

现在,当用户表达“no”或类似于“no”的内容(例如“nope”)时,该 Action 可以正确理解。您需要将 no 用户 intent 添加到 Start 场景,因为用户正在响应 Start 提示(“欢迎使用拼写练习。使用拼音字母拼写单词。

如需为 Start 场景添加此 intent,请按以下步骤操作:

  1. 点击导航栏中的 Start 场景。
  2. Start 场景中,点击“User intenthandling”(用户 intent 处理)旁边的 +(加号)
  3. Intent 部分中,从下拉菜单中选择 no

51f752e78c8b4942

  1. 点击 Send prompts,然后将 speech 字段更新为以下文本:Good Bye

编辑器中的代码应如以下代码段所示:

candidates:
  - first_simple:
      variants:
        - speech: >-
             Goodbye.
  1. Transition 部分中,从下拉菜单中选择 End speech
  2. 点击保存

在模拟器中测试 no intent

此时,您的 Action 可以理解用户何时不想玩游戏,并返回相应的响应。

如需在模拟器中测试此 intent,请按以下步骤操作:

  1. 在导航栏中,点击 Test
  2. 在输入字段中输入 Talk to Spelling Practice,然后按 Enter
  3. Input 字段中输入 No,然后按 Enter 键。或者,点击“No”(否)建议内容信息卡。

7727a456b522f31b

Start 场景添加了系统 YES intent

现在,我们将 SYSTEM intent "YES" 添加到 Start 场景中,因为用户对 Start 提示(“欢迎加入拼写练习使用拼音字母拼写单词。

如需将此用户 intent 添加到 Start 场景,请按以下步骤操作:

  1. 点击导航栏中的 Start 场景。
  2. Start 场景中,点击 User intentHandling(用户 intent 处理)旁边的 +(加号)
  3. 在“所有系统 intent”下,从 intent 下拉菜单中选择 YES

f6cbe789cde49e8f

  1. 点击 Call your webhook,然后使用您之前创建的函数更新 event handler 文本框:getSpellingWordList
  2. Transition 部分中,点击下拉菜单,然后选择 End 会话
  3. 点击保存

在模拟器中测试 YES intent

此时,您的 Action 可以理解用户何时想要玩游戏,并返回相应的响应。

如需在模拟器中测试此 intent,请按以下步骤操作:

  1. 在导航栏中,点击 Test
  2. 如需在模拟器中测试您的 Action,请在 Input 字段中输入 Talk to Spelling Practice,然后按 Enter 键。
  3. Input 字段中输入 Yes,然后按 Enter 键。或者,点击 Yes 建议内容信息卡。

您的 Action 会获取所有拼写练习字词的列表,并将其存储在会话中。然后,您的 Action 会结束会话,因为您为 YES intent 选择了 End conversation 过渡。

创建 Phonetics intent

如需创建 Phonetics intent,请按以下步骤操作:

  1. 点击导航栏中的开发
  2. 点击导航栏中的 Custom intents 以打开 intent 列表。
  3. 点击 intent 列表末尾的 +(加号)。将新 intent 命名为 phonetics,然后按 Enter
  4. 点击 phonetics intent 以打开 phonetics intent 页面。
  5. 在“添加训练短语”部分中,点击输入短语文本框并输入以下短语:
  • how do I spell words
  • phonetics
  • help me with phonetics
  • phonetic alphabet

1455bdfca8dae46

  1. 点击保存

Start 场景添加 phonetics intent

现在,当用户表达“拼音”intent 时,该 Action 就可以理解了。您可以将 phonetics 用户 intent 添加到 Start 场景,因为用户正在响应 Start 提示(“欢迎学习拼写练习。使用拼音字母拼写单词。

如需将此用户 intent 添加到 Start 场景,请按以下步骤操作:

  1. 点击导航栏中的 Start 场景。
  2. Start 场景中,点击“User intenthandling”(用户 intent 处理)旁边的 +(加号)。
  3. 在 intent 下拉菜单中选择 phonetics

67ee2e08000b2aee

  1. Transition 部分中,点击下拉菜单,然后选择 End 会话
  2. 点击保存

从开始场景过渡到拼写场景

在本部分中,您将创建一个名为拼写的新场景,该场景会提示用户使用拼音字母拼写字词。

如需创建此场景并为其添加过渡效果,请按以下步骤操作:

  1. 点击顶部导航栏中的 Develop。然后,点击左侧导航栏中的 Start 场景。
  2. User intenthandling [用户 intent 处理] 部分,点击 when actions.intent.YES is matched,然后在 transition 部分中点击右侧的下拉菜单,然后在文本字段中输入 Spelling
  3. 点击 Add(添加)。这会创建一个名为 Spelling 的场景,并告知 Action 在匹配后通过 YES intent 过渡到 Spelling 场景。
  4. 展开左侧导航栏中的 Scenes 以显示场景列表。
  5. Scenes 下,点击 拼写 以查看 Spelling 场景。
  6. 点击 Spelling 场景的 On enter 部分中的 +
  7. 点击 Call your webhook,然后在事件处理脚本文本框中输入 getpelingWord
  8. 选择 Send prompts
  9. speech 字段 (Enter the response that users will see or hear...) 中的句子替换为 {}。实际提示将由 webhook 填充。

建议内容信息卡可为用户提供可点击的建议,您的 Action 会将这类建议作为用户输入进行处理。

如需将建议内容信息条添加到 Spelling 场景的提示,请按以下步骤操作:

  1. Spelling 场景中,点击代码编辑器下方的建议。此操作会添加三个建议内容信息卡。
  2. title 字段中,将 Suggested Response 替换为 'Repeat'
  3. 使用相同的格式手动添加标题为“'Skip'”的建议条状标签。
  4. 使用相同的格式手动添加标题为“'Quit'”的建议条状标签。您的代码应如以下代码段所示:
  5. 点击保存
suggestions:
      - title: 'Repeat'
      - title: 'Skip'
      - title: 'Quit'

e1d437f714ea1539

创建 Repeat intent

如需创建 repeat intent,请按以下步骤操作:

  1. 点击导航栏中的开发
  2. 点击导航栏中的 Custom intents 以打开 intent 列表。
  3. 点击 intent 列表末尾的 +(加号)。将新 intent 命名为 repeat,然后按 Enter
  4. 点击 repeat intent 以打开 definition intent 页面。
  5. 添加训练短语 (Add Training Directive) 部分中,点击 Enter Phrase 文本框,然后输入以下短语:
  • one more time please
  • say the word again
  • repeat the word
  • tell me again
  • repeat

e61f0b9f80510bc9

  1. 点击保存

Spelling 场景添加 repeat intent

现在,当用户表达“重复” intent 时,该 Action 就可以正确理解了。您可以将 repeat 用户 intent 添加到 Spelling 场景,因为用户是对 Spelling 提示(“使用拼音字母拼写字词”)做出响应。

如需将此用户 intent 添加到 Spelling 场景,请按以下步骤操作:

  1. 点击导航栏中的拼写场景。
  2. Spelling 场景中,点击 User intentHandling(用户 intent 处理)旁边的 +(加号)
  3. 在 intent 下拉菜单中选择 repeat

5cfd623b25bedbed

  1. 选中 Call your webhook,然后在事件处理脚本文本框中输入 repeat 拼写检查 Word 以获取字词定义。
  2. 选中发送提示
  3. speech 字段 (Enter the response that users will see or hear...) 中的句子替换为“”。实际提示将由 webhook 填充。

将建议内容信息条添加到“当与重复项匹配时”

  1. 在“用户 intent 处理”下的“当重复匹配时”中,点击代码编辑器下方的建议。此操作会添加三个建议内容信息卡。
  2. title 字段中,将 Suggested Response 替换为 'Skip'
  3. 使用相同的格式,手动添加标题为“'Quit'”的建议条状标签。您的代码应类似于以下代码段:
suggestions:
      - title: 'Skip'
      - title: 'Quit'

ab40e4b0c432b97c

  1. 点击保存

创建 definition intent

如需创建 definition intent,请按以下步骤操作:

  1. 点击导航栏中的开发
  2. 点击导航栏中的 Custom intents 以打开 intent 列表。
  3. 点击 intent 列表末尾的 +(加号)。将新 intent 命名为 definition,然后按 Enter
  4. 点击 definition intent 以打开 definition intent 页面。
  5. 添加训练短语 (Add Training Directive) 部分中,点击 Enter Phrase 文本框,然后输入以下短语:
  • I would like to know the definition
  • tell me the definition
  • what does it mean
  • meaning
  • definition
  • what is the definition?

c1b88a9c0b1ac082

  1. 点击保存

Spelling 场景添加 definition intent

现在,当用户表达“定义” intent 时,该 Action 就可以理解了。您可以将 definition 用户 intent 添加到 Spelling 场景,因为用户是对 Spelling 提示(“使用拼音字母拼写字词”)做出响应。

如需将此用户 intent 添加到 Spelling 场景,请按以下步骤操作:

  1. 点击导航栏中的拼写场景。
  2. Spelling 场景中,点击 User intentHandling(用户 intent 处理)旁边的 +(加号)
  3. 在 intent 下拉菜单中选择定义

646bdcac3ad3eb0c.png

  1. 选中 Call your webhook,然后在事件处理脚本文本框中输入 definitionOfPitchingWord 即可获取字词定义。
  2. 选中发送提示
  3. speech 字段 (Enter the response that users will see or hear...) 中的句子替换为“‘’。实际提示将由 webhook 填充。

向网络钩子响应添加建议内容信息卡

  1. Start 场景中,点击代码编辑器下方的 suggestions。此操作会添加三个建议内容信息卡。
  2. title 字段中,将 Suggested Response 替换为 'Skip'
  3. 使用相同的格式,手动添加标题为“'Quit'”的建议条状标签。您的代码应类似于以下代码段:
suggestions:
      - title: 'Skip'
      - title: 'Quit'

25227545839d933f.png

  1. 点击保存

创建 skip intent

如需创建 skip intent,请按以下步骤操作:

  1. 点击导航栏中的开发
  2. 点击导航栏中的 Intents 以打开 intent 列表。
  3. 点击 intent 列表末尾的 +(加号)。将新 intent 命名为 skip,然后按 Enter
  4. 点击 skip intent 以打开 skip intent 页面。
  5. 添加训练短语 (Add Training Directive) 部分中,点击 Enter Phrase 文本框,然后输入以下短语:
  • next word
  • go next
  • next
  • skip
  • skip word

d1c4908a3d7882f8.png

  1. 点击保存

Spelling 场景添加 Skip intent

现在,当用户表达“skip” intent 时,该 Action 就可以正确理解了。您可以将 skip 用户 intent 添加到 Spelling 场景,因为用户是对 Spelling 提示(“使用拼音字母拼写字词”)做出响应。

如需将此用户 intent 添加到 Spelling 场景,请按以下步骤操作:

  1. 点击导航栏中的拼写场景。
  2. Spelling 场景中,点击 User intent Handlin 旁边的 +(加号)
  3. 在 intent 下拉菜单中选择 skip

5465f97542217964

  1. 在右侧的 Transition 部分中,点击下拉菜单,然后选择 Spelling

c8072485ca82bd3f

  1. 点击保存

创建 quit intent

如需创建 Quit intent,请按以下步骤操作:

  1. 点击导航栏中的开发
  2. 点击导航栏中的 Intents 以打开 intent 列表。
  3. 点击 intent 列表末尾的 +(加号)。将新 intent 命名为 Quit,然后按 Enter
  4. 点击 Quit intent 以打开定义 intent 页面。
  5. 添加训练短语 (Add Training Directive) 部分中,点击 Enter Phrase 文本框,然后输入以下短语:
  • I quit
  • Goodbye
  • Cancel
  • Exit
  • Quit

9916f77b8766541e

  1. 点击保存

Spelling 场景添加 Quit intent

现在,当用户表达“quit”intent 时,该 Action 便可以正确理解了。您可以将 quit 用户 intent 添加到 Spelling 场景,因为用户是对 Spelling 提示(“使用拼音字母拼写字词”)做出响应。

如需将此用户 intent 添加到 Spelling 场景,请按以下步骤操作:

  1. 点击导航栏中的拼写场景。
  2. Spelling 场景中,点击 User intentHandling(用户 intent 处理)旁边的 +(加号)
  3. 在 intent 下拉菜单中选择 quit

5f62fb18a3653d66.png

  1. 在右侧的 Transition 部分中,点击下拉菜单,然后选择 End conversation1ffbe35a7bbbb4b0
  2. 点击保存

创建 phonetic_alphabet 类型

在本部分中,您将创建一个名为 phonetic_alphabet 的新类型,用于指定用户可以选择的拼音字母选项。您还可以为这些选项定义几个同义词,以防用户说出类似的内容。在后续部分中,您将 phonetic_alphabet 类型添加到某个槽中,以指明您想要获取用户响应。

如需创建 phonetic_alphabet 类型,请按以下步骤操作:

  1. 点击导航栏中的开发
  2. 点击 Types 下的 +(加号)
  3. 输入 phonetic_alphabet,然后按 Enter
  4. 点击 phonetic_alphabet 打开选项。
  5. 此类型支持哪些值?部分,选择字词和同义词选项
  6. 添加条目部分中输入以下条目和相应的值:

alpha、apple、阿姆斯特丹

b

好极了,黄油,巴尔的摩

查理、猫、卡萨布兰卡

delta、dog、丹麦

e

echo、edward、edison

f

foxtrot、fox、佛罗里达州

g

高尔夫、乔治、加里波利

小时

酒店,哈利,哈瓦那

印度、墨水、意大利

J

朱丽叶、约翰尼、耶路撒冷

kilo、king、kilogramme

利马、爱情、伦敦

分钟

mike、money、马达加斯加

n

十一月、纽约、南希

奥斯卡、奥兰治、奥斯陆

爸爸, 巴黎, 彼得

q

魁北克、皇后

romeo、roma、robert

sierra, sugar, santiago

探戈、汤米、三国

u

制服, 雨伞, 叔叔

v

维克托、醋、瓦伦西亚

威士忌、威廉、华盛顿

X 光

洋基、黄、约克

祖鲁、斑马、苏黎世

您的键值对表应如下所示:

5b5a5cd9fa557e1b

  1. 点击保存

配置槽填充

接下来,您需要在拼写场景中配置槽填充。如需配置槽填充逻辑,请按以下步骤操作:

  1. 点击导航栏中的拼写场景。
  2. 点击 Spelling 场景中的 +(加号),以选择槽填充
  3. Enter slot name 字段中,添加 userresponse 作为槽名称。
  4. Select type 下拉列表中,选择 phonetic_alphabet 作为槽类型。
  5. 选中 This slotaccept a list of values
  6. 选中 This slot is required
  7. 选择自定义广告位值回写选项,然后在会话参数文本框中输入用户响应。

ba57a419877a07f3

  1. 点击保存

Spelling 屏幕添加条件

如需向 Spelling 场景添加 Condition,请按以下步骤操作:

  1. 点击导航栏中的拼写场景。
  2. Spelling 场景中,点击“条件”旁边的 +(加号)
  3. 输入 scene.slots.status == "FINAL" 作为条件
  4. 选中 Call your webhook,并在事件处理脚本文本框中输入 verifysmtpingWord 以验证用户响应。
  5. 选中发送提示
  6. speech 字段 (Enter the response that users will see or hear...) 中的句子替换为 {}。实际提示将由 webhook 填充。

向网络钩子响应添加建议内容信息卡

  1. Start 场景中,点击代码编辑器下方的 suggestions。此操作会添加三个建议内容信息卡。
  2. title 字段中,将 Suggested Response 替换为 'Next'
  3. 使用相同的格式,手动添加标题为“'Quit'”的建议条状标签。您的代码应类似于以下代码段:
suggestions:
      - title: 'Next'
      - title: 'Quit'

ac3d7a9366ebc1b1

  1. 点击保存

12. 在模拟器中测试拼写练习

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

  1. 在导航栏中,点击 Test 以转到模拟器。
  2. 如需在模拟器中测试您的 Action,请在“Input”字段中输入 Talk to Spelling Practice
  3. Enter 键。您的 Action 应该会以 Main invocation 提示和添加的 Start 场景提示“Welcome to 拼写练习”使用拼音字母拼写单词。例如,用 alpha 表示 a,用 bravo 表示 b,用 charlie 表示 c,等等。要继续吗?"
  4. 以继续
  5. 模拟器会播放文字发音进行拼写
  6. 您可以使用拼音字母拼写单词。例如,要想获得更好的效果,请说出或输入“bravo echo tango tango echo romeo”
  7. 模拟器将给出正确或错误的回复。
  8. 下一步可继续播放下一个单词,或者说退出即可退出游戏循环。

13. 恭喜

恭喜,您已成功构建自己的拼写练习

现在,您已了解使用 Cloud Firestore、Cloud Functions 和 Google 助理 Action Builder 构建游戏所需的关键步骤。

所学内容

  • 如何与 Cloud Firestore 交互
  • 如何使用槽向用户收集数据
  • 如何处理用户输入并返回响应
  • 如何使用条件向场景添加逻辑
  • 如何添加游戏循环

其他学习资源

您可以探索以下资源,了解如何构建适用于 Google 助理的 Action:

清理项目 [推荐]

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

  1. 如需删除 Firebase 项目和资源,请完成关停(删除)项目部分中列出的步骤。

注意:请务必在 Google Cloud 控制台的设置页面上选择正确的要删除的项目。

  1. 可选:如需立即从 Actions 控制台中移除您的项目,请完成删除项目部分中列出的步骤。如果您没有完成此步骤,您的项目将在大约 30 天后自动移除。

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