Despliega tu chatbot en una hora con Dialogflow

En más de una ocasión, hablando con los compañeros de la oficina, nos hemos dado cuenta de que muchas veces nos perdemos meetups de gran interés. No es algo que nos haya pasado una vez ni dos. Por desgracia, es algo que nos ha ocurrido con frecuencia, bien porque nos enteramos tarde (a veces el mismo día) o incluso a toro pasado.

Por eso, nos propusimos tratar de solucionar este tema de alguna manera, ya que las newsletter de algunos meetups no siempre funcionan o no se les presta la debida atención.

Para resolver este problema, empezamos a pensar en una solución de bajo coste: una pizarra + post-it/rotulador (esto es algo rápido y se puede validar rápidamente si funciona o no).

Pero para que tenga éxito hay que buscar un sitio de paso en el que la gente se detenga delante del tablón a leer la información (no nos vale con que simplemente pasen de largo).

Poner una pizarra de estas características es complicado. Los mejores sitios impactan mucho en la estética de la oficina, así que hemos empezado a abordar otras soluciones de carácter más tecnológico. ¿Cuál ha sido el resultado final? Veámoslo paso a paso.

En estas estábamos cuando alguien sugirió empezar a trabajar con un chatbot, algo rápido y que podemos montar en muchos canales. De esta manera podemos publicar la información que queramos en Slack (y por tanto llegaríamos a los equipos de desarrollo) y en otros canales para hacerlo también accesible a personas que no entren habitualmente en estos chats.

La herramienta: Dialogflow

Elegimos Dialogflow como herramienta core para desarrollar nuestro chatbot porque nos simplifica enormemente el desarrollo, ya que cubre prácticamente toda la funcionalidad que deseamos:

  • Nos proporciona mecanismos de speech-to-text y text-to-speech, lo que nos permite utilizar el chatbot tanto por voz como por texto.
  • Es una tecnología cognitiva. Al utilizar algoritmos de procesamiento de lenguaje natural, no tenemos que programar absolutamente todas las interacciones. Irá aprendiendo en base al entrenamiento de distintas maneras de preguntar lo mismo y distintas respuestas para las mismas preguntas, lo que enriquece la comunicación.
  • Nos da la posibilidad de utilizar contextos. Con esta característica es posible recabar información a lo largo de una conversación, no es necesario que toda la información nos la comunique el usuario en una sola interacción.
  • Facilidad para extender la funcionalidad básica. Simplemente añadiendo un endpoint que soporte la estructura que marca la API podemos conectarlo con cualquier otro sistema para procesar las respuestas.
  • Integración con multitud de canales de “out-of-the-box”: permite una integración sencillísima con multitud de canales, entre los que se encuentran los que necesitamos (Google Assistant y Slack).
  • Tiene capa gratuita. Esto aporta valor en tanto en cuanto que estamos haciendo una PoC para evaluar la viabilidad de la idea, y siempre viene bien poder probar la tecnología sin tener que hacer un desembolso inicial.

Esto no significa que lo que vamos a hacer no se pueda hacer con resto de herramientas que proporcionan capacidades parecidas (wit.ai, Amazon lex, LUIS de Microsoft…), pero Dialogflow cumple perfectamente con nuestras necesidades, es tremendamente sencillo y nos da un ecosistema para trabajar con el que nos sentimos muy cómodos.

Una vez elegida la tecnología, vamos a empezar por codificar nuestro bot. En primer lugar entendamos cómo funciona Dialogflow.

Entendiendo la solución

En un chatbot tendremos una arquitectura del siguiente tipo:

Este dibujo es a nivel global, veamos de qué partes se compone un “agente” (que es como se llaman los bots), en Dialogflow:

  • Entities: corresponden a las entidades de primer nivel que queremos manejar en nuestro agente. En nuestro caso vamos a manejar entidades genéricas (que no hay que dar de alta) y como entidad propia de nuestro caso, el “Topic” que nos fijará el tema sobre el que vamos a consultar.
  • Intents: acciones que corresponden a la lógica de negocio y que va a realizar nuestro agente. En nuestro caso, vamos a tener una única acción que será consultar los meetups que hay.
  • Integrations: son los sistemas con los que podremos integrarnos de forma muy sencilla. Estas integraciones corresponden al canal. Dialogflow nos permite a día de hoy todas estas:

  • Fullfilment: en este apartado es donde podremos extender la funcionalidad del bot para poder añadirle nueva complejidad mediante servicios que desarrollemos.

Dialogflow además cuenta con un par de apartados más en las opciones principales que nos permiten ver todos los mensajes con los que estamos entrenando a nuestro bot (training) y una parte de estadística que nos ayudan a ver el uso que está teniendo (analytics).

También cuenta con agentes pre entrenados o conversaciones tipo que podemos incorporar a nuestro bot.

Manos a la obra

Una vez entendidos los conceptos, es hora de comenzar a codificar nuestro bot. Nuestro caso es muy sencillo, ya que vamos a tener un único Intent, que va a ser consultar los meetups que hay registrados en meetup.com.

Registro

En primer lugar vamos a la página de Dialogflow y nos registramos (esta página nos dará acceso únicamente a la parte gratuita). Para que nos autodetecte los temas, empezamos creando la entidad “tema”.  

Entities

Abrimos el espacio de entities y pulsamos sobre Create Entity. Elegimos un nombre, por ejemplo Topic, y comenzamos a añadir temas, que serán los que podrán elegir nuestros usuarios. Para cada tema pondremos un valor y luego sinónimos, que se traducirán como nuestro valor principal:

Guardamos clicando sobre el botón superior junto al nombre. Ahora ya nos aparecerá nuestra nueva entidad creada:

Intents

Nos vamos al apartado de Intents y creamos la acción para obtener el listado de Meetups, pulsando sobre el botón Create Intent.

Le vamos a poner “Intent.ListMeetups”, indicando que queremos listar los eventos. Antes de comenzar a introducir frases de entrenamiento, vamos a indicarle cuáles son los parámetros que vamos a esperar.

Clicamos sobre new parameter y añadimos el periodo de tiempo y el tema. El primero será del tipo date-period (uno de los tipos predefinidos) y el otro será un Topic, que será la entidad que hemos creado previamente:

Y ahora sí, es el momento de introducir frases de entrenamiento marcándole los parámetros, en caso de que no se reconozcan correctamente de forma automática:

Fullfilment

En este paso vamos a introducir la interacción con el API de meetup.com. Dialogflow va a extraer la intención del usuario y los parámetros que nos ha proporcionado y nosotros, mediante un script, vamos a llamar al API  y devolverlo en el formato que Dialogflow espera.

Para activar esta parte debemos ir al apartado fulfillment y, o bien introducir directamente el código en este punto utilizando el inline editor, o bien poner un endpoint donde levantemos nuestra función.

Nosotros vamos a utilizar esta segunda aproximación, levantando una Cloud Function con Google (podría ser cualquier endpoint que sea accesible desde esa consola).

En este punto es importante señalar que acaban de establecer como API definitiva la V2, así que conviene que los ejemplos que veamos utilicen esta nueva API que trae algunas mejoras (como se puede leer aquí).

Existe una librería de node que podemos usar, pero para ilustrar mejor qué es todo lo que ocurre, he preferido obviar el uso de esta librería para ver cómo funciona internamente y que podáis hacerlo con cualquier lenguaje. Podéis consultar todo el código en el Git de Paradigma.

Nota: aunque la publicación del código en una cloud function queda fuera de la temática del post, hay instrucciones sobre cómo hacerlo en el README del código publicado.

Básicamente lo que hacemos es obtener los parámetros para poder mandárselos al API. Luego hacemos una llamada al servicio de configuración de runtime (lo hacemos de esta forma para no tener que poner el API key en nuestro código). Para invocar este servicio desde una function, utilizamos esta librería.

const parameters = getParameters(req);

topic = getTopic(parameters);
dateFrom = (parameters['date-period'] === '') ? moment() : getDateFrom(parameters);
dateTo = (parameters['date-period'] === '') ? moment(MAX_DATE) : getDateTo(parameters);

Con estos datos ya podemos invocar el API de meetup.com y sólo nos queda procesar la información.

let apiKey = yield runtimeConfig.getVariable('dev-config', 'api-key');
const API_URL = 'https://api.meetup.com/';
const FIND_GROUPS = 'find/groups?';
const KEY = 'key=' + apiKey + '&sign=true';
const ZIP = '&zip=meetup1';
const FILTER_FIELDS = '&only=score,name,link,city,next_event';
const MAX_PAGE = '&page=50';
const TECH_CATEGORY = '&category=34';
const params = KEY + ZIP + TECH_CATEGORY + topicParam + FILTER_FIELDS + MAX_PAGE;

//Invoking API meetup.com and processing the result
let meetups = yield getMeetups(API_URL + FIND_GROUPS + params);

let responseJson = meetups
       .filter(meetupsWithEventAvailable)
       .filter((meetup) =>  moment(meetup.next_event.time).isBetween(dateFrom,dateTo))
       .map(meetupAPItoMeetupDetail);

responseJson.sort(orderDateAsc);

La procesamos de manera distinta según la queramos para Slack o para Google Assistant.

//Header info
if (topic !== '') {
   extraInfo += ' sobre ' + topic;
}

if (parameters['date-period'] !== '') {
   extraInfo += ' entre '+ getDateFrom(parameters).format('DD/MM/YY') + ' y ' + getDateTo(parameters).format('DD/MM/YY');
}

//Detail info
if (responseJson.length > 0) {

   responseText = 'He encontrado ' + responseJson.length + ' resultados ' + extraInfo + '. Son los siguientes :\n';


   //Tendremos 2 respuestas. Una para google assistant, preparada para ser leída y otra para slack, preparada para hacer click.
   responseJson.forEach(function (detail) {
       if (requestSource === 'google') {
           responseText = responseText.concat('El grupo ' + detail.name + ' organiza ' + detail.eventName + ' el próximo día ' + detail.eventDate.format('DD/MM/YY') + '.\n');
       }
       else {
           responseText = responseText.concat('<' + detail.link + ' | ' + detail.name + '> - ' +
               '*' + detail.eventName + '* el próximo día ' + detail.eventDate.format('DD/MM/YY') + '\n');
       }
   });


}

Para que funcione nuestro webhook tenemos que activarlo en nuestro intent:

Integrations

Llegados a este punto, Dialogflow nos vuelve a simplificar mucho la vida. Basta con que le digamos desde dónde queremos probar nuestro agente.

Nosotros vamos a elegir Google Assistant y Slack. Únicamente nos falta seguir los pasos que nos dice cuando activamos cada uno y ya podremos realizar la prueba.

Empezamos por Google Assistant, al clicar en su icono dentro de Integrations nos aparece la ventana:

Hacemos clic en test y ya accedemos al emulador. Una vez dentro, estamos en el ecosistema de Google Assistant y tendremos que invocar nuestro agente. Introducimos el texto “Hablar con mi aplicación de prueba”.

Con este mensaje lanzamos nuestro agente y ya podremos preguntarle por ejemplo por los eventos de Java en el mes de mayo:

Y veamos como se ve la misma pregunta en Slack. En este caso nos va a crear un bot con el que podremos interactuar en la red que tengamos nuestro Slack. Abrimos una conversación con nuestro bot/agente y le preguntamos lo mismo:

Conclusión

Como hemos visto, este ejemplo es muy sencillo, no contemplamos errores y no hemos tenido que añadir contextos ni nada parecido.

Como primera aproximación, para ver qué tal funciona nuestro nuevo sistema de meetups, es suficiente.

Iremos comprobando que aceptación tiene el nuevo sistema y si debemos extender la funcionalidad (Google nos ofrece muchas más opciones que aún no hemos utilizado).

¡Esperemos que os sea de ayuda para vuestros proyectos!

Soy arquitecto Software/Preventa en Paradigma y me aseguro de que las novedades tecnológicas que incorporamos traigan de la mano nuevas posibilidades para nuestros clientes. Últimamente estoy centrado en las arquitecturas Cloud Native así como la nuevas posibilidades que está brindando el tándem potencia de cálculo + inteligencia artificial. Soy un afortunado que trabaja con personas excelentes haciendo lo que le gusta.

Ver toda la actividad de Juan Pablo González de Gracia