Zaawansowany quiz w chatbocie – zarządzanie za pomocą Google Sheets ?

Zaawansowany quiz w chatbocie

W poprzednim wpisie pokazałem jak stworzyć prosty quiz w chatbocie w narzędziu Chatfuel. Dziś chciałem pójść krok dalej – pokażę jak stworzyć zaawansowany quiz w chatbocie, który będzie wykorzystywał Google Sheets, jako bazę pytań, odpowiedzi i wyników quizu poszczególnych użytkowników.

Na wstępie chcę wyjaśnić kilka pojęć, elementów, które będziemy używać podczas tworzenia takiego quizu. Będą to podstawy dla tych, którzy o nich nie słyszeli lub mają o nich małe pojęcie. Jeśli niżej wymienione elementy są Ci znane, możesz spokojnie opuścić ten fragment i przejść bezpośrednio do tworzenia quizu.

Elementy, które wykorzystam w dzisiejszym poradniku to:

  • Atrybuty w Chatfuel
  • Google Sheet
  • Plugin JSON API w Chatfuel

Atrybuty

Atrybuty to bardzo ważny element chatbotów. Mogą być one nazywane w różny sposób w zależności od platformy, na której pracujemy. Ja w tym artykule będę używał tej nazwy, ponieważ używana ona jest w Chatfuel, na którym oparty jest ten poradnik.

A czym są atrybuty? Są to zmienne, cechy, wartości, które możemy ustawiać i przypisywać do użytkowników podczas rozmowy z botem.  Nadal niejasne? Wyobraźcie sobie więc, że chcecie odróżnić w jakiś sposób użytkowników, którzy chcą otrzymać powiadomienia od chatbota, od tych, którzy tego nie chcą. Do tego właśnie może służyć atrybut – przypiszemy atrybut o nazwie wantNotifications i wartości true do danego użytkownika jeśli chce otrzymywać powiadomienia, a ustawimy wartość false jeśli tych powiadomień otrzymywać nie chce.

No ok, spytacie, ale co może mi to dać? W naszym przypadku da nam to informacje do kogo powinniśmy wysłać notyfikację. Będziemy w stanie stworzyć wtedy regułę typu:

  • Wyślij wiadomość tym użytkownikom, którzy mają ustawiony atrybuty o nazwie wantNotifications na wartość true

Innym zastosowaniem atrybutów jest przetrzymywanie tymczasowych danych czy stanu pewnej operacji. I właśnie tego typu zastosowanie będzie miało miejsce w naszym quizie. Co mam tutaj na myśli? Podczas rozwiązywania testu czy quizu powinniśmy przetrzymywać przynajmniej 2 informacje:

  • numer aktualnego pytania, aby wiedzieć jakie będzie kolejne
  • aktualna liczba zdobytych punktów, poprawnych odpowiedzi

Będą one aktualizowane po każdym pytaniu (chyba, że odpowiedź użytkownika była zła, wtedy nie ma sensu aktualizować licznika – liczby zdobytych punktów).

Ok, ale jak mogę ustawić taki atrybut i gdzie jest on trzymany? Używając Chatfuel, dodawanie i zarządzanie atrybutami jest bardzo proste. Ustawiać atrybut możemy używając pluginu Set User Attribute, a przeglądać je możemy otwierając zakładkę People.

Zaawansowany quiz w chatbocie

Tak ustawiony atrybut możemy w prosty sposób wykorzystać jako treść wiadomości lub podczas podejmowania decyzji czy dany element powinien być wyświetlony danemu użytkownikowi. Np.:

Zaawansowany quiz w chatbocieZakładając, że wartość atrybutu o nazwie Total jest ustawiona na 5, tekst, który zostanie wyświetlony użytkownikowi to:

  • Zdobyłeś 5 punktów!

Jeśli chcielibyście więcej dowiedzieć się o atrybutach, jak można je wykorzystać, jak dokładnie działają, dajcie znać to postaram się przygotować kompletny artykuł, który poświęcony byłby temu elementowi. Póki co, na potrzeby tego posta, wiedza, którą przedstawiłem powinna wystarczyć do zrozumienia tematu.

JSON Api

Kolejny element, który będzie wykorzystywany w dzisiejszym wpisie to plugin JSON Api, który umożliwia komunikację i integrację bota z zewnętrznym serwisem. Plugin ten to prawdziwa siła botów, tworzonych w Chatfuel.

Jeśli przyjmiemy, że rolą chatbota jest prezentacja dynamicznych informacji, pozyskiwanie klientów, wysyłanie najnowszych wiadomości czy zbieranie informacji od użytkowników to musimy się zgodzić, że nie da się tych aktywności wykonać bez integracji z zewnętrznym serwisem, systemem czy bazą danych.

  • Użytkownik składa zamówienie za pośrednictwem bota? Powinieneś wysłać do zamówienie do zewnętrznego systemu
  • Chcesz pokazać najnowsze artykuły ze strony? Możesz pobrać je z bazy danych
  • Zadaniem bota jest tłumaczenie słów pomiędzy językami? Musisz odpytać zewnętrzny serwis o to tłumaczenie

Plugin ten, poza tym, że potrafi wysłać request do zewnętrznego serwisu, potrafi również przetworzyć odpowiedź, o ile będzie miała ona odpowiednią postać. Co to znaczy w praktyce? Jeśli wyślemy z zewnętrznego serwisu odpowiednio zbudowaną odpowiedź możemy wtedy m.in.:

  • wyświetlić użytkownikowi wiadomość, przyciski, podpowiedzi
  • wyświetlić obrazki
  • ustawić atrybut
  • pokazać wideo
  • pokazać galerię
  • itp.

Jak powinniśmy zbudować odpowiedź, aby była zrozumiała dla Chatfuel? Żeby nie powtarzać tego, co doskonale wytłumaczone jest w oficjalnej dokumentacji – odsyłam Was TUTAJ.

W dzisiejszym artykule będę chciał pokazać zarządzanie quizem za pomocą Google Sheet, który będzie pełnił rolę zewnętrznej bazy danych. I własnie w celu komunikacji między botem a arkuszem wykorzystywać będę plugin JSON API. Będziemy robić za jego pomocą 2 rzeczy:

  • pobierać i wyświetlać pytania i podpowiedzi
  • zapisywać wyniki quizu poszczególnych użytkowników

Zaawansowany quiz w chatbocie

PS. Jeśli jesteście ciekawi jak dokładnie działa ten plugin i jak go możecie wykorzystać, polecam kompletny poradnik, który można ściągnąć pobierając go z chatbota Twórcy – Link do bota.

Google Sheets

Ostatnim elementem, jaki potrzebny nam będzie do stworzenia zaawansowanego quizu jest usługa, zwana Google Sheets. Zakładam, że większość z Was wie co to jest, ale jeśli nie to na pewno wiecie czym jest Excel. Jeśli tak, to Google Sheets jest odpowiednikiem Excela, ale produkcji Google’a.

Do czego nam będzie służył Arkusz Google’a? Będzie pełnił rolę naszej bazy danych. Możemy w nim przetrzymywać pytania, sugerowane odpowiedzi, a także zapisywać wyniki jakie osiągnęli użytkownicy.

Ale po co nam zewnętrzna baza danych? Powodów jest kilka. Ja wymienię 3 z nich:

  • uniezależniamy się od narzędzie jakim jest Chatfuel
  • łatwiej jest zarządzać pytaniami edytując wiersze w arkuszu, niż bloki w Chatfuel
  • mając dane w Arkuszu, możemy je udostępniać innym działom bez konieczności dawania dostępu do Chatfuel

Dla formalności, aby móc korzystać z Google Sheets, wystarczy założyć konto na Google -> Google Sheets.

Zaczynamy

Zaczniemy nietypowo od Arkusza Google. Tak jak wspomniałem, będzie to centralna część naszego rozwiązania, dlatego warto od niej zacząć. Arkusze Google posiadają ciekawą opcję publikowania arkusza jako aplikacji webowej. Dzięki temu dostajemy publiczny adres url, który pozwala manipulować oraz pobierać dane z aktualnego arkusza. Użyjemy tak opublikowanego adresu, aby zintegrować Chatfuel z Google Sheets za pomocą pluginu JSON API.

Gdybym chciał to co napisałem przedstawić na diagramie, mogłoby to wyglądać tak:

Zaawansowany quiz w chatbocie

Wyjaśnię teraz jak powinien być zbudowany arkusz, który będzie wykorzystywany do budowy quizu. Przygotowałem przykładowy szablon, który znajduje się TUTAJ. Możecie na jego podstawie stworzyć swój arkusz jako kopię i zacząć na nim pracować.

Dokument składa sie z przynajmniej 2 arkuszy:

  • Q&A
  • Results

Zaawansowany quiz w chatbocie

Arkusz Q&A będzie służył do przetrzymywania pytań, sugerowanych odpowiedzi oraz prawidłowych odpowiedzi, a arkusz Results będzie przechowywał wyniki quizu (informacje o użytkowniku + liczba zdobytych punktów).

Arkusz Q&A składa się z następujących kolumn:

  • Question
  • Answer1
  • Answer2
  • Answer3
  • Answer4
  • Answer1_NextBlock
  • Answer2_NextBlock
  • Answer3_NextBlock
  • Answer4_NextBlock

Warto wspomnieć, że arkuszy typu Q&A możemy dodać wiele. Każdy z nich będzie odpowiadał jednemu quizowi. Warto przy tym odróżnić je nadając odpowiednie nazwy. W zakładce z rezultatami będziemy mogli je odróżnić poprzez dodanie kolumny z nazwą quizu.

Na potrzeby tego artkułu zastosowałem tylko jeden arkusz z pytaniami, o nazwie Q&A.

Kolumna Question przechowywać będzie pytanie, jakie zostanie zadane użytkownikowi. Kolumny Answer1-Answer4 zawierają sugerowane odpowiedzi, które w naszym quizie wyświetlać będziemy używając szybkich odpowiedzi (quick replies). Pozostają nam kolumny Answer1_NextBlock-Answer4_NextBlock, które zawierają listę następnym nazw bloków oddzielonych przecinkiem. Piszać bloki, mam tutaj na myśli bloki w rozumieniu Chatfuela. W praktyce taka informacja będzie oznaczała:

  • Po odpowiedzi na pytanie numer X przekieruj użytkownika do bloków Y,Z

Wyjaśnieniem poszczególnych bloków oraz ich zawartości zajmę się w kolejnych sekcjach. Na tą chwilę powinna Wam wystarczyć informacja, że blok o nazwie Question odpowiada za wyświetlenie pytania, blok Right Answer, zwiększa liczbę punktów użytkownika, a blok Summary to blok znajdujący się na końcu quizu, którego rola to podsumowanie wyniku quizu.

Przykładowy arkusz z pytania może wyglądać następująco:

Zaawansowany quiz w chatbocie

Przypominam, że przykładowy arkusz, który możecie skopiować i edytować następnie znajduje się TUTAJ.

 

Opublikowanie arkusza

Kiedy mamy już informacje i szablon naszego quizu, pozostaje nam rzecz najtrudniejsza i najbardziej techniczna z tego poradnika – sprawienie, aby te dane były dostępne z poziomu Chatfuel. Tak jak wspomniałem wcześniej, w sekcji JSON API, Chatfuel potrafi integrować się z zewnętrznymi serwisami za pomocą zapytań HTTP. Aby takie zapytanie było możliwe musimy udostępnić taki serwis publicznie. 

Możemy to osiągnąć dzięki usłudze Google Apps Script, zintegrowanej z arkuszem, która pozwala jednocześnie stworzyć publicznie dostępny endpoint oraz pozwala manipulować danymi przechowywanymi w arkuszu. Usługa polega na implementacji logiki w języku JavaScript, co oznacza, że bez umiejętności programistycznych wiele tutaj nie ugramy. Dla tych jednak, którzy są bardziej biznesowi, a mniej techniczni przygotowałem taki skrypt, który jest gotowy do wykorzystania. Kopiując arkusz, który przygotowałem na potrzeby tego artykułu, ten kod będziecie już mieli zintegrowany. Poza tym w dalszej części zamieszczę źródło do samego skryptu, dla tych którzy chcą usługę implementować samodzielnie.

Aby przejść do usługi Google Apps Script należy wejść w zakładkę Tools -> Script Editor:

Script Editor

Po kliknięciu w Script Editor przejdziemy do okna tworzenia skryptu, który uruchamiany będzie gdy nasz serwis zostanie odpytany. Aby nie wchodzić w szczegóły, na potrzeby naszego quizu powinniśmy zaimplementować 2 metody:

  • doGet (GET)
  • doPost (POST)

Co do zasady, zapytania typu GET, powinny służyć do pobierania danych, dlatego wykorzystam ją do pobierania kolejnego pytania i zwrócenia JSON’a zrozumiałego przez Chatfuel. Metoda typu POST powinna zapisywać dane, więc można ją wykorzystać do zapisania wyników quizu.

Metoda doGet

Metoda doGet, tak jak wspomniałem wcześniej, wykorzystana będzie podczas zadawania kolejnych pytań. Będzie ona częścią większego procesu i integracji Chatfuel oraz opublikowanego endpointa.

Kroki jakie będą miały miejsce wyglądają mniej więcej następująco:

  • Użytkownik rozpoczyna quiz klikając przycisk typu „Start”
  • W tym momencie ustawiamy mu za pomocą Chatfuel atrybut Total na 0, QuestionNumber na 1 i QuizName na nazwę quizu – taki jak nazwa odpowiedniego arkusza (Total odpowiada liczbie zdobytych punktów, a QuestionNumber numerowi  następnego pytania)
  • Użytkownik wchodzi do bloku Question, który zawiera m.in. plugin JSON API
  • Chatfuel, za pomocą pluginu JSON API, wysyła do naszego endpointa zapytanie o kolejne pytanie (załączając wartość atrybutu QuestionNumber, aby wiadomo było, które pytanie zwrócić oraz QuizName, aby wiedzieć do jakiego quizu wysłać pytania)
  • metoda doGet robi następujące rzeczy:
    • odczytuje numer następnego pytania oraz nazwę quizu
    • pobiera pytanie oraz sugerowane odpowiedzi z arkusza o takiej nazwie jak nazwa quizu
    • zwiększa o 1 numer kolejnego pytania – zmienna QuestionNumber
    • buduje odpowiedź w formacie zrozumiałym dla Chatfuel (zgodna z dokumentacją). Dodaje do niej pytanie, sugerowane odpowiedzi (oraz do których bloków prowadzą) i ustawia atrybut QuestionNumber na wartość wcześniej powiększoną o 1
    • wysyła odpowiedź
  • Chatfuel, otrzymując odpowiedź generuje pytanie oraz potencjalne odpowiedzi lub podsumowuje wyniki quizu (w zależności czy było to ostatnie pytanie, czy nie)

Zajmijmy się więc tworzeniem metody doGet. Otwieramy nasz dokument wcześniej stworzony, zawierający 2 arkusze Q&A oraz Results. Przechodzimy to usługi Google Apps Script, klikając Tools -> Script Editor i jesteśmy teraz w trybie edycji skryptu, póki co pustego.

Wklejamy do, pustego na razie, pliku Code.gs następujący kod (znajdziecie go też TUTAJ):

function doGet(e) {

var questionNumber = parseInt(e.parameter.questionNumber);
var quizName = e.parameter.quizName;


var row = getRows(quizName)[questionNumber];

Logger.log('questionNo: '+questionNumber);
Logger.log('quizName: '+quizName);

var result = {
set_attributes: { QuestionNumber: questionNumber+1 },
messages: [
{ text: row[0], quick_replies: getQuickReplies(row) }
]
};

var output = JSON.stringify(result);

Logger.log('output: '+output);

return ContentService.createTextOutput(output).setMimeType(ContentService.MimeType.JSON);
}

function getRows(quizName){
return SpreadsheetApp.getActive().getSheetByName(quizName).getDataRange().getValues();
}

function getQuickReplies(row){
return [
{title: row[1], block_names: getBlocks(row[5])},
{title: row[2], block_names: getBlocks(row[6])},
{title: row[3], block_names: getBlocks(row[7])},
{title: row[4], block_names: getBlocks(row[8])}
];
}

function getBlocks(blocks){
return blocks.split(',');
}

Kolejnym krokiem jest opublikowanie aplikacji, tak aby stała się ona dostępna publicznie. W tym celu klikamy Publish -> Deploy as web app:

Po opublikowaniu aplikacji powinniśmy otrzymać adres url do naszego endpoint’a, który powinien wyglądać mniej więcej tak:

  • https://script.google.com/macros/s/xyz/exec , gdzie xyz to nasz unikalny klucz

Adres, który uzyskaliśmy będziemy wykorzystywać wklejając go w pluginie JSON API, podczas konfiguracji bota w Chatfuel, więc warto go gdzieś zapisać.

Tym sposobem stworzyliśmy metodę, odpowiedzialną za „zadawanie pytania” oraz upubliczniliśmy ją, co umożliwi nam zarządzanie pytaniami z poziomu Google Sheets, a nie z poziomu Chatfuel.

Konfiguracja Chatfuel

Teraz przejdźmy do konfiguracji Chatfuel. Będziemy potrzebować następujących bloków:

  • Quiz start – wyświetlać będzie przycisk umożliwiający rozpoczęcie quizu
  • Quiz init – będzie ustawiać początkowe atrybuty, ewentualnie zerować istniejące
  • Question – będzie odpowiedzialny za pobieranie z arkusza kolejnego pytania i odpowiedzi
  • Right answer – będzie zwiększał licznik punktów
  • Summary – będzie podsumowywał wynik quizu

Przejdę teraz po każdym z ww. bloków i pokażę jak je skonfigurować. Zacznijmy od bloku Quiz start, który pozwoli użytkownikowi podjąć decyzję o rozpoczęciu quizu. Po kliknięciu w przycisk Start ▶️ użytkownik zostanie przeniesiony najpierw do bloku Quiz init, a następnie do pytania, czyli bloku Question.

Blok Quiz start

Kolejny blok o nazwie Quiz init, będzie odpowiedzialny za ustawianie początkowych atrybutów. W naszym przypadku ustawimy:

  • QuizName na Q&A (przypominam, że odpowiada ta wartość nazwie arkusza)
  • QuestionNumber na 1 (ustawiam wskaźnik na pytanie na 1)
  • Total na 0 (użytkownik rozpoczyna test więc nie ma jeszcze punktów)

Powinien on wyglądać tak:

Blok Quiz init

Blok Right answer odpowiada za zwiększanie liczby punktów w przypadku prawidłowej odpowiedzi użytkownika. Zawiera jedynie zwiększenie wartości atrybutu Total o 1:

Blok Right answer

Teraz zaczyna się magia czyli blok o nazwie Question. Tak jak wspomniałem służył on będzie wyświetlaniu kolejnego pytania. Będzie mogł to zrobić integrując się z arkuszem, który wcześniej stworzyliśmy za pomocą metody doGetMusimy więc dodać do bloku plugin JSON API i wypełnić go następującymi wartościami:

  • Type – GET
  • URL – Url, który skopiowaliśmy po opublikowaniu arkusza jako endpoint + atrybuty, które chcemy przesłać do metody w postaci elementów urla. Możecie skopiować stąd podmieniając na Wasz unikalny adres:
    • https://script.google.com/macros/s/xyz/exec?questionNumber={{QuestionNumber}}&quizName={{QuizName}}

Blok Question

Po wejściu w ten blok Chatfuel odpyta nasz arkusz i w odpowiedzi otrzyma pytanie oraz sugerowane odpowiedzi, jakie powinny zostać wyświetlone użytkownikowi. Aby metoda wiedziała, które pytanie zwrócić wysyłamy dodatkowo informacje o numerze pytania oraz o nazwie quizu.

Na koniec został nam blok Summary, który jest ostatnim elementem quizu i wyświetla wynik użytkownika na podstawie wartości atrybutu Total.

Blok Summary

 

Zapis wyniku

Na tym etapie powinniśmy mieć stworzony działający quiz, który może być uruchomiony przez użytkownika. Wartością dodaną dla takiego quizu mogą być jednak informacje o jego wynikach – kto go przeszedł, kiedy czy jaki miał wynik. Aby to zrobić musimy zaimplementować metodę doPost, która przyjmie takie informacje od Chatfuela (JSON API) i zapisze je we wcześniej stworzonym arkuszu Results.

Arkusz ten może zawierać następujące kolumny:

  • Id (Messenger Id)
  • Name (Może być imię)
  • Date (Data ukończenia quizu)
  • QuizName (Nazwa testu)
  • Result (Liczba punktów)

Arkusz Results

Kiedy mamy już arkusz skonfigurowany, przechodzimy do edytora kodu (Tools -> ScriptEditor) i dodajemy metodę doPost następującą (lub wklejcie zawartość tego pliku):


function doPost(e){
  
  var data = JSON.parse(e.postData.contents)
  
  var result = parseInt(data.result);
  var quizName = data.quizName;
  var id = data.id;
  var name = data.name;
  
  Logger.log('result: '+result);
  Logger.log('quizName: '+quizName);
  Logger.log('id: '+id);
  Logger.log('name: '+name);
  
  var sheet = SpreadsheetApp.getActive().getSheetByName('Results');
  sheet.appendRow([id,name,new Date(),quizName, result]);
  
  return ContentService.createTextOutput(JSON.stringify({})).setMimeType(ContentService.MimeType.JSON);
}

Po ponownym opublikowaniu endpoint, który przyjmuje zapytania typu POST powinien być już dostępny. Ostatnim krokiem jest konfiguracja po stronie Chatfuel. Naszym celem jest wysłanie ww. informacji po zakończeniu quizu. Możemy to zrobić w bloku Summary, który będzie zawierał dodatkowo wysłanie zapytania do arkusza wraz potrzebnymi informacjami.

Dodajmy więc plugin JSON API z następującymi wartościami:

  • Type – POST
  • URL – Url, który skopiowaliśmy po opublikowaniu arkusza jako endpoint
  • Send – musimy stworzyć JSON z informacjami, które chcemy przesłać. Może on wyglądać następująco (istotne są nazwy parametrów – muszą odpowiadać tym nazwom, których użyliśmy podczas implementacji metody doPost)

{
"id": "{{messenger user id}}",
"name": "{{first name}}",
"quizName": "{{QuizName}}",
"result": {{Total}}
}

Blok Send results

Efekt

Tak skonfigurowany system jest gotowy, aby spełnić rolę jaką sobie założyliśmy na początku artykułu. Po rozpoczęciu testu, otrzymujemy po kolei pytania, zliczane są punkty, a na końcu otrzymujemy podsumowanie naszego wyniku, a jednocześnie zapisujemy go w osobnym arkuszu. Dzięki temu trzymamy w jednym miejscu, zarówno pytania, jak i rezultaty.

Poniżej pokazuję jak to wygląda i działa złozone w całość.

Prezentacja

Przypominam, że możecie gotowy szablon, który budowaliśmy w tym artykule pobrać z TEGO linku i utworzyć na jego podstawie kopię arkusza, na którym będziecie pracować.

 

Jeśli podoba się Wam artykuł i chcielibyście wiecej tego typu treści lub macie jakieś uwagi co do poradnika, zachęcam do pozostawiania komentarzy.