使用 Actions Builder 為 Google 助理建構互動式畫布動作

1. 總覽

Actions on Google 是開發人員平台,可讓您建立軟體,擴充 Google 助理 (Google 的虛擬個人助理) 的功能,並在超過 10 億部裝置上使用,包括智慧音箱、手機、汽車、電視、耳機等。使用者可以透過與 Google 助理對話來完成各種工作,例如購買雜貨或預約叫車。如需目前可執行的完整動作清單,請參閱動作目錄。開發人員可以使用 Actions on Google,輕鬆建立及管理使用者與第三方服務之間的對話式體驗,提供實用又愉快的互動。

本程式碼實驗室是進階單元,適合已有建構 Google 助理動作經驗的讀者。如果您先前沒有使用 Actions on Google 的開發經驗,請先完成入門程式碼實驗室 ( 第 1 級和第 2 級),熟悉這個平台。這些單元將引導您完成一系列功能,協助您擴充動作功能並拓展目標對象。

在本程式碼實驗室中,您將使用 Interactive Canvas (以 Google 助理為基礎建構的架構),在對話動作中加入全螢幕遊戲。這款遊戲是互動式網頁應用程式,Google 助理會在對話中傳送給使用者。使用者可以透過智慧螢幕和 Android 行動裝置,使用語音或文字輸入來玩遊戲。

您不必自行建構整個遊戲,而是部署部分預先建構的遊戲「Snow Pal」,並在進行程式碼實驗室時新增遊戲邏輯。Snow Pal 是傳統猜單字遊戲的變體,遊戲會顯示代表單字的空格,你必須猜測單字中可能包含的字母。每猜錯一次,雪人就會融化一點。只要在雪人完全融化前猜出單字,就能贏得遊戲。

af9931bb4d507e39.png

圖 1. 尚未完成的雪友遊戲

建構項目

在本程式碼研究室中,您將建構使用互動式畫布的動作。您的動作將具備下列功能:

  • 使用者可透過語音進行的全螢幕文字遊戲
  • 使用者按下後可開始遊戲的按鈕
  • 使用者可按下按鈕,再次玩遊戲

完成本程式碼實驗室後,動作將具備下列對話流程:

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.

使用者會繼續猜字母或猜未知字詞,直到遊戲結束。

課程內容

  • 如何建構及部署互動式 Canvas 動作
  • 如何根據使用者的語音和觸控輸入內容更新文字遊戲
  • 如何使用不同方法將資料傳遞至網頁應用程式
  • 如何對互動式 Canvas 動作進行偵錯

軟硬體需求

本程式碼實驗室的必要條件如下:

強烈建議您熟悉 JavaScript (ES6),以便瞭解本程式碼實驗室使用的程式碼。

選用:取得完整程式碼範例

在本程式碼實驗室中,您將從不完整的版本逐步建構範例。您也可以視需要從 GitHub 存放區取得完整的範例。

2. Interactive Canvas 簡介

Interactive Canvas 是以 Google 助理為基礎建構的架構,可讓您在對話動作中加入全螢幕視覺效果和動畫。

使用互動式畫布的動作與一般對話動作類似。不過,互動式畫布動作還能傳送回應給裝置,開啟全螢幕網頁應用程式。

使用者透過語音或觸控方式向網頁應用程式提供輸入內容,直到對話結束。

fa63a599f215aa81.gif

圖 2. 使用 Interactive Canvas 建構的動作。

在本程式碼實驗室中,專案分為以下三個主要部分:

  • 網頁應用程式:網頁應用程式檔案包含網頁應用程式視覺效果和動畫的程式碼,以及根據使用者輸入內容更新網頁應用程式的邏輯。
  • 對話動作:對話動作包含對話邏輯,可辨識、處理及回應使用者的輸入內容。
  • Webhook:Webhook 會處理遊戲邏輯。在本程式碼實驗室中,您可以將 Webhook 視為遊戲伺服器。

在本程式碼實驗室的每個部分,您都會修改網頁應用程式、對話動作和 Webhook,為互動式畫布動作新增功能。

大致來說,Snow Pal 動作中的對話動作、Webhook 和網頁應用程式會以下列方式運作:

  1. 對話動作會提示使用者猜測字詞中的字母或整個字詞。
  2. 使用者在智慧螢幕上對 Snow Pal 網頁應用程式說「我猜是字母 i」。
  3. 使用者的輸入內容會轉送至對話動作,該動作是在 Actions Builder 和/或 Actions SDK 專案中定義。
  4. 對話動作會處理使用者的輸入內容,並根據輸入內容,觸發 Webhook 中的邏輯來更新網頁應用程式,或傳送中繼資料來直接更新網頁應用程式。
  5. 網頁應用程式會更新,顯示字母在字詞中的位置,並要求使用者再次猜測。

如要進一步瞭解 Interactive Canvas 的運作方式,請參閱「瞭解 Interactive Canvas 基礎架構」一節。瞭解基本概念後,即可開始設定本程式碼實驗室的環境。

3. 設定

檢查 Google 權限設定

如要測試您為本程式碼實驗室建構的動作,請啟用必要權限,讓 Actions 主控台模擬器存取您的動作。如要啟用權限,請按照下列步驟操作:

  1. 前往活動控制項。
  2. 視需要登入 Google 帳戶。
  3. 啟用下列權限:
  • 網路和應用程式活動
  • 在「網路和應用程式活動」下方,勾選「包括 Chrome 歷史記錄,以及採用 Google 服務的網站、應用程式和裝置上的活動記錄」核取方塊。

安裝 gactions 指令列介面

在本程式碼研究室中,您將使用 gactions 指令列介面 (CLI) 工具,在 Actions 控制台和本機檔案系統之間同步處理 Actions 專案。

如要安裝 gactions CLI,請按照「安裝 gactions 指令列工具」一節中的操作說明進行。

安裝 Firebase 指令列介面

Firebase 指令列介面 (CLI) 可讓您將動作專案部署至 Cloud Functions,並託管網頁應用程式。

本程式碼實驗室會使用 npm 安裝 Firebase CLI。請務必安裝 npm,這通常隨附於 Node.js。

  1. 如要安裝或升級 CLI,請開啟終端機並執行下列 npm 指令:
npm install -g firebase-tools
  1. 執行下列指令,確認 CLI 是否正確安裝:
firebase --version

請確認 Firebase CLI 版本為 8 以上,才能使用 Cloud Functions 所需的所有最新功能。如果不是,請執行 npm install -g firebase-tools 進行升級。

  1. 執行下列指令,登入 Firebase:
firebase login

登入 Firebase 時,請務必使用建立動作專案時所用的 Google 帳戶。

複製存放區

在本節中,您將複製本程式碼實驗室所需的檔案。如要取得這些檔案,請按照下列步驟操作:

  1. 開啟終端機,並切換至您通常用來儲存程式碼專案的目錄。如果沒有,請切換至主目錄。
  2. 如要複製這個存放區,請在終端機中執行下列指令:
git clone https://github.com/actions-on-google/actions-builder-canvas-codelab-nodejs

開啟 start/ 目錄。這個存放區包含下列重要目錄,您將會用到:

  • public/:這個目錄包含網頁應用程式的 HTML、CSS 和 JavaScript 程式碼。
  • sdk/custom/:這個目錄包含對話動作的邏輯 (場景、意圖和類型)。
  • sdk/webhooks/:這個目錄是 Webhook,包含遊戲邏輯。

4864e8047bb2c8f6.png

圖 3. start 目錄程式碼的結構。

4. 設定動作專案

在本節中,您將建立及設定動作專案、使用 gactions CLI 將複製存放區中的程式碼推送至 Actions 主控台,以及部署網頁應用程式和 Webhook。

建立動作專案

Actions 專案是動作的容器。如要為這個程式碼實驗室建立動作專案,請按照下列步驟操作:

  1. 開啟 Actions 主控台。
  2. 按一下 [新專案]。
  3. 輸入專案名稱,例如 canvas-codelab。這個名稱僅供內部參考,之後,您可以為專案設定外部名稱。

7ea69f1990c14ed1.png

  1. 按一下 [Create Project]。
  2. 在「What kind of Action do you want to build?」畫面中,選取「Game」資訊卡。
  3. 點選 [下一步]。
  4. 選取「空白專案」資訊卡。
  5. 按一下「Start building」(開始建構)。

儲存動作的專案 ID

專案 ID 是動作的專屬 ID。本程式碼實驗室有幾個步驟會用到專案 ID。

如要擷取專案 ID,請按照下列步驟操作:

  1. 在 Actions 控制台中,依序點選三個垂直點 >「Project settings」(專案設定)。

6f59050b85943073.png

  1. 複製專案 ID。

連結帳單帳戶

如要在本程式碼實驗室稍後使用 Cloud Functions 部署執行要求,您必須將帳單帳戶與 Google Cloud 中的專案建立關聯。如果您已有帳單帳戶,可以忽略下列步驟。

如要將帳單帳戶與專案建立關聯,請按照下列步驟操作:

  1. 前往 Google Cloud Platform 帳單頁面。
  2. 按一下「新增帳單帳戶」或「建立帳戶」。
  3. 填寫付款資訊。
  4. 按一下「開始免費試用」或「提交資訊並啟用計費功能」。
  5. 前往 Google Cloud 帳單頁面。
  6. 按一下「我的專案」分頁標籤。
  7. 依序點選三點圖示 >「變更帳單」。
  8. 在下拉式選單中,選取您設定的帳單帳戶。
  9. 按一下 [設定帳戶]。

如要避免產生費用,請按照「清除專案」一節中的步驟操作。

部署網頁應用程式

在本節中,您將使用 Firebase CLI 部署網頁應用程式 (Snow Pal 遊戲)。部署完成後,即可擷取網頁應用程式的網址,並在瀏覽器中查看遊戲畫面。

如要部署網頁應用程式,請按照下列步驟操作:

  1. 在終端機中前往 start/ 目錄。
  2. 執行下列指令,並將 {PROJECT_ID} 替換為您的專案 ID:
firebase deploy --project {PROJECT_ID} --only hosting

幾分鐘後,您應該會看到 "Deploy complete!",表示您已成功將 Snow Pal 網頁應用程式部署至 Firebase。

如要在瀏覽器中查看 Snow Pal 遊戲,請按照下列步驟操作:

  1. 擷取終端機輸出內容中提供的託管網址。網址格式應為:https://<PROJECT_ID>.web.app
  1. 將網址貼到瀏覽器中。您應該會看到 Snow Pal 遊戲的開始畫面,其中包含「Start Game」按鈕:

68429faae5141ed0.png

將網頁應用程式網址和專案 ID 新增至動作專案

接著,將網頁應用程式網址和專案 ID 新增至 actions.intent.MAIN.yaml 檔案。新增網頁應用程式網址後,對話動作就會知道要將資料傳送至哪個網址,而在 settings.yaml 中新增專案 ID 後,您就能將下載的檔案推送至 Actions 控制台中的正確專案。

如要新增網頁應用程式網址和專案 ID,請按照下列步驟操作:

  1. 在文字編輯器中開啟 start/sdk/custom/global/actions.intent.MAIN.yaml 檔案。
  2. 在「URL」欄位中,將預留位置字串替換為網頁應用程式網址。
  3. 在文字編輯器中開啟 start/sdk/settings/settings.yaml 檔案。
  4. 在 projectId 欄位中,將預留位置字串替換為專案 ID。

將專案推送至 Actions 主控台

如要使用本機專案更新 Actions 主控台,您必須將 Actions 專案推送至 Actions 主控台。步驟如下:

  1. 切換至 sdk 目錄:
cd sdk/
  1. 如要將本機檔案系統的設定複製到 Actions 主控台,請執行下列指令:
gactions push 

部署 Webhook

執行 gactions push 時,您已將起始 Webhook 程式碼匯入 Actions 主控台。在本程式碼實驗室的其餘部分,您可以在 Actions 控制台中編輯 Webhook 程式碼。此時,您可以從 Actions 控制台部署 Webhook。

如要部署 Webhook,請按照下列步驟操作:

  1. 在 Actions 主控台的導覽列中,按一下「Develop」(開發)。
  2. 按一下導覽列中的「Webhook」分頁標籤。
  3. 點選「Deploy Fulfillment」。

Cloud Functions 可能需要幾分鐘的時間,才能佈建及部署執行要求。您應該會看到「Cloud Function deployment in progress...」(Cloud 函式部署中...) 訊息。程式碼部署成功後,訊息會更新為「您的 Cloud 函式部署作業已是最新狀態」。

在模擬工具中測試

此時,動作已連結至網頁應用程式。您可以使用 Actions 主控台模擬器,確保叫用動作時會顯示網頁應用程式。

如要測試動作,請按照下列步驟操作:

  1. 在 Actions 控制台導覽列中,按一下「Test」。
  2. 在「Input」(輸入) 欄位中輸入 Talk to Snow Pal sample,然後按下 Enter 鍵。
  3. 在「Input」(輸入) 欄位中輸入 Yes,然後按下 Enter 鍵。或者,您也可以點選「開始遊戲」。

37f7bc4e550d817c.png

您尚未設定猜字母或猜單字的邏輯,因此如果猜單字或字母,會收到「...Incorrect. 繼續努力!看來我們需要新增更多功能,才能讓這項功能正常運作。」

5. 瞭解 Interactive Canvas 基礎架構

在這個專案中,功能分為三個主要元件:對話動作、網頁應用程式和 Webhook。請注意,這是設定動作的一種模型,並以這種方式組織,以突顯互動式畫布的核心功能。

以下各節將詳細說明對話動作、Webhook 和網頁應用程式如何搭配運作,以及其他重要的 Interactive Canvas 元素。

對話動作

動作的對話動作元件會處理辨識使用者輸入內容、處理輸入內容,並將輸入內容傳送至適當的場景,並在其中建構對使用者的回應。舉例來說,如果使用者在 Snow Pal 遊戲中說「我猜是字母 e」,對話動作會將該字母擷取為意圖參數,並傳遞至適當的遊戲邏輯,判斷猜測是否正確,並據此更新網頁應用程式。您可以在 Actions 建立工具 (Actions 主控台中的網頁式 IDE) 中,查看及修改這項對話邏輯。以下螢幕截圖顯示 Actions Builder 中的部分對話動作:

91d1c5300f015ff9.png

圖 4. Actions Builder 中的 Main invocation 視覺化圖表。

這張螢幕截圖顯示動作的Main invocation,使用者說出「Ok Google,與 Snow Pal 範例交談」等詞組時,就會比對到這個動作。使用者叫用動作時,Main invocation 會傳送提示和 canvas 回應,其中包含網頁應用程式的網址。

動作中的第一個 canvas 回應必須包含網頁應用程式網址。這項回應會指示 Google 助理在使用者裝置上,顯示該網址的網頁應用程式。Actions Builder 中的其他 canvas 回應可包含設為 true 的 send_state_data_to_canvas_app 欄位。當意圖相符時,這個欄位會將意圖名稱和任何參數值傳送至網頁應用程式,而網頁應用程式會根據使用者輸入的這項資料進行更新。

Webhook

在本程式碼實驗室中,您的 Webhook 包含遊戲邏輯 (您可以將 Webhook 視為遊戲伺服器)。遊戲邏輯包含判斷使用者是否猜對、是否獲勝,以及根據結果建構回覆等元素。您可以在 Actions Builder 中修改 Webhook。

當動作需要執行遊戲邏輯時,Actions Builder 會呼叫 Webhook。舉例來說,Game 場景中的 guess 意圖會對 guess 處理常式發出 Webhook 呼叫,然後執行邏輯來判斷使用者的猜測是否正確。Webhook 可以在對應至網頁應用程式檔案的處理常式中加入 Canvas 回應,並適當更新網頁。

網頁應用程式

ca564ef59e1003d4.png

圖 5. 在互動式 Canvas 動作中,對話動作、Webhook 和網頁應用程式之間的互動圖示。

網頁應用程式檔案包含網頁應用程式視覺效果和動畫的程式碼,以及根據使用者輸入內容更新網頁應用程式的邏輯。您可以在文字編輯器中修改網頁應用程式檔案,並使用 Firebase CLI 部署這些變更。

在對話動作和網頁應用程式之間通訊

您必須啟用對話動作和網頁應用程式之間的通訊,網頁應用程式才能根據使用者輸入內容進行更新。舉例來說,如果使用者說「我猜是字母 f」,

對話動作必須將字母 f 提供給網頁應用程式,網頁應用程式才能據此更新。如要將使用者的輸入內容從對話動作傳遞至網頁應用程式,您必須載入 Interactive Canvas API。

這個 API 的指令碼包含在 /public/index.html 中,這是 Snow Pal 遊戲的主要 HTML 檔案。這個檔案定義了 UI 的外觀,並載入多個指令碼:

index.html

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

如要根據使用者輸入內容更新網頁應用程式,您也必須在網頁應用程式檔案中註冊及設定回呼。回呼可讓網頁應用程式回應對話動作的資訊或要求。

/public/js/action.js 中有一個預先設定的類別 Action,用於宣告及註冊回呼。Action 類別是 Interactive Canvas API 的包裝函式。使用 scene.js 中的 create() 函式建立網頁應用程式時,系統會建立新的 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.js 的 Action 類別中。這個函式會宣告回呼,並在遊戲建立時向 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 回應時都會呼叫這個回呼。

下一節將說明如何設定這項專案的特定程式碼,將資料從對話動作傳遞至網頁應用程式。

根據使用者輸入內容更新網頁應用程式

在本程式碼實驗室中,您將使用指令對應,根據使用者輸入內容更新網頁應用程式。舉例來說,當 start_game 意圖與 Welcome 場景相符時,系統會將提示中包含的 canvas 回應傳送至網頁應用程式。onUpdate() 會剖析 canvas 回應中的中繼資料,並呼叫 START_GAME 指令,進而呼叫 scene.js 中的 start() 函式,並更新網頁應用程式,開始新的遊戲工作階段。

scene.js 中的 start() 函式也會呼叫 updateCanvasState() 函式,該函式會使用 setCanvasState() 方法呼叫新增 Webhook 可存取的狀態資料。

updateCanvasState() 方法會在每個指令結束時呼叫 (您將在整個程式碼實驗室中新增這些指令),並更新網頁應用程式的狀態。每次呼叫 updateCanvasState() 時,系統都會根據目前狀態更新 displayedWord 和 incorrectGuesses 的值:

scene.js

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

更新後的狀態會用於下一個對話回合。您可以透過 conv.context.canvas.state 在 Webhook 中存取這個狀態,如以下程式碼片段所示:

index.js

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

6. 新增猜測功能

在本節中,您將在動作中新增 guess 功能,讓使用者猜測字詞中的字母或字詞本身。

對話動作

在「在模擬器中測試」部分,您收到的回覆包含「看來我們需要新增更多功能,才能讓這項功能正常運作。」現在,您可以在 Actions 控制台中刪除該提示,這樣就只會呼叫 Webhook (在 Game 場景中,guess 意圖已設為在比對成功時發出 Webhook 呼叫)。

如要在比對出 guess 意圖時移除靜態提示,請按照下列步驟操作:

  1. 在 Actions 控制台的導覽列中,按一下「Scenes」。
  2. 點選「Game」,前往 Game 場景。
  3. 按一下「使用者意圖處理」下方的「When guess is matched」。清除「傳送提示」,即可移除提示。
  4. 按一下「儲存」。

Webhook

在本節中,您將更新 Webhook,加入將使用者正確或錯誤猜測對應至網頁應用程式檔案中邏輯的邏輯,然後據此更新網頁應用程式。guess 意圖處理常式已在 Webhook 中設定完成,因此您只需在這個意圖中新增 Canvas 回應,即可觸發更新網頁應用程式的邏輯。

如要更新 Webhook,請按照下列步驟操作:

  1. 在 Actions 控制台的導覽列中,按一下「Webhook」。
  2. 在 guess 處理常式下方的 index.js 中加入下列程式碼:

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」。部署完成後,系統會顯示「您的 Cloud 函式部署作業已是最新狀態」訊息。

網頁應用程式

現在可以設定網頁應用程式,處理 CORRECT_ANSWER 和 INCORRECT_ANSWER 指令。

  1. 在文字編輯器開啟 public/js/action.js。
  2. 更新網頁應用程式,以便處理 CORRECT_ANSWER 和 INCORRECT_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. 執行下列指令,更新網頁應用程式:
firebase deploy --project {PROJECT_ID} --only hosting

在模擬器中測試動作

此時,動作可以辨識猜測是否正確,並據此更新網頁應用程式。

如要測試動作,請按照下列步驟操作:

  1. 按一下導覽列中的「測試」。
  2. 在「Input」(輸入) 欄位中輸入 Talk to Snow Pal sample,然後按下 Enter 鍵。
  3. 在「Input」(輸入) 欄位中輸入 Yes,然後按下 Enter 鍵。或者,按一下「是」按鈕。
  4. 在「Input」欄位中輸入要猜測的字母,然後按下 Enter。

1c2c2d59a418642b.png

瞭解程式碼

在上一節中,您新增了程式碼,讓使用者可以在遊戲中猜字母,並在單字或雪人中看到猜測結果。大致來說,當 guess 意圖相符時,您會在 Actions Builder 中發出 Webhook 呼叫,將資料傳遞至網頁應用程式,以便據此更新。舉例來說,如果使用者在 Snow Pal 遊戲中猜中單字中的字母,網頁應用程式就會更新,在單字中的正確位置顯示該字母。

對於使用互動式畫布的動作,資料從 Webhook 傳遞至網頁應用程式的一般流程如下:

  1. 使用者輸入內容與包含 Canvas 回覆的意圖相符。
  2. 對話動作或 Webhook 會傳送 Canvas 回應,觸發 onUpdate() 回呼。
  3. onUpdate() 回呼會對應至自訂邏輯,並據此更新網頁應用程式。

在這個專案中,程式碼的運作方式如下:

  1. 當使用者與 guess 意圖相符時,Actions Builder 會從使用者的輸入內容中擷取字母做為參數。
  2. Actions Builder 會呼叫 Webhook 中的 guess 處理常式,其中包含邏輯,可判斷使用者猜測的字母是否出現在字詞中。
  3. guess 處理常式包含兩個 Canvas 回應,一個在字母正確時執行,另一個在字母不正確時執行。每個 Canvas 回應都會將適當的資料 (CORRECT_ANSWER 或 INCORRECT_ANSWER 指令) 傳遞至網頁應用程式。
  4. Canvas 回應的 data 欄位所含資料會傳遞至 action.js 中的 onUpdate() 方法。onUpdate() 會呼叫 scene.js 中指令對應關係中的適當指令。
  5. 指令對應會對應至 scene.js 中的 correctAnswer() 和 incorrectAnswer() 函式。這些函式會適當更新網頁應用程式,反映使用者的猜測,並呼叫 setCanvasState(),將狀態資料從網頁應用程式傳送至 Webhook。

7. 新增勝負功能

在本節中,您將在動作中加入勝負功能,包括判斷使用者勝負的邏輯,以及根據使用者結果更新網頁應用程式圖片的邏輯。

對話動作

處理使用者贏得或輸掉遊戲的功能會在 guess 意圖中設定,因此您不必在動作建構工具中進行任何額外設定。

Webhook

在本節中,您將更新 Webhook,加入處理使用者贏得或輸掉遊戲的邏輯,並對應至網頁應用程式邏輯,以適當的獲勝或失敗畫面更新遊戲。

如要更新 Webhook,請按照下列步驟操作:

  1. 在 Actions 控制台的導覽列中,按一下「Webhook」。
  2. 在 guess 處理常式下方的 index.js 中加入下列程式碼:

index.js (D 部分):

// Add Section D `if (userHasWon)` content here.
    if (userHasWon) {
      conv.add(`<speak>Let's see if your guess is ther<e...break
        time='>2500ms'/ ${guess} is right. That spells ${correctWord}!  
        ${randomArrayItem(WIN<_RESPO>NSES)}/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 ther<e...break
      time='>2500ms'/ ${guess} is wrong. Sorry you lost. The word is ${c<orrect>Word}!/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」。部署完成後,系統會顯示「您的 Cloud 函式部署作業已是最新狀態」訊息。

您在這裡新增了兩個 Canvas 回應,並使用 WIN_GAME 和 LOSE_GAME 指令,處理使用者贏得或輸掉遊戲的情況。在下一節中,您將新增功能,根據使用者獲勝或落敗,更新網頁應用程式。

網頁應用程式

現在,您可以設定網頁應用程式,根據使用者勝負更新。如要更新網頁應用程式,請按照下列步驟操作:

  1. 在文字編輯器開啟 public/js/action.js。
  2. 更新網頁應用程式,以便處理 WIN_GAME 和 LOSE_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. 執行下列指令,更新網頁應用程式:
firebase deploy --project {PROJECT_ID} --only hosting

在模擬器中測試動作

此時,動作可以處理使用者贏得或輸掉遊戲的情況,並根據結果顯示適當的畫面。

如要測試動作,請按照下列步驟操作:

  1. 在 Actions 控制台導覽列中,按一下「Test」。
  2. 在「Input」(輸入) 欄位中輸入 Talk to Snow Pal sample,然後按下 Enter 鍵。
  3. 在「Input」(輸入) 欄位中輸入 Yes,然後按下 Enter 鍵。或者,您也可以點選「Start game」按鈕。
  4. 猜測字母和單字,直到分出勝負。

ee572870f9a7df36.png

如果要求再次播放,系統會顯示訊息,指出尚未新增再次播放所需的功能。您將在下一節中新增這項功能。

瞭解程式碼

勝負功能與猜測功能的運作方式相同:使用者與 guess 意圖相符,而 Webhook 會評估使用者的猜測。如果猜對,程式碼會檢查使用者是否獲勝;如果獲勝,系統會將 WIN_GAME 指令傳送至網頁應用程式。如果猜錯,程式碼會檢查使用者是否落敗;如果落敗,系統會將 LOSE_GAME 指令傳送至網頁應用程式。這些指令會觸發 scene.js 中的 winGame() 和 loseGame() 函式,更新網頁應用程式,顯示獲勝或落敗畫面,並更新遊戲狀態。

8. 新增重玩功能

在本節中,您將新增功能,讓使用者說出「再玩一次」或點選網頁應用程式中的「再玩一次」按鈕,開始新遊戲。您可以在 Actions Builder 中修改 play_again 意圖,傳送 canvas 回應,適當更新網頁應用程式,並新增邏輯,在使用者點選「Play Again」按鈕時觸發 play_again 意圖。

對話動作

在上一節測試動作時,如果嘗試再次玩遊戲,會收到以下提示:「That would be great, but we will build this functionality in a later section. 目前只要重設動作即可。」現在可以刪除這個提示,並替換成在使用者要求其他遊戲時回覆的提示 (「好的,我們來玩另一款遊戲!」),並加入 canvas 回應,觸發網頁應用程式開始新遊戲。

如要在使用者想再次玩遊戲時更新提示,請按照下列步驟操作:

  1. 在 Actions 主控台中,按一下「Scene」下拉式選單。
  2. 按一下「Game」場景。
  3. 按一下「User intent handling」下方的「When play_again is matched」。
  4. 將提示詞換成下列文字:
candidates:
  - first_simple:
      variants:
        - speech: 'Okay, here''s another game!' 
    canvas:
      sendStateDataToCanvasApp: true
  1. 按一下「儲存」。

Webhook

在本程式碼研究室中,Webhook 會管理遊戲邏輯。由於重玩功能不需要任何邏輯驗證,因此您不需要呼叫 Webhook,而是可以直接從 Actions Builder 傳送 canvas 回應,將必要資料傳遞至網頁應用程式 (您已在上一節中設定這項功能)。

網頁應用程式

現在,您可以修改網頁應用程式檔案,在使用者要求再次玩遊戲時適當更新。如要新增這項功能,請按照下列步驟操作:

  1. 在文字編輯器開啟 public/js/action.js。
  2. 更新網頁應用程式,以處理 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. 更新網頁應用程式,讓使用者點選「Play Again」按鈕時,開始新的遊戲工作階段:

scene.js (J 節):

// Add Section J `sendTextQuery` content here.
     window.interactiveCanvas.sendTextQuery('Play again');
  1. 執行下列指令,更新網頁應用程式:
firebase deploy --project {PROJECT_ID} --only hosting

在模擬器中測試動作

現在,當使用者說出「再玩一次」或點選「再玩一次」按鈕時,動作就能開始新的遊戲工作階段。

如要測試動作,請按照下列步驟操作:

  1. 按一下導覽列中的「測試」。
  2. 在「Input」(輸入) 欄位中輸入 Talk to Snow Pal sample,然後按下 Enter 鍵。
  3. 在「Input」(輸入) 欄位中輸入 Yes,然後按下 Enter 鍵。或者,您也可以點選「Start game」按鈕。
  4. 猜測字母和單字,直到分出勝負。
  5. 在「Input」(輸入) 欄位中輸入 Play again,然後按下 Enter 鍵。或者,點選「再玩一次」按鈕。

1fbc7193f7a9d0f5.png

瞭解程式碼

測試動作時,您可以透過語音輸入 (「再玩一次」) 或觸控輸入 (點選「再玩一次」按鈕) 開始新遊戲。

如果使用者選擇語音輸入,並說出「再玩一次」或類似的話,系統就會比對出 play_again 意圖,並將提示 (「好的,我們再玩一局!」) 新增至提示佇列。提示中包含的 canvas 回應會將意圖名稱和其他中繼資料傳送至網頁應用程式。意圖名稱會傳遞至 onUpdate() 回呼,該回呼會將對應的指令 PLAY_AGAIN 對應至 action.js 中的指令對應。PLAY_AGAIN 指令會觸發 scene.js 中的 start() 函式,並以新的遊戲工作階段更新網頁應用程式。

如要使用觸控輸入選項,請使用 sendTextQuery(),這是一種 Interactive Canvas API,可讓您透過觸控輸入觸發意圖,讓按鈕運作。

在本程式碼實驗室中,您將使用 sendTextQuery(),在使用者點選「Play again」按鈕時叫用 play_again 意圖。Play again 引數與 play_again 意圖中的訓練詞組相符,並會觸發這個意圖,就像使用者說「再玩一次」一樣。play_again 意圖會觸發邏輯,更新網頁應用程式並開始新的遊戲工作階段。

9. 更新 PLAY_GAME 內建意圖

在本節中,您將更新 PLAY_GAME 內建意圖。

PLAY_GAME 內建意圖可讓使用者在提出一般要求時叫用動作,例如「我想玩遊戲」。

原始碼包含 PLAY_GAME 內建意圖,位於 /sdk/custom/global/actions.intent.PLAY_GAME.yaml。這項資訊會顯示在控制台的「Invocation」部分,如以下螢幕截圖所示:PLAY_GAME

c4f11e2d1c255219.png

如要讓使用者透過這個內建意圖叫用動作,您必須在 PLAY_GAME 內建意圖中,新增含有網頁應用程式網址的 canvas 回應。步驟如下:

  1. 在 Actions 控制台的導覽列中,按一下「PLAY_GAME」PLAY_GAME。
  2. 更新提示,加入網頁應用程式網址,如以下程式碼片段所示:
candidates:
  - canvas:
      url: 'http<s://PROJEC>T_ID.web.app'
  1. 按一下「儲存」。

在模擬器中測試動作

您的動作現在支援 PLAY_GAME 內建意圖。

如要測試動作,請按照下列步驟操作:

  1. 按一下導覽列中的「測試」。
  2. 按一下「測試內建意圖處理」。
  3. 按一下「叫用動作」。

1a4f647e17ebab53.png

模擬器應會叫用動作。

10. 附錄:排解互動式畫布動作問題

在本節中,您將瞭解如何對無法正常運作的互動式 Canvas 動作進行偵錯。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;
}

清理專案 [建議]

為避免產生費用,建議您移除不打算使用的專案。如要刪除在本程式碼實驗室建立的專案,請按照下列步驟操作:

  1. 如要刪除 Google Cloud 雲端專案和資源,請完成「關閉 (刪除) 專案」一節列出的步驟。
  1. 選用:如要立即從 Actions 主控台移除專案,請完成「刪除專案」一節列出的步驟。如未完成這個步驟,專案會在約 30 天後自動移除。

11. 恭喜!

您已完成 Interactive Canvas 程式碼實驗室入門課程,現在已具備建構 Interactive Canvas 動作所需的技能。

目前所學內容

  • 如何建構、部署及測試互動式畫布動作
  • 如何使用 Canvas 回覆更新網頁應用程式
  • 如何使用不同方法強化動作,例如 sendTextQuery() 和 setCanvasState()
  • 如何對動作進行偵錯

瞭解詳情

歡迎參考下列資源,進一步瞭解互動式 Canvas:

意見回饋問卷調查

離開前,請填寫簡短的問卷調查,分享你的體驗。