Construa um Chatbot para WhatsApp com Python, Flask e Twilio

September 02, 2020
Escrito por
Revisado por
Gabriela Cavalcante
Contribuidor
As opiniões expressas pelos colaboradores da Twilio são de sua autoria

Construa um Chatbot para WhatsApp com Python, Flask e Twilio

Um chatbot é um aplicativo de software capaz de conduzir uma conversa com um usuário humano por meio de linguagem escrita ou falada. O nível de "inteligência" entre os chatbots varia muito. Enquanto alguns chatbots têm um entendimento bastante básico da linguagem, outros empregam algoritmos sofisticados de inteligência artificial (IA) e aprendizado de máquina (ML) para alcançar um nível de conversação quase humano.

Nesse tutorial eu vou mostrar a você como é fácil construir um chatbot para Whatsapp usando a API da Twilio para WhatsApp e Flask framework para Python. Abaixo você pode ver um exemplo de interação com o chatbot:

project demo

Requisitos do Tutorial

Para seguir esse tutorial você precisa dos seguintes componentes:

  • Python 3.6 ou mais recente. Se seu sistema operacional não tem um interpretador Python, você pode ir em python.org  para baixar o instalador.
  • Flask. Nós vamos criar uma aplicação web que responde mensagens vindas do WhatsApp.
  • ngrok. Nós vamos usar esse utilitário para conectar a aplicação Flask em execução no seu sistema a uma URL pública que a Twilio possa se conectar. Isso é necessário para a versão de desenvolvimento da aplicação, porque seu computador provavelmente está atrás de um roteador ou firewall e, portanto, não está acessível diretamente na Internet. Se você não possui o ngrok instalado, pode fazer o download de uma cópia para Windows, MacOS ou Linux.
  • Um smartphone com um número de telefone ativo e WhatsApp instalado.
  • Uma conta na Twilio. Se você é novo na Twilio, crie uma conta gratuita agora. Você pode revisar os recursos e limitações da conta gratuita da Twilio.

Configure o Whatsapp Sandbox da Twilio

A Twilio fornece um sandbox para WhatsApp onde você pode facilmente desenvolver e testar sua aplicação. Quando sua aplicação estiver completa, você pode solicitar acesso para o seu número de telefone da Twilio funcionar em produção, o que requer aprovação do WhatsApp.

Vamos conectar seu smartphone na sandbox. No Console da Twilio, selecione Programmable Messaging, então clique em “Try it Out”, e finalmente clique em Try WhatsApp. A página do WhatsApp sandbox vai mostrar a você o número dado a sua conta e um código de entrada.

WhatsApp sandbox configuration

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

Esse passo precisa ser repetido para qualquer outro número de telefone adicional que você queira ter conectado a sua sandbox.

Criando um ambiente virtual Python

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

Se você você está usando um sistema operacional Unix ou Mac OS X, abra o 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

Para aqueles que estiverem seguindo o tutorial no Windows, digite os comandos a seguir no 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 os três pacotes que iremos usar neste projeto, que são:

No momento em que este tutorial foi lançado, estas eram as versões dos pacotes acima e suas 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

Criando um serviço de Chatbot Flask

Agora vamos à parte divertida. Vamos construir um chatbot!

O tipo de chatbot que funcionará melhor para você dependerá das suas necessidades específicas. Neste tutorial, criarei um chatbot extremamente simples que reconhece duas palavras-chave nas mensagens enviadas pelo usuário e reage a elas. Se o usuário escrever algo que contenha a palavra "citação", o chatbot retornará uma citação famosa aleatória. Se, em vez disso, a mensagem tiver a palavra "gato", uma imagem aleatória de gato será retornada. Se "citação" e "gato" estiverem presentes na mesma mensagem, o bot responderá com uma citação e uma foto do gato juntos.

Webhook

A API da Twilio para WhatsApp usa um webhook para notificar uma aplicação quando existe uma mensagem recebida. Nosso chatbot precisa definir um endpoint que será configurado como este webhook, para que o Twilio possa se comunicar com ele.

Com o framework Flask é extremamente simples criar um webhook. Abaixo está o esqueleto da aplicação com um webhook definido. Não se preocupe em copiar esse código. Primeiro, mostrarei todas as diferentes partes da implementação e, depois, mostrarei como todas estas partes estão combinadas na aplicação desenvolvida.

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

Se você não está familiarizado com o framework Flask, na documentação tem uma seção de quick start que deve te ajudar. Se você quiser um material de estudo mais aprofundado, então eu recomendo que você siga meu Flask Mega-Tutorial.

Algo importante para manter em mente sobre o código acima é que a aplicação define um /bot endpoint que suporta requisições POST. Cada vez que uma mensagem de um usuário é recebida pela Twilio este endpoint será chamado. O corpo da função bot() vai analisar a mensagem enviada pelo usuário e fornecer a resposta apropriada.

Mensagens e Respostas

A primeira coisa que nós precisamos em nosso chatbot é obter a mensagem enviada pelo usuário. Essa mensagem vem no payload da requisição POST com a chave ’Body’.  Nós podemos recuperar o ’Body’ no objeto request do Flask:

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

Como faremos uma análise básica da linguagem neste texto, converti o texto para letras minúsculas, para que não tenhamos que nos preocupar com as diferentes variações de maiúsculas e minúsculas que uma palavra pode ter.

A resposta que a Twilio espera do webhook precisa ser dada em TwiML or Twilio Markup Language, que é uma linguagem baseada no XML. A Twilio helper library for Python vem com classes para que você facilmente crie essa resposta sem ter que criar um XML diretamente. Abaixo você pode ver como criar uma resposta que inclui texto e imagem:

from twilio.twiml.messaging_response import MessagingResponse

resp = MessagingResponse()
msg = resp.message()
msg.body('this is the response text')
msg.media(image_url)

Veja que para retornar uma imagem, a Twilio espera uma URL e não a imagem em si.

Lógica do Chatbot

Para a lógica do chatbot, vou usar uma abordagem muito simples, mas surpreendentemente eficaz. O que vou fazer é pesquisar nas mensagens recebidas as palavras-chave ’quote’ e ’cat’. Aqui está a estrutura básica do chatbot:

    responded = False
    if 'citação' in incoming_msg:
        # adicione uma citação à resposta aqui
        responded = True
    if 'gato' in incoming_msg or 'gata' in incoming_msg:
        # adicione uma foto de gato à resposta aqui
        responded = True
    if not responded:
        # retorne uma resposta genérica aqui

Com essa estrutura simples, podemos detectar referências a citações e/ou gatos e configurar o objeto de resposta Twilio de acordo. O booleano responded é útil para rastrear o caso em que a mensagem não inclui nenhuma das palavras-chave que estamos procurando e, neste caso, oferecer uma resposta genérica.

Third-Party APIs

Para o chatbot obter citações originais e fotos de gatos, eu vou usar duas APIs públicas disponíveis. Para citações famosas, eu escolhi a Quotable API de Luke Peavey. Uma requisição GET para https://api.quotable.io/random retorna uma citação aleatória de um conjunto de 1500 citações em formato JSON.

Para as fotos de gatos, eu vou usar a Cat as a Service API de Kevin Balicot. Essa é uma API extremamente simples, a URL https://cataas.com/cat retorna uma imagem de gato diferente a cada requisição (você pode testá-la copiando a URL em um browser e dando refresh para ter novas fotos de gatos). Isso é muito útil porque, como eu mencionei acima, Twilio quer que a imagem seja dada como uma URL quando preparar a resposta TwiML.

Tudo junto

Agora você viu todos os aspectos da implementação do chatbot, então nós estamos prontos para integrar todas as peças no serviço de chatbot completo. Você pode copiar o código abaixo no 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 'citação' in incoming_msg:
        # retorne uma citação 
        r = requests.get('https://api.quotable.io/random')
        if r.status_code == 200:
            data = r.json()
            quote = f'{data["content"]} ({data["author"]})'
        else:
            quote = 'Não consegui recuperar uma citação neste momento, desculpe.'
        msg.body(quote)
        responded = True
    if 'gato' in incoming_msg or 'gata' in incoming_msg:
        # retorne uma foto de gato
        msg.media('https://cataas.com/cat')
        responded = True
    if not responded:
        msg.body(Só conheço frases e gatos famosos, desculpe!')
    return str(resp)

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

Testando o Chatbot

Você está pronto para testar o chatbot? Depois que você copiar o código abaixo no arquivo *bot.py*, inicie o chatbot executando python bot.py; tenha certeza que o seu ambiente virtual Python está ativo quando você executar o comando. A saída deve ser algo assim:

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

O serviço agora está sendo executado como um serviço privado na porta 5000 dentro do seu computador e ficará lá aguardando conexões de entrada. Para tornar esse serviço acessível a partir da Internet, precisamos usar o ngrok.

Abra uma segunda janela do terminal e execute ngrok http 5000 para alocar um domínio público temporário que redireciona HTTP requests para a porta local 5000. Em computadores Unix ou Mac OS, você pode precisar usar ./ngrok http 5000 se você tem o executável do ngrok executable no seu diretório atual. A saída do ngrok deve ser algo como:

ngrok screenshot

Observe as linhas que começam com "Forwarding". Elas mostram a URL pública que o ngrok usa para redirecionar solicitações para o nosso serviço. O que precisamos fazer agora é dizer à Twilio para usar essa URL para enviar notificações de mensagens recebidas.

Volte para o Twilio Console, clique em Programmable Messaging, então em Settings, e finalmente em WhatsApp Sandbox Settings. Copie a URL https:// da saída do ngrok e cole no campo “When a message comes in”. Como nosso chatbot está exposto na URL /bot, adicione-a no final da 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 na parte inferior da página para registrar essas alterações.

WhatsApp webhook

Agora você pode começar a enviar mensagens para o chatbot a partir do smartphone conectado à sandbox. Você pode digitar qualquer frase que desejar e sempre que as palavras "citação" e "gato" aparecem nas mensagens, o chatbot invocará as APIs de terceiros e retornará algum conteúdo novo para você. Caso você tenha perdido no início do artigo, aqui está uma sessão de exemplo que realizei com o chatbot:

demo

Lembre-se de que ao usar o ngrok gratuitamente, existem algumas limitações. Em particular, você não pode manter um URL do ngrok por mais de 8 horas, e o nome de domínio atribuído a você será diferente toda vez que iniciar o comando ngrok. Você precisará atualizar o URL no Twilio Console toda vez que reiniciar o ngrok.

Notas sobre Deploy em Produção

Eu pensei que seria útil terminar este tutorial com uma lista de coisas que você precisará considerar se decidir implantar um chatbot do WhatsApp para uso em produção.

Antes de mais nada, você viu que, ao iniciar o aplicativo Flask, há um aviso bastante assustador sobre não usar um servidor de desenvolvimento para produção. O servidor web que vem com o Flask é muito conveniente para desenvolvimento e teste de uma aplicação, mas não é robusto o suficiente para lidar com demandas de uso em produção. Os dois servidores web mais comuns preparados para uso em produção para aplicações Python são o gunicorn e o uWSGI. Ambos podem ser instalados no seu ambiente virtual com pip.  Por exemplo, aqui está como executar o chatbot com gunicorn:

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

Lembre-se também de que para um deploy em produção, você irá executar um serviço em um servidor na nuvem e não no seu próprio computador, então não há necessidade de usar ngrok.

Conclusão

As empresas estão cada vez mais recorrendo aos chatbots para oferecer a seus clientes acesso imediato a suporte, vendas ou marketing. Um chatbot pode ser útil na coleta de informações de clientes antes que um atendente humano assuma. E um chatbot bem projetado pode ser capaz de lidar com diferentes fluxos de atendimento inteiramente sem assistência humana.

Eu espero que este tutorial tenha sido útil e você agora tenha uma ideia melhor de como construir seu chatbot para o Whatsapp. Abaixo você pode encontrar alguns materiais adicionais sobre como construir chatbot com Python, caso você queria ver mais implementações:

Miguel Grinberg é Python Developer para conteúdo técnico na Twilio.

Nós adoraríamos ver o chatbot que você construiu! Se você quiser compartilhar sobre ou tirar dúvidas, pode falar com a Gabi Cavalcante, desenvolvedora Python que contribuiu na tradução deste artigo. Encontre ela no Twitter @_gabicavalcante e contar mais sobre seus projetos.