ลงมือปฏิบัติ: สร้างการดำเนินการสำหรับทีวีไกด์สำหรับ Google Assistant ด้วย Dialogflow และ Actions on Google

1. บทนำ

คุณกำลังดูทีวีแต่หารีโมตไม่เจอหรือไม่ได้อยากไปที่ช่องทีวีแต่ละช่องเพื่อดูว่ามีอะไรดีๆ บนโทรทัศน์ไหม มาถาม Google Assistant กันว่ามีอะไรฉายในทีวีบ้าง ในห้องทดลองนี้ คุณจะได้สร้างการทำงานง่ายๆ โดยใช้ Dialogflow และเรียนรู้วิธีผสานรวมกับ Google Assistant

แบบฝึกหัดนี้จัดทำขึ้นเพื่อแสดงให้เห็นถึงประสบการณ์ที่นักพัฒนาซอฟต์แวร์ระบบคลาวด์พบได้บ่อย ดังนี้

  1. สร้าง Agent ของ Dialogflow v2
  2. สร้างเอนทิตีที่กำหนดเอง
  3. สร้าง Intent
  4. ตั้งค่าเว็บฮุคด้วยฟังก์ชันของ Firebase
  5. ทดสอบแชทบ็อต
  6. เปิดใช้การผสานรวม Google Assistant

สิ่งที่คุณจะสร้าง

เราจะสร้างตัวแทนแชทบ็อตทีวีแบบอินเทอร์แอกทีฟสำหรับ Google Assistant คุณถามทีวีไกด์ว่ากำลังออกอากาศอะไรอยู่ในช่องใดช่องหนึ่งได้ในตอนนี้ ตัวอย่างเช่น "มีอะไรฉายใน MTV บ้าง" การดำเนินการของ TV Guide จะบอกคุณว่ากำลังเล่นอะไรอยู่และจะเกิดอะไรขึ้นต่อไป

สิ่งที่คุณจะได้เรียนรู้

  • วิธีสร้างแชทบ็อตด้วย Dialogflow v2
  • วิธีสร้างเอนทิตีที่กำหนดเองด้วย Dialogflow
  • วิธีสร้างการสนทนาเชิงเส้นด้วย Dialogflow
  • วิธีตั้งค่าการตอบสนองเว็บฮุคด้วย Dialogflow และฟังก์ชัน Firebase
  • วิธีนำแอปพลิเคชันของคุณมาสู่ Google Assistant ด้วย Actions on Google

ข้อกำหนดเบื้องต้น

  • คุณต้องใช้อีเมลของ Google / Gmail เพื่อสร้าง Agent ของ Dialogflow
  • คุณไม่จำเป็นต้องมีความรู้พื้นฐานเกี่ยวกับ JavaScript แต่จะมีประโยชน์ในกรณีที่คุณต้องการเปลี่ยนโค้ดการดำเนินการของเว็บฮุค

2. การตั้งค่า

เปิดใช้กิจกรรมบนเว็บในเบราว์เซอร์

  1. คลิกที่ http://myaccount.google.com/activitycontrols

  1. ตรวจสอบให้แน่ใจว่าเว็บและ กิจกรรมบนแอปเปิดอยู่

bf8d16b828d6f79a.png

สร้าง Agent ของ 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. ป้อนคำอธิบาย Agent ต่อไปนี้ My TV Guide

26f262d359c49075.png

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

e80c17acc3cce993.png

  1. คลิกบันทึก

กำหนดค่า Actions on Google

  1. คลิกลิงก์ Google Assistant ในหัวข้อดูวิธีการทำงานใน Google Assistant ในแผงด้านขวามือ

5a4940338fc351e3.png

ซึ่งจะเปิดขึ้นใน http://console.actions.google.com

เมื่อเพิ่งเริ่มใช้ Actions on Google คุณจะต้องกรอกข้อมูลในแบบฟอร์มนี้ก่อน

3fd4e594fa169072.png

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

6adb83ffb7adeb78.png

  1. ตรวจสอบว่าเครื่องจำลองมีการตั้งค่าเป็นภาษาอังกฤษ และคลิกพูดกับแอปทดสอบของฉัน

การดำเนินการจะทักทายคุณด้วย Intent เริ่มต้นของ Dialogflow พื้นฐาน ซึ่งหมายความว่าการตั้งค่าการผสานรวมกับ Action on Google จะได้ผล

3. เอนทิตีที่กำหนดเอง

เอนทิตีคือออบเจ็กต์ที่แอปหรืออุปกรณ์ของคุณดำเนินการ เปรียบเสมือนพารามิเตอร์ / ตัวแปร ในคู่มือทีวี เราจะถามว่า "มีอะไรฉายใน MTV" บ้าง MTV คือเอนทิตีและตัวแปร เราขอแนะนำช่องอื่นด้วย เช่น "National Geo" หรือ "Comedy Central" ระบบจะใช้เอนทิตีที่รวบรวมไว้เป็นพารามิเตอร์ในคำขอของฉันที่ส่งไปยังบริการผ่านเว็บของ TV Guide API

ดูข้อมูลเพิ่มเติมเกี่ยวกับเอนทิตีของ Dialogflow

การสร้างเอนทิตีของช่อง

  1. คลิกใน Dialogflow Console ที่รายการเมนู: เอนทิตี
  2. คลิกสร้างเอนทิตี
  3. ชื่อเอนทิตี: channel (ตรวจสอบว่าเป็นตัวพิมพ์เล็กทั้งหมด)
  4. ส่งด้วยชื่อช่อง (บางช่องจะต้องใช้คำพ้องความหมายในกรณีที่ Google Assistant เข้าใจอย่างอื่น) คุณสามารถใช้แป้น Tab และ Enter ได้ขณะพิมพ์ ป้อนหมายเลขช่องเป็นค่าข้อมูลอ้างอิง และชื่อช่องเป็นคำพ้องความหมาย เช่น
  • 1 - 1, Net 1, Net Station 1

ee4e4955aa77232d.png

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

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. Intent

Dialogflow ใช้ความตั้งใจเพื่อจัดหมวดหมู่ความตั้งใจของผู้ใช้ Intent มีวลีการฝึกอบรม ซึ่งเป็นตัวอย่างสิ่งที่ผู้ใช้อาจพูดกับตัวแทนของคุณ เช่น ผู้ใช้ที่ต้องการรู้ว่ามีรายการอะไรในทีวีอาจถามว่า "วันนี้ทีวีมีอะไร" "ตอนนี้ฉายอะไรอยู่" หรือแค่พูดว่า "tvguide"

เมื่อผู้ใช้เขียนหรือพูดบางอย่าง ซึ่งเรียกว่านิพจน์ของผู้ใช้ Dialogflow จะจับคู่นิพจน์ของผู้ใช้กับความตั้งใจที่ดีที่สุดใน Agent การจับคู่ความตั้งใจเรียกอีกอย่างว่าการแยกประเภทความตั้งใจ

ดูข้อมูลเพิ่มเติมเกี่ยวกับ Dialogflow Intents

การแก้ไขจุดประสงค์ในการต้อนรับเริ่มต้น

เมื่อคุณสร้าง Agent ของ Dialogflow ใหม่ ระบบจะสร้าง Intent เริ่มต้น 2 รายการโดยอัตโนมัติ จุดประสงค์ในการต้อนรับเริ่มต้นเป็นขั้นตอนแรกที่คุณไปถึงเมื่อเริ่มต้นการสนทนากับตัวแทน Intent สำรองเริ่มต้น คือขั้นตอนที่คุณจะได้รับเมื่อตัวแทนไม่เข้าใจคุณ หรือจับคู่ Intent กับสิ่งที่คุณพูดไม่ได้

  1. คลิกจุดประสงค์เริ่มต้นในการต้อนรับ

ในกรณีของ Google Assistant ฟีเจอร์นี้จะเริ่มต้นโดยอัตโนมัติด้วย Intent การต้อนรับเริ่มต้น เนื่องจาก Dialogflow กำลังฟังกิจกรรมต้อนรับ อย่างไรก็ตาม คุณสามารถเรียกใช้ Intent ได้โดยพูดวลีการฝึกที่ป้อนมา 1 วลี

6beee64e8910b85d.png

ข้อความต้อนรับสำหรับจุดประสงค์เริ่มต้นในการต้อนรับมีดังนี้

ผู้ใช้

ตัวแทน

"Ok Google ขอคุยกับ your-name-tvguide"

"ยินดีต้อนรับ ฉันเป็นตัวแทนไกด์ทีวี ฉันบอกคุณได้ว่ากำลังฉายอะไรในช่องทีวี เช่น ถามได้เลยว่ามีอะไรใน MTV บ้าง"

  1. เลื่อนลงไปที่การตอบกลับ
  2. ล้างการตอบกลับข้อความทั้งหมด
  3. สร้างการตอบกลับข้อความใหม่ 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?

84a1110a7f7edba2.png

  1. คลิกบันทึก

สร้าง Intent ในการทดสอบชั่วคราว

เราจะสร้าง Intent ในการทดสอบชั่วคราวเพื่อทดสอบเว็บฮุคในภายหลัง

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

925e02caa4de6b99.png

  1. คลิกเพิ่มวลีการฝึก
  • Test my agent
  • Test intent

2e44ddb2fae3c841.png

  1. คลิกการดำเนินการตามคำสั่งซื้อ > เปิดใช้การดำเนินการตามคำสั่งซื้อ

7eb73ba04d76140e.png

ครั้งนี้เราไม่ได้ฮาร์ดโค้ดคำตอบ คำตอบจะมาจากฟังก์ชันระบบคลาวด์

  1. เลื่อนสวิตช์เปิดใช้การเรียกเว็บฮุคสำหรับ Intent นี้

748a82d9b4d7d253.png

  1. คลิกบันทึก

สร้างจุดประสงค์ของช่อง

ความตั้งใจของช่องจะประกอบด้วยการสนทนาส่วนนี้ ดังนี้

ผู้ใช้

ตัวแทน

"มีอะไรใน Comedy Central บ้าง"

""ขณะนี้ช่อง Comedy Central ตั้งแต่ 18:00 น. ทีม The Simpsons ฉายอยู่ หลังจากนั้นเวลา 19:00 น. Family Guy จะเริ่มเล่น""

  1. คลิกที่รายการในเมนู Intent อีกครั้ง
  2. คลิกสร้างความตั้งใจ
  3. ป้อนชื่อ Intent: Channel Intent (ใช้อักษรตัวพิมพ์ใหญ่ T และอักษรตัวพิมพ์ใหญ่ I) - หากคุณสะกด Intent ต่างกัน บริการแบ็กเอนด์จะไม่ทำงาน)
  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 ที่ Dialogflow รู้จัก ระบบจะส่งชื่อพารามิเตอร์และค่าพารามิเตอร์ไปยังบริการเว็บของคุณในภายหลังในเว็บฮุค เช่น

channel=8

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

  1. ทำเครื่องหมายช่องว่าต้องการ

เมื่อคุณสนทนากับตัวแทนคำแนะนำทีวี คุณจะต้องกรอกชื่อพารามิเตอร์ของช่อง 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. คลิกการดำเนินการตามคำสั่งซื้อ

ครั้งนี้เราไม่ได้ฮาร์ดโค้ดคำตอบ คำตอบจะมาจากฟังก์ชันระบบคลาวด์ จากนั้นเปิดสวิตช์เปิดใช้การเรียกเว็บฮุคสำหรับ Intent นี้

  1. คลิกบันทึก

5. การดำเนินการตามเว็บฮุค

หาก Agent ต้องการการตอบกลับ Intent แบบคงที่มากกว่า คุณต้องใช้ Fulfillment เพื่อเชื่อมต่อบริการบนเว็บกับ Agent ของคุณ การเชื่อมต่อบริการเว็บช่วยให้คุณดำเนินการตามนิพจน์ของผู้ใช้และส่งคำตอบแบบไดนามิกกลับไปให้ผู้ใช้ได้ ตัวอย่างเช่น หากผู้ใช้ต้องการรับกำหนดเวลาทีวีสำหรับ MTV บริการบนเว็บของคุณจะตรวจสอบในฐานข้อมูลและตอบกลับผู้ใช้ รวมถึงกำหนดเวลาสำหรับ MTV ได้

  1. คลิกการดำเนินการคำสั่งซื้อในเมนูหลัก
  2. เปิดใช้สวิตช์เครื่องมือแก้ไขในบรรทัด

cc84351f0d03ab6f.png

คุณสามารถใช้ตัวแก้ไขในบรรทัดหากต้องการทดสอบและติดตั้งเว็บฮุคแบบง่ายๆ โดยใช้ Cloud Functions for Firebase แบบ Serverless

  1. คลิกแท็บ 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);
});

cc84351f0d03ab6f.png

  1. คลิกแท็บ 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"
  }
}

af01460c2a023e68.png

  1. คลิกปุ่มทำให้ใช้งานได้ อาจใช้เวลาสักครู่ เนื่องจากกำลังทำให้ฟังก์ชันแบบ Serverless ใช้งานได้ ที่ด้านล่างของหน้าจอจะมีป๊อปอัปที่แจ้งสถานะของคุณ
  2. ลองทดสอบเว็บฮุคเพื่อดูว่าโค้ดทำงานได้ไหม ในเครื่องมือจำลองทางด้านขวา ให้พิมพ์

Test my agent.

เมื่อทุกอย่างถูกต้อง คุณควรเห็นข้อความ "นี่คือข้อความทดสอบ"

  1. มาทดสอบจุดประสงค์ของช่องกัน แล้วถามคำถามต่อไปนี้

What's on MTV?

เมื่อข้อมูลทุกอย่างถูกต้อง คุณควรจะเห็นสิ่งต่อไปนี้

"ใน MTV ตั้งแต่เวลา 16:00 น. MTV Unplugged และหลังจากนั้น เวลา 17:00 น. Rupauls Drag Race จะเริ่มต้นขึ้น"

ขั้นตอนทางเลือก - Firebase

เมื่อทดสอบกับช่องอื่น คุณจะสังเกตเห็นว่าผลการดูทีวีเหมือนกัน เนื่องจากฟังก์ชันระบบคลาวด์ยังไม่ได้ดึงข้อมูลจากเว็บเซิร์ฟเวอร์จริง

ในการดำเนินการดังกล่าว เราจะต้องเชื่อมต่อเครือข่ายขาออก

หากต้องการทดสอบแอปพลิเคชันนี้กับบริการบนเว็บ ให้อัปเกรดแผน Firebase เป็น Blaze หมายเหตุ: ขั้นตอนเหล่านี้เป็นขั้นตอนที่ไม่บังคับ นอกจากนี้คุณยังสามารถไปที่ขั้นตอนถัดไปของห้องทดลองนี้เพื่อทดสอบแอปพลิเคชันต่อใน Actions on Google

  1. ไปที่คอนโซล Firebase: https://console.firebase.google.com

  1. ที่ด้านล่างของหน้าจอ ให้กดปุ่มอัปเกรด

ad38bc6d07462abf.png

เลือกแพ็กเกจ Blaze ในป๊อปอัป

  1. เมื่อเราทราบแล้วว่าเว็บฮุคทำงานได้แล้ว ต่อไปก็ดำเนินการต่อและแทนที่โค้ดของ 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 Assistant

ลองทดสอบการสนทนาต่อไปนี้

ผู้ใช้

Google Assistant

"Ok Google คุยกับ your-name-tv-guide"

"ได้สิ ขอฟัง your-name-tv-guide หน่อย"

ผู้ใช้

ตัวแทน Your-Name-TV-Guide

-

"ยินดีต้อนรับ นี่คือทีวีไกด์...."

ทดสอบตัวแทนของฉัน

"นี่คือข้อความทดสอบ เมื่อเห็นข้อความนี้ แสดงว่าการตอบสนองเว็บฮุคใช้งานได้"

มีอะไรฉายใน MTV บ้าง

ใน MTV ตั้งแต่เวลา 16:00 น. MTV Unplugged และหลังจากนั้น เวลา 17:00 น.จะเริ่มเล่น Rupauls Drag Race

  1. เปลี่ยนกลับไปใช้เครื่องจำลอง Google Assistant

เปิด: https://console.actions.google.com

  1. คลิกไอคอนไมโครโฟนและถามคำถามต่อไปนี้

c3b200803c7ba95e.png

  • Talk to my test agent
  • Test my agent

Google Assistant ควรตอบกลับด้วยข้อความต่อไปนี้

5d93c6d037c8c8eb.png

  1. คราวนี้ลองถามตัวเองว่า
  • 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 จริง คุณจะส่งการดำเนินการเพื่อขออนุมัติได้ อ่านคู่มือนี้เพื่อดูข้อมูลเพิ่มเติม

หัวข้อที่ครอบคลุม

  • วิธีสร้างแชทบ็อตด้วย Dialogflow v2
  • วิธีสร้างเอนทิตีที่กำหนดเองด้วย Dialogflow
  • วิธีสร้างการสนทนาเชิงเส้นด้วย Dialogflow
  • วิธีตั้งค่าการตอบสนองเว็บฮุคด้วย Dialogflow และฟังก์ชัน Firebase
  • วิธีนำแอปพลิเคชันของคุณมาสู่ Google Assistant ด้วย Actions on Google

สิ่งที่ต้องทำต่อไป

ชอบ Code Lab นี้ไหม ลองดูห้องทดลองที่ยอดเยี่ยมเหล่านี้สิ

ใช้ Code Lab นี้ต่อโดยการผสานรวมกับ Google Chat

สร้างคู่มือรายการทีวี Google Chat ด้วย G Suite และ Dialogflow