1. บทนำ
คุณกำลังดูทีวี แต่หารีโมตไม่เจอ หรืออาจไม่ต้องการไปที่ช่องทีวีแต่ละช่องเพื่อดูว่ามีรายการน่าสนใจหรือไม่ มาถาม Google Assistant กันว่ามีอะไรในทีวีบ้าง ในแล็บนี้ คุณจะได้สร้างการกระทําอย่างง่ายโดยใช้ Dialogflow และเรียนรู้วิธีผสานรวมกับการกระทําของ Google Assistant
แบบฝึกหัดจะเรียงตามลำดับเพื่อให้สอดคล้องกับประสบการณ์การใช้งานของผู้พัฒนาบนระบบคลาวด์ทั่วไป
- สร้าง Agent Dialogflow v2
- สร้างเอนทิตีที่กำหนดเอง
- สร้างความตั้งใจ
- ตั้งค่า Webhook ด้วย Firebase Functions
- ทดสอบแชทบ็อต
- เปิดใช้การผสานรวม 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 ทดสอบชั่วคราวเพื่อให้ทดสอบเว็บฮุกได้ในภายหลัง
- คลิกรายการเมนูเจตนาอีกครั้ง
- คลิกสร้างความตั้งใจ
- ป้อนชื่อความตั้งใจ:
Test Intent(ตรวจสอบว่าคุณใช้ T และ I ตัวพิมพ์ใหญ่ - หากคุณสะกดเจตนาแตกต่างออกไป บริการแบ็กเอนด์จะทำงานไม่ได้)

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

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

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

- คลิกบันทึก
สร้างความตั้งใจของแชแนล
เจตนาของช่องจะมีส่วนของการสนทนาต่อไปนี้
ผู้ใช้ | 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"
}
}

- คลิกปุ่มติดตั้งใช้งาน ระบบจะใช้เวลาสักครู่เนื่องจากกำลังติดตั้งฟังก์ชันแบบไม่ใช้เซิร์ฟเวอร์ ป๊อปอัปจะปรากฏที่ด้านล่างของหน้าจอเพื่อแจ้งสถานะของคุณ
- มาทดสอบเว็บฮุกเพื่อดูว่าโค้ดใช้งานได้ไหม ในโปรแกรมจำลองทางด้านขวา ให้พิมพ์
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 "ดั้งเดิม" ซึ่งหมายความว่าทุกสิ่งที่คุณขอจากเอเจนต์นับจากนี้ไปจะต้องสร้างขึ้นโดยคุณ คุณไม่สามารถถาม Google Assistant เกี่ยวกับข้อมูลสภาพอากาศของ Google ได้ทันทีหากต้องการทราบข้อมูลดังกล่าว คุณควรออกจาก (ปิด) ขอบเขตของการดำเนินการ (แอปของคุณ) ก่อน
ทดสอบการดำเนินการในโปรแกรมจำลอง Google Assistant
มาทดสอบการสนทนาต่อไปนี้กัน
ผู้ใช้ | Google Assistant |
"Ok Google คุยกับyour-name-tv-guide" | "ได้เลย ขอดูyour-name-tv-guide หน่อย" |
ผู้ใช้ | ตัวแทน Your-Name-TV-Guide |
- | "ยินดีต้อนรับ ฉันคือทีวีไกด์...." |
ทดสอบ Agent ของฉัน | "นี่คือข้อความทดสอบ เมื่อคุณเห็นข้อความนี้ แสดงว่าการดำเนินการตามคำสั่งของ Webhook ทำงานแล้ว" |
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 นี้ต่อโดยผสานรวมกับ Google Chat
สร้างแชท Google Chat สำหรับรายการทีวีด้วย G Suite และ Dialogflow
- สร้างการทำงานสำหรับ Google Assistant ด้วย Dialogflow (ระดับ 1)
- สร้าง Actions สำหรับ Google Assistant ด้วย Dialogflow (ระดับ 2)
- สร้าง Actions สำหรับ Google Assistant ด้วย Dialogflow (ระดับ 3)
- ทำความเข้าใจการดำเนินการตามคำสั่งโดยการผสานรวม Dialogflow กับ Google ปฏิทิน
- ผสานรวม Google Cloud Vision API กับ Dialogflow
