實作內容:使用 Dialogflow 和 Actions on Google 為 Google 助理建立電視導覽動作

1. 簡介

你正在看電視,但找不到遙控器,或是不想一一造訪各電視頻道,查明電視是否有比較好的內容?告訴 Google 助理電視有什麼內容!在這個研究室中,您將使用 Dialogflow 建構簡單的動作,並瞭解如何與 Google 助理整合。

這些練習經過排序,以反映常見的雲端開發人員體驗:

  1. 建立 Dialogflow v2 虛擬服務專員
  2. 建立自訂實體
  3. 建立意圖
  4. 使用 Firebase 函式設定 Webhook
  5. 測試聊天機器人
  6. 啟用 Google 助理整合功能

建構目標

我們會為 Google 助理打造互動式電視節目表聊天機器人代理程式。你可以詢問電視節目表,瞭解特定頻道正在播放的內容。例如:「MTV 上有什麼節目?」「電視節目指南」會顯示目前正在播放的內容以及即將播放的內容。

課程內容

  • 如何使用 Dialogflow v2 建立聊天機器人
  • 如何透過 Dialogflow 建立自訂實體
  • 如何使用 Dialogflow 建立線性對話
  • 如何使用 Dialogflow 和 Firebase 函式設定 Webhook 執行要求
  • 如何透過 Actions on Google 將應用程式與 Google 助理整合

必要條件

  • 您需要有 Google 身分 / Gmail 地址,才能建立 Dialogflow 虛擬服務專員。
  • 您不一定要具備 JavaScript 的基本知識,但這有助於您變更 Webhook 執行要求程式碼。

2. 開始設定

在瀏覽器中啟用網路活動

  1. 點選:http://myaccount.google.com/activitycontrols

  1. 確認應用程式活動已啟用

bf8d16b828d6f79a.png

建立 Dialogflow 虛擬服務專員

  1. 開啟:https://console.dialogflow.com

  1. 在左側列的標誌下方,選取 [Create New Agent] (建立新代理程式)。如果您有現有服務專員,請先點選下拉式選單。

1d7c2b56a1ab95b8.png

  1. 指定代理程式名稱:your-name-tvguide (使用自己的名稱)

35237b5c5c539ecc.png

  1. 預設語言為 [英文 - en]
  2. 將時區設為預設時區,請選擇離你最近的時區。
  3. 按一下 [建立]

設定 Dialogflow

  1. 在左側選單中,按一下專案名稱旁邊的「齒輪」圖示。

1d7c2b56a1ab95b8.png

  1. 輸入下列代理程式說明:My TV Guide

26f262d359c49075.png

  1. 向下捲動至「Log Settings」(記錄設定),然後左右切換兩個開關,以記錄 Dialogflow 互動,並在 Google Cloud Stackdriver 中記錄所有互動。稍後需要輸入這個 ID,以便對動作進行偵錯。

e80c17acc3cce993.png

  1. 點選「儲存」

設定 Actions on Google

  1. 在右側面板中點選「瞭解 Google 助理的運作方式」中的「Google 助理」連結。

5a4940338fc351e3.png

隨即開啟:http://console.actions.google.com

如果您是第一次使用 Actions on Google,請先填妥這份表單:

3fd4e594fa169072.png

  1. 按一下專案名稱,嘗試在模擬器中開啟動作**。**
  2. 在選單列中選取「測試」

6adb83ffb7adeb78.png

  1. 確認模擬工具已設為「English」,然後按一下「Talk to my test-app」

這項操作將以基本 Dialogflow 預設意圖向您問候。也就是說,與 Action on Google 整合的設定可順利運作!

3. 自訂實體

實體是指應用程式或裝置對其執行動作的物件。您可將其視為參數 / 變數。在電視節目表中,我們會詢問:「MTV 上有什麼節目」。MTV 是實體和變數。我也可以要求我顯示其他頻道,例如:「國家地理」或「喜劇中心」收集的實體將做為我向 TV Guide API Web-service 要求的參數。

如要進一步瞭解 Dialogflow 實體,請參閱本文

建立 Channel 實體

  1. 在 Dialogflow 控制台中,按一下選單項目:[Entities] (實體)
  2. 按一下「建立實體」
  3. 實體名稱:channel (必須全部為小寫)
  4. 輸入頻道名稱。(有些頻道需要一個同義詞,以便 Google 助理理解其他內容)。您可以在輸入時使用 Tab 鍵和 Enter 鍵,輸入頻道編號做為參照值。頻道名稱會用同義詞,例如:
  • 1 - 1, Net 1, Net Station 1

ee4e4955aa77232d.png

5**.**按一下藍色儲存按鈕旁的選單按鈕,切換至「原始編輯」模式。

e294b49b123e034f.png

  1. 複製和以 CSV 格式貼上其他實體:
"2","2","Net 2, Net Station 2"
"3","3","Net 3, Net Station 3"
"4","4","RTL 4"
"5","5","Movie Channel"
"6","6","Sports Channel"
"7","7","Comedy Central"
"8","8","Cartoon Network"
"9","9","National Geographic"
"10","10","MTV"

ed78514afd5badef.png

  1. 按一下「儲存」

4. 意圖

Dialogflow 使用意圖來分類使用者的意圖。意圖包含訓練詞組,這是使用者可能會向代理程式說的內容範例。舉例來說,如果使用者想知道電視上有什麼,就可以在詢問「今天有什麼電視節目?」、「現在播的是什麼?」,或是直接說「tvguide」。

當使用者撰寫或說出特定內容時 (稱為「使用者運算式」),Dialogflow 會將使用者表達內容與代理程式中最相符的意圖進行比對。比對意圖的作業也稱為「意圖分類」

進一步瞭解 Dialogflow 意圖

修改預設歡迎意圖

建立新的 Dialogflow 代理程式時,系統會自動建立兩個預設意圖。預設歡迎意圖是您與代理程式開始對話時進入的第一個流程。「預設備用意圖」是指在代理程式無法理解您,或無法將意圖與您剛剛說的內容配對時,您所使用的流程。

  1. 點選「Default Welcome Intent」(預設的歡迎意圖)

如果是 Google 助理,系統會自動以預設歡迎意圖自動啟動。這是因為 Dialogflow 正在監聽歡迎事件。不過,您也可以說出輸入的其中一個訓練詞組來叫用意圖。

6beee64e8910b85d.png

以下是預設歡迎意圖的歡迎訊息:

使用者

代理程式

「Ok Google,說出你的名稱-tvguide。」

「歡迎,我是電視節目表服務專員。我可以告訴你目前正在電視頻道播放的內容。例如,你可以問我「有什麼 MTV 的內容」。

  1. 向下捲動至「回應」
  2. 清除所有簡訊回應。
  3. 建立一個新的文字回應,其中包含以下問候語:

Welcome, I am the TV Guide agent. I can tell you what's currently playing on a TV channel. For example, you can ask me: What's on MTV?

84a1110a7f7edba2.png

  1. 點選「儲存」

建立臨時測試意圖

為進行測試,我們會建立臨時測試意圖,以便稍後測試 Webhook。

  1. 再次按一下「Intents」(意圖) 選單項目。
  2. 點選「建立意圖」
  3. 輸入意圖名稱:Test Intent (請務必使用大寫 T 和大寫 I.- 如果拼寫出不同的意圖,後端服務將無法運作!)

925e02caa4de6b99.png

  1. 按一下「新增訓練詞組」
  • Test my agent
  • Test intent

2e44ddb2fae3c841.png

  1. 按一下「執行要求」>「執行要求」啟用執行要求

7eb73ba04d76140e.png

這次,我們不會將回應寫死。回應將來自 Cloud 函式!

  1. 翻轉「Enable Webhook call for this intent」切換鈕。

748a82d9b4d7d253.png

  1. 按一下「儲存」

建立頻道意圖

Channel Intent 會包含這段對話的部分:

使用者

代理程式

「What's on Comedy Central?」

「"目前正在播放下午 6 點的喜劇中心,The Simpsons 正在播放。下午 7 點後,《Family Guy》將開始。"

  1. 再次按一下「Intents」(意圖) 選單項目。
  2. 點選「建立意圖」
  3. 輸入意圖名稱:Channel Intent (請務必使用大寫 T 和大寫 I。- 如果拼寫出不同的意圖,後端服務將無法運作!)
  4. 按一下 [新增訓練詞組],並新增下列內容:
  • What's on MTV?
  • What's playing on Comedy Central?
  • What show will start at 8 PM on National Geographic?
  • What is currently on TV?
  • What is airing now.
  • Anything airing on Net Station 1 right now?
  • What can I watch at 7 PM?
  • What's on channel MTV?
  • What's on TV?
  • Please give me the tv guide.
  • Tell me what is on television.
  • What's on Comedy Central from 10 AM?
  • What will be on tv at noon?
  • Anything on National Geographic?
  • TV Guide

6eee02db02831397.png

  1. 向下捲動至「動作和參數」

b7e917026760218a.png

請注意,@channel@sys.time 實體。稍後在 Webhook 中,參數名稱和參數值將會傳送至您的網路服務。例如:

channel=8

time=2020-01-29T19:00:00+01:00

  1. channel 標示為 quired

與電視節目指南服務專員對話時,一律需要填入版位參數名稱 channel。如果對話開始時沒有提及頻道名稱,Dialogflow 會進一步詢問,直到所有參數版位都填完為止。6f36973fd789c182.png

請在提示訊息中輸入:

  • For which TV channel do you want to hear the tv guide information?
  • In which TV channel are you interested?

cdb5601ead9423f8.png

  1. 請勿視需要設定時間參數。

時間是選填資訊。如未指定時間,網路服務會傳回目前時間。

  1. 按一下「執行要求」

這次,我們不會將回應寫死。回應將來自 Cloud 函式!因此,請翻轉「Enable Webhook call for this intent」切換鈕。

  1. 按一下「儲存」

5. Webhook 執行要求

如果您的代理程式需要更多靜態意圖回應,則您必須使用執行要求,將網路服務連結至代理程式。連結網路服務後,即可根據使用者表達內容執行動作,並將動態回應傳回給使用者。舉例來說,如果使用者想收到 MTV 的電視節目時間表,您的網路服務可以檢查資料庫,並回覆使用者「MTV 的節目」時間表。

  1. 按一下主選單中的「Fulfillment」
  2. 啟用「Inline Editor」(內嵌編輯器) 切換按鈕

cc84351f0d03ab6f.png

如要進行簡單的 Webhook 測試和實作,您可以使用內嵌編輯器。您使用無伺服器 Cloud Functions for Firebase

  1. 按一下編輯器中的 index.js 分頁標籤,然後複製以下這一段適用於 Node.js 程式碼的 JavaScript:
'use strict';

process.env.DEBUG = 'dialogflow:debug';

const {
  dialogflow,
  BasicCard,
  Button,
  Image,
  List
 } = require('actions-on-google');

const functions = require('firebase-functions');
const moment = require('moment');
const TVGUIDE_WEBSERVICE = 'https://tvguide-e4s5ds5dsa-ew.a.run.app/channel';
const { WebhookClient } = require('dialogflow-fulfillment');
var spokenText = '';
var results = null;


/* When the Test Intent gets invoked. */
function testHandler(agent) {
    let spokenText = 'This is a test message, when you see this, it means your webhook fulfillment worked!';

    if (agent.requestSource === agent.ACTIONS_ON_GOOGLE) {
        let conv = agent.conv();
        conv.ask(spokenText);
        conv.ask(new BasicCard({
            title: `Test Message`,
            subTitle: `Dialogflow Test`,
            image: new Image({
                url: 'https://dummyimage.com/600x400/000/fff',
                alt: 'Image alternate text',
            }),
            text: spokenText,
            buttons: new Button({
                title: 'This is a button',
                url: 'https://assistant.google.com/',
            }),
        }));
        // Add Actions on Google library responses to your agent's response
        agent.add(conv);
    } else {
        agent.add(spokenText);
    }
}

/* When the Channel Intent gets invoked. */
function channelHandler(agent) {
    var jsonResponse = `{"ID":10,"Listings":[{"Title":"Catfish Marathon","Date":"2018-07-13","Time":"11:00:00"},{"Title":"Videoclips","Date":"2018-07-13","Time":"12:00:00"},{"Title":"Pimp my ride","Date":"2018-07-13","Time":"12:30:00"},{"Title":"Jersey Shore","Date":"2018-07-13","Time":"13:00:00"},{"Title":"Jersey Shore","Date":"2018-07-13","Time":"13:30:00"},{"Title":"Daria","Date":"2018-07-13","Time":"13:45:00"},{"Title":"The Real World","Date":"2018-07-13","Time":"14:00:00"},{"Title":"The Osbournes","Date":"2018-07-13","Time":"15:00:00"},{"Title":"Teenwolf","Date":"2018-07-13","Time":"16:00:00"},{"Title":"MTV Unplugged","Date":"2018-07-13","Time":"16:30:00"},{"Title":"Rupauls Drag Race","Date":"2018-07-13","Time":"17:30:00"},{"Title":"Ridiculousness","Date":"2018-07-13","Time":"18:00:00"},{"Title":"Punk'd","Date":"2018-07-13","Time":"19:00:00"},{"Title":"Jersey Shore","Date":"2018-07-13","Time":"20:00:00"},{"Title":"MTV Awards","Date":"2018-07-13","Time":"20:30:00"},{"Title":"Beavis & Butthead","Date":"2018-07-13","Time":"22:00:00"}],"Name":"MTV"}`;
    var results = JSON.parse(jsonResponse);
    var listItems = {};
    spokenText = getSpeech(results);

    for (var i = 0; i < results['Listings'].length; i++) {
        listItems[`SELECT_${i}`] = {
            title: `${getSpokenTime(results['Listings'][i]['Time'])} - ${results['Listings'][i]['Title']}`,
            description: `Channel: ${results['Name']}`
        }
    }
    if (agent.requestSource === agent.ACTIONS_ON_GOOGLE) {
        let conv = agent.conv();
        conv.ask(spokenText);
        conv.ask(new List({
            title: 'TV Guide',
            items: listItems
        }));
        // Add Actions on Google library responses to your agent's response
        agent.add(conv);
    } else {
        agent.add(spokenText);
    }
}

/**
 * Return a text string to be spoken out by the Google Assistant
 * @param {object} JSON tv results
 */
var getSpeech = function(tvresults) {
    let s = "";
    if(tvresults['Listings'][0]) {
        let channelName = tvresults['Name'];
        let currentlyPlayingTime = getSpokenTime(tvresults['Listings'][0]['Time']);
        let laterPlayingTime = getSpokenTime(tvresults['Listings'][1]['Time']);
        s = `On ${channelName} from ${currentlyPlayingTime}, ${tvresults['Listings'][0]['Title']} is playing.
        Afterwards at ${laterPlayingTime}, ${tvresults['Listings'][1]['Title']} will start.`
    }

    return s;
}

/**
 * Return a natural spoken time
 * @param {string} time in 'HH:mm:ss' format
 * @returns {string} spoken time (like 8 30 pm i.s.o. 20:00:00)
 */
var getSpokenTime = function(time){
    let datetime = moment(time, 'HH:mm:ss');
    let min = moment(datetime).format('m');
    let hour = moment(datetime).format('h');
    let partOfTheDay = moment(datetime).format('a');

    if (min == '0') {
        min = '';
    }

    return `${hour} ${min} ${partOfTheDay}`;
};

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
    var agent = new WebhookClient({ request, response });

    console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
    console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
   
    let channelInput = request.body.queryResult.parameters.channel;
    let requestedTime = request.body.queryResult.parameters.time;
    let url = `${TVGUIDE_WEBSERVICE}/${channelInput}`;

    var intentMap = new Map();
    intentMap.set('Test Intent', testHandler);
    intentMap.set('Channel Intent', channelHandler);
    agent.handleRequest(intentMap);
});

cc84351f0d03ab6f.png

  1. 按一下編輯器中的 package.json 分頁標籤,然後複製這段 JSON 程式碼,即可匯入所有 Node.js 套件管理工具 (NPM) 程式庫:
{
  "name": "tvGuideFulfillment",
  "description": "Requesting TV Guide information from a web service.",
  "version": "1.0.0",
  "private": true,
  "license": "Apache Version 2.0",
  "author": "Google Inc.",
  "engines": {
    "node": "8"
  },
  "scripts": {
    "start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
    "deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
  },
  "dependencies": {
    "actions-on-google": "^2.2.0",
    "firebase-admin": "^5.13.1",
    "firebase-functions": "^2.0.2",
    "request": "^2.85.0",
    "request-promise": "^4.2.5",
    "moment" : "^2.24.0",
    "dialogflow-fulfillment": "^0.6.1"
  }
}

af01460c2a023e68.png

  1. 按一下「Deploy」按鈕。請稍候,系統正在部署無伺服器函式。系統會在畫面底部顯示一個彈出式視窗,說明你的狀態。
  2. 請測試 Webhook,看看程式碼是否能正常運作。在右側的模擬工具中輸入:

Test my agent.

如果一切正確無誤,畫面上應會顯示:「這是測試訊息」。

  1. 現在我們來測試頻道意圖,接下來請思考以下問題:

What's on MTV?

如果一切正確無誤,您應該會看到:

「在 MTV 下午 4 點 30 點開始,MTV Unplugged 正在播放。下午 5 點後,Rupauls 拖曳競速賽即將開始。」

選用步驟 - Firebase

使用不同的頻道進行測試時,會發現電視結果相同。這是因為 Cloud 函式尚未從實際的網路伺服器擷取。

為此,我們需要建立「傳出網路連線」

如果您想使用網路服務測試這個應用程式,請將 Firebase 方案升級至 Blaze。注意:這些步驟是選擇性步驟。你也可以前往這個研究室的後續步驟,繼續在 Actions on Google 中測試應用程式。

  1. 前往 Firebase 控制台:https://console.firebase.google.com

  1. 按下畫面底部的「升級」按鈕

ad38bc6d07462abf.png

在彈出式視窗中選取「Blaze」方案。

  1. 我們已確認 Webhook 運作正常,現在可以繼續並將 index.js 的程式碼替換為以下程式碼。這將確保您可以向網路服務索取電視節目表資訊:
'use strict';

process.env.DEBUG = 'dialogflow:debug';

const {
  dialogflow,
  BasicCard,
  Button,
  Image,
  List
 } = require('actions-on-google');

const functions = require('firebase-functions');
const moment = require('moment');
const { WebhookClient } = require('dialogflow-fulfillment');
const rp = require('request-promise');

const TVGUIDE_WEBSERVICE = 'https://tvguide-e4s5ds5dsa-ew.a.run.app/channel';
var spokenText = '';
var results = null;


/* When the Test Intent gets invoked. */
function testHandler(agent) {
    let spokenText = 'This is a test message, when you see this, it means your webhook fulfillment worked!';

    if (agent.requestSource === agent.ACTIONS_ON_GOOGLE) {
        let conv = agent.conv();
        conv.ask(spokenText);
        conv.ask(new BasicCard({
            title: `Test Message`,
            subTitle: `Dialogflow Test`,
            image: new Image({
                url: 'https://dummyimage.com/600x400/000/fff',
                alt: 'Image alternate text',
            }),
            text: spokenText,
            buttons: new Button({
                title: 'This is a button',
                url: 'https://assistant.google.com/',
            }),
        }));
        // Add Actions on Google library responses to your agent's response
        agent.add(conv);
    } else {
        agent.add(spokenText);
    }
}

/* When the Channel Intent gets invoked. */
function channelHandler(agent) {
    var listItems = {};
    spokenText = getSpeech(results);

    for (var i = 0; i < results['Listings'].length; i++) {
        listItems[`SELECT_${i}`] = {
            title: `${getSpokenTime(results['Listings'][i]['Time'])} - ${results['Listings'][i]['Title']}`,
            description: `Channel: ${results['Name']}`

        }
    }
    if (agent.requestSource === agent.ACTIONS_ON_GOOGLE) {
        let conv = agent.conv();
        conv.ask(spokenText);
        conv.ask(new List({
            title: 'TV Guide',
            items: listItems
        }));
        // Add Actions on Google library responses to your agent's response
        agent.add(conv);
    } else {
        agent.add(spokenText);
    }
}

/**
 * Return a text string to be spoken out by the Google Assistant
 * @param {object} JSON tv results
 */
var getSpeech = function(tvresults) {
    let s = "";
    if(tvresults && tvresults['Listings'][0]) {
        let channelName = tvresults['Name'];
        let currentlyPlayingTime = getSpokenTime(tvresults['Listings'][0]['Time']);
        let laterPlayingTime = getSpokenTime(tvresults['Listings'][1]['Time']);
        s = `On ${channelName} from ${currentlyPlayingTime}, ${tvresults['Listings'][0]['Title']} is playing.
        Afterwards at ${laterPlayingTime}, ${tvresults['Listings'][1]['Title']} will start.`
    }

    return s;
}

/**
 * Return a natural spoken time
 * @param {string} time in 'HH:mm:ss' format
 * @returns {string} spoken time (like 8 30 pm i.s.o. 20:00:00)
 */
var getSpokenTime = function(time){
    let datetime = moment(time, 'HH:mm:ss');
    let min = moment(datetime).format('m');
    let hour = moment(datetime).format('h');
    let partOfTheDay = moment(datetime).format('a');

    if (min == '0') {
        min = '';
    }

    return `${hour} ${min} ${partOfTheDay}`;
};

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
    var agent = new WebhookClient({ request, response });

    console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
    console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
   
    let channelInput = request.body.queryResult.parameters.channel;
    let requestedTime = request.body.queryResult.parameters.time;
    let url = `${TVGUIDE_WEBSERVICE}/${channelInput}`;

    if (requestedTime) {
        console.log(requestedTime);
        let offsetMin = moment().utcOffset(requestedTime)._offset;
        console.log(offsetMin);
        let time = moment(requestedTime).utc().add(offsetMin,'m').format('HH:mm:ss');
        url = `${TVGUIDE_WEBSERVICE}/${channelInput}/${time}`;
      }
    
      console.log(url);
  
      var options = {
          uri: encodeURI(url),
          json: true
      };
       
      // request promise calls an URL and returns the JSON response.
      rp(options)
        .then(function(tvresults) {
            console.log(tvresults);
            // the JSON response, will need to be formatted in 'spoken' text strings.
            spokenText = getSpeech(tvresults);
            results = tvresults;
        })
        .catch(function (err) {
            console.error(err);
        })
        .finally(function(){
            // kick start the Dialogflow app
            // based on an intent match, execute
            var intentMap = new Map();
            intentMap.set('Test Intent', testHandler);
            intentMap.set('Channel Intent', channelHandler);
            agent.handleRequest(intentMap);
        });
});

6. Actions on Google

Actions on Google 是 Google 助理的開發平台,Gemini 可讓第三方開發「動作」,也就是為 Google 助理提供擴充功能的小工具。

您必須叫用 Google 動作,方法是要求 Google 開啟或對應用程式說話。

這項操作會開啟動作、變更語音,選擇保留「母語」Google 助理範圍。換句話說,您在此階段要求服務專員的所有資訊都必須由您建立。您無法突然要求 Google 助理提供 Google 天氣資訊 (如果這是自己想要的)您應先保留 (關閉) 動作範圍 (應用程式)。

在 Google 助理模擬工具中測試動作

我們來測試下列對話:

使用者

Google 助理

「Ok Google,下達 your-name-tv-guide 的人。」

「沒問題,讓我來叫 your-name-tv-guide。」

使用者

您的姓名-TV-Guide 服務專員

-

「歡迎,我是電視指南...」

測試我的虛擬服務專員

「這是測試訊息,如果看到這則訊息,表示 Webhook 執行要求運作正常!」

MTV 有什麼內容?

在 MTV 中午 4 點後開始播放 MTV Unplugged。下午 5 點 30 分後,Rupauls 拖曳競速賽即將開始。

  1. 切換回 Google 助理模擬器

開啟: https://console.actions.google.com

  1. 按一下麥克風圖示,並詢問下列事項:

c3b200803c7ba95e.png

  • Talk to my test agent
  • Test my agent

Google 助理會回應以下內容:

5d93c6d037c8c8eb.png

  1. 現在,請思考:
  • What's on Comedy Central?

這應該會傳回:

目前播出時間為下午 6 點的喜劇中心,《The Simpsons》即將播放。下午 7 點後,Family Guy 將開始運動。

7. 恭喜

您已成功透過 Dialogflow 建立第一個 Google 助理動作!

您可能已經注意到,您的動作是以與 Google 帳戶連結的「測試模式」執行。請在 iOS 或 Android 手機上的 Nest 裝置或 Google 助理應用程式中使用相同的帳戶。您也可以測試動作。

這是研討會示範不過,如果你是為 Google 助理開發人員打造應用程式,可以提交該項動作申請核准。詳情請參閱這份指南

涵蓋內容

  • 如何使用 Dialogflow v2 建立聊天機器人
  • 如何透過 Dialogflow 建立自訂實體
  • 如何使用 Dialogflow 建立線性對話
  • 如何使用 Dialogflow 和 Firebase 函式設定 Webhook 執行要求
  • 如何透過 Actions on Google 將應用程式與 Google 助理整合

後續步驟

喜歡這個程式碼研究室嗎?快去看看這些實用的研究室功能吧!

將這個程式碼研究室與 Google Chat 整合,即可繼續進行這個研究室:

使用 G Suite 和 Dialogflow 製作電視指南 Google Chat