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 TV nhưng không tìm thấy điều khiển từ xa, hoặc có thể bạn không muốn truy cập vào từng kênh truyền hình để xem có nội dung nào hay không? Hãy hỏi Trợ lý Google xem có 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 thao tác đó với Trợ lý Google.

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

  1. Tạo một nhân viên hỗ trợ dự án 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ử chatbot
  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 ta sẽ tạo một tác nhân chatbot hướng dẫn chương trình truyền hình tương tác cho Trợ lý Google. Bạn có thể hỏi hướng dẫn truyền hình về chương trình đang phát sóng trên một kênh cụ thể. Ví dụ: "What's on MTV?" (MTV đang chiếu gì?) Thao tác TV Guide (Hướng dẫn truyền hình) sẽ cho bạn biết chương trình đang phát và chương trình sẽ phát tiếp theo.

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

  • Cách tạo chatbot 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 yêu cầu 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 sẽ cần có một danh tính Google / địa chỉ Gmail để tạo một tác nhân Dialogflow.
  • Bạn không cần có kiến thức cơ bản về JavaScript, nhưng kiến thức này có thể hữu ích trong trường hợp bạn 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. Nhấp vào: http://myaccount.google.com/activitycontrols

  1. Đảm bảo chế độ Hoạt động trên web và ứng dụng đang ở trạng thái bật:

bf8d16b828d6f79a.png

Tạo một nhân viên hỗ trợ Dialogflow

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

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

1d7c2b56a1ab95b8.png

  1. Chỉ định tên nhân viên hỗ trợ: your-name-tvguide (sử dụng tên của bạn)

35237b5c5c539ecc.png

  1. Chọn ngôn ngữ mặc định là: Tiếng Anh – en
  2. Chọn múi giờ gần bạn nhất làm múi giờ mặc định.
  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 của bạn.

1d7c2b56a1ab95b8.png

  1. Nhập nội dung mô tả sau đây về tác nhân: My TV Guide

26f262d359c49075.png

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

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 Trợ lý Google trong phần Xem cách hoạt động của Trợ lý Google ở bảng điều khiển bên phải.

5a4940338fc351e3.png

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

Nếu 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.png

  1. 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. Đảm bảo trình mô phỏng được đặt thành tiếng Anh và nhấp vào Talk to my test-app (Trò chuyện với ứng dụng thử nghiệm của tôi)

Hành động này sẽ chào bạn bằng ý định mặc định cơ bản của Dialogflow. Điều đó có nghĩa là bạn đã thiết lập thành công mối liên kết với Action on Google!

3. Thực thể 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 đó là các tham số / biến. Trong phần Lịch phát sóng truyền hình, chúng tôi sẽ hỏi: "MTV đang chiếu gì". MTV là thực thể và biến số. Tôi cũng có thể yêu cầu các kênh khác, chẳng hạn như "National Geographic" hoặc "Comedy Central". Thực thể được thu thập sẽ được dùng làm tham số trong yêu cầu của tôi đối với dịch vụ web API Hướng dẫn truyền hình.

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

Tạo thực thể Kênh

  1. Nhấp vào mục trong trình đơn Thực thể trên Bảng điều khiển Dialogflow
  2. Nhấp vào Tạo thực thể
  3. Tên pháp nhân: channel (đảm bảo tất cả đều là chữ thường)
  4. Truyền 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 nhầm). Bạn có thể 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 dưới dạng 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 ở đị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ụm từ huấn luyện, là ví dụ về những gì người dùng có thể nói với trợ lý ảo của bạn. Ví dụ: người dùng muốn biết chương trình đang phát trên TV có thể hỏi "Hôm nay có chương trình gì trên TV?", "What's currently playing?" (Chương trình đang phát sóng) hoặc chỉ cần nói "tvguide" (hướng dẫn truyền hình).

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

Sau đây là thông tin khác về Ý định trong Dialogflow.

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

Khi bạn tạo một đặc vụ Dialogflow mới, hai ý định mặc định sẽ được tạo tự động. Ý định chào mừng mặc định là luồng đầu tiên bạn nhận được 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 mà bạn sẽ nhận được khi tác nhân không hiểu bạn hoặc không thể so khớp ý định với những gì bạn vừa nói.

  1. Nhấp vào Default Welcome Intent (Ý đị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. Điều này là do Dialogflow đang lắng 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

Sau đây là thông điệp chào mừng cho Ý định chào mừng mặc định:

Người dùng

Tác nhân

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

"Chào mừng bạn, tôi là tác nhân Lịch phát sóng truyền hình. Tôi có thể cho bạn biết nội dung đang phát trên một kênh truyền hình. Ví dụ: bạn có thể hỏi tôi: "MTV đang chiếu gì?"

  1. Di chuyển xuống mục Câu trả lời.
  2. Xoá tất cả Phản hồi bằng văn bản.
  3. Tạo một câu trả lời dạng văn bản mới có 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.png

  1. Nhấp vào Lưu

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

Để kiểm thử, chúng ta sẽ tạo ý định kiểm thử tạm thời để có thể kiểm thử webhook sau này.

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

925e02caa4de6b99.png

  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 ta sẽ không mã hoá cứng một phản hồi. Phản hồi sẽ đến từ một hàm đám mây!

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

748a82d9b4d7d253.png

  1. Nhấp vào Lưu

Tạo ý định về kênh

Ý định của kênh sẽ chứa phần này của cuộc trò chuyện:

Người dùng

Tác nhân

"Comedy Central có gì?"

""Hiện tại, The Simpsons đang phát trên Comedy Central từ 18:00. Sau đó, lúc 7 giờ tối, phim Gia đình Simpson sẽ bắt đầu.""

  1. Nhấp lại vào mục trong trình đơn Ý định.
  2. Nhấp vào Tạo ý định
  3. Nhập Tên ý định: Channel Intent (nhớ dùng chữ T và chữ I viết hoa. – Nếu bạn đánh vần ý định theo cách khác, 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 những cụm từ 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.png

  1. Di chuyển xuống phần Hành động và thông số

b7e917026760218a.png

Hãy lưu ý các thực thể @channel@sys.time mà Dialogflow biết. Sau đó, trong webhook, tên tham số và giá trị tham 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 kênhbắt buộc

Khi trò chuyện với nhân viên hỗ trợ của Lịch phát sóng truyền hình, bạn luôn cần điền tên tham số vị trí channel. Nếu tên kênh không được đề cập ở đầu cuộc trò chuyện, Dialogflow sẽ hỏi thêm cho đến khi điền hết tất cả các vị trí tham số. 6f36973fd789c182.png

Nhập câu lệnh:

  • 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 tham số thời gian theo yêu cầu.

Thời gian là không bắt buộc. Khi không có thời gian nào được chỉ định, 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 ta sẽ không mã hoá cứng một phản hồi. Phản hồi sẽ đến từ hàm đám mây! Do đó, hãy chuyển công tắc Bật lệnh gọi Webhook cho ý định này.

  1. Nhấp vào Lưu

5. Webhook Fulfillment

Nếu cần nhiều hơn các câu trả lời tĩnh cho ý định, thì bạn cần sử dụng tính năng thực hiện để kết nối dịch vụ web với trợ lý ảo. Khi kết nối dịch vụ web, bạn có thể thực hiện các hành động dựa trên biểu thức của người dùng và gử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 của MTV, dịch vụ web của bạn có thể kiểm tra trong cơ sở dữ liệu và trả lời cho người dùng lịch phát sóng 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

Để kiểm thử và triển khai webhook đơn giản, bạn có thể sử dụng trình chỉnh sửa nội tuyến. Ứng dụng này sử dụng Cloud Functions cho Firebase không máy chủ.

  1. Nhấp vào thẻ index.js trong trình chỉnh sửa rồi sao chép và 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 và dán đoạn mã JSON này. Đoạn mã này sẽ nhập tất cả các thư viện của Trình quản lý gói Node.js (NPM):
{
  "name": "tvGuideFulfillment",
  "description": "Requesting TV Guide information from a web service.",
  "version": "1.0.0",
  "private": true,
  "license": "Apache Version 2.0",
  "author": "Google Inc.",
  "engines": {
    "node": "8"
  },
  "scripts": {
    "start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
    "deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
  },
  "dependencies": {
    "actions-on-google": "^2.2.0",
    "firebase-admin": "^5.13.1",
    "firebase-functions": "^2.0.2",
    "request": "^2.85.0",
    "request-promise": "^4.2.5",
    "moment" : "^2.24.0",
    "dialogflow-fulfillment": "^0.6.1"
  }
}

af01460c2a023e68.png

  1. Nhấp vào nút Triển khai. Quá trình này sẽ mất một chút thời gian vì nó đang triển khai hàm không cần máy chủ của bạn. Ở cuối màn hình, một cửa sổ bật lên sẽ xuất hiện để cho biết trạng thái của bạn.
  2. Hãy kiểm thử webhook để xem mã có hoạt động hay không. Trong trình mô phỏng ở bên phải, hãy nhập:

Test my agent.

Khi mọi thứ đều chính xác, bạn sẽ thấy: "Đây là một tin nhắn kiểm thử".

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

What's on MTV?

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

"MTV Unplugged đang phát sóng trên MTV từ 16:30. Sau đó, lúc 5 giờ 30 phút chiều, chương trình RuPaul's Drag Race sẽ bắt đầu."

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

Khi kiểm thử điều này với một kênh khác, bạn sẽ nhận thấy kết quả trên TV vẫn như vậy. Điều này là do hàm đám mây chưa tìm nạp từ một máy chủ web thực.

Để làm được việc này, chúng ta cần thiết lập một kết nối mạng đi.

Trong trường hợp bạn muốn kiểm thử ứ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 gói Blaze. Lưu ý: Bạn không bắt buộc phải thực hiện các bước này. Bạn cũng có thể chuyển sang các bước tiếp theo của lớp học này để tiếp tục kiểm thử ứng dụng của mình trong Actions on Google.

  1. Truy cập vào 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 vào nút Nâng cấp

ad38bc6d07462abf.png

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

  1. Giờ thì chúng ta đã biết rằng webhook hoạt động, chúng ta có thể tiếp tục và thay thế mã của index.js bằng mã bên dưới. Việc này sẽ đảm bảo rằng bạn có thể yêu cầu thông tin về hướng dẫn 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. Nền tảng này cho phép bên thứ ba phát triển "hành động" – các ứng dụng nhỏ cho Trợ lý Google có chức năng mở rộng.

Bạn sẽ cần gọi một Thao tác 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ẽ rời khỏi phạm vi của Trợ lý Google "gốc". Điều này có nghĩa là mọi thứ bạn yêu cầu nhân viên hỗ trợ từ thời điểm này đều do bạn tạo. Bạn không thể đột ngột yêu cầu Trợ lý Google cung cấp thông tin thời tiết của Google nếu đó là điều bạn muốn; trước tiên, bạn nên rời khỏi (đóng) phạm vi hành động (ứng dụng của bạn).

Kiểm thử hành động trong trình mô phỏng Trợ lý Google

Hãy thử cuộc trò chuyện sau:

Người dùng

Trợ lý Google

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

"Được. Để tôi lấy your-name-tv-guide."

Người dùng

Your-Name-TV-Guide Agent

-

"Chào mừng bạn đến với hướng dẫn về truyền hình...."

Thử nghiệm nhân viên hỗ trợ của tôi

"Đây là một tin nhắn kiểm thử. Khi bạn thấy tin nhắn này, tức là yêu cầu thực hiện webhook của bạn đã hoạt động!"

MTV có gì?

MTV Unplugged đang phát trên MTV từ 16:30. Sau đó, lúc 5 giờ 30 phút chiều, chương trình RuPaul's Drag Race sẽ bắt đầu.

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

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

  1. Nhấp vào biểu tượng micrô rồi hỏi những câ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. Bây giờ, hãy đặt câu hỏi:
  • What's on Comedy Central?

Thao tác này sẽ trả về:

The Simpsons hiện đang phát trên Comedy Central từ 18:00. Sau đó, vào lúc 7 giờ tối, phim Gia đình Simpson sẽ bắt đầu.

7. Xin chúc mừng

Bạn đã tạo hành động đầu tiên cho Trợ lý Google bằng Dialogflow. Chúc mừng bạn!

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.

Đây là bản minh hoạ trong hội thảo. Nhưng khi xây dựng các ứng dụng cho Trợ lý Google, bạn có thể gửi Hành động của mình để được 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 chatbot 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 yêu cầu 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 có thích lớp học lập trình này không? Hãy khám phá những phòng thí nghiệm tuyệt vời này!

Tiếp tục phòng thí nghiệm lập trình này bằng cách tích hợp cho Google Chat:

Tạo hướng dẫn truyền hình trên Google Chat bằng G Suite và Dialogflow