Criar um chatbot para WhatsApp com Python, Flask e Twilio

November 20, 2019
Escrito por

Criar um chatbot para WhatsApp com Python, Flask e Twilio

Um chatbot é um aplicativo de software capaz de conversar com um usuário humano por meio de linguagem escrita ou falada. O grau de "inteligência" entre os chatbots varia muito. Enquanto alguns deles têm uma compreensão bastante básica da linguagem, outros empregam algoritmos sofisticados de inteligência artificial e aprendizado de máquina para atingir um nível de conversação quase humano.

Neste tutorial, vou mostrar como é fácil criar um chatbot para WhatsApp usando a API da Twilio para WhatsApp e a estrutura do Flask para Python. Veja um exemplo de interação que tive com este chatbot:

WhatsApp chatbot demo session

Requisitos do tutorial

Para seguir este tutorial, você precisa dos seguintes componentes:

  • Python 3.6 ou mais recente. Se o seu sistema operacional não fornecer um interpretador Python, você pode acessar python.org para fazer o download de um instalador.
  • Flask. Vamos criar um aplicativo da Web que responde às mensagens recebidas no WhatsApp.
  • ngrok. Vamos usar este utilitário prático para conectar o aplicativo Flask em execução no seu sistema a um URL público ao qual a Twilio possa se conectar. Ele é necessário para a versão de desenvolvimento do chatbot porque provavelmente seu computador usa um roteador ou firewall, o que faz com que ele não possa ser acessado diretamente na Internet. Se o ngrok não estiver instalado, baixe uma cópia para Windows, MacOS ou Linux.
  • Um smartphone com um número de telefone ativo e o WhatsApp instalado.
  • Uma conta da Twilio. Se você é novo na Twilio, crie uma conta gratuita. Confira os recursos e as limitações de uma conta gratuita da Twilio.

Configurar a sandbox da Twilio para WhatsApp

A Twilio fornece uma sandbox para WhatsApp na qual você pode desenvolver e testar seu aplicativo facilmente. Depois que seu aplicativo estiver finalizado, você poderá solicitar o acesso de produção para o número de telefone da Twilio, que exige a aprovação pelo WhatsApp.

Vamos conectar o smartphone à sandbox. No console da Twilio, selecione Programmable Messaging, clique em "Try it Out" (Experimentar) e, por último, clique em Try WhatsApp (Experimentar WhatsApp). A página da sandbox do WhatsApp mostrará o número da sandbox atribuído à sua conta e um código de ingresso.

Captura de tela da configuração da sandbox do WhatsApp

Para ativar a sandbox do WhatsApp em seu smartphone, envie uma mensagem pelo WhatsApp com o código fornecido para o número atribuído à sua conta. O código vai começar com a palavra join, seguida de uma frase com duas palavras gerada aleatoriamente. Logo após enviar a mensagem, você deverá receber uma resposta do Twilio indicando que seu número de celular está conectado à sandbox e já pode começar a enviar e receber mensagens.

Esta etapa deverá ser repetida para todos os outros telefones que você quiser conectar à sandbox.

Criar um ambiente virtual Python

Seguindo as práticas recomendadas do Python, vamos criar um diretório separado para nosso projeto de chatbot e, dentro dele, vamos criar um ambiente virtual. Em seguida, vamos instalar os pacotes Python necessários para nosso chatbot.

Se você estiver usando um sistema Unix ou MacOS, abra um terminal e digite os seguintes comandos para realizar as tarefas descritas acima:

$ 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

Se você estiver seguindo o tutorial no Windows, digite os seguintes comandos em uma janela do prompt de comando:

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

O último comando usa pip, o instalador de pacotes Python, para instalar estes três pacotes que vamos usar no projeto:

Para sua referência, quando este tutorial foi lançado, estas eram as versões dos pacotes acima e das respectivas dependências testadas:

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

Criar um serviço de chatbot com Flask

Agora, chegamos à parte divertida. Vamos criar um chatbot!

O tipo de chatbot mais adequado para você depende, em grande parte, das suas necessidades específicas. Neste tutorial, vou criar um chatbot extremamente simples que reconhece duas palavras-chave nas mensagens enviadas pelo usuário e que reage a elas. Se o usuário escrever uma frase contendo a palavra "quote" (citação), o chatbot retornará uma citação aleatória de um autor famoso. Se, em vez disso, a mensagem tiver a palavra "cat" (gato), será retornada uma foto aleatória de um gato. Se as palavras "quote" e "cat" estiverem na mensagem, o bot responderá com uma citação e uma foto de gato.

Webhook

API da Twilio para WhatsApp usa um webhook para notificar um aplicativo quando uma mensagem é recebida. Nosso aplicativo de chatbot precisa definir um endpoint, que será configurado como o webhook para que a Twilio possa se comunicar com ele.

Com a estrutura do Flask, é extremamente fácil definir um webhook. Veja abaixo um esqueleto de aplicativo com uma definição do webhook. Não se preocupe em copiar este código; primeiro, vou mostrar as diferentes partes da implementação e, depois que você entender todas elas, vou mostrar como elas se combinam em um aplicativo em funcionamento.

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()

Caso você não esteja familiarizado com a estrutura do Flask, na documentação existe uma seção de início rápido que pode ser bastante útil. Se você quiser um recurso de estudo mais aprofundado, recomendo seguir meu Mega tutorial do Flask.

O mais importante a ser lembrado sobre o código acima é que o aplicativo define um endpoint /bot que escuta solicitações POST. Cada vez que a Twilio recebe uma mensagem de usuário, esse endpoint é chamado. O corpo da função bot() vai analisar a mensagem enviada pelo usuário e dar a resposta apropriada.

Mensagens e respostas

A primeira coisa que precisamos fazer no chatbot é obter a mensagem digitada pelo usuário. Essa mensagem é exibida no payload da solicitação POST com uma chave de ’Body’. Podemos acessá-la por meio do objeto request do Flask:

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

Como vamos fazer uma análise básica da linguagem neste texto, converti o texto para minúsculas, assim não precisamos nos preocupar com todas as diferentes formas que uma palavra pode ter quando usamos variações de maiúsculas e minúsculas.

A resposta que a Twilio espera do webhook precisa ser dada em TwiML (Twilio Markup Language), que é uma linguagem baseada em XML. A biblioteca auxiliar do Twilio para Python vem com classes que facilitam a criação dessa resposta sem a necessidade de criar o XML diretamente. Veja abaixo como criar uma resposta que inclua texto e imagem:

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')

Para retornar uma imagem, a Twilio espera uma URL que aponte para ela, e não os dados da imagem propriamente dita.

Lógica do chatbot

Para a lógica do chatbot, vou usar uma abordagem muito simples, mas surpreendentemente eficaz. Vou procurar nas mensagens recebidas as palavras-chave ’quote’ e ’cat’. Esta é a estrutura básica do chatbot:

    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

Com esta estrutura simples, podemos detectar referências a quotes e/ou cats e configurar o objeto de resposta da Twilio de acordo. O booleano responded é útil para monitorar casos em que a mensagem não inclui nenhuma das palavras-chave que estamos procurando e, quando isso acontece, é fornecida uma resposta genérica.

APIs de terceiros

Para fornecer ao chatbot as citações e fotos de gato originais, vou usar duas APIs que estão disponíveis publicamente. Para citações de autores famosos, escolhi a API Quotable, do Luke Peavey. Uma solicitação GET para https://api.quotable.io/random retorna uma citação aleatória de um pool de 1500 no formato JSON.

Para fotos de gato, vou usar a API Cat as a Service, de Kevin Balicot. É uma API extremamente simples, e o URL https://cataas.com/cat retorna uma foto de gato diferente a cada solicitação (você pode fazer um teste colando o URL na barra de endereço do navegador e atualizando a página para ter novas fotos). Isso é muito útil porque, como eu disse acima, a Twilio quer que a imagem seja fornecida como URL ao preparar a resposta em TwiML.

Tudo junto

Agora que vimos todos os aspectos da implementação do chatbot, estamos prontos para integrar todos os elementos no serviço de chatbot completo. Você pode copiar o código abaixo em um arquivo 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()

Testando o chatbot

Pronto para testar o chatbot? Depois de copiar o código acima no arquivo bot.py, inicie o chatbot executando python bot.py, verificando se o ambiente virtual Python está ativado. A saída deve ser parecida com esta:

(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)

Agora, o serviço está sendo executado como serviço privado na porta 5000 do computador e ficará lá aguardando conexões de entrada. Para torná-lo acessível na Internet, precisamos usar o ngrok.

Abra uma segunda janela de terminal e execute ngrok http 5000 para alocar um domínio público temporário que redirecione as solicitações HTTP para nossa porta local 5000. Em um computador Unix ou MacOS, talvez você precise usar ./ngrok http 5000 se tiver o executável do ngrok no diretório atual. A saída do ngrok deve ser parecida com esta:

captura de tela do ngrok

Observe as linhas que começam com "Forwarding". Elas mostram o URL público usado pelo ngrok para redirecionar solicitações para o nosso serviço. O que precisamos fazer agora é instruir o Twilio a usar este URL para enviar notificações de mensagem recebida.

Volte ao Console Twilio, clique em Programmable Messaging (Mensagens programáveis), depois em Settings (Configurações) e, por último, em WhatsApp Sandbox Settings (Configurações de sandbox para WhatsApp). Copie o URL https:// da saída do ngrok e cole-o no campo "When a message comes in" (Quando receber uma mensagem). Como nosso chatbot está exposto no URL /bot, acrescente-o no final do URL raiz do ngrok. Verifique se o método de solicitação está definido como HTTP Post. Não se esqueça de clicar no botão vermelho Save (Salvar), na parte inferior da página, para registrar essas alterações.

Captura de tela da configuração da sandbox da Twilio para WhatsApp

Agora, você pode começar a enviar mensagens para o chatbot usando o smartphone que conectou à sandbox. Digite as frases que você quiser e, sempre que as palavras "quote" e "cat" aparecerem nas mensagens, o chatbot chamará as APIs de terceiros e retornará algum conteúdo novo. Caso você tenha perdido no início do artigo, aqui está um exemplo de sessão que fiz com o chatbot:

WhatsApp chatbot demo session

Lembre-se de que o uso gratuito do ngrok traz algumas limitações. Especificamente, não é possível manter um URL do ngrok por mais de oito horas, e o nome de domínio atribuído será diferente sempre que você iniciar o comando ngrok. Você deve atualizar o URL no Console da Twilio toda vez que reiniciar o ngrok.

Observações sobre a implantação em produção

Pensei que seria útil encerrar este tutorial com uma lista de coisas a serem consideradas caso você decida implantar um chatbot para WhatsApp para uso em produção.

Antes de mais nada, você percebeu que, ao iniciar o aplicativo Flask, aparece um aviso bastante assustador sobre não usar um servidor de desenvolvimento para produção. O servidor Web que acompanha o Flask é muito prático para desenvolver e testar um aplicativo, mas não é robusto o suficiente para as demandas de uso em produção. Os dois servidores Web mais comuns prontos para uso em produção para aplicativos da Web em Python são o gunicorn e o uWSGI, e ambos podem ser instalados no seu ambiente virtual com pip. Veja, por exemplo, como executar o chatbot com gunicorn:

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

Também é importante lembrar que, para uma implantação em produção, você vai executar o serviço em um servidor de nuvem e não no seu computador, por isso não é preciso usar o ngrok.

Conclusão

As empresas estão cada vez mais recorrendo aos chatbots para oferecer aos clientes acesso imediato a suporte, vendas ou marketing. Um chatbot pode ser útil na coleta de informações do cliente antes que um agente humano entre em ação; um chatbot bem projetado também deve ser capaz de lidar com fluxos de trabalho comuns de clientes sem assistência humana.

Espero que este tutorial tenha sido útil e que agora você tenha uma ideia melhor de como criar um chatbot para WhatsApp. Abaixo, você pode encontrar mais alguns recursos sobre como criar chatbots com Python se quiser ver outras implementações:

Eu adoraria ver o chatbot que você criou!

Este artigo foi traduzido do original "Build a WhatsApp Chatbot With Python, Flask and Twilio". Enquanto melhoramos nossos processos de tradução, adoraríamos receber seus comentários em help@twilio.com - contribuições valiosas podem render brindes da Twilio.