Integracja interfejsu Vision API z Dialogflow

1. Zanim zaczniesz

W ramach tego ćwiczenia w programie zintegrujesz interfejs Vision API z Dialogflow, aby zapewnić obszerne i dynamiczne odpowiedzi oparte na systemach uczących się na przesyłane przez użytkowników obrazy. Tworzysz aplikację czatbota, która pobiera obraz jako dane wejściowe, przetwarza go w interfejsie Vision API i zwraca zidentyfikowany punkt orientacyjny użytkownikowi. Jeśli na przykład użytkownik prześle zdjęcie Tadź Mahal, czatbot zwróci odpowiedź Tadż Mahal.

To przydatne, ponieważ umożliwia analizę elementów na obrazie i podejmowanie działań na podstawie uzyskanych informacji. Możesz też utworzyć system przetwarzania zwrotów, aby ułatwić użytkownikom przesyłanie paragonów, wyodrębnianie z potwierdzenia daty zakupu i w razie potrzeby przetwarzanie zwrotu środków.

Przyjrzyj się temu przykładowemu oknie dialogowym:

Użytkownik: Cześć

Czatbot: Cześć! Możesz przesłać zdjęcie, by poznać punkty orientacyjne

Użytkownik: prześlij zdjęcie, na którym widać Tadź Mahal.

Czatbot: Plik jest przetwarzany. Oto wyniki: Tadż Mahal, Ogród Tadż Mahal, Tadż Mahal.

15a4243e453415ca.png

Wymagania wstępne

Zanim przejdziesz dalej, musisz ukończyć te ćwiczenia z programowania:

  1. Tworzenie harmonogramu spotkań przy użyciu Dialogflow
  2. Integracja czatbota Dialogflow z Actions on Google
  3. Omówienie encji w Dialogflow
  4. Tworzenie klienta Django frontendu dla aplikacji Dialogflow

Musisz też zapoznać się z podstawowymi pojęciami i konstrukcjami Dialogflow. Możesz je obejrzeć w poniższych filmach na ścieżce Build a czatbot with Dialogflow (Tworzenie czatbota przy użyciu Dialogflow):

Czego się nauczysz

  • Jak utworzyć agenta Dialogflow
  • Jak zaktualizować agenta Dialogflow w celu przesyłania plików
  • Jak skonfigurować połączenie Vision API z realizacją Dialogflow
  • Jak skonfigurować i uruchomić aplikację frontendową Django dla Dialogflow
  • Jak wdrożyć aplikację frontendową Django w Google Cloud z użyciem App Engine
  • Jak przetestować aplikację Dialogflow z wykorzystaniem niestandardowego frontendu

Co utworzysz

  • Tworzenie agenta Dialogflow
  • Wdrażanie frontendu Django w celu przesłania pliku
  • Wdróż realizację Dialogflow, aby wywołać interfejs Vision API na podstawie przesłanego obrazu

Czego potrzebujesz

  • Podstawowa znajomość języka Python
  • Podstawowa znajomość interfejsu Dialogflow
  • Podstawowa znajomość interfejsu Vision API

2. Omówienie architektury

Utworzysz nowe środowisko konwersacyjne z niestandardowym frontendem Django i dodasz możliwość integracji z interfejsem Vision API. Skompilujesz frontend z użyciem platformy Django, uruchomisz go i przetestujesz lokalnie, a potem wdrożysz w App Engine. Frontend będzie wyglądać tak:

5b07e09dc4b84646.png

Przepływ żądania będzie wyglądał tak, jak na ilustracji poniżej:

  1. Użytkownik wyśle żądanie przez frontend.
  2. Spowoduje to wywołanie interfejsu DialogflowDetectIntent API w celu zmapowania wypowiedzi użytkownika na właściwą intencję.
  3. Gdy zostanie wykryta intencja punktu orientacyjnego odkrywania, realizacja Dialogflow wyśle żądanie do interfejsu Vision API, otrzyma odpowiedź i wyśle ją do użytkownika.

153725eb50e008d4.png

Tak będzie wyglądać ogólna architektura.

a2fcea32222a9cb4.png

3. Czym jest Vision API?

Vision API to już wytrenowany model ML, który czerpie informacje z obrazów. Zapewnia dostęp do wielu statystyk, takich jak oznaczanie obrazów etykietami, wykrywanie twarzy i punktów orientacyjnych, optyczne rozpoznawanie znaków oraz oznaczanie treści dla dorosłych. Więcej informacji znajdziesz na stronie Vision AI.

4. Tworzenie agenta Dialogflow

  1. Otwórz konsolę Dialogflow.
  2. Zaloguj się. Jeśli robisz to po raz pierwszy, podczas rejestracji użyj adresu e-mail.
  3. Zaakceptuj warunki korzystania z usługi, aby przejść do konsoli.
  4. Kliknij d9e90c93fc779808.png, przewiń w dół i kliknij Utwórz nowego agenta. 3b3f9677e2a26d93.png
  5. Wpisz „VisionAPI” w polu Agent name (Nazwa agenta).
  6. Kliknij Utwórz.

Dialogflow tworzy 2 domyślne intencje w ramach agenta:

  1. Domyślna intencja powitalna wita użytkowników.
  2. Domyślna intencja kreacji zastępczej wychwytuje wszystkie pytania, których bot nie rozumie.

Na tym etapie masz działającego bota, który wita użytkowników. Musisz go jednak zaktualizować, aby poinformować użytkowników, że mogą przesłać obraz, aby poznać punkty orientacyjne.

Zaktualizuj domyślną intencję powitalną, aby powiadomić użytkownika o możliwości przesłania obrazu

  1. Kliknij Default Welcome Intent (Domyślna intencja powitalna).
  2. Przejdź do sekcji Odpowiedzi > Domyślny > Wyślij tekst lub odpowiedź SSML i wpisz „Cześć! Możesz przesłać zdjęcie, aby poznać punkty orientacyjne”.

f9cd9ba6917a7aa9.png

Utwórz encję

  1. Kliknij Encje.

432fff294b666c93.png

  1. Kliknij Utwórz encję i nazwij ją „nazwa pliku”. i kliknij Zapisz.

602d001d684485de.png

Utwórz nową intencję

  1. Kliknij Intents (Intencje). Create Intent (Utwórz intencję).
  2. Wpisz „Przeglądaj przesłany obraz” w polu Nazwa intencji.
  3. Kliknij Wyrażenia na potrzeby trenowania > Dodaj wyrażenia na potrzeby trenowania i wpisz „plik to demo.jpg” i „plik to taj.jpeg” , jako wyrażenia użytkownika z encję @filename.

dd54ebda59c6b896.png

  1. Kliknij Odpowiedzi > Dodaj odpowiedź > Domyślny > Tekst lub SSML Response. Wpisz „Plik oceniany” i kliknij Dodaj odpowiedzi.
  2. Kliknij Fulfillment (Realizacja) > Włącz realizację i zaznacz opcję Włącz wywołanie webhooka dla tej intencji.

b32b7ac054fcc938.png

5. Skonfiguruj realizację, aby przeprowadzić integrację z interfejsem Vision API

  1. Kliknij Fulfillment (Realizacja).
  2. Włącz Wbudowany edytor.

c8574c6ef899393f.png

  1. Zaktualizuj index.js za pomocą poniższego kodu, a YOUR-BUCKET-NAME podaj nazwę swojego zasobnika Cloud Storage.
'use strict';

const functions = require('firebase-functions');
const {google} = require('googleapis');
const {WebhookClient} = require('dialogflow-fulfillment');
const vision = require('@google-cloud/vision');
  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
const bucketName = 'YOUR-BUCKET-NAME';
const timeZone = 'America/Los_Angeles';
const timeZoneOffset = '-07:00';

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
  const agent = new WebhookClient({ request, response });
  console.log("Parameters", agent.parameters);

  function applyML(agent){
    const filename = agent.parameters.filename;
    console.log("filename is: ", filename);

    // call vision API to detect text
    return callVisionApi(agent, bucketName, filename).then(result => {
                      console.log(`result is ${result}`);
                      agent.add(`file is being processed, here are the results:  ${result}`);
            //agent.add(`file is being processed ${result}`);
        }).catch((error)=> {
            agent.add(`error occurred at apply ml function`  + error);
        });
  }

  let intentMap = new Map();
  intentMap.set('Explore uploaded image', applyML);
  agent.handleRequest(intentMap);
});


async function callVisionApi(agent, bucketName, fileName){
    // [START vision_text_detection_gcs]
  // Imports the Google Cloud client libraries
  // Creates a client
  
  const client = new vision.ImageAnnotatorClient();
    try {
        // Performs text detection on the gcs file
        const [result] = await client.landmarkDetection(`gs://${bucketName}/${fileName}`);
        const detections = result.landmarkAnnotations;
        var detected = [];
        detections.forEach(text => {
            console.log(text.description);
            detected.push(text.description);
        });
        return detected;
    }
    catch(error) {
        console.log('fetch failed', error);
        return [];
    }
}
  1. Wklej ten kod do pola package.json, aby zastąpić jego zawartość.
{
  "name": "dialogflowFirebaseFulfillment",
  "description": "Dialogflow fulfillment for the bike shop sample",
  "version": "0.0.1",
  "private": true,
  "license": "Apache Version 2.0",
  "author": "Google Inc.",
  "engines": {
    "node": "6"
  },
  "scripts": {
    "lint": "semistandard --fix \"**/*.js\"",
    "start": "firebase deploy --only functions",
    "deploy": "firebase deploy --only functions"
  },
  "dependencies": {
    "firebase-functions": "2.0.2",
    "firebase-admin": "^5.13.1",
    "actions-on-google": "2.2.0", 
    "googleapis": "^27.0.0",
    "dialogflow-fulfillment": "^0.6.1",
    "@google-cloud/bigquery": "^1.3.0",
    "@google-cloud/storage": "^2.0.0",
    "@google-cloud/vision": "^0.25.0"
  }
}
  1. Kliknij Zapisz.

6. Pobieranie i uruchamianie aplikacji frontendowej

  1. Skopiuj to repozytorium na komputer lokalny:
https://github.com/priyankavergadia/visionapi-dialogflow.git
  1. Przejdź do katalogu zawierającego kod. Możesz też pobrać przykładowy plik jako plik ZIP i go rozpakować.
cd visionapi-dialogflow

7. Konfigurowanie środowiska lokalnego

Po wdrożeniu aplikacja do komunikacji z instancją Cloud SQL używa serwera proxy Cloud SQL, który jest wbudowany w standardowe środowisko App Engine. Aby jednak przetestować aplikację lokalnie, musisz zainstalować lokalną kopię serwera proxy Cloud SQL i używać jej w środowisku programistycznym. Aby dowiedzieć się więcej, przeczytaj Informacje o Cloud SQL Proxy.

Do wykonywania podstawowych zadań administracyjnych w instancji Cloud SQL możesz użyć klienta Cloud SQL for MySQL.

Instalowanie serwera proxy Cloud SQL

Pobierz i zainstaluj serwer proxy Cloud SQL za pomocą poniższego polecenia. Serwer proxy Cloud SQL służy do nawiązywania połączenia z instancją Cloud SQL, gdy działasz lokalnie.

Pobierz serwer proxy:

curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64

Ustaw serwer proxy jako wykonywalny.

chmod +x cloud_sql_proxy

Tworzenie instancji Cloud SQL

  1. Tworzenie instancji Cloud SQL for MySQL drugiej generacji. Wpisz "polls-instance" lub podobną nazwę. Przygotowanie instancji może potrwać kilka minut. Gdy będzie gotowy, powinien być widoczny na liście instancji.
  2. Teraz za pomocą narzędzia wiersza poleceń gcloud uruchom podane niżej polecenie, w którym [YOUR_INSTANCE_NAME] reprezentuje nazwę Twojej instancji Cloud SQL. Zanotuj wartość wyświetlaną w polu connectionName w następnym kroku. Format: [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME].
gcloud sql instances describe [YOUR_INSTANCE_NAME]

Możesz też kliknąć instancję w konsoli, aby uzyskać nazwę połączenia instancji.

c11e94464bf4fcf8.png

Inicjowanie instancji Cloud SQL

Uruchom serwer proxy Cloud SQL przy użyciu interfejsu connectionName z poprzedniej sekcji.

./cloud_sql_proxy -instances="[YOUR_INSTANCE_CONNECTION_NAME]"=tcp:3306

Zastąp [YOUR_INSTANCE_CONNECTION_NAME] wartością zarejestrowaną w poprzedniej sekcji. Spowoduje to nawiązanie połączenia między komputerem lokalnym a instancją Cloud SQL na potrzeby testów lokalnych. Zadbaj o to, aby serwer proxy Cloud SQL działał przez cały czas, gdy testujesz aplikację lokalnie.

Następnie utwórz nowego użytkownika i nową bazę danych Cloud SQL.

  1. Za pomocą konsoli Google Cloud utwórz nową bazę danych dla instancji Cloud SQL o nazwie polls-instance. Na przykład możesz wpisać „ankiety” . a3707ec9bc38d412.png
  2. W konsoli Cloud utwórz nowego użytkownika instancji Cloud SQL o nazwie polls-instance. f4d098fca49cccff.png

Skonfiguruj ustawienia bazy danych

  1. Otwórz plik mysite/settings-changeme.py do edycji.
  2. Zmień nazwę pliku na setting.py.
  3. W 2 miejscach zastąp [YOUR-USERNAME] i [YOUR-PASSWORD] nazwą użytkownika i hasłem do bazy danych utworzonymi w poprzedniej sekcji. Ułatwia to skonfigurowanie połączenia z bazą danych na potrzeby wdrażania App Engine i testów lokalnych.
  4. W wierszu ‘HOST': ‘cloudsql/ [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME]' Zastąp [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME] nazwą instancji uzyskaną w poprzedniej sekcji.
  5. Uruchom to polecenie i skopiuj wartość connectionName wyjściową do następnego kroku.
gcloud sql instances describe [YOUR_INSTANCE_NAME]
  1. Zastąp [YOUR-CONNECTION-NAME] wartością zarejestrowaną w poprzednim kroku
  2. Zastąp [YOUR-DATABASE] nazwą wybraną w poprzedniej sekcji.
# [START db_setup]
if os.getenv('GAE_APPLICATION', None):
    # Running on production App Engine, so connect to Google Cloud SQL using
    # the unix socket at /cloudsql/<your-cloudsql-connection string>
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': '/cloudsql/[PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME]',
            'USER': '[YOUR-USERNAME]',
            'PASSWORD': '[YOUR-PASSWORD]',
            'NAME': '[YOUR-DATABASE]',
        }
    }
else:
    # Running locally so connect to either a local MySQL instance or connect to
    # Cloud SQL via the proxy. To start the proxy via command line:
    #     $ cloud_sql_proxy -instances=[INSTANCE_CONNECTION_NAME]=tcp:3306
    # See https://cloud.google.com/sql/docs/mysql-connect-proxy
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': '127.0.0.1',
            'PORT': '3306',
            'NAME': '[YOUR-DATABASE]',
            'USER': '[YOUR-USERNAME]',
            'PASSWORD': '[YOUR-PASSWORD]'
        }
    }
# [END db_setup]
  1. Zamknij i zapisz plik settings.py.

8. Skonfiguruj konto usługi

  1. W konsoli Dialogflow kliknij 21a21c1104f5fdf3.png. Na karcie Ogólne przejdź do Projektu Google > Identyfikator projektu i kliknij Google Cloud7b2236f5627c37a0.png, aby otworzyć konsolę Cloud. a4cfb880b3c8e789.png
  2. Kliknij Menu nawigacyjne OK > Uprawnienia Administracja > Konta usługi, a następnie kliknij 796e7c9e65ae751f.png obok Integracje Dialogflow i Utwórz klucz.

3d72abc0c184d281.png

  1. Na komputer zostanie pobrany plik JSON potrzebny do konfiguracji w kolejnych sekcjach.

9. Skonfiguruj punkt końcowy wykrywania intencji Dialogflow, który będzie wywoływany z aplikacji

  1. W folderze czatu zastąp key-sample.json plikiem JSON z danymi logowania i nadaj mu nazwę key.json.
  2. W pliku views.py w folderze czatu zmień GOOGLE_PROJECT_ID = "<YOUR_PROJECT_ID>" na identyfikator projektu.

10. Tworzenie zasobników Cloud Storage

Tworzenie zasobnika Cloud Storage dla obiektów statycznych frontendu

  1. W konsoli Cloud kliknij Nawigacja w Menu nawigacyjnym ☰ > Miejsce na dane.

87ff9469db4eb77f.png

  1. Kliknij Utwórz zasobnik.
  2. Podaj niepowtarzalną globalnie nazwę.

a15a6612e92a39d3.png

  1. Wybierz, gdzie chcesz zapisywać dane. Wybierz Region, a następnie lokalizację, która najlepiej odpowiada Twoim potrzebom.
  2. Jako domyślną klasę pamięci wybierz Standardowa.

9c56abe632cf61db.png

  1. Wybierz Ustaw uprawnienia jednolicie na poziomie zasobnika (Tylko zasady zasobnika), a następnie kliknij Dalej, aby utworzyć zasobnik.

f175ac794049df04.png

  1. Po utworzeniu zasobnika kliknij Menu nawigacyjne OK > Miejsce na dane > Użyj przeglądarki i znajdź utworzony przez siebie zasobnik.

9500ee19b427158c.png

  1. Kliknij 796e7c9e65ae751f.png obok odpowiedniego zasobnika i wybierz Edytuj uprawnienia zasobnika.

fd0a310bc3656edd.png

  1. Kliknij Dodaj członków, kliknij Nowi użytkownicy, wpisz „allUsers”. a następnie kliknij Wybierz rolę > Wyświetlający obiekty Cloud Storage. Daje to użytkownikowi allUsers uprawnienia do wyświetlania statycznych plików frontendu. Nie jest to idealne ustawienie zabezpieczeń dla plików, ale na potrzeby tego konkretnego ćwiczenia z programowania sprawdza się.

7519116abd56d5a3.png

Tworzenie zasobnika Cloud Storage dla obrazów przesłanych przez użytkowników

Wykonaj te same instrukcje, aby utworzyć oddzielny zasobnik do przesyłania obrazów użytkowników. Ustaw uprawnienia na „allUsers” , ale wybierz role Twórca obiektów Cloud Storage i Wyświetlający obiekty Cloud Storage.

11. Konfigurowanie zasobników Cloud Storage w aplikacji frontendowej

Skonfiguruj zasobnik Cloud Storage w pliku settings.py

  1. Otwórz pokój mysite/setting.py.
  2. Znajdź zmienną GCS_BUCKET i zastąp ‘<YOUR-GCS-BUCKET-NAME> ze statycznym zasobnikiem Cloud Storage.
  3. Znajdź zmienną GS_MEDIA_BUCKET_NAME i zastąp ‘<YOUR-GCS-BUCKET-NAME-MEDIA> nazwą zasobnika Cloud Storage dla obrazów.
  4. Znajdź zmienną GS_STATIC_BUCKET_NAME i zastąp ciąg ‘<YOUR-GCS-BUCKET-NAME-STATIC> nazwą zasobnika Cloud Storage na pliki statyczne.
  5. Zapisz plik.
GCS_BUCKET = '<YOUR-GCS-BUCKET-NAME>'
GS_MEDIA_BUCKET_NAME = '<YOUR-GCS-BUCKET-NAME-MEDIA>'
GS_STATIC_BUCKET_NAME = '<YOUR-GCS-BUCKET-NAME-STATIC>'

Skonfiguruj zasobnik Cloud Storage na stronie home.html

  • Otwórz folder czatu, a następnie otwórz templates i zmień nazwę home-changeme.html na home.html.
  • Znajdź ciąg <YOUR-GCS-BUCKET-NAME-MEDIA> i zastąp go nazwą zasobnika, w którym chcesz zapisać plik przesłany przez użytkownika. Uniemożliwia to przechowywanie pliku przesłanego przez użytkownika we frontendzie oraz przechowywanie zasobów statycznych w zasobniku Cloud Storage. Interfejs Vision API wywołuje zasobnik Cloud Storage, aby pobrać plik i wygenerować prognozę.

12. Kompilowanie i uruchamianie aplikacji lokalnie

Aby uruchomić aplikację Django na komputerze lokalnym, musisz skonfigurować środowisko programistyczne Pythona, w tym Python, pip i virtualenv. Odpowiednie instrukcje znajdziesz w artykule Konfigurowanie środowiska programistycznego w Pythonie.

  1. Utwórz izolowane środowisko Pythona i zainstaluj zależności.
virtualenv env
source env/bin/activate
pip install -r requirements.txt
  1. Uruchom migracje Django, aby skonfigurować modele.
python3 manage.py makemigrations
python3 manage.py makemigrations polls
python3 manage.py migrate
  1. Uruchom lokalny serwer WWW.
python3 manage.py runserver
  1. W przeglądarce otwórz stronę http://localhost:8000/. Powinna wyświetlić się prosta strona internetowa podobna do tej:

8f986b8981f80f7b.png

Strony aplikacji przykładowych są dostarczane przez serwer WWW Django uruchomiony na Twoim komputerze. Gdy wszystko będzie gotowe, naciśnij Control+C (Command+C na Macu), aby zatrzymać lokalny serwer WWW.

Korzystanie z konsoli administracyjnej Django

  1. Utwórz superużytkownika.
python3 manage.py createsuperuser
  1. Uruchom lokalny serwer WWW.
python3 manage.py runserver
  1. W przeglądarce otwórz stronę http://localhost:8000/admin/. Aby zalogować się na stronie administratora, wpisz nazwę użytkownika i hasło utworzone podczas uruchamiania programu createsuperuser.

13. Wdrażanie aplikacji w standardowym środowisku App Engine

Umieść wszystkie treści statyczne w jednym folderze, uruchamiając to polecenie, które przenosi wszystkie pliki statyczne aplikacji do folderu określonego w zasadzie STATIC_ROOT w zasadzie settings.py:

python3 manage.py collectstatic

Prześlij aplikację, uruchamiając to polecenie w katalogu, w którym znajduje się plik app.yaml:

gcloud app deploy

Poczekaj na komunikat z informacją, że aktualizacja została zakończona.

14. Testowanie aplikacji frontendowej

W przeglądarce otwórz stronę https://<identyfikator_projektu>.appspot.com

Tym razem Twoje żądanie jest obsługiwane przez serwer WWW działający w standardowym środowisku App Engine.

Polecenie app deploy wdraża aplikację w sposób opisany w sekcji app.yaml i ustawia nowo wdrożoną wersję jako wersję domyślną, co powoduje, że obsługuje ona cały nowy ruch.

15. Produkcja

Gdy Twoje treści będą gotowe do wyświetlania w wersji produkcyjnej, zmień zmienną DEBUG na False w tagu mysite/settings.py.

16. Testowanie czatbota

Możesz przetestować czatbota w symulatorze albo użyć wcześniej utworzonej integracji z internetem lub Google Home.

  1. Użytkownik: „hi”
  2. Czatbot: „Cześć! Możesz przesłać zdjęcie, aby poznać punkty orientacyjne”.
  3. Użytkownik przesyła obraz.

Pobierz ten obraz, nadaj mu nazwę demo.jpg i użyj go.

c3aff843c9f132e4.jpeg

  1. Chatbot: „Plik jest przetwarzany. Oto wyniki: Golden Gate Bridge, National Recreation Area (Golden Gate Bridge), most Golden Gate Bridge, most Golden Gate Bridge)

Ogólnie powinno to wyglądać tak:

228df9993bfc001d.png

17. Czyszczenie danych

Jeśli chcesz ukończyć inne ćwiczenia z programowania Dialogflow, pomiń tę sekcję i wróć do niej później.

Usuwanie agenta Dialogflow

  1. Kliknij ca4337eeb5565bcb.png obok obecnego agenta.

520c1c6bb9f46ea6.png

  1. Na karcie General (Ogólne) przewiń w dół i kliknij Delete this Agent (Usuń tego agenta).
  2. W wyświetlonym oknie wpisz Usuń i kliknij Usuń.

18. Gratulacje

Udało Ci się utworzyć czatbota w Dialogflow i zintegrować go z Vision API. Jesteś teraz czatbotem.

Więcej informacji

Aby dowiedzieć się więcej, zapoznaj się z przykładowym kodem na stronie Dialogflow GitHub.