<<

IMPLEMENTACIÓ D’UN ASSISTENT DE RESERVES A TRAVÉS DE CANALS DE MISSATGERIA INSTANTÀNIA

TFG - Memòria

Escola Tècnica d'Enginyeria de Telecomunicació de Barcelona Universitat Politècnica de Catalunya per Jordi Alonso Llovet

Enginyeria Telemàtica

Tutors: Jorge Mata Diaz i Joan Salvatella Ibáñez

Barcelona, Agost 2020 Abstract

The company Bookline has developed a virtual that attends calls to restaurants and helps users at making reservations. This project aims to implement all of the assistant’s functions in a [1] that would allow the assistant to attend users through the most popular services. My objective is to design a program capable of attending users through in Whatsapp, Telegram and Messenger, and make it easy to extend it to other services through some minimal modifications. For the development of this project the tools that have been primarily used were some services from Cloud Platform [2] and the programming language Python. The project’s final result is a chatbot for each messaging service that can follow a conversation in Spanish or English, capable of responding to any question as Bookline’s assistant would, and capable of booking a table in any restaurant that has hired this service.

2 Resum

L’empresa Bookline ha desenvolupat un assistent virtual que pot atendre les trucades a restaurants i ajudar als usuaris a realitzar una reserva. Aquest treball pretén implementar totes les seves funcions a través d’un chatbot [1] que permeti a l’assistent atendre als usuaris a través dels serveis de missatgeria instantània més populars. L’objectiu és dissenyar un programa que pugui atendre als usuaris a través de chatbots de Whatsapp, Telegram i , i que es pugui estendre fàcilment a altres serveis fent les modificacions mínimes. Per al desenvolupament d’aquest projecte s’han fet servir principalment serveis de Google Cloud Platform [2] i el llenguatge de programació Python. El resultat final del projecte és un chatbot per a cada servei de missatgeria que permet dialogar amb castellà o anglès, capaç de respondre a qualsevol pregunta igual que l’assistent de Bookline i que permeti reservar una taula en els restaurants que contractin aquest servei.

3 Resumen

La empresa Bookline ha desarrollado un asistente virtual que puede atender llamadas a restaurantes y ayudar a los usuarios a realizar una reserva. Este trabajo pretende implementar todas sus funcionalidades a través de un chatbot [1] que permita al asistente atender a usuarios a través de los servicios de mensajería instantánea más populares. El objetivo és diseñar un programa que pueda atender a los usuarios a través de chatbots de Whatsapp, Telegram y Facebook Messenger, y que se pueda extender fácilmente a otros servicios insertando unas mínimas modificaciones. Para el desarrollo de este proyecto se han utilizado principalmente servicios de Google Cloud Platform [2] y el lenguaje de programación Python. El resultado final del proyecto és un chatbot para cada servicio de mensajería que permita dialogar en castellano o inglés, capaz de responder a cualquier pregunta igual que lo haría el asistente de Bookline y que permita reservar una mesa en los restaurantes que contraten este servicio.

4 Agraïments

Abans d’explicar el contingut d’aquest treball vull agrair a la meva família el seu suport constant durant aquest projecte; la meva mare Nuria Llovet Tahull, el meu pare Javier Alonso Sancho i en especial al meu germà, qui ’ha ajudat immensament a tirar endavant el treball, Xavi Alonso Llovet. També vull expressar la meva gratitud cap als codirectors d’aquest treball; Jorge Mata Diaz per aconsellar-me i revisar tota la documentació, i a Joan Salvatella Ibañez per donar-me la oportunitat de dur a terme aquest projecte a l’empresa Bookline i guiar-me durant el procés.

5 Historial de revisió i registre d’aprovació

Revisió Data Propòsit

0 15/07/2020 Creació del document

1 24/07/2020 Revisió del document

Participants del document

Nombre e-mail

Jordi Alonso Llovet [email protected]

Jorge Mata Diaz [email protected]

Joan Salvatella Ibáñez [email protected]

Escrit per: Revisat i aprovat per:

Data 15/07/2020 Data 24/07/2020

Nom Jordi Alonso Llovet Nom Jorge Mata Diaz

Posició Autor Posició Tutor

6 Index

Abstract...... 2 Resum...... 3 Resumen...... 4 Agraïments...... 5 Historial de revisió i registre d’aprovació...... 6 Index...... 7 Glossary...... 10 1. Introducció...... 11 1.1. Contextualització...... 11 1.2. Objectius...... 11 1.3. Requeriments i especificacions...... 11 1.4. Mètodes I procediments...... 12 1.4.1. Google Kubernetes Engine...... 12 1.4.2. Flask...... 13 1.4.3. FFmpeg...... 13 1.4.4. ...... 13 1.4.5. Redis...... 13 1.4.6. Bookline Virtual Assistant...... 13 1.4.7. Google Speech-to-Text...... 13 1.4.8. Cloud Firestore...... 13 1.5. Pla de Treball...... 13 1.5.1. Paquets de Treball...... 14 1.5.2. Diagrama de Gantt...... 16 1.5.3. Desviacions...... 16 2. Estat de l’Art:...... 17 2.1. Altres ChatBot...... 17 3. Metodologia i Desenvolupament:...... 19 3.1. Creació d’un Bot de Telegram...... 19 3.1.1. BotFather...... 19 3.1.2. Rebre actualitzacions...... 20 3.1.3. Flask...... 20 3.1.4. Dispatcher i Handlers...... 22

7 3.1.4.1. Text Handler...... 23 3.1.4.2. Voice Handler...... 23 3.1.4.3. Command Handler...... 23 3.1.5. Obtenir una resposta...... 24 3.1.6. Canvis de conversació...... 26 3.2. Integració de Whatsapp...... 26 3.2.1. Twilio...... 27 3.2.2. Dispatcher i Handlers...... 27 3.3. Integració de Facebook Messenger...... 28 3.3.1. Token d’Accés...... 28 3.3.2. Webhooks...... 29 3.3.3. Dispatcher i Handlers...... 30 3.3.4. Registrar Clients...... 30 3.4. Modificacions a l’Assistent Virtual...... 30 3.4.1. Modificar respostes segons el canal configurat...... 30 3.4.1.1. Solució...... 32 3.4.2. Handover...... 33 3.5. Base de Dades...... 34 3.5.1. Estructura...... 34 3.5.2. Nova Col·lecció...... 34 3.6. Desplegament...... 35 3.6.1. Que és un contenidor?...... 35 3.6.2. Clusters...... 35 3.6.3. Node del Chatbot...... 35 3.7. Proves de Funcionament...... 36 3.7.1. Chatbots de prova...... 36 4. Resultats...... 37 5. Costos...... 38 5.1. Desenvolupament del projecte...... 38 5.2. Costos de desplegament...... 38 5.2.1. Twilio...... 39 5.2.2. Cost Mensual Total...... 39 6. Conclusions...... 40 6.1. Desenvolupament Futur...... 40

8 Bibliografia...... 41 Annex A: Paquets de Dades...... 43

Llista de Figures Figura 1: Estructura del Projecte...... 12 Figura 2: Diagrama de Gantt...... 16 Figura 3: Creixement de les aplicacions de missatgeria instantània vs rets social entre 2011 i 2017...... 17 Figura 4: Conversació amb el ChatBot de Bodegas Mezquita per Facebook Messenger ...... 18 Figura 5: Creació d’un Bot de Telegram amb BotFather...... 19 Figura 6: Funcionament d'un Webhook...... 20 Figura 7: ChatBot utilitzant la Classe telegram.ext.Updater...... 21 Figura 8: Estructura de l'aplicació amb Flask...... 22 Figura 9: Paràmetres que utilitza el ChatBot...... 23 Figura 10: Diagrama de Flux...... 24 Figura 11: Descripció del JSON que s'envia a l'assistent virtual...... 25 Figura 12: Expressions regulars (regex) utilitzades...... 25 Figura 13: Estructura del Dispatcher implementat per a Whatsapp...... 28 Figura 14: Procés per a obtenir el Token d'Accés...... 29 Figura 15: Utilitzem la URL del servidor de Bookline per al Webhook...... 30 Figura 16: Exemple de dues respostes que pot donar l'Assistent Virtual...... 31 Figura 17: Funció que escolleix la frase que envia l'assistent...... 32 Figura 18: Exemple d'una resposta amb una versió per telèfon i un altra per a xat...... 33 Figura 19: Funció _choose() modificada...... 33 Figura 20: Dades d'un Bot d'exemple a Firebase...... 34 Figura 21: Estructura d'una Màquina Virtual comparada a un Contenidor...... 35 Figura 22: Intercanvi de paquets des de els servidors de el serveis de missatgeria fins a l'Assistent Virtual de Bookline...... 43

Llista de Taules Taula 1: Hores dedicades al projecte...... 38 Taula 2: Costos de Bookline durant el mes de Juliol...... 38 Taula 3: Cost mensual aproximat del projecte...... 39

9 Glossary

GKE: Google Kubernetes Engine API: Application Program Interface UUID: Universal Unique Identifier NLP: Natural Language Processing NLU / NLI: Natural Language Understanding / Interpretation NLG: Natural Language Generation SSML: Markup Language JSON: JavaScript Object Notation NoSQL: Non Structured Query Language

10 1. Introducció

1.1. Contextualització Aquest projecte s'ha realitzat en col·laboració amb Bookline [3], una empresa startup que ha creat des de zero un assistent virtual per restaurants que pot atendre automàticament trucades, donar informació sobre el restaurant i administrar reserves de manera totalment automàtica, tot a través del telèfon. L’assistent virtual utilitza tecnologies de processament de llenguatge natural [4] i sintetització de veu per poder donar el mateix nivell d’atenció al client que una persona. Aquest servei permet als restaurants que el contracten gestionar qualsevol quantitat de trucades encara que no hi hagi ningú disponible per atendre-les, i redueix el numero de hores que s’han de dedicar a atendre el telèfon. Alguns dels clients de Bookline també han expressat interès en que s’expandeixi la funcionalitat de l’assistent per poder atendre trucades a través de serveis de missatgeria instantània.

1.2. Objectius El projecte consisteix en crear un Chatbot [1] per als serveis de missatgeria instantània més populars actualment que serveixi com a pont per poder utilitzar l'assistent virtual de Bookline a través de serveis com Whatsapp, Telegram o Facebook Messenger. Un Chatbot es una aplicació en línia dissenyada per conduir conversacions via text imitant la manera de parlar d’un humà (llenguatge natural). En aquest cas tot el processament de llenguatge natural i la lògica que controla com es respon ja forma part de l’assistent virtual de Bookline, el projecte pretén connectar aquest assistent amb els serveis de missatgeria esmentats. També s'ha de tenir en compte que certes respostes o comportaments de l'assistent virtual estan dissenyats per a una conversa telefònica i no són compatibles en el format de missatgeria instantània. Per tant part del projecte consistirà en modificar l'assistent virtual de Bookline per solucionar aquests problemes sense modificar el funcionament a través del telèfon.

1.3. Requeriments i especificacions Els requeriments per al Bot són: • Rebre missatges de diversos serveis al mateix temps. • Corregir errors ortogràfics en els missatges del client. • Les respostes de l'assistent virtual estan pensades pe enviar-se a un programa de text a veu. És necessari formatar correctament el text abans d'enviar-lo a l'usuari. • Utilitzar per defecte l'idioma de l'usuari si és un idioma vàlid per l'assistent. • El Bot ha de funcionar tant amb missatges de text com notes de veu. El requeriments per l'assistent virtual són:

11 • L'assistent virtual necessita reconèixer el principi i el final d'una sessió. En el cas del telèfon la sessió comença i acaba amb la trucada, però a part del primer missatge que enviï un usuari, per missatgeria instantània no hi ha manera de discernir on acaba una sessió i comença la següent. • A través del telèfon l'assistent pot redirigir la trucada a una persona real si té problemes per entendre al client, si se li fa una pregunta que no sap respondre o si el client simplement demana parlar amb una persona. Diversos restaurants han expressat que no volen que les gestions a través de missatgeria instantània es desviïn a un empleat, per tant, en aquestes circumstàncies l'assistent ha d'oferir al client una alternativa per posar-se en contacte directament amb el restaurant. • Per últim, s'han de modificar algunes respostes de l'assistent que no tenen sentit en el context d’una conversa per xat, com les que fan referència a una trucada.

1.4. Mètodes I procediments Aquest projecte s’ha realitzat al voltant de l’Assistent Virtual de Bookline i s’ha d’integrar en el Cluster que tenen desplegat a Google Kubernetes Engine [5]. La figura a continuació mostra tots els elements que formen part del projecte.

Figura 1: Estructura del Projecte

1.4.1. Google Kubernetes Engine Kubernetes és un sistema de codi obert que permet automatitzar el desplegament d’aplicacions en contenidors. Google Kubernetes Engine permet desplegar un entorn de Kubernetes o Cluster, en els servidors de Google. És on Bookline té desplegat el seu assistent virtual i és on desplegarem el nostre Bot. [5]

12 1.4.2. Flask Microframework de desenvolupament web escrit en Python. Degut a la seva senzillesa s’ha utilitzat per dissenyar l’aplicació web que controla el ChatBot. [6]

1.4.3. FFmpeg Software utilitzat per convertir els arxius de les notes de veu (format «.ogg») a format «.flac» i poder transcriure la frase amb Google Speech. [8]

1.4.4. Hunspell Hunspell és el corrector de text utilitzat per LibreOffice, OpenOffice, Mozilla Firefox y Google Chrome entre altres. El nostre Bot l’utilitza per corregir els errors ortogràfics del usuaris que podrien confondre a l’Assistent Virtual. [9]

1.4.5. Redis Redis és una base de dades en memòria que utilitzem per guardar variables no persistents. És open source i es pot fer servir des de Python. S’ha utilitzat per guardar i consultar dades específiques de cada sessió, com la duració d’una conversa o l’idioma de la conversa. [10]

1.4.6. Bookline Virtual Assistant L’Assistent Virtual de Bookline rep les trucades dirigides als restaurants que han contractat el servei i administra automàticament les reserves. Està desplegat en el mateix Cluster de Kubernetes que el nostre bot.

1.4.7. Google Speech-to-Text Servei de Google que permet transcriure un arxiu de veu a text. És la mateixa eina que Bookline fa servir per transcriure a temps real les converses amb l'Assistent Virtual i en aquest projecte ho farem servir per transcriure notes de veu. [11]

1.4.8. Cloud Firestore Firestore és una base de dades NoSQL creada per Google on Bookline guarda les dades dels seus clients. [12]

1.5. Pla de Treball El desenvolupament d’aquest projecte es dividirà en 3 parts. En primer lloc la creació d’un prototip, durant la qual s’investigarà sobre les biblioteques que podem utilitzar i les tecnologies de les que disposem. Per completar aquesta part és necessari familiaritzar- se amb Python, l’API de Telegram per a la creació de Bots, Redis i lògicament fa falta un enteniment bàsic de com funciona l'Assistent Virtual de Bookline. El segon pas serà expandir les funcionalitats del prototip per a que pugui ser utilitzat per l’empresa. Ha de poder funcionar a través de múltiples serveis de missatgeria instantània, funcionar per diferents restaurants al mateix temps i el codi s’ha de poder expandir fàcilment en el futur per afegir mes serveis de missatgeria o comportaments específics per a cada servei.

13 Per últim, s’ha de modificar l’Assistent Virtual de Bookline perquè adapti les seves respostes al canal de xat i funcioni correctament a través del nou mitjà, però sense afectar el comportament a través de les trucades telefòniques.

1.5.1. Paquets de Treball

Projecte: Desenvolupament del Prototip WP ref: WP1 Major constituent: Software Descripció: Escriure una primera versió del programa que funcioni amb el Start event: 5/01/2020 xat de Telegram. Es tracta només d’un prototip que no funciona End event: 22/20/2020 amb diferents serveis de missatgeria instantània ni pot administrar reserves per a mes d’un restaurant alhora. Telegram és el servei de missatgeria instantània amb l’API més avançada i millor documentació per crear un Bot.

Internal task T1: Estudi del funcionament d’un Bot de Telegram i de l’API pertinent. Internal task T2: Desenvolupament d’un broker de missatges que enviï els missatges rebuts per Telegram a l'Assistent Virtual i viceversa. Internal task T3: Crear un Handler per quan es rep una nota de veu. La nota de veu es transcriu utilitzant Google Speech. Internal task T4: Reconèixer el final d’una conversació. Internal task T5: Implementar un auto-corrector per a l’input de l’usuari.

Projecte: Integració d’altres serveis WP ref: WP2 Major constituent: Software Descripció: Programar un «gateway» dins l’aplicació que adapti el Start event: 22/01/2020 funcionament del bot segons el servei del que provenen els End event: 21/02/2020 missatges.

Internal task T1: Desenvolupar codi que pugui rebre missatges des de diferents aplicacions. Internal task T2: Integrar Whatsapp Internal task T3: Integrar Facebook Messenger Internal task T4: Adaptar el programa per a què sigui capaç de funcionar en diversos Bots simultàniament (es crearà un bot diferent per cada restaurant)

14 Projecte: Modificar l’Assistent Virtual WP ref: WP3 Major constituent: Software Descripció: Modificar les respostes de l’assistent virtual de Bookline Start event: 21/02/2020 únicament per a les converses a través del xat. End event: 5/03/2020

Internal task T1: Modificar les respostes segons el canal utilitzat (veu o xat) Internal task T2: Modificar l'assistent perquè no requereixi un numero de telèfon a través del xat. Internal task T3: Evitar que l'assistent intenti passar una conversa de xat a una persona.

15 1.5.2. Diagrama de Gantt

WP1 – Tasca 1 WP1 – Tasca 2 WP1 – Tasca 3 WP1 – Tasca 4 WP1 – Tasca 5

WP2 – Tasca 1 WP2 – Tasca 2 WP2 – Tasca 3 WP2 – Tasca 4

WP2 – Tasca 1 WP2 – Tasca 2 WP2 – Tasca 3 Tests 0 10 20 30 40 50 60 70 80 Days of the Project

Figura 2: Diagrama de Gantt

1.5.3. Desviacions Durant el desenvolupament del projecte han sorgit els següents imprevistos. 1. Degut a la manera en que està dissenyat l’Assistent Virtual, necessita rebre un número de telèfon per identificar a cada usuari però amb la excepció de Whatsapp els serveis de missatgeria no permeten l’accés d’un bot a aquesta informació. 2. Hunspell pot fallar a l’hora de corregir alguns errors ortogràfics. S’han hagut de prendre mesures per a què sempre identifiqui les paraules clau que s’utilitzen per a la interpretació de llenguatge natural. 3. Hunspell pot detectar erròniament un nom propi com una falta d'ortografia i canviar el nom de l’usuari o del restaurant. S’ha de prevenir l'ús del corrector quan s’espera que l’usuari introdueixi un nom propi. 4. Utilitzar el servei de Google Speech per transcriure un missatge de veu té un petit cost. Per tant, existeix el perill de que algú enviï una gran quantitat de notes de veu, provocant un enorme cost per al client o per a Bookline.

16 2. Estat de l’Art :

En els últims anys la popularitat de les aplicacions de missatgeria instantània ha estat creixent exponencialment. Els usuaris no només es connecten per parlar amb amics i família, també s’ha convertit en un canal per posar-se en contacte amb marques, buscar merchandising o consumir entreteniment. Des de 2015 les 4 aplicacions de missatgeria mes populars del mercat han superat a les aplicacions de les rets socials més populars en número d’usuaris actius.

Les 4 aplicacions de missatgeria instantània més grans són Whatsapp, Messenger, WeChat i Viber.

Les 4 reds socials mes grans són Facebook, Instagram, Twitter i Linkedin

Figura 3: Creixement de les aplicacions de missatgeria instantània vs rets social entre 2011 i 2017

Empreses com Tommy Hilfiger, o la CNN han creat chatbots per a Facebook Messenger que faciliten informació sobre el seus productes o serveis. En el sector de la restauració han aparegut algunes empreses que ofereixen chatbots personalitzats per a Messenger, Whatsapp o Telegram, com Grizzly-DC [13] o Feebi [14].

2.1. Altres ChatBot Bookline no és la primera empresa interessada en crear un bot per automatitzar les reserves per a restaurants. A través de Messenger i Telegram alguns restaurants ja han implementat Bots conversacionals que atenen a potencials client i ajuden a realitzar reserves.

17 Figura 4: Conversació amb el ChatBot de Bodegas Mezquita per Facebook Messenger

Com es pot veure en la imatge, aquests bots solen guiar a l’usuari utilitzant botons i tot i que en aquest cas sí que té un cert nivell d’interpretació de llenguatge natural no ha pogut entendre peticions com canviar l’idioma. A més, no és capaç de registrar automàticament una reserva; els botons per fer una reserva porten a l’usuari a la pàgina web de Bodegas Mezquita, des d’on poden fer la seva reserva.

18 3. Metodologia i Desenvolupament :

3.1. Creació d’un Bot de Telegram A diferencia d’altres serveis de missatgeria, els Bots són aplicacions molt comuns a Telegram degut al suport que ofereix l’empresa als desenvolupadors. Tenen una API [15] dedicada al seu desenvolupament i han automatitzat el procés de creació a través d’un Bot creat per Telegram.

3.1.1. BotFather BotFather [16] és un bot creat per Telegram que automatitza la creació de nous bots. Per accedir-hi només fa falta registrar-se a Telegram i obrir una conversa amb el Bot. Per crear un nou Bot n’hi ha prou amb escriure el comandament ‘/newbot’. BotFather respondrà preguntant el nom del Bot i un nom d’usuari per registrar-lo. A partir d’aquí ja es pot obrir una conversació amb el Bot, tot i que encara no es capaç de respondre. Quan es crea el Bot, també es genera un Token d’autorització que permet a una aplicació controlar el Bot.

Figura 5: Creació d’un Bot de Telegram amb BotFather

19 3.1.2. Rebre actualitzacions Hi ha dos maneres de rebre les actualitzacions enviades pels usuaris; [17] • La funció getUpdates() de l’API de Telegram permet rebre una llista amb totes les actualitzacions pendents des del servidor de Telegram. • Creant un Webhook totes les actualitzacions s'enviaran automàticament a la URL indicada a utilitzant HTTP. El primer mètode requereix que l’aplicació demani actualitzacions al servidor de Telegram constantment per poder respondre a tots els missatges ràpidament i el nostre bot ha de poder respondre immediatament a les peticions. Per tant és molt millor la segona opció; crear un Webhook per a que totes les actualitzacions s'enviïn al Cluster de GDK creat per Bookline a la URL ‘ https:// bot.dev.bookline.io/ ’ per al Cluster de desenvolupament o ‘https://bot.bookline.io/’ per al Cluster de producció (els Clusters s’expliquen en detall a l’apartat 3.6.2).

Figura 6: Funcionament d'un Webhook

3.1.3. Flask Un cop creat el Webhook l’API de Telegram per a Python incorpora la Classe telegram.ext.Updater, que s’encarrega de rebre les actualitzacions i passar-les al Dispatcher (s’explica en detall a l’apartat 3.1.4). La primera versió del ChatBot utilitzava aquesta classe, però com que ha de poder rebre actualitzacions des de diversos serveis de missatgeria l’aplicació no pot dependre de l’API de Telegram per aquest pas. Com a alternativa s’ha creat una aplicació web utilitzant Flask [6].

20 Figura 7: ChatBot utilitzant la Classe telegram.ext.Updater

Flask és un entorn de treball per a aplicacions web (web framework) escrit en Python que permet escriure aplicacions web de manera simple i ràpida. Aquesta és la estructura mínima d’una aplicació web en Flask [7]: from flask import Flask app = Flask(__name__)

@app.route('/', methods = ['GET']) def hello_world(): return 'Hello, World!'

Aquest codi importa la Classe Flask, crea una instància de la classe i s’indica amb el decorador ‘app.route()’ que la funció hello_world() s’ha d’executar quan es rebi una petició amb el mètode ‘GET’ a la URL indicada. Un decorador és equivalent a una funció que pren com a paràmetre una altra funció. Afegir un decorador a una funció es equivalent a escriure ‘func = decorador(func) o en el cas del codi mostrat a dalt; hello_world = app.route(hello_world, '/', methods = ['GET'])

Utilitzant el mateix esquema, podem crear una funció diferent per a cada servei de missatgeria instantània configurant els Webhooks per a cada servei amb direccions diferents; per tant en comptes de dirigir totes les actualitzacions a ‘https://bot.bookline.io/’ s’enviaran respectivament a les següents direccions: • ‘https://bot.bookline.io/telegram’ per als missatges de Telegram • ‘https://bot.bookline.io/whatsapp’ per als missatges de Whatsapp • ‘https://bot.bookline.io/facebook’ per als missatges de Facebook Messenger

Addicionalment, per raons de seguretat quan es treballa amb ChatBots es recomanable afegir un Token d’autorització a la URL del Webhook, això prevén que tercers puguin enviar peticions a l’aplicació sense conèixer el Token. Donat que l’aplicació web ha de

21 poder controlar els Bots de diversos clients aquest Token també serveix per identificar el Bot al que va dirigida l’actualització.

Figura 8: Estructura de l'aplicació amb Flask

3.1.4. Dispatcher i Handlers Els Bots de Telegram funcionen generalment seguint un patró de disseny Command and Dispatcher [18], un patró de disseny basat en desvincular la implementació d’una ordre i la seva petició. Aquest patró inclou sempre tres conceptes: • Command: Qualsevol tipus d’objecte de transferència de dades que conté els paràmetres de l’ordre. En aquest cas es tracta de les actualitzacions que arriben des de Telegram. • Dispatcher: Element que aparella cada Command amb el Handler apropiat. En el cas de Telegram pren com a criteri el tipus de missatge rebut (missatges de text, notes de veu, imatges...). • Handler: Rep el Command com a paràmetre i executa l’acció.

Perquè el ChatBot pugui escalar-se en el futur cada Handler se separarà en dos parts, primer s’ha de crear un Diccionari [19] amb totes els paràmetres necessaris del Command rebut i aquest Diccionari es passa com a paràmetre a les funcions que es comuniquen amb l’assistent virtual, les quals també es podran fer servir per a les actualitzacions rebudes des de qualsevol servei.

22 El diccionari té la següent estructura.

Figura 9: Paràmetres que utilitza el ChatBot

3.1.4.1. Text Handler Es el Handler que s’encarrega dels missatges de text. L’Assistent Virtual no està dissenyat per rebre missatges escrits per una persona i especialment per xat la gent tendeix a cometre errors ortogràfics i utilitzar abreviatures. Per això cal passar el text per un corrector ortogràfic. La correcció ortogràfica es fa utilitzant la llibreria Hunspell [9], que revisa les paraules una per una i retorna una llista de possibles correccions si la paraula no és correcta (de més probable a menys). Generalment se selecciona el resultat més probable automàticament, però s’ha incorporat una llista de paraules que tenen prioritat si apareixen com un possible resultat ja que són mes probables en el context de l’aplicació. Algunes d’aquestes paraules són totes les variants del verb «reservar» o la paraula «mañana», però se'n podran afegir moltes més quan l’aplicació es faci pública i es puguin recollir dades sobre les paraules amb les que tingui dificultats.

3.1.4.2. Voice Handler S’encarrega de rebre els missatges que contenen una nota de veu. Ha de descarregar l’arxiu d'àudio a la memòria de la Màquina Virtual, convertir l’arxiu de format ‘.ogg’ a format ’.flac’. Per transcriure l'àudio s’utilitza Google Speech, el mateix servei que fa servir Bookline per transcriure les converses per telèfon a temps real. Un cop es té el missatge en text s’eliminen els arxius d’àudio de la memòria i s’envia el missatge a l’Assistent Virtual. El procés per transcriure la nota de veu pot tardar uns segon, així que per indicar a l’usuari que el Bot està funcionant s’envia un ‘Typing Event’ quan es rep una nota de veu. Un ‘Typing Event’ fa que l’usuari vegi una notificació indicant que el Bot està escrivint.

3.1.4.3. Command Handler El Command Handler es un Handler propi de Telegram que s’ocupa dels missatges que contenen una ordre especificada prèviament. Aquestes ordres sempre venen indicades per el símbol ‘/’ al principi del missatge. L’assistent virtual de Bookline interpreta llenguatge natural així que no tenim necessitat d’especificar ordres per a que el Bot funcioni correctament. Tot i així, per disseny tots el Bots de Telegram han de tenir un Handler per a l’ordre ‘/start’.

23 ‘/start’ és el missatge que s’envia automàticament quan un usuari inicia una conversació amb un Bot i li dóna permís per enviar missatges pel xat. Normalment es respon a aquesta ordre amb un missatge introductori i instruccions per utilitzar el Bot, però en el nostre cas la presentació queda en mans de l’Assistent Virtual. En canvi, aquest Handler ha d’enviar a l’assistent un missatge amb el codi *start*. Aquest codi s’envia normalment sempre que s’inicia una trucada i indica a l’assistent que ha de començar una nova conversa. Més endavant el Bot ha de ser capaç de decidir quan cal iniciar una conversa nova i enviar aquest codi automàticament, però l’ordre ‘/start’ permet forçar un reset de la conversa quan s'està testejant el Bot.

Figura 10: Diagrama de Flux

3.1.5. Obtenir una resposta En termes generals, l’assistent virtual de Bookline utilitza processament de llenguatge natural (NLP) [4] per identificar la intenció dels missatges que rep i generar una resposta adequada. Els missatges enviats a l’assistent han de contenir els següents paràmetres en format JSON.

24 Figura 11: Descripció del JSON que s'envia a l'assistent virtual * La majoria de serveis de missatgeria instantània no donen accés al número de telèfon de l’usuari, utilitzarem el telèfon «000000000» afegint el codi regional per indicar a l’assistent quin idioma ha d’utilitzar. «000000000» és el número que es dóna a les trucades amb número ocult.

La resposta de l’assistent sempre inclou dos camps; un número que identifica el tipus de resposta que s’ha donat i el text que s’ha generat per a la resposta. El número indica la intenció de la resposta, pot ser saludar, confirmar que s’ha fet una reserva, fer una pregunta a l’usuari, informar sobre els horaris del restaurant... El text generat és el que s’envia a l’usuari, i normalment se selecciona aleatòriament d’entre una llista de respostes formulades de manera lleugerament diferent per donar una sensació de varietat i que el Bot sembli més humà. Les respostes de l’assistent estan dissenyades per enviar-se a un sintetitzador de veu i per tant poden contenir una sèrie d’errors de format que s’han d’arreglar abans d’enviar- se per xat. Per fer-ho, utilitzarem una serie d'expressions regulars [22] que compleixen els següents objectius. • Eliminar les etiquetes del llenguatge ssml. • Eliminar els símbols de puntuació a l’inici del text. • Afegir un espai després de cada símbol de puntuació. • Eliminar tots els espais que estiguin just abans d’un símbol de puntuació, al principi del text o al final. • Que la primera lletra de cada frase estigui en majúscula.

Figura 12: Expressions regulars (regex) utilitzades

25 3.1.6. Canvis de conversació A través del telèfon es fàcil indicar a l’assistent virtual quan comença una conversació; sempre que s’inicia una trucada se li envia el codi *start* per indicar al bot que ha d’iniciar una nova sessió. Quan es parla per xat mai es penja el telèfon, no hi ha un moment en que l’usuari tanqui el xat i es pugui considerar que s’ha acabat la conversació i per tant el ChatBot tractarà qualsevol interacció amb el mateix usuari com una sola sessió. Això pot provocar que l’assistent digui a l’usuari que ja té una reserva si l’ha fet servir en el passat o que reprengui una conversació antiga que es va quedar a mitges quan s’intenta fer una reserva nova. Per resoldre aquest problema, el ChatBot ha d’enviar per si mateix el codi *start* a l’assistent quan l’usuari inicia una nova sessió. Hi han diverses solucions possibles per detectar quan s’ha d’iniciar una nova sessió. La primera és demanar un input manual de l’usuari per indicar que està obrint una nova conversació. Aquesta solució ja està implementada per facilitar els tests del ChatBot com s’explica a l’apartat 3.1.4.3 i és la única opció amb fiabilitat total. El problema és que depèn de que l’usuari es llegeixi el missatge orientatiu del bot i ha de recordar d’introduir l’ordre en el futur. Per crear una experiència més natural i fluida es millor un sistema automàtic. La segona opció és marcar un esdeveniment que causi el canvi de sessió. Completar una reserva, podria servir per indicar el final d’una sessió, però moltes converses poden acabar sense que l’usuari arribi a fer una reserva. Inversament podríem iniciar una conversació quan l’usuari diu hola, però molta gent no saludaria sabent que parlen amb una màquina. Aquesta opció es completament inviable. La solució que s’ha implementat al final és que es reinici la conversa passat un cert temps des de el primer missatge enviat. Tot i que no és absolutament infal·lible, es pot considerar que si es parla dos cops en un sol dia amb el bot serà per administrar o consultar la mateixa reserva i de la mateixa manera, encara una conversa per xat es pot allargar si l’usuari tarda en respondre és poc probable que passat un dia l’usuari vulgui seguir amb la mateixa reserva. Per això es considera que passades 12 hores la conversa acaba. Per implementar aquesta solució podem registrar la sessió a Redis. Cada vegada que un usuari enviï un missatge s’ha de comprovar si el mateix usuari té una sessió oberta amb el bot del restaurant (s’ha de tenir en compte que un usuari podria obrir converses amb el bot de diversos clients). Si no hi ha sessió es genera un nou UUID [23] i es guarda a Redis amb un temps d’expiració de 12 hores, després el bot ha d’enviar dos missatges; el codi *start* seguit del missatge enviat per l’usuari. Si ja existeix una sessió el missatge s‘envia amb normalitat.

3.2. Integració de Whatsapp Whatsapp és el servei de missatgeria instantània més utilitzat del món, i per tant es el servei en el que hi ha més interès per integrar en l’aplicació. El problema és que a diferència de Telegram, Whatsapp no disposa d’una API pública que permeti la creació d’un ChatBot, però a 2018 Facebook, la companyia propietària de Whatsapp, va publicar Whatsapp Business API, una API per a grans i mitjanes empreses

26 orientada a impulsar la comunicació amb els client i establir la presència d’un negoci a través de Whatsapp. [25] Per utilitzar-la cal obtenir el permís de l’equip de Whatsapp directament per Facebook o a través d’un dels Partners de Whatsapp. El procés per obtenir el permís directe de l’equip de Whatsapp és complex tant en termes d’implementació com de temps, mentre que utilitzant un Partner el procés es pot completar en una mitja de 7 dies, és molt més simple i proveeixen un número de telèfon per al ChatBot. Per a desenvolupar aquest projecte, Bookline ha contractat els serveis de Twilio, un dels principals Partners que proveeixen accés a Whatsapp Business API.

3.2.1. Twilio Twilio és una companyia que ofereix una plataforma de comunicacions a través d’internet. Permet a desenvolupadors de software enviar i rebre SMS, fer trucades de telèfon o altres funcions relacionades amb les comunicacions de manera programable a través de la seva API. Com a part de la seva plataforma de missatgeria programable Twilio ofereix una API que permet enviar notificació, obrir conversacions o desenvolupar un ChatBot a través de Whatsapp. Per utilitzar aquest servei és necessari registrar-se com a usuari de Twilio, comprar un dels números que proveeixen i enviar una petició amb informació sobre la empresa i l’aplicació que es vol desenvolupar. [26] Un cop l’equip de Twilio ha aprovat la petició només cal configurar des de la seva pàgina web el telèfon des de’l que es vol enviar i rebre missatges i la direcció del webhook (com ja s’ha explicat a les seccions 3.1.2 i 3.1.3). En el futur aquest pas s’haurà de repetir per al bot de cada client de Bookline i s’haurà de comprar un nou número per a cada un. Com ja s’ha explicat a la secció 3.1.3 la direcció del webhook és ‘https://bot.bookline.io/whatsapp/{TOKEN}’, on {TOKEN} ha de ser un identificador diferent per a cada client. Per simplicitat, utilitzarem el mateix token d’autorització assignat al Bot de Telegram del mateix restaurant.

3.2.2. Dispatcher i Handlers A diferència de l’API de Telegram, que inclou diverses Classes i eines per facilitar la programació d’un ChatBot, l’API de Twilio [27] només inclou les Classes necessàries per generar, enviar i respondre missatges a través de Whatsapp. Això vol dir que s’ha de crear una nova implementació del patró de disseny descrit en l’apartat 3.1.4. El codi dissenyat ha de complir el següents requeriments. • Crear un Diccionari amb els paràmetres necessaris com s’indica a la Figura 6. • Si el text del missatge es l’ordre ‘/start’ es passa el Diccionari al Command Handler (Apartat 3.1.4.3). • Si és un missatge de text diferent a ‘/start’ es passa al Text Handler (Apartat 3.1.4.1). • Si el missatge conté una nota de veu es descarrega l'àudio i es passa el diccionari al Voice Handler (Apartat 3.1.4.2).

27 • Si el missatge conté un altre tipus d’arxiu s’ignora. • Finalment s’envia la resposta generada a través de Whatsapp.

Figura 13: Estructura del Dispatcher implementat per a Whatsapp

3.3. Integració de Facebook Messenger Per crear un ChatBot a través del xat de Facebook cal crear una aplicació a la plataforma de Facebook Developer [28]. Aquesta plataforma permet als desenvolupadors crear aplicacions que accedeixen a les dades de Facebook a través de diverses eines. Una d’aquestes eines és la Plataforma Messenger, que permet connectar a través d’un Webhook al xat de la pàgina d’una empresa a Facebook amb una aplicació.

3.3.1. Token d’Accés Per poder accedir al xat d’una página de Facebook s’ha de crear un Token d’accés que permeti al Bot respondre als missatges. Aquest Token és el que permetrà al Chatbot rebre i enviar missatges per Facebook Messenger com si fos l’administrador de la pàgina de cada restaurant particular i per tant s’ha d’obtenir un Token diferent per cada Client de Bookline.

28 Figura 14: Procés per a obtenir el Token d'Accés

3.3.2. Webhooks A diferència de la integració per a Telegram o Whatsapp, la plataforma de Messenger utilitza un sol webhook per a totes les pagines que utilitzin el Bot.

29 Figura 15: Utilitzem la URL del servidor de Bookline per al Webhook

En comptes d’afegir un Token com a paràmetre al final de la URL, es pot identificar el Client amb el que cal fer la reserva per la ID de la seva pàgina de Facebook, que s’inclou com a paràmetre al JSON que envia el servidor de Facebook (Veure Annex A).

3.3.3. Dispatcher i Handlers Igual que per a Whatsapp, és necessari crear una implementació del patró de disseny «Command Dipatcher» per al bot de Facebook. Podem utilitzar la mateixa lògica que s’ha fet servir per la implementació de Whatsapp utilitzant la llibreria «pymessenger.bot» [29].

3.3.4. Registrar Clients Tot i que no ha set un problema en la fase de desenvolupament, el procés descrit a l’apartat 3.3.1 exigeix que Bookline tingui accés d’administrador a les pàgines dels seus clients o que els administradors de dites pàgines tinguin accés a l’aplicació. Per raons de seguretat cap d’aquestes opcions és viable, per tant s’ha d’implementar una pàgina que permeti als Clients de Bookline donar els permisos necessaris a l’aplicació. Per resoldre aquest problema s’ha de crear una pàgina web que permeti fer Login a un compte de Facebook i donar permisos a la nostra aplicació, i per a fer això existeix la plataforma Facebook Login [30]. Hem creat una pàgina dins de la web de Bookline que permet als clients seleccionar la pàgina de Facebook on volen que funcioni el bot i donar els permisos necessaris de manera fàcil i ràpida. Link: https://app.bookline.io/p/empezar-con-el-chatbot

3.4. Modificacions a l’Assistent Virtual En aquest punt el ChatBot ja funciona i compleix tots els requeriments, però l’Assistent Virtual de Bookline no està dissenyat per mantenir una conversació per xat, per això s’ha de modificar per a que pugui distingir entre els missatges que arriben a través d’una trucada o a través d’un xat i que respongui de manera adequada segons el canal. A continuació s’expliquen els canvis implementats

3.4.1. Modificar respostes segons el canal configurat En primer lloc, s’han de canviar algunes de les respostes configurades de l’assistent perquè tinguin més sentit en el nou mitjà; el canvi mes obvi es que s’han de canviar totes

30 les frases que facin referència a la trucada, com «gràcies per trucar» o «truqui mes tard». També és necessari modificar el primer missatge que sol enviar l’assistent per saludar i expandir-lo per a que doni la informació necessària per a fer servir el ChatBot. Per fer aquests canvis sense modificar el comportament de l’assistent a través del telèfon primer s’ha d’inspeccionar com s’escolleix la frase a utilitzar. Bookline ha introduït totes les respostes possibles de l’assistent en un arxiu JSON. L’arxiu conté per a cada possible resposta un nom, un identificador i una llista amb diverses possibles frases a enviar; aquestes frases estan formulades de maneres diferents per donar una mica de varietat a l’assistent, però totes tenen el mateix significat.

Figura 16: Exemple de dues respostes que pot donar l'Assistent Virtual

Dins el codi de l’assistent hi ha una classe anomenada MessageGenerator() que s’ocupa de la generació de Llenguatge Natural, el que ens interessa és buscar en quin punt se selecciona la frase que s'utilitzarà com a resposta. Aquesta es la funció _choose().

31 Figura 17: Funció que escolleix la frase que envia l'assistent

Els paràmetres d’aquesta funció són el següents. • ‘self’: En Python, el paràmetre ‘self’ sempre representa l’objecte que executa la funció, en aquest cas una instància de la classe MessageGenerator() o un altra classe que hereti d’aquesta. • ‘action’: És l’acció que l’assistent ha decidit que ha d’emprendre segons l’input de l’usuari i el context de la conversació. És un nom que defineix el tipus de resposta que s’ha d’enviar; per exemple «address» indica que s’ha d’enviar la direcció del restaurant, «Greet» significa que s’ha de saludar a l’usuari, «thanks» és la resposta que s’ha de donar si l’usuari dóna les gràcies al bot... Aquest paràmetre és el nom que identifica cada conjunt de frases, com es veu en la Figura 17. • ‘answers’: És una llista amb totes les respostes que pot enviar l’assistent amb l’estructura mostrada en la Figura 16. L’objectiu d’aquesta funció és simplement elegir aleatòriament una de les possibles frases assegurant-se de no repetir la mateixa frase dos cops seguits.

3.4.1.1. Solució En primer lloc, per poder canviar les respostes sense afectar a les converses per telèfon cal afegir un paràmetre nou a la funció que indiqui el canal a través del que s’està parlant, que s’haurà d’afegir a totes les crides que es fan a la funció _choose(). A l’arxiu JSON on estan les respostes s’afegeix un nou paràmetre només per a les frases que s’hagin de canviar amb una llista que contingui les noves opcions per a enviar. Després es modifica la funció _choose() per a que utilitzi les opcions del paràmetre «chat» en comptes de «answers» si es compleixen dues condicions.

32 Figura 18: Exemple d'una resposta amb una versió per telèfon i un altra per a xat • El paràmetre «channel» indica que s’enviarà la frase per xat. • La resposta «action» té paràmetre «chat».

Figura 19: Funció _choose() modificada

3.4.2. Handover El major problema que presenta el comportament de l’assistent virtual a través del xat és que està dissenyat per transferir les trucades a una persona si es dóna un del següents casos. • L’assistent no pot entendre amb èxit la intenció de l’usuari. • L’assistent no és capaç de respondre les preguntes de l’usuari. • L’usuari demana parlar amb una persona. Els clients de Bookline no volen haver de tenir empleats atenent trucades per un costat i usuaris del Chatbot per l’altre, així que han demanat que totes les converses a través de qualsevol xat siguin resoltes d’una manera o altra per l’assistent. Per tant, el que s’ha de fer es oferir a l’usuari una manera de contacte alternativa si es dóna qualsevol dels casos anteriors.

33 Per implementar aquesta solució, s’ha creat una nova acció per l’assistent (veure secció 3.4.1) amb el nom «transferChat». Aquesta acció se seleccionarà en comptes de qualsevol de les accions que comporten transferir la trucada sempre que el canal de la sessió sigui un xat i generarà una resposta informant a l’usuari de tots els canals alternatius dels que disposa per posar-se en contacte amb el restaurant. Aquests canals poden diferir segons les dades que hagi introduït cada client, però solen incloure un número de telèfon i un correu electrònic.

3.5. Base de Dades Aquest projecte utilitza la mateixa base de dades que l’Assistent Virtual de Bookline, Cloud Firestore [31]. És una base de Dades NoSQL creada i mantinguda per Google.

3.5.1. Estructura Cloud Firestore utilitza una estructura jeràrquica per organitzar les seves dades. Ofereix diverses versions de la seva estructura segons les necessitats de cada usuari, en el cas de Bookline s’utilitza la estructura de col·leccions. Les dades es divideixen en diferents col·leccions, que contenen documents amb diversos paràmetres. Per exemple, la col·lecció «clients» conté un document per a cada client de Bookline i dins de cada document hi ha una llista de paràmetres amb tota la informació del client.

3.5.2. Nova Col·lecció Per guardar els paràmetres dels Chatbots de cada client s’ha creat una nova col·lecció, «Bots». Dins d’aquesta col·lecció hi ha un Document per cada client que vulgui utilitzar el Chatbot de Bookline. Cada document conté els següents paràmetres:

Figura 20: Dades d'un Bot d'exemple a Firebase

34 3.6. Desplegament Igual que l’Assistent Virtual de Bookline, el Chatbot s’ha desplegat com una càpsula de Kubernetes [32], un sistema que automatitza el desplegament d’aplicacions en contenidors [33].

3.6.1. Que és un contenidor? Un contenidor es un concepte similar a una màquina virtual; permet executar aplicacions en un entorn aïllat amb el seu propi sistema operatiu. La diferència és que els contenidors comparteixen un mateix Kernel, facilitant la comunicació entre diversos contenidors i millorant l’eficiència quan cal executar diversos contenidors al mateix temps.

Figura 21: Estructura d'una Màquina Virtual comparada a un Contenidor

3.6.2. Clusters Un entorn de Kubernetes s’anomena Cluster. Un Cluster de Kubernetes consisteix en un grup de màquines (físiques o virtual) anomenades nodes i els nodes contenen les aplicacions en contenidors (pods).[34] Bookline té dos Clusters de GKE [6], un de producció on s’executen les aplicacions que fan sevir els clients i un altre de desenvolupament per poder provar els canvis abans de passar-lo a producció. En el moment en que s’escriu aquest document el Chatbot només s’ha desplegat en el Cluster de desenvolupament. Dins del Cluster de Bookline hi ha tres aplicacions funcionant en nodes separats; l’Assistent Virtual de Bookline, el Chatbot i la base de dades de Redis.

3.6.3. Node del Chatbot Per a executar l’aplicació que controlarà els Chatbots hem configurat un node amb Ubuntu 16.04 i Python 3.5. En l’Annex B es pot veure el Dockerfile de la imatge utilitzada, la llista de llibreries instal·lades i el fitxer «.yaml» amb la configuració del Node. El punt més destacable de la configuració és que s’ha afegit una variable d’entorn anomenada

35 CLUSTER que indica si s’està executant en desenvolupament (dev), producció (pro) o en un Cluster local (local).

3.7. Proves de Funcionament Per realitzar les proves de funcionament s’han mantingut nombroses converses amb el bot a través de cada un dels sistemes de missatgeria, comprovant un per un que es complissin tots els requeriments. Per ajudar amb les proves el programa mostra per consola els missatges que l’hi arriben de l’usuari, els paquets de dades que envia a l’Assistent Virtual i notificacions per avisar de quan s’inicia una nova sessió (Veure apartat 3.1.6). • S’ha comprovat que és possible completar el procés per fer una reserva. • S’ha comprovat que les notes de veu es transcriuen correctament. • S’ha comprovat que el bot funciona encara que es cometin errors comuns a l’hora d’escriure paraules clau gràcies a l’auto-corrector. • S’ha comprovat que el bot pot detectar si l’usuari parla en un altre idioma o demana que es canviï l’idioma. • S’ha intentat rebre totes les respostes possibles de l’assistent per comprovar que s’escriuen correctament a través del xat (Veure apartat 3.1.5). Donat el número de respostes programades en l’Assistent Virtual i la manera semi-aleatòria en que s’escolleixen no ha set possible comprovar-les absolutament totes. • S’ha provat a reduir el temps límit d’una sessió a un minut per comprovar que segueix el comportament esperat passat aquest temps.

3.7.1. Chatbots de prova Com és lògic, per a fer les proves no utilitzem els telèfons ni els bots de clients reals. Bookline ha creat a la base de dades una sèrie de restaurants falsos amb números de telèfon de l’empresa per poder realitzar proves sense fer reserves reals. Addicionalment, per a cada servei de missatgeria instantània s’ha creat un bot de prova connectat a un d’aquests restaurants falsos. Per Telegram s’ha creat un Bot de la manera descrita a l’apartat 3.1, per a whatsapp, Twilio ofereix un número per a fer proves de desenvolupament i en el cas de facebook s’ha creat una segona aplicació a Facebook for Developers, una copia exacta de l’aplicació real però que es mantindrà en estat de desenvolupament i amb un Webhook configurat per al Cluster de desenvolupament (apartat 3.6.2) en comptes del Cluster de producció.

36 4. Resultats

Tenim una aplicació web allotjada en el servidor de Bookline que controla el comportament de múltiples Chatbots, tot i que en el moment en que s’escriu aquest text encara no està en versió de producció i per tant no s’està fent servir per a cap restaurant real. Si vol, el lector pot provar per si mateix el resultat a través de Telegram buscant el bot amb el nom d’usuari @bookline_bot. Desgraciadament les versions de prova per a Whatsapp i Facebook Messenger només responen als missatges dels administradors (en aquest cas, els membres de Bookline). S’ha afegit un vídeo demostrant el funcionament del projecte a l'Annex C.

37 5. Costos

5.1. Desenvolupament del projecte He treballat en aquest projecte durant les meves pràctiques laborals a Bookline des del 5 de Gener fins al 5 de Març, treballant a mitja jornada (4 hores diàries a l’empresa) i escrivint la documentació des de casa.

Etapa Setmanes Dies Hores Cost laboral dedicades Laborables dedicades (A 8€ / hora)

Telegram Bot 4 23 92 736

Integració Whatsapp / 3 12 48 384 Facebook

Modificacions a l’Assistent 2 9 36 288 Virtual

Tests 1 6 24 192

Total 10 50 200 1600 €

Taula 1: Hores dedicades al projecte

Considerant el sou mínim indicat per els convenis de pràctiques de la UPC, 8 € la hora, el cost laboral seria de 1600 €.

5.2. Costos de desplegament Per desplegar i mantenir l’aplicació en funcionament s’ha de pagar mensualment els costos del serveis de Google Cloud Platform, que inclouen el Cluster de GKE, l’ús de Google speech-to-text i la base de dades Firestore. Addicionalment, per cada client que vulgui el Bot a través de Whatsapp s’ha de comprar un número de Telèfon a Twilio i també hi ha un cost per missatge enviat a través del servei.

Servei Cost mensual

Google speech-to-text 59€

Infraestructura Google Cloud 171€

Netelip* 282€

Total 512€

Taula 2: Costos de Bookline durant el mes de Juliol

38 *Netelip [37] és el servei que utilitza Bookline per a redirigir les trucades a través de l’Assistent Virtual. Tot i que és imprescindible per al funcionament d’aquest a través de telèfon no es necessari per a utilitzar-lo a través de serveis de xat. Els costos de Telefonia (Netelip) i Google speech-to-text poden variar segons la quantitat de trucades rebudes, mentre que els costos del servidor de Google Cloud són constants.

5.2.1. Twilio Ja que el projecte encara no s’ha comercialitzat és difícil saber quin flux de missatges es pot esperar a través de Twilio i per tant no es pot calcular un cost mensual exacte. El preu a Espanya per enviar un missatge a través de Twilio és de 0,043$ [35] per missatge o 0,037€ actualment. Durant el mes de juliol Bookline ha rebut 6500 trucades. Considerant que un cop s’obri la possibilitat d’utilitzar l’Assistent Virtual a través de xat un 10% d’usuaris l'utilitzaran, tindríem un 650 usuaris al mes. Tenint en compte el numero d’usuaris de cada un dels sistemes de missatgeria implementats [36] aproximadament el 55% d’usuaris utilitzaran Whatsapp i generalment una sessió es completa amb una mitja de 10 missatges. Així doncs, podem calcular un flux aproximat de 3575 missatges al mes, que tindrien un cost final de 132,2€ al mes. Addicionalment, cada mes s’ha de pagar un import de 1$ (0,84€) per el número de telèfon assignat al bot de cada client. Ara mateix Bookline està oferint els seus serveis a 13 cadenes de restaurants, així que si tots volen tenir la funcionalitat del bot a través de Whatsapp seria un cost de 10,92€ al mes.

5.2.2. Cost Mensual Total

Servei Cost mensual

Google speech-to-text 59€

Infraestructura Google Cloud 171€

Twilio 132,2€

Números de Telèfon 10,92€

Total 373,12€

Taula 3: Cost mensual aproximat del projecte Nota: No s’han inclòs els costos de Netelip perquè no és necessari per a que l’assistent funcioni a través de cap servei de missatgeria instantània.

39 6. Conclusions

En aquesta secció s’analitza si s’han complert tots els requeriments del projecte. S’ha aconseguit connectar amb èxit totes les funcionalitats de l’Assistent Virtual de Bookline amb els xats de diversos sistemes de missatgeria instantània, a través dels qual es poden utilitzar totes les funcions de l’assistent amb la única excepció de transferir la conversa a un humà (per les raons explicades a l’apartat 3.4.2). Tots els missatges enviats per l’assistent virtual es mostren correctament per text en un format fàcilment llegible i gramaticalment correcte. L’usuari pot triar entre escriure a través del xat o enviar notes de veu. L’aplicació pot controlar els Chatbots per a tots els Clients al mateix temps utilitzant la informació de la base de dades de Bookline. Els Chatbots poden detectar l’idioma que té configurat l’usuari per defecte, excepte a través de Whatsapp, on podem utilitzar el número de telèfon per saber la nacionalitat). Després del primer missatge el bot canviarà l’idioma que utilitza si ho fa l’Assistent Virtual. Tot i que no hem trobat una manera infal·lible per decidir quan s’ha d’acabar una sessió (apartat 3.1.6), hem implementat una solució raonable al problema. L'únic objectiu que no s’ha arribat a complir en el moment en que s’escriu aquest text és que algun dels Clients de Bookline comenci a utilitzar el Chatbot per assistir als clients. La principal causa es la paràlisis en el sector de la restauració causada pel COVID-19.

6.1. Desenvolupament Futur Després d’acabar aquest treball es continuarà el desenvolupament d’aquest projecte amb Bookline, analitzant les dades obtingudes quan es comenci a utilitzar comercialment i buscant maneres de millorar les seves respostes i fer que l'ús del Chatbot sigui més intuïtiu. Actualment estem buscant maneres de facilitar l'ús del Chatbot a través de les eines úniques que ofereixen alguns xats, com l'ús de botons que permetin a l’usuari seleccionar la seva resposta entre diverses opcions (per exemple, permetria escollir fàcilment el restaurant en el que es vol reservar si es tracta del Chatbot d’una cadena de restaurants). També volem afegir imatges o emoticones que acompanyin a alguns missatges.

40 Bibliografia

1. What is a ChatBot? | https://expertsystem.com/chatbot/ [Últim accés 3/07/2020] 2. Google Cloud Platform | https://cloud.google.com/ [Últim accés 9/07/2020] 3. Bookline | https://bookline.io/agencia [Últim accés 12/07/2020] 4. Natural Language Processing | https://en.wikipedia.org/wiki/Natural_language_processing [Últim accés 29/06/2020] 5. Google Kubernetes Engine | https://cloud.google.com/kubernetes-engine [Últim accés 12/07/2020] 6. Flask | https://flask.palletsprojects.com/en/1.1.x/ [Últim accés: 27/06/2020] 7. Flask Quickstart | https://flask.palletsprojects.com/en/1.1.x/quickstart/#a-minimal-application [Últim accés: 27/06/2020] 8. About Ffmpeg | https://ffmpeg.org/about.html [Últim accés: 25/07/2020] 9. About Hunspell | http://hunspell.github.io/ [Últim accés: 25/07/2020] 10. Introduction to Redis | https://redis.io/topics/introduction [Últim accés: 25/07/2020] 11. Google Speech-to-Text | https://cloud.google.com/speech-to-text [Últim accés: 25/07/2020] 12. Cloud Firestore | https://firebase.google.com/docs/firestore [Últim accés: 25/07/2020] 13. Grizzly-DC | https://soft.grizzly-dc.com/service/development-chat-bot.html [Últim accés 9/07/2020] 14. Feebi | https://getfeebi.com/features/ [Últim accés 9/07/2020] 15. Telegram Bot API | https://core.telegram.org/bots/api [Últim accés: 27/06/2020] 16. Bots: An introduction for developers. | https://core.telegram.org/bots [Últim accés: 27/06/2020] 17. Python Telegram Bot Documentation | https://python-telegram-bot.readthedocs.io/en/stable/index.html [Últim accés: 27/06/2020] 18. The Command Dispatcher Pattern | https://olvlvl.com/2018-04-command-dispatcher-pattern [Últim accés: 28/06/2020] 19. Python Data Structures | https://docs.python.org/3/tutorial/datastructures.html [Últim accés 28/06/2020] 20. Natural Language Understanding | https://en.wikipedia.org/wiki/Natural-language_understanding [Últim accés 29/06/2020] 21. Natural Language Generation | https://en.wikipedia.org/wiki/Natural-language_generation [Últim accés 29/06/2020] 22. Python regular expressions | https://docs.python.org/3/howto/regex.html [Últim accés 29/06/2020] 23. Universal Unique Identifier | https://en.wikipedia.org/wiki/Universally_unique_identifier [Últim accés 29/06/2020] 24. UUID generation with Python | https://docs.python.org/3/library/UUID.html [Últim accés 29/06/2020] 25. What is Whatsapp Business API | https://respond.io/blog/whatsapp-business-api/#3f4mb [Últim accés 12/07/2020] 26. How to get acces to Whatsapp Business with Twilio | https://www.callbell.eu/en/request-access- whatsapp-business-api-twilio/ [Últim accés 30/06/2020] 27. Twilio Documentation | https://www.twilio.com/docs/whatsapp/api [Últim accés 30/06/2020] 28. Facebook for Developers | https://developers.facebook.com/ [Últim accés 30/06/2020] 29. Pymessenger | https://github.com/davidchua/pymessenger [Últim accés 6/07/2020] 30. Facebook Login Overview | https://developers.facebook.com/docs/facebook-login/overview [Últim accés 15/07/2020] 31. Estructura de Firestore | https://firebase.google.com/docs/firestore/manage-data/structure-data [Últim accés 3/07/2020] 32. What is kubernetes? | https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/ [Últim accés 3/07/2020] 33. A practical guide to choosing between Docker Containers and Virtual Machines | https://www.weave.works/blog/a-practical-guide-to-choosing-between-docker-containers-and-vms [Últim accés 3/07/2020] 34. Kubernetes Concepts | https://kubernetes.io/docs/concepts/ [Últim accés 3/07/2020]

41 35. Cost d’enviar un missatge a través de Twilio | https://www.twilio.com/whatsapp/pricing/es [Últim accés 3/08/2020] 36. Serveis de Missatgeria instantània més utilitzats| https://www.messengerpeople.com/global- messenger-usage-statistics/#:~:text=With%202%20billion%20active%20users,over%20800%20million %20active%20users. [Últim accés 9/07/2020] 37. Netelip - ¿Qué es una Centralita Virtual? | https://www.netelip.com/centro-de-ayuda/centralita- virtual/ [Últim accés 6/08/2020]

42 Annex A: Paquets de Dades

En aquest annex es farà una breu descripció dels paquets de dades que es reben o s’envien des de l’aplicació.

Figura 22: Intercanvi de paquets des de els servidors de el serveis de missatgeria fins a l'Assistent Virtual de Bookline

La Figura 22 enumera els paquets segons l’ordre en que s'envien. A continuació es mostra un exemple de cada tipus de paquet amb una breu descripció dels camps més pertinents

Paquets 1 i 4: Es el missatge enviat per l’usuari a través de Telegram, Whatsapp o Messenger. Hi ha tres versions diferents d’aquest paquet segons quina aplicació s’ha utilitzat. El paquet 4 és la resposta del Chatbot a l’usuari i per tant utilitza la mateixa estructura que el paquet 1, canviant les dades del remitent per les del receptor.

43 Telegram: "message":{ "channel_chat_created":False, "from":{ //Informació de l'usuari "first_name":"Jordi", "id":329277545, "is_bot":False, "last_name":"Alonso", "language_code":"es" }, "chat":{ //Informació de la sala del xat. "first_name":"Jordi", //Com que es una conversa privada "id":329277545, //coincideix amb les dades de l'usuari. "type":"private", "last_name":"Alonso" }, "voice":{ //Arxiu de veu. Només existeix si "file_id":"AwACAgQAAxC", //el missatge és una nota de veu. "file_size":8783, "mime_type":"audio/ogg", "duration":2 }, "text":"Hola", //Text del missatge. Si no es un "supergroup_chat_created":False, //missatge de text està buit. "delete_chat_photo":False, "group_chat_created":False, "date":1596640240, "message_id":1673, }, "update_id":164384314 //ID que identifica al paquet. }

44 Whatsapp: CombinedMultiDict( [ ImmutableMultiDict([]), ImmutableMultiDict( [ #Numero del Bot ('To', 'whatsapp:+14155238886'), #Numero de l'usuari ('From', 'whatsapp:+34608194004'), ('SmsStatus', 'received'), ('NumSegments', '1'), ('SmsSid', 'SMa3ba314f97f3c26d2a19d72af10c90bb'), ('AccountSid', 'AC15b1917a323b2a6906d62bcb8e891c66'), #ID que identifica al paquet. ('SmsMessageSid', 'SMa3ba314f97f3c26d2a19d72af10c90bb'), #Numero d'arxius Media adjunts en el missatge ('NumMedia', '1'), #Tipus d'arxius Media adjunts en el missatge. # Aquest camp no existeis per a missatges de text ('MediaContentType0', 'audio/ogg'), # URL per descargar l'arxiu Media (si n'hi ha) ('MediaUrl0', 'https://api.twilio.com/2010-04-01/...'), ('MessageSid', 'SMa3ba314f97f3c26d2a19d72af10c90bb'), ('ApiVersion', '2010-04-01'), #Text del missatge ('Body', 'Hola'), ] ) ] )

45 Facebook Messenger: { "object":"page", "entry":[ { "id":"107927764264165", //ID que identifica al paquet. "messaging":[ { "sender":{ "id":"2621331404638314" //ID de l'usuari }, "recipient":{ "id":"107927764264165" //ID del Bot }, "message":{ "attachments":[ //Arxius Media adjunts al missatge. { //Aquest camp no existeix si "type":"image", //és un missatge de text. "payload":{ "sticker_id":369239263222822, "url":"https://scontent.xx.fbcdn.net/..." } } ], "mid":"m_UOqQMoD-l7gwFqyzGEg", "text":"Hola" //Text del missatge. Si no es un missatge }, //de veu aquest camp està vuit. "timestamp":1596642841349 } ], "time":1596642841765 } ] }

46 Paquet 2: Es el paquet que s’envia a l’assistent de Bookline i ha de tenir els mateixos camps que els paquets que l’assistent rebria de Netelip si es tractés d’una trucada telefònica.

Paquet 3: És el missatge de resposta de l’Assistent Virtual. El camp «answer» conté el text a enviar i l’ID de la resposta, el camp «tts_lang» indica l’idioma del missatge i la resta només són rellevants per passar el text a veu.

47 { "query": #El missatge de l'usuari "session": #uuid de la conversasió "user_id": #Numero de telefon de l'usuari* "client_id": #Numero de telefon del restaurant "diversion_reason": #Indica si la trucada s'ha transferit, #no s'utilitza per chat "trunk_id": #identificador comú per a una cadena de trucades, #per chat s'utilitza el mateix uuid que per "session" "channel": #Canal per on arriva el missatge (whatsapp, Telegram o Facebook) }

resp = { "answer": { "id": 1.6, "message": ”Bienvenido a Bookline Dev1”, }, "action": {}, "phrases": {}, "tts_lang": ”es-ES”, "stt_lang": ”es-ES”, "voice_provider": ”Lucia”, "handover_phone": ”000000000”, "handover_context": {}, "single_uterrance": True, "wait": get_duration(action, answer["message"]) }

48