Thực hành: Tạo một thao tác trong hướng dẫn về chương trình truyền hình cho Trợ lý Google bằng Dialogflow và Actions on Google

1. Giới thiệu

Bạn đang xem tivi, nhưng không tìm thấy điều khiển từ xa hoặc có lẽ bạn không muốn truy cập từng kênh tivi để tìm hiểu xem có điều gì thú vị trên tivi không? Hãy hỏi Trợ lý Google xem gì trên TV! Trong phòng thí nghiệm này, bạn sẽ tạo một thao tác đơn giản bằng Dialogflow và tìm hiểu cách tích hợp công cụ này với Trợ lý Google.

Các bài tập được sắp xếp để phản ánh trải nghiệm phổ biến của nhà phát triển trên đám mây:

  1. Tạo nhân viên hỗ trợ Dialogflow phiên bản 2
  2. Tạo thực thể tuỳ chỉnh
  3. Tạo ý định
  4. Thiết lập webhook bằng Hàm Firebase
  5. Kiểm thử bot trò chuyện
  6. Bật tính năng tích hợp Trợ lý Google

Sản phẩm bạn sẽ tạo ra

Chúng tôi sẽ xây dựng một nhân viên hỗ trợ bot trò chuyện có hướng dẫn truyền hình tương tác cho Trợ lý Google. Bạn có thể hỏi Guide Guide về chương trình truyền hình về nội dung đang phát sóng trên một kênh cụ thể. Ví dụ: "Có gì trên MTV?" Hành động trong Hướng dẫn truyền hình sẽ cho bạn biết nội dung nào đang phát và nội dung nào sẽ phát tiếp theo.

Kiến thức bạn sẽ học được

  • Cách tạo bot trò chuyện bằng Dialogflow phiên bản 2
  • Cách tạo thực thể tuỳ chỉnh bằng Dialogflow
  • Cách tạo cuộc trò chuyện tuyến tính bằng Dialogflow
  • Cách thiết lập phương thức thực hiện webhook bằng Dialogflow và Hàm Firebase
  • Cách đưa ứng dụng của bạn lên Trợ lý Google bằng Actions on Google

Điều kiện tiên quyết

  • Bạn cần có một địa chỉ Google Identity / Gmail để tạo nhân viên hỗ trợ Dialogflow.
  • Bạn không bắt buộc phải có kiến thức cơ bản về JavaScript, nhưng có thể áp dụng nếu muốn thay đổi mã thực hiện webhook.

2. Thiết lập

Bật chế độ Hoạt động trên web trong trình duyệt

  1. Lượt nhấp: http://myaccount.google.com/activitycontrols

  1. Đảm bảo Web & Hoạt động ứng dụng được bật:

bf8d16b828d6f79a.png

Tạo nhân viên hỗ trợ dự án Dialogflow

  1. Mở: https://console.dialogflow.com

  1. Trên thanh bên trái, bên dưới biểu trưng, hãy chọn "Create New Agent" (Tạo nhân viên hỗ trợ mới). Trong trường hợp bạn đang có nhân viên hỗ trợ, trước tiên, hãy nhấp vào trình đơn thả xuống.

1d7c2b56a1ab95b8.pngS

  1. Chỉ định tên nhân viên hỗ trợ: your-name-tvguide (hãy dùng tên của chính bạn)

35237b5c5c539ecc.pngS

  1. Để làm ngôn ngữ mặc định, hãy chọn: Tiếng Anh – en
  2. Làm múi giờ mặc định, chọn múi giờ gần bạn nhất.
  3. Nhấp vào Tạo

Định cấu hình Dialogflow

  1. Nhấp vào biểu tượng bánh răng trong trình đơn bên trái, bên cạnh tên dự án.

1d7c2b56a1ab95b8.pngS

  1. Nhập nội dung mô tả nhân viên hỗ trợ sau: My TV Guide

26f262d359c49075.pngS

  1. Di chuyển xuống phần Cài đặt nhật ký rồi gạt cả hai nút chuyển để Ghi lại hoạt động tương tác của Dialogflow và để ghi tất cả hoạt động tương tác trong Google Cloud Stackdriver. Chúng ta sẽ cần thông tin này vào lúc khác, phòng trường hợp muốn gỡ lỗi hành động của mình.

e80c17acc3cce993.png

  1. Nhấp vào Lưu

Định cấu hình Actions on Google

  1. Nhấp vào đường liên kết đến Trợ lý Google trong phần Xem cách hoạt động của tính năng này trong Trợ lý Google ở bảng điều khiển bên phải.

5a4940338fc351e3.pngS

Thao tác này sẽ mở ra: http://console.actions.google.com

Khi mới sử dụng Actions on Google, trước tiên, bạn cần điền vào biểu mẫu này:

3fd4e594fa169072.pngS

  1. Hãy thử mở thao tác của bạn trong trình mô phỏng** bằng cách nhấp vào tên dự án.**
  2. Chọn Test (Kiểm thử) trong thanh trình đơn

6adb83ffb7adeb78.png

  1. Hãy đảm bảo rằng bạn đặt trình mô phỏng thành Tiếng Anh và Nhấp vào Trò chuyện với ứng dụng thử nghiệm của tôi

Thao tác sẽ chào đón bạn, với ý định mặc định cơ bản của Dialogflow. Điều đó có nghĩa là việc thiết lập chế độ tích hợp với Action on Google đã mang lại hiệu quả!

3. Pháp nhân tuỳ chỉnh

Thực thể là những đối tượng mà ứng dụng hoặc thiết bị của bạn thực hiện hành động. Hãy coi đây là các tham số / biến. Trong phần Hướng dẫn về truyền hình, chúng ta sẽ hỏi: "MTV đang chiếu gì". MTV là thực thể và biến. Tôi cũng có thể hỏi các kênh khác, chẳng hạn như: "National Địa lý" hoặc "Trung tâm hài kịch". Thực thể được thu thập sẽ được dùng làm tham số trong yêu cầu của tôi tới dịch vụ web TV Guide API.

Đây là thông tin khác về các Thực thể Dialogflow.

Tạo thực thể kênh

  1. Nhấp vào Bảng điều khiển Dialogflow trên mục trong trình đơn: Thực thể
  2. Nhấp vào Tạo thực thể
  3. Tên thực thể: channel (hãy đảm bảo tất cả đều là chữ thường)
  4. Nhập tên kênh. (một số kênh sẽ cần từ đồng nghĩa trong trường hợp Trợ lý Google hiểu được nội dung khác). Bạn có thể sử dụng phím tab và phím Enter trong khi nhập. Nhập số kênh làm giá trị tham chiếu. Và tên kênh là từ đồng nghĩa, chẳng hạn như:
  • 1 - 1, Net 1, Net Station 1

ee4e4955aa77232d.png

5**.** Chuyển sang chế độ **Chỉnh sửa thô** bằng cách nhấp vào nút trình đơn bên cạnh nút lưu màu xanh dương.

e294b49b123e034f.png

  1. Sao chép và dán các thực thể khác vào định dạng 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. Nhấp vào Lưu

4. Ý định

Dialogflow sử dụng ý định để phân loại ý định của người dùng. Ý định có các Cụm từ huấn luyện, là ví dụ về những gì người dùng có thể nói với tác nhân của bạn. Ví dụ: người dùng muốn biết có gì trên TV có thể hỏi "TV hôm nay có gì?", "Nội dung gì đang phát?" hoặc chỉ cần nói "tvguide".

Khi người dùng viết hoặc nói điều gì đó, còn gọi là biểu thức người dùng, Dialogflow sẽ so khớp biểu thức người dùng với ý định tốt nhất mà nhân viên hỗ trợ của bạn có được. Việc so khớp một ý định còn được gọi là phân loại ý định.

Dưới đây là thông tin khác về ý định Dialogflow.

Sửa đổi ý định chào mừng mặc định

Khi bạn tạo một nhân viên hỗ trợ Dialogflow mới, 2 ý định mặc định sẽ được tạo tự động. Ý định chào mừng mặc định là quy trình đầu tiên bạn thực hiện khi bắt đầu cuộc trò chuyện với nhân viên hỗ trợ. Ý định dự phòng mặc định là luồng bạn sẽ nhận được khi tác nhân không thể hiểu ý định của bạn hoặc không thể so khớp một ý định với ý định bạn vừa nói.

  1. Nhấp vào Ý định chào mừng mặc định

Trong trường hợp Trợ lý Google, Trợ lý sẽ tự động bắt đầu bằng Ý định chào mừng mặc định. Lý do là Dialogflow đang nghe Sự kiện chào mừng. Tuy nhiên, bạn cũng có thể gọi ý định bằng cách nói một trong các cụm từ huấn luyện đã nhập.

6beee64e8910b85d.png.

Dưới đây là tin nhắn chào mừng của Ý định chào mừng mặc định:

User

Nhân viên hỗ trợ

"Ok Google, trò chuyện với hướng dẫn viên tên-tv."

"Chào mừng bạn, tôi là nhân viên hỗ trợ của TV Guide. Tôi có thể cho bạn biết nội dung nào đang phát trên một kênh tivi. Ví dụ: Bạn có thể hỏi tôi: MTV có gì."

  1. Di chuyển xuống phần Câu trả lời.
  2. Xoá tất cả câu trả lời dạng văn bản.
  3. Tạo một phản hồi mới bằng văn bản, chứa lời chào sau đây:

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

  1. Nhấp vào Lưu

Tạo một ý định kiểm thử tạm thời

Vì mục đích thử nghiệm, chúng tôi sẽ tạo ý định thử nghiệm tạm thời để có thể thử nghiệm webhook sau này.

  1. Nhấp lại vào mục trong trình đơn Intents (Ý định).
  2. Nhấp vào Tạo ý định
  3. Nhập Tên ý định: Test Intent (hãy nhớ sử dụng chữ T viết hoa và I viết hoa. – Nếu bạn viết ý định theo cách khác, thì dịch vụ phụ trợ sẽ không hoạt động!)

925e02caa4de6b99.pngS

  1. Nhấp vào Thêm cụm từ huấn luyện
  • Test my agent
  • Test intent

2e44ddb2fae3c841.png.

  1. Nhấp vào Thực hiện đơn hàng > Bật tính năng thực hiện đơn hàng

7eb73ba04d76140e.png.

Lần này, chúng tôi không mã hoá cứng phản hồi. Phản hồi sẽ đến từ chức năng đám mây!

  1. Lật nút chuyển Bật lệnh gọi Webhook cho ý định này.

748a82d9b4d7d253.pngS

  1. Nhấp vào Lưu

Tạo ý định kênh

Channel Intent (Ý định kênh) sẽ chứa phần sau của cuộc trò chuyện:

User

Nhân viên hỗ trợ

"Có gì trên Comedy Central?"

""Hiện có trên Comedy Central từ 6 giờ chiều, Gia đình gia đình đang phát. Sau 7 giờ tối, Family Guy sẽ bắt đầu.""

  1. Nhấp lại vào mục trong trình đơn Intents (Ý định).
  2. Nhấp vào Tạo ý định
  3. Nhập Tên ý định: Channel Intent (hãy nhớ sử dụng chữ T viết hoa và chữ I viết hoa. – Nếu bạn viết ý định theo cách khác, thì dịch vụ phụ trợ sẽ không hoạt động!)
  4. Nhấp vào Thêm cụm từ huấn luyện rồi thêm đoạn mã sau:
  • 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.pngS

  1. Di chuyển xuống mục Hành động và thông số

b7e917026760218a.png

Để ý đến biểu tượng @channel và Các thực thể @sys.time mà Dialogflow biết. Sau đó trong webhook, tên thông số và giá trị thông số sẽ được gửi đến dịch vụ web của bạn. Ví dụ:

channel=8

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

  1. Đánh dấu channel là rEqured

Khi trò chuyện với nhân viên hỗ trợ TV Guide, bạn sẽ luôn phải điền tên kênh cho thông số vị trí. Nếu tên kênh không được đề cập trong phần đầu cuộc trò chuyện, thì Dialogflow sẽ hỏi thêm, cho đến khi họ điền hết tất cả các ô thông số. 6f36973fd789c182.pngs

Với lời nhắc, hãy nhập:

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

cdb5601ead9423f8.png

  1. Không đặt thông số thời gian theo yêu cầu.

Bạn không bắt buộc phải chọn thời gian. Khi bạn không chỉ định thời gian, dịch vụ web sẽ trả về thời gian hiện tại.

  1. Nhấp vào Thực hiện đơn hàng

Lần này, chúng tôi không mã hoá cứng phản hồi. Phản hồi sẽ đến từ chức năng đám mây! Do đó, hãy lật nút chuyển Bật lệnh gọi Webhook cho ý định này.

  1. Nhấp vào Lưu

5. Thực hiện webhook

Nếu tác nhân của bạn cần nhiều hơn phản hồi ý định tĩnh, bạn cần sử dụng phương thức thực hiện để kết nối dịch vụ web với tác nhân. Việc kết nối dịch vụ web cho phép bạn hành động dựa trên biểu cảm của người dùng và gửi lại phản hồi động cho người dùng. Ví dụ: nếu người dùng muốn nhận lịch phát sóng truyền hình của MTV, thì dịch vụ web của bạn có thể kiểm tra trong cơ sở dữ liệu của bạn và phản hồi người dùng, lịch biểu của MTV.

  1. Nhấp vào Thực hiện đơn hàng trong trình đơn chính
  2. Bật nút chuyển Trình chỉnh sửa cùng dòng

cc84351f0d03ab6f.png

Để thử nghiệm và triển khai webhook đơn giản, bạn có thể sử dụng trình chỉnh sửa cùng dòng. Giải pháp này sử dụng Chức năng đám mây dành cho Firebase không máy chủ.

  1. Nhấp vào thẻ index.js trong trình chỉnh sửa và sao chép, dán đoạn mã JavaScript này cho mã 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. Nhấp vào thẻ package.json trong trình chỉnh sửa rồi sao chép, dán đoạn mã JSON sau. Mã này sẽ nhập tất cả các thư viện Node.js Package Manager (chặn) Node.js:
{
  "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. Nhấp vào nút Deploy (Triển khai). Quá trình này sẽ mất chút thời gian vì hệ thống đang triển khai chức năng không máy chủ. Ở cuối màn hình, sẽ có một cửa sổ bật lên cho biết trạng thái của bạn.
  2. Hãy kiểm tra webhook để xem mã có hoạt động hay không. Trong trình mô phỏng ở phía bên phải, hãy nhập:

Test my agent.

Khi mọi thông tin đều chính xác, bạn sẽ thấy thông báo: "Đây là tin nhắn thử nghiệm".

  1. Hãy kiểm thử ý định của kênh, bây giờ hãy đặt câu hỏi:

What's on MTV?

Khi mọi thông tin đều chính xác, bạn sẽ thấy:

"Trên MTV từ 4 giờ 30 chiều, MTV Takeout sẽ phát. Sau đó, lúc 5 giờ 30 chiều, Cuộc đua kéo Rupauls sẽ bắt đầu."

Các bước không bắt buộc – Firebase

Khi thử nghiệm kết quả này với một kênh khác, bạn sẽ nhận thấy các kết quả trên TV đều giống nhau. Điều này là do chức năng đám mây chưa được tìm nạp từ máy chủ web thực.

Để thực hiện việc này, chúng tôi cần tạo một kết nối mạng ra ngoài.

Trong trường hợp bạn muốn thử nghiệm ứng dụng này bằng một dịch vụ web, hãy nâng cấp gói Firebase của bạn lên Blaze. Lưu ý: những bước này là không bắt buộc. Bạn cũng có thể chuyển sang các bước tiếp theo của phòng thí nghiệm này để tiếp tục kiểm thử ứng dụng trong Actions on Google.

  1. Chuyển đến bảng điều khiển của Firebase: https://console.firebase.google.com

  1. Ở cuối màn hình, hãy nhấn nút Nâng cấp

ad38bc6d07462abf.png

Chọn gói Blaze trong cửa sổ bật lên.

  1. Vì đã biết webhook đang hoạt động, nên chúng ta có thể tiếp tục và thay thế mã index.js bằng mã bên dưới. Điều này đảm bảo rằng bạn có thể yêu cầu thông tin hướng dẫn về chương trình truyền hình từ dịch vụ web:
'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 là một nền tảng phát triển dành cho Trợ lý Google. API này cho phép bên thứ ba phát triển "hành động" – các chương trình phụ trợ dành cho Trợ lý Google nhằm cung cấp chức năng mở rộng.

Bạn sẽ cần gọi một Hành động của Google bằng cách yêu cầu Google mở hoặc trò chuyện với một ứng dụng.

Thao tác này sẽ mở hành động của bạn, thay đổi giọng nói và bạn sẽ thoát khỏi "gốc" Phạm vi của Trợ lý Google. Tức là mọi nội dung bạn yêu cầu nhân viên hỗ trợ của bạn bắt đầu từ thời điểm này đều phải do bạn tạo. Bạn không thể đột nhiên hỏi Trợ lý Google thông tin thời tiết nếu đó là điều bạn muốn; bạn nên để (đóng) phạm vi hành động (ứng dụng của bạn) trước.

Thử nghiệm hành động trong trình mô phỏng Trợ lý Google

Hãy kiểm tra cuộc trò chuyện sau:

User

Trợ lý Google

"Ok Google, nói chuyện với your-name-tv-guide."

"Chắc chắn rồi. Để tôi tìm giúp bạn your-name-tv-guide."

User

Nhân viên hỗ trợ hướng dẫn viên trong TV tên bạn

-

"Chào mừng bạn, tôi là hướng dẫn viên truyền hình...."

Thử nghiệm nhân viên hỗ trợ

"Đây là tin nhắn thử nghiệm. Nếu bạn nhìn thấy thông báo này, điều đó có nghĩa là phương thức thực hiện webhook của bạn đã hoạt động!"

MTV có gì?

Trên MTV từ 4 giờ 30 chiều, MTV Takeout sẽ phát. Sau đó, lúc 5 giờ 30 chiều, Cuộc đua kéo Rupauls sẽ bắt đầu.

  1. Chuyển về trình mô phỏng Trợ lý Google

Mở: https://console.action.google.com

  1. Hãy nhấp vào biểu tượng micrô và hỏi những điều sau:

c3b200803c7ba95e.png

  • Talk to my test agent
  • Test my agent

Trợ lý Google sẽ phản hồi bằng:

5d93c6d037c8c8eb.png.

  1. Giờ hãy đặt câu hỏi:
  • What's on Comedy Central?

Giá trị này sẽ trả về:

Hiện có trên Comedy Central từ 6 giờ chiều và The gia đình bạn đang chiếu. Sau 7 giờ tối, Family Guy sẽ bắt đầu.

7. Xin chúc mừng

Rất tốt! Bạn đã tạo hành động đầu tiên của mình trên Trợ lý Google bằng Dialogflow!

Như bạn có thể nhận thấy, hành động của bạn đang chạy ở chế độ thử nghiệm được liên kết với Tài khoản Google của bạn. Nếu bạn đăng nhập vào thiết bị Nest hoặc ứng dụng Trợ lý Google trên điện thoại iOS hoặc Android bằng cùng một tài khoản. Bạn cũng có thể kiểm thử hành động của mình.

Hiện tại, đây là bản minh hoạ hội thảo. Tuy nhiên, trong quá trình xây dựng ứng dụng thực sự cho Trợ lý Google, bạn có thể gửi Hành động của mình để yêu cầu phê duyệt. Hãy đọc hướng dẫn này để biết thêm thông tin.

Nội dung đã đề cập

  • Cách tạo bot trò chuyện bằng Dialogflow phiên bản 2
  • Cách tạo thực thể tuỳ chỉnh bằng Dialogflow
  • Cách tạo cuộc trò chuyện tuyến tính bằng Dialogflow
  • Cách thiết lập phương thức thực hiện webhook bằng Dialogflow và Hàm Firebase
  • Cách đưa ứng dụng của bạn lên Trợ lý Google bằng Actions on Google

Tiếp theo là gì?

Bạn thích lớp học lập trình này? Hãy khám phá các phòng thí nghiệm tuyệt vời này!

Tiếp tục lớp học lập trình này bằng cách tích hợp lớp học lập trình này vào Google Chat:

Tạo hướng dẫn về Google Chat cho TV bằng G Suite và Dialogflow