Crear un chatbot de WhatsApp con Python, Flask y Twilio

November 20, 2019
Redactado por

Crear un chatbot de WhatsApp con Python, Flask y Twilio

Un bot de chat es una aplicación de software que puede llevar a cabo una conversación con un usuario humano a través de lenguaje escrito o hablado. El nivel de “inteligencia” entre bots de chat varía considerablemente. Aunque algunos bots de chat tienen una comprensión bastante básica del lenguaje, otros emplean algoritmos sofisticados de inteligencia artificial (IA) y de aprendizaje automático (ML) para lograr un nivel de conversación casi humano.

En este tutorial, voy a enseñarles lo fácil que es crear un bot de chat para WhatsApp mediante la API de Twilio para WhatsApp y el marco de Flask para Python. A continuación, puede ver una interacción de ejemplo que tuve con este bot de chat:

Sesión demostrativa del bot de chat de WhatsApp

Requisitos del tutorial

Para seguir este tutorial, necesita los siguientes componentes:

  • Python 3.6 o más reciente. Si su sistema operativo no proporciona un intérprete de Python, puede ir a python.org para descargar un instalador.
  • Flask. Crearemos una aplicación web que responda a los mensajes entrantes de WhatsApp.
  • ngrok. Utilizaremos esta práctica utilidad para conectar la aplicación Flask que se ejecuta en su sistema a una URL pública a la que Twilio pueda conectarse. Esto es necesario para la versión de desarrollo del bot de chat, ya que es probable que su computadora se encuentre detrás de un enrutador o firewall, por lo que no es posible acceder directamente a ella por Internet. Si no tiene instalado ngrok, puede descargar una copia para Windows, MacOS o Linux.
  • Un teléfono inteligente con un número de teléfono activo y la aplicación WhatsApp instalada.
  • Una cuenta de Twilio. Si es nuevo en Twilio, cree una cuenta gratuita ahora. Puede revisar las funciones y limitaciones de una cuenta de Twilio gratuita.

Configurar el sandbox de Twilio para WhatsApp

Twilio ofrece un sandbox para WhatsApp donde puede desarrollar y probar fácilmente su aplicación. Una vez que se complete la aplicación, puede solicitar acceso de producción a su número de teléfono de Twilio, lo cual requiere aprobación mediante WhatsApp.

Conectemos su teléfono inteligente al sandbox. Desde su Consola de Twilio, seleccione Programmable Messaging (Mensajería programable), luego haga clic en “Try it Out” (Probar) y finalmente haga clic en Try WhatsApp (Probar WhatsApp). La página del sandbox de WhatsApp le mostrará el número del sandbox asignado a su cuenta y un código para entrar.

Captura de pantalla de configuración del sandbox de WhatsApp

Para activar el sandbox de WhatsApp para su teléfono inteligente, envíe un mensaje de WhatsApp con el código proporcionado al número asignado a su cuenta. El código debe comenzar con la palabra join, seguido de una frase de dos palabras generada aleatoriamente. Poco después de enviar el mensaje, debe recibir una respuesta de Twilio, la cual indica que su número de teléfono celular está conectado al sandbox y puede comenzar a enviar y recibir mensajes.

Tenga en cuenta que este paso debe repetirse para cualquier teléfono adicional que desee conectar a su sandbox.

Crear un entorno virtual de Python

Siguiendo las prácticas recomendadas de Python, vamos a crear un directorio separado para nuestro proyecto de bot de chat y, dentro de él, crearemos un entorno virtual. Luego, vamos a instalar en este entorno los paquetes Python que necesitamos para nuestro bot de chat.

Si está utilizando un sistema operativo Unix o Mac, abra un terminal e ingrese los siguientes comandos para realizar las tareas descritas anteriormente:

$ mkdir whatsapp-bot
$ cd whatsapp-bot
$ python3 -m venv whatsapp-bot-venv
$ source whatsapp-bot-venv/bin/activate
(whatsapp-bot-venv) $ pip install twilio flask requests

Para quienes siguen el tutorial en Windows, ingrese los siguientes comandos en una ventana del símbolo del sistema:

$ mkdir whatsapp-bot
$ cd whatsapp-bot
$ python3 -m venv whatsapp-bot-venv
$ whatsapp-bot-venvScripts\activate
(whatsapp-bot-venv) $ pip install twilio flask requests

El último comando utiliza pip, el instalador de paquetes de Python, para instalar los tres paquetes que usaremos en este proyecto, que son los siguientes:

Para su referencia, en el momento en que se publicó este tutorial, estas eran las versiones de los paquetes anteriores y las dependencias que se probaron:

certifi==2019.9.11
chardet==3.0.4
Click==7.0
Flask==1.1.1
idna==2.8
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
PyJWT==1.7.1
pytz==2019.3
requests==2.22.0
six==1.13.0
twilio==6.33.1
urllib3==1.25.7
Werkzeug==0.16.0

Crear un servicio de bot de chat de Flask

Ahora vamos a la parte divertida. Construyamos un bot de chat.

El tipo de bot de chat que mejor funcionará para usted dependerá en gran medida de sus necesidades particulares. En este tutorial, voy a crear un bot de chat extremadamente simple que reconoce dos palabras clave en los mensajes enviados por el usuario y que reacciona ante dichas palabras. Si el usuario escribe algo que contenga la palabra “quote” (cita), el bot de chat devolverá una cita famosa aleatoria. Si, en cambio, el mensaje tiene la palabra “cat” (gato), entonces aparecerá una imagen de gatos aleatoria. Si “quote” y “cat” están presentes en el mensaje, el bot responderá con una cita y una imagen de gatos.

Webhook

La API de Twilio para WhatsApp utiliza un webhook para notificar a una aplicación cuando hay un mensaje entrante. Nuestra aplicación de bot de chat debe definir un punto final que se configurará como este webhook para que Twilio pueda comunicarse con él.

Con el marco de Flask, es extremadamente fácil definir un webhook. A continuación, se muestra una aplicación tipo esqueleto con una definición de webhook. No se preocupe por copiar este código. Primero, le mostraré todas las diferentes partes de la implementación. Luego, una vez que las comprenda, le mostraré cómo se combinan en una aplicación funcional.

from flask import Flask

app = Flask(__name__)


@app.route('/bot', methods=['POST'])
def bot():
    # add webhook logic here and return a response


if __name__ == '__main__':
    app.run()

Si no está familiarizado con el marco de Flask, su documentación tiene una sección de inicio rápido que lo pondrá al día rápidamente. Si desea un recurso de aprendizaje más detallado, entonces le recomiendo seguir mi Megatutorial de Flask.

Lo importante que hay que tener en cuenta acerca del código anterior es que la aplicación define un punto final /bot que escucha solicitudes POST. Cada vez que Twilio reciba un mensaje entrante de un usuario, este activará este punto final. El cuerpo de la función bot() analizará el mensaje enviado por el usuario y proporcionará la respuesta apropiada.

Mensajes y respuestas

Lo primero que debemos hacer en nuestro bot de chat es obtener el mensaje ingresado por el usuario. Este mensaje viene en la carga útil de la solicitud POST con una clave “Body”. Podemos acceder a él a través del objeto request de Flask:

from flask import request
incoming_msg = request.values.get('Body', '').lower()

Dado que vamos a realizar algunos análisis básicos de idioma en este texto, también dejé el texto en minúscula, de forma que no debamos preocuparnos de todas las diferentes formas en que puede aparecer una palabra cuando introduzcan variaciones entre mayúsculas y minúsculas.

La respuesta que Twilio espera del webhook se debe proporcionar en TwiML o Twilio Markup Language, los cuales corresponden a un idioma basado en XML. La biblioteca auxiliar de Twilio para Python viene con clases que facilitan la creación de esta respuesta sin tener que crear directamente un XML. A continuación, puede ver cómo crear una respuesta que incluya componentes de texto y medios:

from twilio.twiml.messaging_response import MessagingResponse

resp = MessagingResponse()
msg = resp.message()
msg.body('this is the response text')
msg.media('https://example.com/path/image.jpg')

Tenga en cuenta que, para devolver una imagen, Twilio espera una dirección URL que apunte a ella en lugar de los datos reales de la imagen.

Lógica del bot de chat

Para la lógica real del bot de chat, usaré un enfoque muy simple, pero sorprendentemente efectivo. Lo que haré es buscar en los mensajes entrantes las palabras clave “quote” y “cat”. Esta es la estructura básica del bot de chat:

    responded = False
    if 'quote' in incoming_msg:
        # add a quote to the response here
        responded = True
    if 'cat' in incoming_msg:
        # add a cat picture to the response here
        responded = True
    if not responded:
        # return a generic response here

Con esta estructura simple, podemos detectar referencias a citas o gatos y configurar el objeto de respuesta de Twilio como corresponda. El valor booleano responded (respondió) es útil para rastrear el caso en el que el mensaje no incluye ninguna de las palabras clave que estamos buscando y, en ese caso, ofrecer una respuesta genérica.

API de terceros

Para proporcionar al bot de chat citas originales e imágenes de gatos, usaré dos API disponibles públicamente. Para las citas famosas, elegí la API Quotable de Luke Peavey. Una solicitud GET a https://api.quotable.io/random devuelve una cita aleatoria de un conjunto de 1500 citas en formato JSON.

Para las imágenes de gatos, usaré la API Cat as a Service de Kevin Balicot. Esta es una API extremadamente simple, la URL https://cataas.com/cat devuelve una imagen de gatos diferente cada vez (puede probarla pegando esta URL en la barra de direcciones del navegador y, luego, tocando el botón Actualizar para obtener una nueva imagen de gatos). Esto es muy práctico, ya que, como mencioné anteriormente, Twilio desea que la imagen se entregue como una dirección URL cuando prepara la respuesta TwiML.

Todo junto

Acaba de ver todos los aspectos de la implementación del bot de chat, de modo que estamos listos para integrar todas las piezas en el servicio completo del bot de chat. Puede copiar el siguiente código en un archivo bot.py:

from flask import Flask, request
import requests
from twilio.twiml.messaging_response import MessagingResponse

app = Flask(__name__)


@app.route('/bot', methods=['POST'])
def bot():
    incoming_msg = request.values.get('Body', '').lower()
    resp = MessagingResponse()
    msg = resp.message()
    responded = False
    if 'quote' in incoming_msg:
        # return a quote
        r = requests.get('https://api.quotable.io/random')
        if r.status_code == 200:
            data = r.json()
            quote = f'{data["content"]} ({data["author"]})'
        else:
            quote = 'I could not retrieve a quote at this time, sorry.'
        msg.body(quote)
        responded = True
    if 'cat' in incoming_msg:
        # return a cat pic
        msg.media('https://cataas.com/cat')
        responded = True
    if not responded:
        msg.body('I only know about famous quotes and cats, sorry!')
    return str(resp)


if __name__ == '__main__':
    app.run()

Probar el bot de chat

¿Está listo para probar el bot de chat? Después de copiar el código anterior en el archivo bot.py, inicie el bot de chat ejecutando python bot.py. Asegúrese de hacerlo mientras el entorno virtual de Python está activado. La salida debe ser algo como lo siguiente:

(whatsapp-bot-venv) $ python bot.py
 * Serving Flask app "bot" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

El servicio se está ejecutando ahora como servicio privado en el puerto 5000 dentro de su computadora y se asentará allí a la espera de conexiones entrantes. Para poder acceder a este servicio desde Internet, debemos usar ngrok.

Abra una segunda ventana de terminal y ejecute ngrok http 5000 para asignar un dominio público temporal que redireccione las solicitudes HTTP a nuestro puerto local 5000. En una computadora con sistema operativo Unix o Mac, es posible que deba usar ./ngrok http 5000 si tiene el archivo ejecutable ngrok en su directorio actual. El resultado de ngrok debe ser algo como lo siguiente:

captura de pantalla de ngrok

Observe las líneas que comienzan con “Forwarding” (Reenviando). Estas muestran la URL pública que utiliza ngrok para redirigir las solicitudes a nuestro servicio. Lo que debemos hacer ahora es decirle a Twilio que utilice esta dirección URL para enviar notificaciones de mensajes entrantes.

Vuelva a la consola de Twilio, haga clic en Programmable Messaging (Mensajería programable), luego en Settings (Configuración), y finalmente en WhatsApp Sandbox Settings (Configuración de sandbox de WhatsApp). Copie la URL https:// desde la salida de ngrok y, luego, péguela en el campo “When a message comes in” (Cuando aparezca un mensaje). Debido a que nuestro bot de chat se expone en la URL /bot, anexe eso al final de la URL ngrok de raíz. Asegúrese de que el método de solicitud esté configurado en HTTP Post. No olvide hacer clic en el botón rojo Save (Guardar) en la parte inferior de la página para registrar estos cambios.

Captura de pantalla de la configuración del sandbox de Twilio para WhatsApp

Ahora puede comenzar a enviar mensajes al bot de chat desde el teléfono inteligente que conectó al sandbox. Puede escribir las frases que desee y cada vez que las palabras “quote” y “cat” aparezcan en los mensajes, el bot de chat invocará las API de terceros y le devolverá algún contenido nuevo. En caso de que no la haya visto en la parte superior del artículo, aquí hay una sesión de ejemplo que tuve con el bot de chat:

Sesión demostrativa del bot de chat de WhatsApp

Tenga en cuenta que, cuando se utiliza ngrok de forma gratuita, existen algunas limitaciones. En particular, no puede conservar una dirección URL ngrok durante más de 8 horas y el nombre de dominio que se le asigna será diferente cada vez que inicie el comando ngrok. Deberá actualizar la dirección URL en la consola de Twilio cada vez que reinicie ngrok.

Notas sobre la implementación de producción

Creo que sería útil finalizar este tutorial con una lista de cosas que deberá considerar si decide implementar un bot de chat de WhatsApp para fines de producción.

En primer lugar, ha visto que cuando se inicia la aplicación Flash, se muestra una advertencia bastante alarmante acerca de no utilizar un servidor de desarrollo para fines de producción. El servidor web que viene con Flask es muy conveniente para desarrollar y probar una aplicación, pero no es lo suficientemente sólido para manejar las demandas de uso en producción. Los dos servidores web más comunes de uso inmediato en producción para aplicaciones web de Python son gunicorn y uWSGI; ambos se pueden instalar en su entorno virtual con pip`. Por ejemplo, aquí se muestra cómo ejecutar el bot de chat con gunicorn:

(whatsapp-bot-venv) $ gunicorn -b :5000 bot:app

Además, tenga en cuenta que, para una implementación de producción, usted ejecutará el servicio en un servidor en la nube y no desde su propia computadora, por lo que no hay necesidad de utilizar ngrok.

Conclusión

Las empresas están recurriendo cada vez más a bots de chat para ofrecer a sus clientes acceso inmediato a soporte, ventas o marketing. Un bot de chat puede ser útil para recopilar información del cliente antes de que se involucre un agente humano, y un bot de chat bien diseñado también debe ser capaz de manejar flujos de trabajo comunes del cliente sin asistencia humana.

Espero que este tutorial haya sido útil y ahora tenga una mejor idea de cómo crear su bot de chat de WhatsApp. A continuación, puede encontrar algunos recursos adicionales para crear bots de chat con Python en caso de que desee ver más implementaciones:

Me encantaría ver el bot de chat que va a construir.

Este artículo fue traducido del original "Build a WhatsApp Chatbot With Python, Flask and Twilio". Mientras estamos en nuestros procesos de traducción, nos encantaría recibir sus comentarios en help@twilio.com - las contribuciones valiosas pueden generar regalos de Twilio.