1. บทนำ
คุณกำลังดูทีวี แต่หารีโมตไม่เจอ หรืออาจไม่ต้องการไปที่ช่องทีวีแต่ละช่องเพื่อดูว่ามีรายการน่าสนใจหรือไม่ มาถาม Google Assistant กันว่ามีอะไรในทีวีบ้าง ในแล็บนี้ คุณจะได้สร้างการดำเนินการอย่างง่ายโดยใช้ Dialogflow และเรียนรู้วิธีผสานรวมกับการดำเนินการของ Google Assistant
แบบฝึกหัดจะเรียงตามลำดับเพื่อให้สอดคล้องกับประสบการณ์การใช้งานของผู้พัฒนาบนระบบคลาวด์ทั่วไป
- สร้าง Agent Dialogflow v2
- สร้างเอนทิตีที่กำหนดเอง
- สร้างความตั้งใจ
- ตั้งค่าเว็บฮุคด้วยฟังก์ชันของ Firebase
- ทดสอบแชทบ็อต
- เปิดใช้การผสานรวม Google Assistant
สิ่งที่คุณจะสร้าง
เราจะสร้างเอเจนต์แชทบ็อตทีวีไกด์แบบอินเทอร์แอกทีฟสำหรับ Google Assistant คุณสามารถถามรายการทีวีว่าขณะนี้ช่องใดกำลังออกอากาศอะไรอยู่ เช่น "MTV กำลังฉายอะไร" การดำเนินการในคู่มือทีวีจะบอกให้คุณทราบว่าตอนนี้กำลังฉายอะไรและจะฉายอะไรต่อไป |
|
สิ่งที่คุณจะได้เรียนรู้
- วิธีสร้างแชทบ็อตด้วย Dialogflow v2
- วิธีสร้างเอนทิตีที่กำหนดเองด้วย Dialogflow
- วิธีสร้างการสนทนาแบบเส้นตรงด้วย Dialogflow
- วิธีตั้งค่าการดำเนินการตามเว็บฮุคด้วย Dialogflow และฟังก์ชันของ Firebase
- วิธีนำแอปพลิเคชันของคุณมาใช้กับ Google Assistant ด้วย Actions on Google
ข้อกำหนดเบื้องต้น
- คุณจะต้องมีข้อมูลประจำตัวของ Google / อีเมล Gmail เพื่อสร้าง Agent ของ Dialogflow
- คุณไม่จำเป็นต้องมีความรู้พื้นฐานเกี่ยวกับ JavaScript แต่การมีความรู้ดังกล่าวจะเป็นประโยชน์ในกรณีที่คุณต้องการเปลี่ยนโค้ดการดำเนินการตามคำสั่งของเว็บฮุค
2. การเริ่มต้นใช้งาน
เปิดใช้กิจกรรมบนเว็บในเบราว์เซอร์
- ตรวจสอบว่าเปิดใช้กิจกรรมบนเว็บและแอปแล้ว โดยทำดังนี้

สร้างเอเจนต์ Dialogflow
- ในแถบด้านซ้าย ใต้โลโก้ ให้เลือก "สร้างเอเจนต์ใหม่" หากมีตัวแทนอยู่แล้ว ให้คลิกเมนูแบบเลื่อนลงก่อน

- ระบุชื่อตัวแทน:
your-name-tvguide(ใช้ชื่อของคุณเอง)

- เลือกภาษาเริ่มต้นเป็น English - en
- เลือกเขตเวลาที่ใกล้กับคุณมากที่สุดเป็นเขตเวลาเริ่มต้น
- คลิกสร้าง
กำหนดค่า Dialogflow
- คลิกไอคอนเฟืองในเมนูด้านซ้ายข้างชื่อโปรเจ็กต์

- ป้อนคำอธิบาย Agent ต่อไปนี้ My TV Guide

- เลื่อนลงไปที่การตั้งค่าบันทึก แล้วสลับทั้ง 2 สวิตช์เพื่อบันทึกการโต้ตอบของ Dialogflow และบันทึกการโต้ตอบทั้งหมดใน Google Cloud Stackdriver เราจะต้องใช้ข้อมูลนี้ในภายหลังในกรณีที่ต้องการแก้ไขข้อบกพร่องของการดำเนินการ

- คลิกบันทึก
กำหนดค่า Actions on Google
- คลิกลิงก์ Google Assistant ในดูวิธีการทำงานใน Google Assistant ในแผงด้านขวา

ซึ่งจะเปิด http://console.actions.google.com
หากเพิ่งเริ่มใช้ Actions on Google คุณจะต้องกรอกแบบฟอร์มนี้ก่อน

- ลองเปิดการดำเนินการในเครื่องจำลอง** โดยคลิกชื่อโปรเจ็กต์**
- เลือกทดสอบในแถบเมนู

- ตรวจสอบว่าได้ตั้งค่าโปรแกรมจำลองเป็นภาษาอังกฤษแล้วคลิกคุยกับแอปทดสอบของฉัน
Action จะทักทายคุณด้วย Intent เริ่มต้นพื้นฐานของ Dialogflow ซึ่งหมายความว่าการตั้งค่าการผสานรวมกับ Action on Google ทำงานได้แล้ว
3. เอนทิตีที่กำหนดเอง
เอนทิตีคือออบเจ็กต์ที่แอปหรืออุปกรณ์ของคุณดำเนินการ คิดว่าเป็นพารามิเตอร์ / ตัวแปร ในผังรายการทีวี เราจะถามว่า "MTV กำลังฉายอะไร" MTV คือเอนทิตีและตัวแปร ฉันขอช่องอื่นๆ ได้ด้วย เช่น "National Geographic" หรือ "Comedy Central" ระบบจะใช้เอนทิตีที่รวบรวมเป็นพารามิเตอร์ในคำขอของฉันไปยังเว็บเซอร์วิส TV Guide API
ดูข้อมูลเพิ่มเติมเกี่ยวกับเอนทิตี Dialogflow
การสร้างเอนทิตีของช่อง
- คลิกรายการเมนูเอนทิตีในคอนโซล Dialogflow
- คลิกสร้างเอนทิตี
- ชื่อเอนทิตี:
channel(ตรวจสอบว่าใช้ตัวพิมพ์เล็กทั้งหมด) - ส่งชื่อช่อง (บางช่องอาจต้องใช้คำพ้องความหมายในกรณีที่ Google Assistant เข้าใจเป็นอย่างอื่น) คุณใช้ปุ่ม Tab และ Enter ขณะพิมพ์ได้ ป้อนหมายเลขช่องเป็นค่าอ้างอิง และชื่อช่องเป็นคำพ้องความหมาย เช่น
1 - 1, Net 1, Net Station 1

5**.** เปลี่ยนเป็นโหมดการแก้ไขแบบดิบโดยคลิกปุ่มเมนูข้างปุ่มบันทึกสีน้ำเงิน

- คัดลอกและวางเอนทิตีอื่นๆ ในรูปแบบ 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"

- คลิกบันทึก
4. Intent
Dialogflow ใช้ความตั้งใจเพื่อจัดหมวดหมู่ความตั้งใจของผู้ใช้ เจตนามีวลีการฝึก ซึ่งเป็นตัวอย่างของสิ่งที่ผู้ใช้อาจพูดกับตัวแทนของคุณ เช่น ผู้ใช้ที่ต้องการทราบว่ามีอะไรในทีวีบ้างอาจถามว่า "วันนี้มีอะไรในทีวี" "ตอนนี้เปิดอะไรอยู่" หรือพูดว่า "ทีวีไกด์"
เมื่อผู้ใช้เขียนหรือพูดอะไรบางอย่าง ซึ่งเรียกว่าการแสดงออกของผู้ใช้ Dialogflow จะจับคู่การแสดงออกของผู้ใช้กับเจตนาที่ดีที่สุดในเอเจนต์ การจับคู่ความตั้งใจเรียกอีกอย่างว่าการจัดประเภทความตั้งใจ
ดูข้อมูลเพิ่มเติมเกี่ยวกับเจตนาของ Dialogflow
การแก้ไขเจตนาต้อนรับเริ่มต้น
เมื่อสร้างเอเจนต์ Dialogflow ใหม่ ระบบจะสร้าง Intent เริ่มต้น 2 รายการโดยอัตโนมัติ เจตนาต้อนรับเริ่มต้นคือโฟลว์แรกที่คุณจะได้รับเมื่อเริ่มการสนทนากับตัวแทน เจตนาสำรองเริ่มต้นคือโฟลว์ที่คุณจะได้รับเมื่อตัวแทนไม่เข้าใจคุณหรือไม่สามารถจับคู่เจตนากับสิ่งที่คุณเพิ่งพูด
- คลิก Default Welcome Intent
ในกรณีของ Google Assistant ระบบจะเริ่มทำงานโดยอัตโนมัติด้วยเจตนาต้อนรับเริ่มต้น เนื่องจาก Dialogflow กำลังรอเหตุการณ์ต้อนรับ แต่คุณยังเรียกใช้ Intent ได้ด้วยการพูดวลีการฝึกที่ป้อนไว้

นี่คือข้อความต้อนรับสำหรับเจตนาต้อนรับเริ่มต้น
ผู้ใช้ | Agent |
"Ok Google คุยกับ your-name-tvguide" | "ยินดีต้อนรับ ฉันคือตัวแทนทีวีไกด์ ฉันบอกได้ว่าตอนนี้ช่องทีวีกำลังออกอากาศอะไรอยู่ เช่น คุณสามารถถามว่า "ตอนนี้ MTV กำลังฉายอะไร" |
- เลื่อนลงไปที่คำตอบ
- ล้างคำตอบที่เป็นข้อความทั้งหมด
- สร้างคำตอบแบบข้อความใหม่ 1 รายการซึ่งมีคำทักทายต่อไปนี้
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?

- คลิกบันทึก
สร้างเจตนาทดสอบชั่วคราว
เพื่อวัตถุประสงค์ในการทดสอบ เราจะสร้าง Intent ทดสอบชั่วคราวเพื่อให้เราทดสอบ Webhook ได้ในภายหลัง
- คลิกรายการเมนูความตั้งใจอีกครั้ง
- คลิกสร้างความตั้งใจ
- ป้อนชื่อความตั้งใจ:
Test Intent(ตรวจสอบว่าคุณใช้ T และ I ตัวพิมพ์ใหญ่ - หากคุณสะกดเจตนาแตกต่างออกไป บริการแบ็กเอนด์จะทำงานไม่ได้)

- คลิกเพิ่มวลีการฝึก
Test my agentTest intent

- คลิกการจัดการคำสั่งซื้อ > เปิดใช้การจัดการคำสั่งซื้อ

คราวนี้เราจะไม่ฮาร์ดโค้ดคำตอบ การตอบกลับจะมาจาก Cloud Function
- พลิกสวิตช์เปิดใช้การเรียกใช้ Webhook สำหรับความตั้งใจนี้

- คลิกบันทึก
สร้างความตั้งใจของแชแนล
Channel Intent จะมีการสนทนาส่วนนี้
ผู้ใช้ | Agent |
"มีอะไรฉายใน Comedy Central บ้าง" | ""ตอนนี้ The Simpsons กำลังฉายทาง Comedy Central ตั้งแต่เวลา 18:00 น. จากนั้นเวลา 19:00 น. จะเริ่มฉาย Family Guy"" |
- คลิกรายการเมนูความตั้งใจอีกครั้ง
- คลิกสร้างความตั้งใจ
- ป้อนชื่อความตั้งใจ:
Channel Intent(ตรวจสอบว่าคุณใช้ T และ I ตัวพิมพ์ใหญ่ - หากคุณสะกดเจตนาแตกต่างออกไป บริการแบ็กเอนด์จะทำงานไม่ได้) - คลิกเพิ่มวลีการฝึก แล้วเพิ่มวลีต่อไปนี้
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

- เลื่อนลงไปที่การดำเนินการและพารามิเตอร์

โปรดสังเกตเอนทิตี @channel และ @sys.time ที่ Dialogflow รู้จัก ในภายหลังใน Webhook ระบบจะส่งชื่อพารามิเตอร์และค่าพารามิเตอร์ไปยังบริการเว็บ เช่น
channel=8
time=2020-01-29T19:00:00+01:00
- ทำเครื่องหมายช่องว่าต้องระบุ
เมื่อสนทนากับตัวแทนของคู่มือทีวี คุณจะต้องกรอกชื่อพารามิเตอร์ของช่อง channel เสมอ หากไม่ได้กล่าวถึงชื่อช่องในช่วงต้นของการสนทนา Dialogflow จะถามเพิ่มเติมจนกว่าจะกรอกช่องพารามิเตอร์ทั้งหมด 
ป้อนพรอมต์ต่อไปนี้
For which TV channel do you want to hear the tv guide information?In which TV channel are you interested?

- อย่าตั้งค่าพารามิเตอร์เวลาเป็น "ต้องระบุ"
โดยคุณจะระบุเวลาหรือไม่ก็ได้ เมื่อไม่ได้ระบุเวลา เว็บเซอร์วิสจะแสดงเวลาปัจจุบัน
- คลิกการจัดการคำสั่งซื้อ
คราวนี้เราจะไม่ฮาร์ดโค้ดคำตอบ การตอบกลับจะมาจาก Cloud Function ดังนั้น ให้พลิกสวิตช์เปิดใช้การเรียกใช้ Webhook สำหรับความตั้งใจนี้
- คลิกบันทึก
5. การดำเนินการตามคำสั่งผ่านเว็บฮุค
หากตัวแทนต้องการมากกว่าการตอบกลับตามความตั้งใจแบบคงที่ คุณต้องใช้การดำเนินการตามคำสั่งเพื่อเชื่อมต่อบริการเว็บกับตัวแทน การเชื่อมต่อบริการเว็บช่วยให้คุณดำเนินการตามสิ่งที่ผู้ใช้แสดงออกและส่งการตอบกลับแบบไดนามิกไปยังผู้ใช้ได้ ตัวอย่างเช่น หากผู้ใช้ต้องการรับตารางรายการทีวีของ MTV บริการเว็บของคุณสามารถตรวจสอบในฐานข้อมูลและตอบกลับผู้ใช้ด้วยตารางรายการของ MTV
- คลิกการปฏิบัติตามคำสั่งซื้อในเมนูหลัก
- เปิดสวิตช์โปรแกรมแก้ไขในบรรทัด

คุณสามารถใช้เครื่องมือแก้ไขแบบอินไลน์สำหรับการทดสอบและการติดตั้งใช้งานเว็บบุ๊กอย่างง่าย โดยใช้ Cloud Functions for Firebase แบบไร้เซิร์ฟเวอร์
- คลิกแท็บ index.js ในเครื่องมือแก้ไข แล้วคัดลอกและวางโค้ด JavaScript สำหรับโค้ด Node.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 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);
});

- คลิกแท็บ package.json ในโปรแกรมแก้ไข แล้วคัดลอกและวางโค้ด JSON นี้ ซึ่งจะนำเข้าไลบรารี Node.js Package Manager (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"
}
}

- คลิกปุ่มติดตั้งใช้งาน ระบบจะใช้เวลาสักครู่เนื่องจากกำลังทำให้ฟังก์ชันแบบ Serverless ของคุณใช้งานได้ ที่ด้านล่างของหน้าจอจะมีป๊อปอัปแจ้งสถานะของคุณ
- มาทดสอบเว็บฮุกเพื่อดูว่าโค้ดใช้งานได้หรือไม่ ในโปรแกรมจำลองทางด้านขวา ให้พิมพ์
Test my agent.
เมื่อทุกอย่างถูกต้อง คุณควรเห็นข้อความว่า "นี่คือข้อความทดสอบ"
- มาทดสอบความตั้งใจของช่องกัน ตอนนี้ให้ถามคำถามต่อไปนี้
What's on MTV?
เมื่อทุกอย่างถูกต้อง คุณควรเห็นข้อมูลต่อไปนี้
"MTV Unplugged กำลังเล่นทาง MTV ตั้งแต่เวลา 16:30 น. จากนั้นเวลา 17:30 น. จะเริ่มรายการ RuPaul's Drag Race"
ขั้นตอนที่ไม่บังคับ - Firebase
เมื่อทดสอบด้วยช่องอื่น คุณจะเห็นว่าผลลัพธ์ของทีวีเหมือนกัน เนื่องจากฟังก์ชัน Cloud ยังไม่ได้ดึงข้อมูลจากเว็บเซิร์ฟเวอร์จริง
เราจะต้องสร้างการเชื่อมต่อเครือข่ายขาออกเพื่อดำเนินการนี้
หากต้องการทดสอบแอปพลิเคชันนี้กับเว็บเซอร์วิส ให้อัปเกรดแพ็กเกจ Firebase เป็น Blaze หมายเหตุ: ขั้นตอนเหล่านี้เป็นขั้นตอนที่ไม่บังคับ นอกจากนี้ คุณยังไปที่ขั้นตอนถัดไปของแล็บนี้เพื่อทดสอบแอปพลิเคชันใน Actions on Google ต่อได้ด้วย
- ไปที่คอนโซล Firebase: https://console.firebase.google.com
- กดปุ่มอัปเกรดที่ด้านล่างของหน้าจอ

เลือกแพ็กเกจ Blaze ในป๊อปอัป
- ตอนนี้เราทราบแล้วว่า 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 Assistant ซึ่งช่วยให้บุคคลที่สามพัฒนา "การดำเนินการ" ได้ ซึ่งเป็นการดำเนินการขนาดเล็กสำหรับ Google Assistant ที่ให้ฟังก์ชันการทำงานเพิ่มเติม
คุณจะต้องเรียกใช้ Google Action โดยขอให้ Google เปิดหรือพูดคุยกับแอป
การดำเนินการนี้จะเปิดการดำเนินการของคุณ เปลี่ยนเสียง และคุณจะออกจากขอบเขต Google Assistant "ดั้งเดิม" ซึ่งหมายความว่าทุกสิ่งที่คุณขอจาก Agent ตั้งแต่ตอนนี้เป็นต้นไปจะต้องสร้างขึ้นโดยคุณ คุณไม่สามารถขอข้อมูลสภาพอากาศของ Google จาก Google Assistant ได้ทันทีหากต้องการทำเช่นนั้น คุณควรออกจาก (ปิด) ขอบเขตของการดำเนินการ (แอปของคุณ) ก่อน
ทดสอบการดำเนินการในโปรแกรมจำลอง Google Assistant
มาทดสอบการสนทนาต่อไปนี้กัน
ผู้ใช้ | Google Assistant |
"Ok Google คุยกับyour-name-tv-guide หน่อย" | "ได้เลย ขอyour-name-tv-guide หน่อย" |
ผู้ใช้ | ตัวแทน Your-Name-TV-Guide |
- | "ยินดีต้อนรับ ฉันคือทีวีไกด์...." |
ทดสอบ Agent ของฉัน | "นี่คือข้อความทดสอบ เมื่อคุณเห็นข้อความนี้ แสดงว่าการจัดการเว็บฮุกทำงานแล้ว" |
มีอะไรฉายใน MTV บ้าง | MTV Unplugged กำลังเล่นทาง MTV ตั้งแต่เวลา 16:30 น. จากนั้นเวลา 17:30 น.จะเริ่มรายการ RuPaul's Drag Race |
- เปลี่ยนกลับไปใช้โปรแกรมจำลอง Google Assistant
เปิด: https://console.actions.google.com
- คลิกไอคอนไมโครโฟนแล้วถามคำถามต่อไปนี้

Talk to my test agentTest my agent
Google Assistant ควรตอบกลับด้วยข้อความต่อไปนี้

- มาถามกันเลย
What's on Comedy Central?
ซึ่งควรแสดงผลดังนี้
ตอนนี้ The Simpsons กำลังฉายทาง Comedy Central ตั้งแต่เวลา 18:00 น. จากนั้นเวลา 19:00 น.จะเริ่มฉาย Family Guy
7. ขอแสดงความยินดี
คุณได้สร้างการทำงานของ Google Assistant รายการแรกด้วย Dialogflow แล้ว ขอแสดงความยินดีด้วย
ดังที่คุณอาจทราบ การดำเนินการของคุณทำงานในโหมดทดสอบซึ่งเชื่อมโยงกับบัญชี Google ของคุณ หากคุณจะเข้าสู่ระบบในอุปกรณ์ Nest หรือแอป Google Assistant ในโทรศัพท์ iOS หรือ Android ด้วยบัญชีเดียวกัน คุณยังทดสอบการดำเนินการได้ด้วย
ตอนนี้เราจะมาดูการสาธิตเวิร์กช็อป แต่เมื่อสร้างแอปพลิเคชันสำหรับ Google Assistant จริงๆ คุณจะส่ง Action เพื่อขอรับการอนุมัติได้ อ่านข้อมูลเพิ่มเติมได้ในคู่มือนี้
สิ่งที่เราได้พูดถึง
- วิธีสร้างแชทบ็อตด้วย Dialogflow v2
- วิธีสร้างเอนทิตีที่กำหนดเองด้วย Dialogflow
- วิธีสร้างการสนทนาแบบเส้นตรงด้วย Dialogflow
- วิธีตั้งค่าการดำเนินการตามเว็บฮุคด้วย Dialogflow และฟังก์ชันของ Firebase
- วิธีนำแอปพลิเคชันของคุณมาใช้กับ Google Assistant ด้วย Actions on Google
สิ่งต่อไปที่ควรทำ
คุณชอบ Codelab นี้ไหม ลองดูห้องทดลองที่ยอดเยี่ยมเหล่านี้
ทำ Codelab นี้ต่อโดยผสานรวมกับ Google Chat ดังนี้
สร้าง Google Chat ทีวีไกด์ด้วย G Suite และ Dialogflow
- สร้าง Actions สำหรับ Google Assistant ด้วย Dialogflow (ระดับ 1)
- สร้าง Actions สำหรับ Google Assistant ด้วย Dialogflow (ระดับ 2)
- สร้าง Actions สำหรับ Google Assistant ด้วย Dialogflow (ระดับ 3)
- ทำความเข้าใจการดำเนินการตามคำขอโดยการผสานรวม Dialogflow กับ Google ปฏิทิน
- ผสานรวม Google Cloud Vision API กับ Dialogflow
