Ćwiczenie: tworzenie działania w przewodniku po TV dla Asystenta Google przy użyciu Dialogflow i Actions on Google

1. Wprowadzenie

Oglądasz telewizję, ale nie możesz znaleźć pilota? A może nie chcesz przeglądać wszystkich kanałów, żeby sprawdzić, czy jest coś ciekawego? Zapytajmy Asystenta Google, co jest w telewizji. W tym module utworzysz prostą czynność za pomocą Dialogflow i dowiesz się, jak zintegrować ją z Asystentem Google.

Ćwiczenia zostały ułożone w kolejności wykonywania typowych zadań przez programistę w chmurze:

  1. Tworzenie agenta Dialogflow w wersji 2
  2. Tworzenie niestandardowego typu informacji
  3. Tworzenie intencji
  4. Konfigurowanie webhooka za pomocą Funkcji Firebase
  5. Testowanie czatbota
  6. Włączanie integracji z Asystentem Google

Co utworzysz

Utworzymy interaktywnego chatbota z przewodnikiem po programach telewizyjnych dla Asystenta Google. Możesz zapytać przewodnika po programach, co jest obecnie nadawane na danym kanale. Na przykład: „Co jest na MTV?”. Funkcja Przewodnik po programach telewizyjnych poinformuje Cię, co jest obecnie nadawane i co będzie następne.

Czego się nauczysz

  • Tworzenie czatbota za pomocą Dialogflow w wersji 2
  • Jak tworzyć encje niestandardowe za pomocą Dialogflow
  • Tworzenie rozmowy liniowej za pomocą Dialogflow
  • Jak skonfigurować realizację za pomocą webhooka w Dialogflow i Funkcjach Firebase
  • Jak udostępnić aplikację w Asystencie Google za pomocą Actions on Google

Wymagania wstępne

  • Aby utworzyć agenta Dialogflow, musisz mieć tożsamość Google lub adres Gmail.
  • Podstawowa znajomość JavaScriptu nie jest wymagana, ale może się przydać, jeśli chcesz zmienić kod realizacji webhooka.

2. Przygotowania

Włączanie aktywności w internecie w przeglądarce

  1. Kliknij: http://myaccount.google.com/activitycontrols

  1. Sprawdź, czy Aktywność w internecie i aplikacjach jest włączona:

bf8d16b828d6f79a.png

Tworzenie agenta Dialogflow

  1. Otwórz: https://console.dialogflow.com

  1. Na pasku po lewej stronie, tuż pod logo, kliknij „Utwórz nowego agenta”. Jeśli masz już agentów, najpierw kliknij menu.

1d7c2b56a1ab95b8.png

  1. Podaj nazwę agenta: your-name-tvguide (użyj własnej nazwy)

35237b5c5c539ecc.png

  1. Jako język domyślny wybierz English - en.
  2. Jako domyślną strefę czasową wybierz strefę, która znajduje się najbliżej Ciebie.
  3. Kliknij Utwórz.

Konfigurowanie Dialogflow

  1. W menu po lewej stronie kliknij ikonę koła zębatego obok nazwy projektu.

1d7c2b56a1ab95b8.png

  1. Wpisz ten opis agenta: My TV Guide

26f262d359c49075.png

  1. Przewiń w dół do sekcji Ustawienia logowania i przesuń oba przełączniki, aby włączyć logowanie interakcji Dialogflow i wszystkich interakcji w Google Cloud Stackdriver. Będzie nam to potrzebne później, jeśli będziemy chcieli debugować działanie.

e80c17acc3cce993.png

  1. Kliknij Zapisz.

Konfigurowanie Actions on Google

  1. W panelu po prawej stronie kliknij link Asystent Google w sekcji Zobacz, jak to działa w Asystencie Google.

5a4940338fc351e3.png

Otworzy się strona http://console.actions.google.com.

Jeśli dopiero zaczynasz korzystać z Actions on Google, musisz najpierw wypełnić ten formularz:

3fd4e594fa169072.png

  1. Spróbuj otworzyć działanie w symulatorze**, klikając nazwę projektu.**
  2. Na pasku menu kliknij Test.

6adb83ffb7adeb78.png

  1. Upewnij się, że symulator jest ustawiony na język angielski, i kliknij Talk to my test-app (Porozmawiaj z aplikacją testową).

Działanie powita Cię za pomocą podstawowej domyślnej intencji Dialogflow. Oznacza to, że konfiguracja integracji z Action on Google się powiodła.

3. Encje niestandardowe

Jednostki to obiekty, w przypadku których aplikacja lub urządzenie podejmuje działania. Można je traktować jako parametry lub zmienne. W przewodniku po programach telewizyjnych zapytamy: „Co jest na MTV?”. MTV to podmiot i zmienna. Mogę też poprosić o inne kanały, np. „National Geographic” lub „Comedy Central”. Zebrana jednostka będzie używana jako parametr w moim żądaniu do usługi internetowej TV Guide API.

Więcej informacji o encjach Dialogflow

Tworzenie encji kanału

  1. W konsoli Dialogflow kliknij pozycję menu Entities (Rodzaje).
  2. Kliknij Utwórz encję.
  3. Nazwa jednostki: channel (pamiętaj, aby używać tylko małych liter)
  4. Przekaż nazwę kanału. (niektóre kanały będą wymagać synonimu, jeśli Asystent Google zrozumie coś innego); Podczas pisania możesz używać klawiszy Tab i Enter. Wpisz numer kanału jako wartość odwołania. oraz nazwy kanałów jako synonimy, np.:
  • 1 - 1, Net 1, Net Station 1

ee4e4955aa77232d.png

5**.** Przejdź do trybu **Edycja surowa**, klikając przycisk menu obok niebieskiego przycisku zapisywania.

e294b49b123e034f.png

  1. Skopiuj i wklej pozostałe elementy w formacie 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. Kliknij Zapisz.

4. Intencje

Dialogflow używa intencji do kategoryzowania intencji użytkownika. Intencje mają wyrażenia na potrzeby trenowania, czyli przykłady tego, co użytkownik może powiedzieć agentowi. Na przykład użytkownik, który chce wiedzieć, co jest w telewizji, może zapytać „Co jest dzisiaj w telewizji?”. „Co jest teraz odtwarzane?” lub po prostu „przewodnik po programach”.

Gdy użytkownik coś napisze lub powie (wypowiedź użytkownika), Dialogflow dopasowuje tę wypowiedź do najbardziej odpowiedniego zamiaru w Twoim agencie. Dopasowywanie intencji jest też nazywane klasyfikacją intencji.

Więcej informacji o intencjach Dialogflow

Modyfikowanie domyślnej intencji powitalnej

Gdy utworzysz nowego agenta Dialogflow, automatycznie utworzą się 2 domyślne intencje. Domyślna intencja powitalna to pierwszy przepływ, który pojawia się po rozpoczęciu rozmowy z agentem. Domyślny zamiar rezerwowy to ścieżka, którą otrzymasz, gdy agent nie będzie w stanie Cię zrozumieć lub dopasować zamiaru do tego, co właśnie powiedziałeś(-aś).

  1. Kliknij Domyślna intencja powitalna.

W przypadku Asystenta Google uruchomi się on automatycznie z domyślną intencją powitalną. Dzieje się tak, ponieważ Dialogflow nasłuchuje zdarzenia powitania. Możesz jednak wywołać intencję, wypowiadając jedną z wpisanych fraz szkoleniowych.

6beee64e8910b85d.png

Oto wiadomość powitalna dla domyślnej intencji powitalnej:

Użytkownik

Agent

„OK Google, porozmawiaj z your-name-tvguide”.

„Witamy, jestem agentem programu telewizyjnego. Mogę Ci powiedzieć, co jest obecnie odtwarzane na kanale telewizyjnym. Możesz na przykład zapytać: „Co leci na MTV?”.

  1. Przewiń w dół do sekcji Odpowiedzi.
  2. Usuń wszystkie odpowiedzi tekstowe.
  3. Utwórz 1 nową odpowiedź tekstową zawierającą to powitanie:

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. Kliknij Zapisz.

Tworzenie tymczasowego testowego zamiaru

Na potrzeby testów utworzymy tymczasowy testowy zamiar, aby później przetestować webhook.

  1. Ponownie kliknij opcję Intents (Intencje).
  2. Kliknij Utwórz intencję.
  3. Wpisz nazwę intencji: Test Intent (pamiętaj, aby użyć wielkich liter T i I. – Jeśli wpiszesz intencję w inny sposób, usługa backendowa nie będzie działać).

925e02caa4de6b99.png

  1. Kliknij Dodaj wyrażenia na potrzeby trenowania.
  • Test my agent
  • Test intent

2e44ddb2fae3c841.png

  1. Kliknij Realizacja > Włącz realizację.

7eb73ba04d76140e.png

Tym razem nie zakodujemy odpowiedzi na stałe. Odpowiedź pochodzi z funkcji w chmurze.

  1. Przesuń przełącznik Enable Webhook call for this intent (Aktywuj wywołanie webhooka dla tej intencji).

748a82d9b4d7d253.png

  1. Kliknij Zapisz.

Utwórz intencję kanału

Intencja kanału będzie zawierać tę część rozmowy:

Użytkownik

Agent

„Co jest na Comedy Central?”

„„Obecnie na kanale Comedy Central od godziny 18:00 są emitowane Simpsonowie. Potem o 19:00 zacznie się serial Family Guy”.

  1. Ponownie kliknij opcję Intents (Intencje).
  2. Kliknij Utwórz intencję.
  3. Wpisz nazwę intencji: Channel Intent (pamiętaj, aby użyć wielkich liter T i I. – Jeśli wpiszesz intencję w inny sposób, usługa backendowa nie będzie działać).
  4. Kliknij Add Training phrases (Dodaj wyrażenia na potrzeby trenowania) i dodaj te wyrażenia:
  • 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. Przewiń w dół do sekcji Działanie i parametry.

b7e917026760218a.png

Zwróć uwagę na encje @channel@sys.time, które są znane Dialogflow. Później w webhooku nazwa i wartość parametru zostaną wysłane do Twojej usługi internetowej. Na przykład:

channel=8

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

  1. Oznacz kanał jako wymagany.

Podczas rozmowy z agentem Przewodnika TV zawsze musisz wypełnić nazwę parametru gniazda channel. Jeśli nazwa kanału nie została wymieniona na początku rozmowy, Dialogflow będzie zadawać kolejne pytania, dopóki nie wypełni wszystkich miejsc na parametry. 6f36973fd789c182.png

Wpisz prompt:

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

cdb5601ead9423f8.png

  1. Nie ustawiaj parametru czasu jako wymaganego.

Godzina będzie opcjonalna. Jeśli nie podasz czasu, usługa sieciowa zwróci bieżący czas.

  1. Kliknij Realizacja.

Tym razem nie zakodujemy odpowiedzi na stałe. Odpowiedź pochodzi z funkcji w chmurze. Włącz przełącznik Enable Webhook call for this intent (Aktywuj wywołanie webhooka dla tej intencji).

  1. Kliknij Zapisz.

5. Realizacja za pomocą webhooka

Jeśli Twój agent potrzebuje więcej niż statycznych odpowiedzi na intencje, musisz użyć realizacji, aby połączyć usługę internetową z agentem. Połączenie z usługą internetową umożliwia podejmowanie działań na podstawie wypowiedzi użytkowników i wysyłanie do nich dynamicznych odpowiedzi. Jeśli na przykład użytkownik chce otrzymać harmonogram programów telewizyjnych MTV, Twoja usługa internetowa może sprawdzić bazę danych i odpowiedzieć użytkownikowi, podając harmonogram programów MTV.

  1. W menu głównym kliknij Fulfillment (Realizacja).
  2. Włącz przełącznik Edytor wbudowany.

cc84351f0d03ab6f.png

Do prostego testowania i wdrażania webhooków możesz użyć edytora wbudowanego. Korzysta z bezserwerowych Cloud Functions dla Firebase.

  1. W edytorze kliknij kartę index.js i skopiuj ten fragment kodu JavaScript dla 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. W edytorze kliknij kartę package.json i skopiuj ten fragment kodu JSON, który importuje wszystkie biblioteki menedżera pakietów 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. Kliknij przycisk Wdróż. Potrwa to chwilę, ponieważ wdrażana jest funkcja bezserwerowa. U dołu ekranu pojawi się wyskakujące okienko z informacją o stanie.
  2. Przetestujmy webhook, aby sprawdzić, czy kod działa. W symulatorze po prawej stronie wpisz:

Test my agent.

Jeśli wszystko się zgadza, powinien wyświetlić się komunikat „This is a test message” (To jest wiadomość testowa).

  1. Przetestujmy teraz intencję dotyczącą kanału. Zadaj pytanie:

What's on MTV?

Jeśli wszystko jest w porządku, zobaczysz:

„Na MTV od 16:30 jest emitowany program MTV Unplugged. Potem o 17:30 rozpocznie się RuPaul’s Drag Race”.

Kroki opcjonalne – Firebase

Jeśli przetestujesz to na innym kanale, zauważysz, że wyniki telewizora są takie same. Wynika to z faktu, że funkcja w chmurze nie pobiera jeszcze danych z prawdziwego serwera WWW.

Aby to zrobić, musimy nawiązać połączenie sieciowe wychodzące.

Jeśli chcesz przetestować tę aplikację za pomocą usługi internetowej, zmień abonament Firebase na Blaze. Uwaga: te kroki są opcjonalne. Możesz też przejść do kolejnych kroków tego modułu, aby kontynuować testowanie aplikacji w Actions on Google.

  1. Otwórz konsolę Firebase: https://console.firebase.google.com

  1. U dołu ekranu kliknij przycisk Zmień.

ad38bc6d07462abf.png

W wyskakującym okienku wybierz subskrypcję Blaze.

  1. Skoro wiemy już, że webhook działa, możemy przejść dalej i zastąpić kod index.js poniższym kodem. Dzięki temu będziesz mieć możliwość wysyłania do usługi internetowej próśb o informacje z przewodnika telewizyjnego:
'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 to platforma do programowania Asystenta Google. Umożliwia tworzenie przez deweloperów zewnętrznych „akcji”, czyli apletów dla Asystenta Google, które zapewniają rozszerzoną funkcjonalność.

Musisz wywołać działanie Google, prosząc Google o otworzenie aplikacji lub rozmowę z nią.

Spowoduje to otwarcie działania, zmianę głosu i opuszczenie „natywnego” zakresu Asystenta Google. Oznacza to, że wszystko, o co poprosisz agenta od tego momentu, musi zostać utworzone przez Ciebie. Nie możesz nagle poprosić Asystenta Google o informacje o pogodzie w Google, jeśli tego chcesz. Najpierw musisz opuścić (zamknąć) zakres działania (aplikację).

Testowanie działania w symulatorze Asystenta Google

Przetestujmy tę rozmowę:

Użytkownik

Asystent Google

„OK Google, porozmawiaj z your-name-tv-guide”.

„Jasne. Otwieram your-name-tv-guide”.

Użytkownik

Your-Name-TV-Guide Agent

-

„Witaj, jestem przewodnikiem po telewizji….”

Testowanie agenta

„To jest wiadomość testowa. Jeśli ją widzisz, oznacza to, że realizacja webhooka działa prawidłowo”.

Co jest w MTV?

Na MTV od 16:30 leci MTV Unplugged. Potem o 17:30 rozpocznie się RuPaul’s Drag Race.

  1. Powrót do symulatora Asystenta Google

Otwórz: https://console.actions.google.com

  1. Kliknij ikonę mikrofonu i zadaj pytanie:

c3b200803c7ba95e.png

  • Talk to my test agent
  • Test my agent

Asystent Google powinien odpowiedzieć:

5d93c6d037c8c8eb.png

  1. Teraz zadajmy pytanie:
  • What's on Comedy Central?

Powinno zostać zwrócone:

Obecnie na kanale Comedy Central od godziny 18:00 są emitowane Simpsonowie. Potem o 19:00 rozpocznie się serial Family Guy.

7. Gratulacje

Gratulacje! Udało Ci się utworzyć pierwszą czynność Asystenta Google za pomocą Dialogflow.

Jak zapewne wiesz, Twoja czynność była wykonywana w trybie testowym, który jest powiązany z Twoim kontem Google. Jeśli zalogujesz się na urządzeniu Nest lub w aplikacji Asystent Google na telefonie z Androidem lub iOS, używając tego samego konta. Możesz też przetestować działanie.

To jest wersja demonstracyjna warsztatów. Jeśli jednak tworzysz aplikacje dla Asystenta Google na potrzeby rzeczywistego użytkowania, możesz przesłać działanie do zatwierdzenia. Więcej informacji znajdziesz w tym przewodniku

Omówione zagadnienia

  • Tworzenie czatbota za pomocą Dialogflow w wersji 2
  • Jak tworzyć encje niestandardowe za pomocą Dialogflow
  • Tworzenie rozmowy liniowej za pomocą Dialogflow
  • Jak skonfigurować realizację za pomocą webhooka w Dialogflow i Funkcjach Firebase
  • Jak udostępnić aplikację w Asystencie Google za pomocą Actions on Google

Co dalej?

Podobało Ci się to laboratorium? Zapoznaj się z tymi świetnymi laboratoriami.

Kontynuuj ten moduł, integrując go z Google Chat:

Tworzenie przewodnika po programach telewizyjnych w Google Chat przy użyciu G Suite i Dialogflow