現在您已經瞭解基本概念,現在可以強化及自訂動作了 搭配 Canvas 專用方法使用您可以選擇使用 用戶端執行要求模型 或伺服器端的執行要求模型。適用對象 如要進一步瞭解這些選項,請參閱 啟用互動式畫布。
如果選取用戶端執行要求模型選項,可以在以下位置使用 您的動作:
- 「Build with 用戶端執行要求」下方列出的所有 API
onTtsMark()
回呼
如果選取伺服器執行要求模型選項,可以在以下位置使用 您的動作:
- 「Build with Server-side fulfillment」下方列出的所有 API
- 回呼
某些互動式 Canvas API 不適合用於特定 執行要求模型下表列出點選後已啟用的 API 用戶端執行要求選項,以及這些 API 是建議使用還是 不建議採用以下方法:
API 名稱 | 伺服器執行要求模型是否支援? | 用戶端執行要求模型是否支援? |
sendTextQuery()
|
是 | 支援但不建議使用 (請參閱 sendtextQuery() ) |
outputTts()
|
是 | 是 |
triggerScene()
|
否 | 是 |
createIntentHandler(), expect(), clearExpectations(), prompt()
|
否 | 是 |
createNumberSlot(),createTextSlot, createConfirmationSlot, createOptionsSlot()
|
否 | 是 |
setHomeParam(), getHomeParam(), setUserParam(), getUserParam()
|
否 | 是 |
以下各節將說明如何為用戶端和 互動式畫布動作的伺服器端執行要求模型。
透過用戶端執行要求建構
您可以在網頁應用程式邏輯中,實作下列互動式畫布 API:
outputTts()
這個 API 可讓你從裝置輸出文字轉語音 (TTS),不必傳送
Actions Builder 的靜態提示或叫用 Webhook如果沒有伺服器端
需要使用與 TTS 相關聯的邏輯,因此您可以使用 outputTts()
用戶端便能略過伺服器行程,並快速回應
對使用者的影響。
用戶端outputTts()
可能會中斷或取消伺服器端 TTS。請避免
中斷伺服器端 TTS,請採取這些預防措施:
- 避免在工作階段開始時呼叫
outputTts()
。建議改用伺服器端 TTS。 - 請避免在使用者未操作的情況下連續呼叫
outputTts()
。
下列程式碼片段說明如何使用 outputTts()
從
用戶端:
interactiveCanvas.outputTts(
'<speak>This is an example response.</speak>', true);
您也可以將 outputTts()
與 onTtsMark()
搭配使用
將 SSML 標記放在文字序列中使用 onTtsMark()
可同步處理你的網路
應用程式動畫或遊戲狀態在 SSML TTS 字串的特定時間點,如圖所示
在以下程式碼片段中:
interactiveCanvas.outputTts(
'<speak>Speak as <mark name="number" /> number <break time="700ms"/>' +
'<say-as interpret-as="cardinal">12345</say-as> <break time="300ms"/> ' +
'Speak as <mark name="digits" /> digits <break time="700ms"/>' +
'<say-as interpret-as="characters">12345</say-as></speak>', true);
上述範例中的兩個標記 自訂回應會傳送至網頁應用程式,且回應要求傳送至 TTS。
在用戶端處理意圖執行要求
在互動式畫布的伺服器執行要求模型中,所有意圖 無須由 Webhook 處理,因此動作的延遲時間會增加。改為 您可以在網頁應用程式內處理意圖的執行要求。
如要在用戶端處理意圖,您可以使用下列 API:
createIntentHandler()
:一種方法,可讓您在自己的 網頁應用程式程式碼 (適用於 Actions Builder 中定義的自訂意圖)。expect()
:可啟動/註冊意圖處理常式的方法, 使用者比對意圖clearExpectations()
:這個方法能取消所有對 以便系統比對意圖 使用者說出的內容符合意圖。deleteHandler()
:可停用個別意圖處理常式的方法, 也無法比對意圖
透過這些 API,您可以依據不同的需求,選擇要啟用或停用意圖
互動畫布動作的狀態您必須在意圖上使用 expect()
處理常式來啟用這些意圖
啟用意圖處理常式
啟用意圖處理常式分為兩個步驟。首先,您必須定義
意圖。接下來,如要讓意圖可比對,您必須
在意圖處理常式上呼叫 expect()
。
如要在用戶端設定並啟用意圖處理常式,請按照下列步驟操作: 步驟如下:
- 在 Actions 主控台中開啟專案,並新增自訂意圖。
在「Is this Global intent?」部分選取「Yes」。
設定意圖,然後按一下「Save」。
在網頁應用程式邏輯中,定義意圖的處理常式,如以下程式碼片段所示:
/** * Define handler for intent. */ const bookTableIntent = interactiveCanvas.createIntentHandler('reserveTable', matchedIntent => { console.log("Intent match handler to reserve a table was triggered!"); }); /** * Define handler for intent with an argument. */ const bookTableIntent = interactiveCanvas.createIntentHandler('reserveTable', matchedIntent => { const numberOfPeople = matchedIntent.getIntentArg('numberOfPeople'); console.log(`Intent match handler to reserve a table for ${number of people} was triggered!`); });
呼叫
expect()
方法以註冊意圖處理常式,如 程式碼片段:/** * Define handler for intent and expect() it. */ const bookTableIntent = interactiveCanvas.createIntentHandler('reserveTable', matchedIntent => { console.log("Intent match handler to reserve a table was triggered!"); }); var handler = interactiveCanvas.expect(bookTableIntent);
停用意圖處理常式
定義意圖處理常式後,您可以啟用或停用意圖處理常式
將意圖視為動作所需的意圖呼叫 expect()
啟動
意圖後,它會傳回含有 deleteHandler()
方法的物件,供您用於
停用新建立的處理常式。即使意圖處理常式定義仍存在
如果意圖目前為未啟用狀態,您可以在以下情況再次啟用意圖:
。
如要停用意圖處理常式,請在意圖處理常式上呼叫 deleteHandler()
。
如以下程式碼片段所示:
/** * Define handler for intent and expect() it. */ const bookTableIntent = interactiveCanvas.createIntentHandler('reserveTable', matchedIntent => { console.log("Intent match handler to reserve a table was triggered!"); }); var handler = interactiveCanvas.expect(bookTableIntent); // Delete the handler for `bookTableIntent`. handler.deleteHandler();
您可以呼叫 expect()
來重新新增已停用的意圖處理常式,如
程式碼片段:
// Re-add the `bookTableIntent` handler.
handler = interactiveCanvas.expect(bookTableIntent);
如要大量停用意圖,您可以使用 clearExpectations()
方法。
會停用所有目前啟用的意圖。下列程式碼片段說明如何
清楚說明所有意圖處理常式的期望:
interactiveCanvas.clearExpectations();
在用戶端處理運算單元填充
除了在 Actions Builder 中為場景新增運算單元填充以外, 直接處理運算單元填充作業
如要在用戶端處理運算單元填充作業,您必須先使用 下列任一 API:
createNumberSlot(callback, hints)
:這個方法可讓您定義 正確編號。用於提示使用者輸入號碼。createTextSlot(callback, hints)
:此方法可讓您定義文字 加入原始碼用來提示使用者輸入字詞。createConfirmationSlot(callback, hints)
:這個方法可讓您 在網頁應用程式程式碼中定義確認版位。用於提示使用者 以確認 (是/否)。createOptionsSlot(options, callback, hints)
:這個方法可讓您 在網頁應用程式程式碼中定義選項版位。用來提示使用者 然後從預先定義的選項清單中選取
建立運算單元時,您可以選擇定義 triggerHints
改善自然語言理解 (NLU) 系統的關鍵字
開拍這些關鍵字應該是使用者在網站上可能說的簡短字詞
填滿運算單元。舉例來說,數字版位的 triggerHints
關鍵字可以
應為 years
。使用者在對話中回覆有關年齡的問題
並在回應中加上「我三十歲」回應,表示您的動作
以便識別使用者填入版位的正確性
建立運算單元後,您可以透過 prompt
API 提示使用者預約版位:
prompt(tts, slot)
:這個方法會將 TTS 輸出給使用者,提示使用者要填入預期的版位。
呼叫 prompt()
會傳回承諾產品的狀態及值
廣告空缺
建立號碼版位
您可以用數字版位,在活動期間提示使用者輸入電話號碼 對話。如要進一步瞭解運算單元填充,請參閱 運算單元填充部分 操作建構工具的說明文件
如要提示使用者在用戶端填入號碼版位,請按照下列步驟操作:
呼叫
createNumberSlot()
方法,在網頁建立號碼版位 應用程式邏輯:/** * Create number slot. */ const triggerHints = { associatedWords: ['guess number', 'number'] }; const slot = interactiveCanvas.createNumberSlot( number => { console.log(`Number guessed: ${number}.`); }, triggerHints);
呼叫
prompt()
方法,提示使用者提供版位,並處理 運算單元值,如以下程式碼片段所示:const promptPromise = interactiveCanvas.prompt( { text: 'What number am I thinking of between 1 and 10?' }, slot); promptPromise.then( answer => { if (answer.status == interactiveCanvas.AnswerStatus.ANSWERED) { // answer === {value: 5, status: ANSWERED} // Do something with answer.value } else { console.error('Promise returned unsuccessful status ' + answer.status); } });
建立文字位置
文字版位可讓您在搜尋期間提示使用者輸入字詞 對話。如要進一步瞭解運算單元填充,請參閱 運算單元填充部分 操作建構工具的說明文件
如要提示使用者在用戶端填入文字版位,請按照下列步驟操作:
呼叫
createTextSlot()
方法,在網頁應用程式邏輯中建立文字版位:/** * Create text slot. */ const triggerHints = { associatedWords: ['favorite color', 'color'] }; const slot = interactiveCanvas.createTextSlot( text => { console.log(`Favorite color: ${text}.`); }, triggerHints);
呼叫
prompt()
方法,提示使用者提供版位,並處理 運算單元值,如以下程式碼片段所示:const promptPromise = interactiveCanvas.prompt( { text: 'What is your favorite color?' }, slot); promptPromise.then( answer => { if (answer.status == interactiveCanvas.AnswerStatus.ANSWERED) { // answer === {value: "red", status: ANSWERED} // Do something with answer.value } else { console.error('Promise returned unsuccessful status ' + answer.status); } });
建立確認運算單元
透過確認版位,您可以提示使用者確認 回覆「是」或「否」填滿版位)。如要進一步瞭解運算單元填充,請參閱 運算單元填充部分 操作建構工具的說明文件
如要提示使用者在用戶端填寫確認版位,請遵循 步驟如下:
呼叫
createConfirmationSlot()
方法,在以下位置建立確認版位 您的網頁應用程式邏輯:/** * Create confirmation slot (boolean). */ const triggerHints = { associatedWords: ['user confirmation', 'confirmation'] }; const slot = interactiveCanvas.createConfirmationSlot( yesOrNo => { console.log(`Confirmation: ${yesOrNo}`); }, triggerHints);
呼叫
prompt()
方法,提示使用者提供版位,並處理 運算單元值,如以下程式碼片段所示:const promptPromise = interactiveCanvas.prompt( { text: 'Do you agree to the Terms of Service?' }, slot); promptPromise.then( answer => { if (answer.status == interactiveCanvas.AnswerStatus.ANSWERED) { // answer === {value: true, status: ANSWERED} // Do something with answer.value } else { console.error('Promise returned unsuccessful status ' + answer.status); } });
建立選項版位
選項版位可讓您提示使用者從清單中選取 預先定義的選項如要進一步瞭解運算單元填充,請參閱 運算單元填充部分 操作建構工具的說明文件
如要提示使用者在用戶端填入選項版位,請按照下列步驟操作:
呼叫
createOptionsSlot()
方法,在 網頁應用程式邏輯:/** * Create options slot (list selection). */ const triggerHints = { associatedWords: ['select fruit', 'choose fruit'] }; // Define selectable options const options = [{ key: 'apple', synonyms: ['apple', 'large apple', 'gala apple'], }, { key: 'banana', synonyms: ['banana', 'green banana', 'plantain'], }]; const slot = interactiveCanvas.createOptionsSlot( options, selectedOption => { console.log(`You have selected ${selectedOption} as your fruit.`); }, triggerHints);
呼叫
prompt()
方法,提示使用者提供版位,並處理 運算單元值,如以下程式碼片段所示:const promptPromise = interactiveCanvas.prompt( { text: 'Would you like a banana or an apple?' }, slot); promptPromise.then( answer => { if (answer.status == interactiveCanvas.AnswerStatus.ANSWERED) { // answer === {value: 'apple', status: ANSWERED} // Do something with answer.value } else { console.error('Promise returned unsuccessful status ' + answer.status); } });
triggerScene()
triggerScene()
API 可用來轉換至
透過用戶端執行要求執行互動式畫布動作。取代為
triggerScene()
,您也可以從用戶端執行要求切換為伺服器端
當使用者需要存取
Actions Builder 中的系統情境
也需要使用 Webhook例如,您可以在使用者呼叫 triggerScene()
時呼叫
需要連結帳戶或接收通知;接著,您可以從
並在用戶端執行要求時輸入 Canvas
提示。
下列程式碼片段說明如何在動作中實作 triggerScene()
:
interactiveCanvas.triggerScene('SceneName').then((status) => {
console.log("sent the request to trigger scene.");
}).catch(e => {
console.log("Failed to trigger a scene.");
})
用戶端的住家和使用者儲存空間
您不必使用 Webhook 取得及設定住家和使用者儲存空間值,您可以 呼叫用戶端 API,處理網頁應用程式中的主畫面和使用者儲存空間。你的網路 便可將這些儲存的值用於多個工作階段 (例如 提示和條件),以及存取特定住家或 使用者。使用這些 API 可縮短互動式畫布的延遲時間 操作:您不再需要呼叫 Webhook 即可取得及設定 Storage 值
網頁應用程式首頁和使用者儲存空間的一般原則與 將資料儲存在 Webhook 中如要進一步瞭解住家和使用者儲存空間,請參閱: 「住家儲存空間」說明文件 和使用者儲存空間。
用戶端住家儲存空間
你可以在家用儲存空間中,根據 首頁圖 等 在家中各不間斷。舉例來說,如果使用者播放互動式畫布 遊戲的得分可儲存在家庭儲存空間中 其他家庭成員可以根據儲存的分數繼續玩這款遊戲。
如要讓動作支援住家儲存空間,請按照下列步驟操作:
- 在「Actions」控制台中,前往「部署」部署>目錄資訊 > 其他資訊。
勾選「您的動作會使用住家儲存空間嗎?」的「是」方塊。
如要在網頁應用程式寫入家用儲存空間的值,請呼叫 setHomeParam()
方法,如以下程式碼片段所示:
interactiveCanvas.setHomeParam('familySize', 10).then(
result => {
console.log('Set home param success');
},
fail => {
console.error(err);
});
如要在網頁應用程式讀取家用儲存空間的值,請呼叫 getHomeParam()
方法,如以下程式碼片段所示:
interactiveCanvas.getHomeParam('familySize').then(
value => {
console.log(JSON.stringify(result));
},
err => {
console.error(err);
}
);
如要清除所有現有住家儲存空間,請呼叫 resetHomeParam()
方法,如下所示
在以下程式碼片段中:
interactiveCanvas.resetHomeParam();
用戶端使用者儲存空間
使用者儲存空間可讓你儲存特定已驗證使用者的參數值 跨多個工作階段例如,如果玩家正在玩遊戲, 遊戲就會為該使用者儲存在後續的遊戲工作階段中,使用者 就能繼續以相同的分數繼續玩遊戲
如要在網頁應用程式中的使用者儲存空間寫入值,請呼叫 setUserParam()
方法,如以下程式碼片段所示:
interactiveCanvas.setUserParam('color', 'blue').then(
result => {
console.log('Set user param success');
},
err => {
console.error(err);
});
如要讀取網頁應用程式中的使用者儲存空間值,請呼叫 getUserParam()
方法,如以下程式碼片段所示:
interactiveCanvas.getUserParam('color').then(
value => {
console.log(JSON.stringify(result));
},
err => {
console.error(err);
}
);
如要清除所有現有使用者儲存空間,請呼叫 resetUserParam()
方法,如下所示
在以下程式碼片段中:
interactiveCanvas.resetUserParam();
setCanvasState()
setCanvasState()
方法可讓您透過 Interactive 傳送狀態資料
將 Canvas 網頁應用程式新增至執行要求,並通知 Google 助理網頁應用程式
更新狀態網頁應用程式會以 JSON 物件的形式傳送更新狀態。
呼叫 setCanvasState()
並不會叫用意圖。更新後
如果叫用 sendTextQuery()
或使用者查詢,則叫用 setCanvasState()
符合對話中的意圖,即使用 setCanvasState()
設定的資料
就能從上一個對話回合
對話。
在下列程式碼片段中,網頁應用程式使用 setCanvasState()
設定 Canvas 狀態
資料:
JavaScript
this.action.canvas.setCanvasState({ score: 150 })
來自 Webhook 的參照畫布狀態
您可以在執行要求程式碼中參照已儲存的 Canvas 狀態值。如要參照
值,請使用 conv.context.canvas.state.KEY
語法,其中
KEY
是設定 Canvas 狀態值時所給定的鍵。
舉例來說,如果您先前在 Canvas 中儲存了某款遊戲的最高分
狀態做為參數 score
,請使用
使用 conv.context.canvas.state.score
即可在執行要求中存取該值:
Node.js
app.handle('webhook-name', conv => { console.log(conv.context.canvas.state.score); })
在提示中參照 Canvas 狀態
您可以在提示中參照已儲存的 Canvas 狀態值。如要參照
值,請使用 $canvas.state.KEY
語法,其中
KEY
是設定 Canvas 狀態值時所給定的鍵。
舉例來說,如果您先前在 Canvas 中儲存了某款遊戲的最高分
狀態做為參數 score
,請使用 $canvas.state.score
參照該值
在提示中存取該值:
JSON
{ "candidates": [{ "first_simple": { "variants": [{ "speech": "Your high score is $canvas.state.score." }] } }] }
參照畫布狀態在條件下
您也可以在條件中參照已儲存的 Canvas 狀態值。目的地:
參照該值,請使用 canvas.state.KEY
語法,其中 KEY
是 Canvas
狀態值設定完成。
舉例來說,如果您先前在 Canvas 中儲存了某款遊戲的最高分
做為參數 score
,而您想要與 999
值
條件式清單,您可以使用
canvas.state.score
。條件運算式如下所示:
條件語法
canvas.state.score >= 999
sendTextQuery()
sendTextQuery()
方法會將文字查詢傳送至對話動作
透過程式輔助方式比對意圖這個範例使用 sendTextQuery()
重新啟動
當使用者點選按鈕時,就會出現三角形轉動的遊戲。使用者點擊
「重新開始遊戲」按鈕,sendTextQuery()
會傳送文字查詢
符合 Restart game
意圖並傳回承諾。這個承諾會導致
如果意圖已觸發,則為 SUCCESS
;如果不觸發,則為 BLOCKED
。下列
程式碼片段會比對意圖,並處理
承諾:
JavaScript
… /** * Handle game restarts */ async handleRestartGame() { console.log(`Request in flight`); this.button.texture = this.button.textureButtonDisabled; this.sprite.spin = false; const res = await this.action.canvas.sendTextQuery('Restart game'); if (res.toUpperCase() !== 'SUCCESS') { console.log(`Request in flight: ${res}`); return; } console.log(`Request in flight: ${res}`); this.button.texture = this.button.textureButtonDisabled; this.sprite.spin = false; } …
如果承諾的結果產生 SUCCESS
,Restart game
Webhook 處理常式就會傳送
網頁應用程式的 Canvas
回應:
JavaScript
… app.handle('restart', conv => { conv.add(new Canvas({ data: { command: 'RESTART_GAME' } })); }); …
這個 Canvas
回應會觸發 onUpdate()
回呼,而後者會執行
將程式碼加到以下 RESTART_GAME
程式碼片段中:
JavaScript
… RESTART_GAME: (data) => { this.scene.button.texture = this.scene.button.textureButton; this.scene.sprite.spin = true; this.scene.sprite.tint = 0x00FF00; // green this.scene.sprite.rotation = 0; }, …
使用伺服器端執行要求建構
您可以在 Webhook 中實作下列互動式 Canvas API:
啟用全螢幕模式
根據預設,互動式畫布網頁應用程式會納入一個「標頭」
查看動作名稱。您可以使用「enableFullScreen
」
移除標頭並替換為
載入畫面,可讓使用者享有全螢幕體驗
互動情形浮動式訊息顯示 Action 的顯示畫面
名稱、開發人員名稱、退出動作的操作說明,以及浮動式訊息
色彩會隨著使用者在裝置上選擇的主題而改變。
如果使用者經常與動作互動,浮動式訊息會暫時顯示 停止出現在載入畫面上。如果使用者未在 執行動作一段時間後,浮動式訊息會再次出現,
您可以在 Webhook 或在靜態提示訊息中啟用全螢幕模式 。
如要在 Webhook 中啟用全螢幕模式,請按照下列步驟操作:
將第一個
canvas
回應中的enableFullScreen
欄位設為true
包含在工作階段中 Webhook 傳回的字串以下程式碼片段為範例 使用 Node.js 用戶端程式庫進行實作:const { conversation, Canvas } = require('@assistant/conversation'); const functions = require('firebase-functions'); const app = conversation(); app.handle('invocation_fullscreen', conv => { conv.add(new Canvas( { url: 'https://example-url.com', enableFullScreen: true })); }); exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app);
如要在 Actions Builder 的靜態提示中啟用全螢幕模式,請按照下列步驟操作:
- 在 Actions 主控台中開啟專案。
- 按一下導覽列中的「開發」,然後開啟包含
前
canvas
則回應。 將
enable_full_screen
設為true
,如以下程式碼片段所示:{ "candidates": [ { "canvas": { "url": "https://example-url.com", "enable_full_screen": true } } ] }
continueTtsDuringTouch
根據預設,使用者在使用互動式畫布時輕觸螢幕時
動作遊戲, TTS 會停止播放。你可以啟用文字轉語音功能繼續播放
當使用者透過 continueTtsDuringTouch
輕觸螢幕時。這項行為不得
您可以在同一個工作階段中
開啟或關閉這項設定
您可以在 Webhook 或靜態提示中實作這項行為 。
如要啟用 TTS 以便在使用者輕觸 Webhook 畫面後繼續操作,請按照 這個步驟:
將第一個
canvas
回應中的continueTtsDuringTouch
欄位設為true
包含在工作階段中 Webhook 傳回的字串以下程式碼片段為範例 使用 Node.js 用戶端程式庫進行實作:const { conversation, Canvas } = require('@assisant/conversation'); const functions = require('firebase-functions'); const app = conversation(); app.handle('intent-name', conv => { conv.add(new Canvas( { url: 'https://example-url.com', continueTtsDuringTouch: true })); }); exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app);
如要啟用文字轉語音功能,在使用者輕觸 操作建立工具,請按照下列步驟操作:
- 在 Actions 主控台中開啟專案。
- 按一下導覽列中的「Develop」(開發),開啟包含
前
canvas
則回應。 將
continue_tts_during_touch
設為true
,如以下程式碼片段所示:{ "candidates": [ { "canvas": { "url": "https://example-url.com", "continue_tts_during_touch": true } } ] }