Como criar um bot no WhatsApp em 5 minutos em Node.js

February 08, 2021
Escrito por

Como criar um bot no WhatsApp em 5 minutos em Node.js

 

Introdução

"Missão dada é missão cumprida!", mas se você, assim como alguns desenvolvedores, já recebeu alguma demanda para integrar um serviço no WhatsApp, provavelmente teve dificuldades em encontrar uma documentação consistente sobre o processo de usar a API do WhatsApp e como ativar seu serviço na plataforma.

Neste artigo eu quero desmistificar essa dificuldade e apontar alguns caminhos para construir um chatbot no WhatsApp. Se você ainda não sabe, a Twilio possui uma espécie de API de testes, que chamamos de "Sandbox" para que você consiga testar seu serviço no WhatsApp, sem precisar passar por todo o processo de aprovação.

Durante os próximos 5 minutos, construirei com você um chatbot para realizar uma atividade simples: jogar com o usuário o jogo "Pedra, Papel e Tesoura". Ao fazer isso, você vai entender alguns conceitos que são necessários para desenvolver bots de mensagem e como integrar a Twilio com esses serviços, em especial o WhatsApp.

Minuto 1: a regra do jogo

Para que nosso jogo funcione, temos algumas premissas que você precisa considerar:

  1. Crie uma conta da Twilio: você pode utilizar o limite gratuito para testar seu protótipo. Neste momento não é necessário adquirir um número de telefone para começar a usar a API do WhatsApp.
  2. Tenha um servidor para responder o webhook da Twilio: no meu caso vou utilizar uma ferramenta chamada Ngrok para executar localmente meu código, mas você pode utilizar a Twilio Functions também ou qualquer outro serviço de "cloud functions", plataformas na nuvem ou servidor "on premises", desde que possa receber chamadas HTTPS e possua uma URL pública.
  3. Configurou a Sandbox WhatsApp da Twilio: apontando para sua url com HTTPS. Eu criei um tutorial para configurar a Sandbox WhatsApp da Twilio, caso ainda não tenha ativado a sua. Nós abordaremos essa ativação/configuração em um momento apropriado dentro deste tutorial.

Explicando o funcionamento do nosso chatbot: toda vez que um usuário enviar uma mensagem para nossa conta, a Twilio fará uma chamada HTTP para o servidor, repassando os dados do remetente e sua mensagem. Uma vez que seu servidor recebeu essa requisição, ele pode autenticar a mensagem recebida e deve responder essa chamada usando um padrão que chamamos de Twiml e essa resposta será enviada de volta para o usuário através do WhatsApp.

Você pode optar por não responder a mensagem, mas a resposta da requisição deve estar no padrão da Twiml, mesmo que esteja vazia. O seu servidor também deve responder o status HTTP como 200, caso contrário isso resultará numa mensagem de erro dentro da plataforma da Twilio.

Na lógica do jogo, vamos esperar que o usuário envie uma das opções (pedra, papel ou tesoura) e responda informando a escolha do servidor e quem ganhou a rodada. Neste momento não vamos contabilizar quantas vezes o usuário ganhou ou perdeu. A resposta pode conter textos e arquivos, então podemos usar nossa criatividade nessa mensagem.

Importante: toda e qualquer lógica para armazenar informações da conversa e estado de determinados fluxos de conversação devem ser construídas pelo desenvolvedor.

Minuto 2: instalando a biblioteca no projeto em Node.js

Para preparar nosso ambiente em Node.js, vamos instalar 3 bibliotecas: Express, BodyParser e a biblioteca da Twilio. Para instalá-las, execute os comandos abaixo no seu terminal:

npm install express
npm install body-parser
npm install twilio

A biblioteca Express será utilizada para levantar nosso servidor web que receberá as chamadas do webhook da Twilio, quando o usuário enviar uma mensagem via WhatsApp. Já a BodyParser tem como função otimizar o tratamento dos dados recebidos do webhook e convertê-los em um objeto JSON, facilitando o seu acesso. Finalmente, a biblioteca da Twilio terá a função de montar a mensagem de resposta, embora você possa fazer muitas outras ações, como por exemplo, disparar mensagens assíncronas ou efetuar ligações.

Veja como carregar as bibliotecas e inicializar o Express e o BodyParser:

const express = require('express');
const bodyParser = require('body-parser');
const twilio = require('twilio');

const app = express();
app.use(bodyParser.urlencoded({ extended: true }));

// aqui vamos inserir a lógica do jogo

app.listen(3000, function(){
    console.log('Servidor ativo na porta 3000!');
})

Minuto 3: construindo o jogo

Por padrão, vamos considerar que o usuário que interagir com nosso número tem a intenção de jogar imediatamente, mas isso pode nem sempre acontecer ou ele pode também enviar algum outro texto.

Quando estamos desenvolvendo chatbots, um conceito importante é da intenção ou "intent" do usuário. Ao enviar um determinado texto, o serviço precisa descobrir o que ele quer dizer com o que escreveu e o seu serviço precisa tratar isso de acordo com o que ele oferece.

No jogo de pedra-papel-tesoura, o usuário deve enviar um dos três itens para jogar, caso contrário, precisamos responder com uma instrução sobre como jogar. Quando isso acontece, chamamos de "fallback intent" e é onde ocorre o tratamento desse tipo de erro.

No código não vou criar nenhum tipo de sistema de pontuação ou registro histórico, por isso o bot será bem simples, mas se você implementar essa funcionalidade, me avisa que vou ficar feliz em compartilhar com a comunidade.

const opcoes = [
    'pedra', 'papel', 'tesoura'
];

const perde = {
    'pedra': 'papel',
    'papel': 'tesoura',
    'tesoura': 'pedra'
}

Como utilizamos a biblioteca BodyParser vamos acessar a escolha do usuário da seguinte forma:

const usuario = req.body.Body.toLowerCase();

Enquanto o participante enviará a escolha dele, o serviço precisa escolher uma as opções de forma aleatória, vamos fazer isso com o seguinte código:

const computador = opcoes[Math.floor(Math.random() * opcoes.length)];

Um detalhe importante, precisamos tratar antes desse sorteio, se o usuário enviou uma das opções válidas. Veja como fiz isso no código abaixo:

switch(usuario) {
    case 'pedra':
    case 'papel': 
    case 'tesoura':
        // fazer a escolha do computador e responder quem ganhou

    default:
        // tratar "fallback intent"
        break;
}

Agora vamos para a etapa de receber e responder as mensagens dos jogadores. Você pode usar a biblioteca da Twilio para gerar a mensagem de resposta no formato Twiml, similar ao XML, mas com alguns parâmetros específicos da nossa plataforma. Outra opção é gerar o Twiml manualmente. Em ambos os casos isso é feito de forma simples:

res.send(`<Response><Message>Eu escolhi *${computador}*</Message><Message>Você ganhou, mas quero jogar novamente!</Message></Response>`);

O exemplo acima envia cria uma resposta no formato Twiml direto no objeto de resposta da requisição HTTP. Ele não valida o tipo de conteúdo e nem se a estrutura enviada está consistente. O lado positivo de montar a resposta neste formato é que você não precisa da biblioteca da Twilio instalada, porém, no longo prazo, dar manutenção em códigos assim e validar se está no padrão pode ser um desafio.

const twiml = new twilio.twiml.MessagingResponse();
twiml.message(`Eu escolhi *${computador}*`);
twiml.message('Ganhei! Ganhei!!!')
    .media('https://farm8.staticflickr.com/7090/6941316406_80b4d6d50e_z_d.jpg');
res.send(twiml.toString());

Nesse exemplo, utilizamos a classe MessagingResponse da biblioteca Twilio. O ponto principal sobre usar essa abordagem é que o formato Twiml permanecerá consistente, independente dos ajustes no protocolo.

Um ponto interessante do último exemplo é que ele visualmente gera duas mensagens e ainda adiciona uma imagem na segunda mensagem. Você pode responder a chamada do Webhook com uma única mensagem ou múltiplas, conforme esse exemplo.

Caso não queira responder nada no primeiro momento, basta gerar um Twiml com a resposta vazia:

res.send(<Response></Response>);

Veja como ficou todo o nosso código final. Salve o código a seguir no arquivo server.js:


app.post('/message', (req, res) => {
    console.log('nova mensagem', req.body.Body);
    const usuario = req.body.Body.toLowerCase();
    switch(usuario) {
        case 'pedra':
        case 'papel': 
        case 'tesoura':
            // fazer a escolha do computador e responder quem ganhou
            const computador = opcoes[Math.floor(Math.random() * opcoes.length)];


            if (computador === usuario) {
                res.send('<Response><Message>Ops, deu empate!</Message></Response>')
            } else {
                if (perde[computador] === usuario) {
                    // computador perdeu
                    res.send(`<Response><Message>Eu escolhi *${computador}*</Message><Message>Você ganhou, mas quero jogar novamente!</Message></Response>`);
                } else {
                    // computador ganhou
                    const twiml = new twilio.twiml.MessagingResponse();
                    twiml.message(`Eu escolhi *${computador}*`);
                    twiml.message('Ganhei! Ganhei!!!')
                        .media('https://farm8.staticflickr.com/7090/6941316406_80b4d6d50e_z_d.jpg');
                    res.send(twiml.toString());
                }
            }
            break;

        default:
            // tratar "fallback intent"
            res.send('<Response><Message>Escolha Pedra, Papel ou Tesoura!</Message></Response>')
            break;
    }
    
});

Minuto 4: configuração da Sandbox

Agora que já temos nosso jogo pronto, precisamos ativar a Sandbox de WhatsApp da Twilio. Isso permitirá que você possa testar dentro do próprio WhatsApp e com um número real tanto a API quanto a interatividade com o usuário, permitindo validar o funcionamento do jogo e tratar erros que possam ocorrer durante seu uso.

Para facilitar o processo de ativação, eu criei um artigo específico para ativar e configurar a Sandbox de WhatsApp. Basta seguir o tutorial acima e seguir para o próximo passo para configurar a URL do Webhook.

Minuto 5: testando o jogo com webhook local

Como estamos testando um projeto que vai ser acionado pela API de WhatsApp da Twilio, você precisa ter uma URL pública e acessível pela internet. Uma das soluções mais simples para fazer isso em ambiente de desenvolvimento é utilizar uma ferramenta chamada ngrok. Ao executar essa ferramenta, ela cria um gateway entre uma URL pública com sua aplicação local, o que facilita no momento de testar a execução do código e debugar algum tipo de comportamento da aplicação, sem a necessidade de subir um servidor web completo.

Uma vez instalado o ngrok, você precisa de duas telas de terminal: uma para executar o node.js do seu script e ativar o servidor e a outra com o comando do ngrok para criar o gateway:

Para ativar o servidor, execute o comando a seguir no seu terminal:

node index.js

E para ativar o gateway do ngrok, basta executar o comando abaixo:

ngrok http 3000

Observe na imagem abaixo que foi criada uma URL aleatória para minha conta. Essa URL deve ser inserida nas configurações da Sandbox do WhatsApp.

Tela do console com o Ngrok em execução

 

Dica: use sempre a url com HTTPS!

Tela de configuração do link do webhook da Sandbox de WhatsApp

Uma vez que você configurou a url e ativou seu número de WhatsApp, é hora de testar. Como eu já ativei o meu número, basta enviar qualquer mensagem para receber as instruções, ou enviar "pedra", "papel" ou "tesoura" para que o servidor jogue comigo.

Agora é com você!

Teste o jogo

Se você quiser jogar a minha versão do jogo, envie pelo WhatsApp o texto "join pass-fall" para o número +1 415 523 8886. Você também pode utilizar o QRCode a seguir:

QRCode com o texto "join pass-fall" para o número +1 415 523 8886

Uma vez que tenha enviado o código de ativação, você poderá começar a jogar.

Importante: fique a vontade para interagir, não vamos enviar nenhuma mensagem para seu número de telefone e os registros serão removidos.

Faça seu próprio jogo

Disponibilizei o código deste jogo no GitHub para você usar como referência. Baixe e teste com sua própria conta. Como não implementei o sistema de pontuação, caso você faça isso, entre em contato comigo :D

Se você quiser testar o jogo de uma forma mais permanente, você pode utilizar a Twilio Functions para rodar seu código do webhook em um servidor na nuvem da Twilio. Um dos grandes benefícios em utilizar a Twilio Functions é que ela faz automaticamente a verificação da origem da mensagem e valida o webhook automaticamente, garantindo que o acesso teve como origem um servidor da Twilio.

Torne seu jogo disponível no WhatsApp

Existem alguns passos para colocar um chatbot no WhatsApp em produção, vou resumir os pontos importantes e que você precisa ficar atento, especialmente em função dos prazos do próprio Facebook nos processos de verificação e aprovação da conta:

  1. Crie uma conta de negócios (business account) da sua empresa no Facebook: é necessário que possua uma conta de negócios no Facebook e que ela esteja verificada antes de começar. Na Central de Ajuda do Facebook, há um artigo em Português sobre o processo de verificação da empresa.
  2. Vincule sua Business Account com o projeto da Twilio: assim você poderá registrar as mensagens de template, vincular seu número de WhatsApp da Twilio ou próprio e configurar o webhook de produção. Veja neste artigo em inglês sobre como conectar seu número Twilio com o Perfil de Negócios do WhatsApp.

 

Espero que tenha gostado deste artigo e que comece a prototipar suas ideias com a Sandbox da API de WhatsApp da Twilio.

Fique a vontade para tirar dúvidas, enviar sugestões e conversar comigo sobre seus projetos. Mal posso esperar para ver o que você vai construir.