Desde que comecei a escrever artigos sobre soluções por aqui, eu tento fazer com que todo o passo a passo pra criação seja o mais agradável possível e isso vai alem de escrever bem e ser claro. Os cases precisam ser interessantes e trazer soluções diferentes, que de fato podemos usar no dia a dia.
No case deste artigo, o nosso objetivo é apresentar uma integração com o whatsapp e para isso vamos utilizar o Twilio, que para quem nunca ouviu falar, é uma plataforma de comunicação na nuvem, muito utilizada para uso de mensagens em SMS.
Reforçando o que falei no inicio, não tenho a intenção de apresentar artigos focados somente em uma tecnologia, mesmo sendo fã da AWS, é importante para um arquiteto e desenvolvedor conhecer outras plataformas, tirar suas próprias conclusões e decidir o que funciona melhor para sua necessidade.
A solução que vamos criar hoje, será construída na cloud da IBM, pegando carona no meu ultimo artigo sobre a IBM Cloud.
Para quem leu o artigo AWS Experience, teve contato com o Lambda, que é o serviço da Amazon AWS para construção de código serverless. O IBM Cloud Functions, que vamos usar hoje, é o equivalente ao lambda, dentro da cloud da IBM.
Antes de prosseguir com esse artigo é importante que você tenha em mente o seguinte:
- A IBM simplesmente adora mudar o nome dos serviços dentro da sua cloud, isso quando a própria cloud não muda de nome, não é bluemix? Portanto, se você estiver lendo esse artigo num futuro não muito distante, talvez tenha dificuldade em encontrar o nome do serviço na cloud e ai … quem descobrir primeiro conta pro outro ;-).
- Neste exato momento o Facebook está testando a API oficial do whatsapp e somente algumas empresas estão participando desse processo. Em breve (não sabemos quando) será possível se conectar diretamente ao whatsapp, mas como vocês vão ver mais adiante, essa integração é bastante complexa e envolve um custo financeiro para manutenção de dois servidores, portanto, quando liberarem a API, considerem utilizar o Twilio como service provider.
Com tudo isso em mente, é hora do rock’n roll!
Twilio
O Twilio é uma plataforma em nuvem focada em comunicação. Nosso escopo neste artigo é bem pequeno em relação a todos os seus recursos, como integração por SMS, integração por voz, mail marketing (SendGrid), vídeo em tempo real e muitos outros.
Nós vamos iniciar a configuração do serviço WhatsApp, que está em versão beta e vamos executar o nosso teste em um modelo de sandbox do Twilio.
Vamos iniciar acessando a url de apresentação do serviço
Como eu já tenho a minha conta, o fluxo a partir daqui pode ser um pouco diferente, então sugiro que vocês cliquem em LOG IN no menu superior direito e na tela seguinte cliquem em SIGN UP FOR FREE. Ao terminar de cadastrar a sua conta e efetuar o login, vão ser direcionados para a tela abaixo:
Clique em Create New Project. Na tela seguinte selecione Products e escolha o produto Programmable SMS.
Na tela seguinte, você deve escolher o nome do projeto. O nosso projeto se chama codechain.
No passo seguinte, clique em skip, pois não vamos adicionar nenhum membro além de nós. Nosso projeto está criado e possui um ACCOUNT SID e AUTH TOKEN associado.
Agora vamos iniciar nossos testes com o whatsapp. Clique no ícone de conversation na esquerda e na tela que será aberta, clique em Whatsapp Beta e Learn. Será apresentada uma lightbox de confirmação que você deve confirmar.
modulo de aprendizado do whatsapp
Agora vamos fazer alguns testes para entender como funciona a integração. Na primeira tela do módulo Learn, é exibida a seguinte mensagem:
To begin testing, connect to your sandbox by sending a WhatsApp message from your device to +1 415 523 8886 with code join shells-wrong.
O que vamos fazer agora é acessar o nosso whatsapp pelo aplicativo e adicionar o número +1 415 523 8886 aos nossos contatos. Adicione o número e salve ele como Twilio Sandbox.
Após salvar o contato, envie uma mensagem para ele com o texto
join shells-wrong.
ATENÇÃO: O Texto é diferente para cada processo de Learn criado, no seu caso o texto será diferente.
Apos enviar a mensagem, será informado na tela que ela foi recebida pelo Twilio.
Agora seu whatsapp já esta participando do fluxo criado pelo sandbox. Existem dois tipos de mensagem para integração com a API que vamos ver abaixo
One-Way-Message
Mensagens do tipo one-way são mensagems que não possuem interação com o usuário, como por exemplo, notificações de compra de produto e agendamento de consultas.
Ao prosseguir com o módulo de Learn, a primeira etapa será o teste com uma mensagem deste tipo. Clique em uma das 3 opções de mensagens e clique em make request.
Neste resultado temos tudo que precisamos para construção da uma API de integração. Um exemplo de request em curl/nodejs com o response e um formulário de entrada que atualiza os dados da requisição.
O processo é bem simples e vamos usa-lo sempre que a ação iniciar do lado do cliente e não do usuário. O próximo passo, two-way-message será utilizado em situações que requerem um fluxo de conversação com o usuário, ou seja, estamos falando de um chatbot e ação parte sempre do usuário para o cliente.
clique em next para seguir ao próximo passo do módulo learn.
Two-Way-Message
Neste tipo de mensagem, nos aguardamos que o usuário inicie a interação. A tela abaixo exibe uma mensagem informando que está sendo aguardada uma mensagem
vamos para o whatsapp então e vamos enviar a mensagem “Bom dia! você pode me ajudar?”. Ao enviar a mensagem, recebemos uma resposta automática do sandbox informando que recebeu a mensagem.
De volta ao console do Twilio, podemos ver que a resposta foi recebida. Clique no botão make request para enviar uma resposta ao usuário. Veja o resultado
Uma grande diferença entre o one-way-message e two-way-message é que este último, após receber a mensagem do usuário, permite que você troque mensagem com ele por 24 horas sem o uso de templates.
Com esse ultimo teste, fechamos o modulo de Learn e já obtemos exemplos, incluindo código em curl/nodejs, para iniciarmos a integração com o whatsapp através do Twilio. Clique no link sandbox no Twilio e vamos dar uma rápida olhada nas configurações.
Sandbox setup
A configuração do sandbox é bastante simples e possui 3 blocos de configuração
sandbox configuration
Nesta etapa você pode configurar dois webhooks para a integração. Quando o numero do whatsapp do sandbox receber uma mensagem, ele deve envia-la para uma URL que é configurada no primeiro campo texto. Esta vai ser sua URL, que possivelmente será uma API REST que vai implementar recursos de um chatbot.
O Segundo campo texto, não é obrigatório, mas nele você também pode informar uma URL para que receba informações de status de entrega de mensagem do whatsapp.
sandbox participants
Qualquer usuário pode participar do sandbox, basta enviar uma mensagem com o código informando neste bloco para o número também informado.
sandbox message template
Aqui você deve configurar os templates que são exigidos pelo whatsapp para mensagens do tipo one-way-message. Vamos ver este item logo abaixo.
WhatsApp Api for Business
Como falamos no inicio do artigo, a API do Whatsapp está sendo liberada aos poucos e somente para empresas que se inscreveram para participar do beta. O Twilio é uma delas.
Tudo que o Twilio faz neste caso, é fazer uma ponte entre a API deles e a API do whatsapp for business. Independente de utilizar a API pelo Twilio ou diretamente pelo whatsapp é importante conhecer as regras que precisam ser respeitadas.
A base de toda informação está acessível na URL abaixo, que é a documentação oficial da API:
https://developers.facebook.com/docs/whatsapp/overview
Você já deve ter esbarrado na internet com algumas soluções e gambiarras utilizando script em conjunto com o whatsapp web pra utilizar o whatsapp integrado ao seu sistema, tome cuidado. Está bem claro na documentação oficial: Se você usar algo que não seja a API oficial do WhatsApp Business ou outras ferramentas oficiais do WhatsApp, reservamos o direito de limitar ou remover seu acesso ao WhatsApp, pois isso viola nossas políticas
modelos \ templates
Mesmo que você tenha feito toda a integração e ela esteja funcionando, você não pode enviar qualquer tipo de mensagem para os seus usuários. As mensagens precisam seguir um template aprovado pelo whatsapp, para evitar que você envie spam para os usuários. (somente no modo one-way-message)
aceitação \ opt-in
Você não pode enviar mensagem para um número que não tenha aceitado explicitamente receber informação pelo whatsapp. Exemplo:
client api proprietária
Ao contrário das APIs que estamos acostumados a consumir, onde construímos um cliente REST para chamar uma URL enviando e recebendo json, para se comunicar diretamente com o whatsapp é um pouco diferente.
É necessário instalar um cliente e chama-lo via REST. Este cliente deve ser instalado em um servidor, que vai fazer a comunicação com o whatsapp através de uma caixa preta. É necessário tambem outro servidor rodando um banco mysql.
Como podem ver, não é nada simples, existe um custo envolvido nessa infraestrutura e ela vai consumir recursos caros que custam no seu bolso.
Talvez neste ponto do artigo, você esteja se interessando mais em utilizar a API do Twilio :).
A configuração minima recomendada pelo whatsapp é utilizar uma maquina com 250 GB SSD, 16 GB DE RAM com 4 CORES. Na AWS uma instancia reservada com configuração similar custa em torno de $ 120 por mês (na cotação de hoje: R$ 450/mês). Alem disso precisamos configurar o mysql em um servidor físico diferente do cliente, o que aumenta o custo mais uma vez da sua infraestrutura.
Já falamos também que o whatsapp não liberou ainda o valor referente ao custo por mensagem ? o que sabemos hoje é que será cobrado por mensagens do tipo one-way-message.
Se você não planeja dar conta dessa estrutura, a sua outra solução para se comunicar com o whatsapp é usar service providers, como o Twilio. Pelo menos por enquanto, não considero outra opção devido as dificuldades apresentadas aqui e varias outras (até a latência entre as maquinas são validadas pela API).
vamos seguir em frente agora iniciando a integração com o Twilio
IBM Cloud Function
Antes de seguir em frente, sugiro uma visita ao artigo sobre a cloud da IBM, nesse artigo explicamos sobre o funcionamento da cloud da IBM e vai servir de base para a criação da cloud function neste artigo.
Caso já conheça a IBM Cloud, vamos começar a construção da integração.
one-way-message
Clique em Create Resource e procure pelo serviço Cloud Functions, ou acesse a url https://cloud.ibm.com/openwhisk
A Cloud Function é um código que é executado em um serviço da IBM sem que você precise subir e gerenciar qualquer tipo de servidor ou maquina virtual (serverless). Se você conhece a AWS, é o equivalente ao AWS Lambda, que falamos no artigo AWS Experience.
Clique em Start Creating -> Create Action. Informe o nome de um package para agrupar as funções que vamos criar, nomeie a sua função como whatsapp-one-way e selecione o seu runtime. No nosso caso estamos utilizando o nodeJS v10, mas caso queira utilizar outra linguagem fique a vontade.
Apos clicar em create você será direcionado para a tela do action que foi criado (menu code).
O código acima não faz nada, é uma casca, vamos altera-lo logo, mas antes vamos fazer algumas configurações. Clique no menu Parameters a esquerda e inclua os parâmetros accountSID e o authToken para a sua conta do Twilio (geramos eles ao criar nossa conta no inicio do artigo) .
Inclua também os parâmetros From , To e mensagem, para indicar os números de telefone do whatsapp de origem e destino e a mensagem que será enviada.
Todos os valores precisam estar dentro de aspas duplas, pois vamos tratar todos como String
Os valores parametrizados são “selados” na função, você não vai conseguir mudar os valores ao invocar a API . Nos configuramos desta forma para poder testar facilmente, mas vamos remover alguns deles mais a frente.
Agora clique em Runtime e você verá a tela abaixo
Não precisa mexer em nada por enquanto, apenas saiba que aqui nesta interface, você pode configurar o tempo de timeout da sua função e o total de memoria que será alocada. Como somos cobrados por tempo e consumo de memoria, esta é uma configuração bem importante.
Não se preocupe por enquanto com preço, pois as primeiras 5.000.000 requisições são gratuitas, mas vale um lembrete!
😉
seguindo em frente, clique em endpoints e agora vamos precisar fazer uma modificação. Marque a opção Enable as Web Action. Quando esta caixa é marcada, a sua função passa a estar disponível em uma URL como micro serviço sem autenticação.
Veja a imagem abaixo com a URL gerada selecionada.
Se você jogar no browser ou chamar via POST, será apresentada a mensagem “Hello World” no formato JSON.
Repare que existe uma diferença entre Web Action e Rest API. A Rest API funciona da mesma forma que o Web Action, porem ela requer uma API KEY para autenticação e somente é invocada via POST. No caso do WEB ACTION, a API está aberta e cabe a você desenvolver a autenticação.
Vamos retornar agora ao menu Code e trocar o código da nossa função pelo código abaixo.
//importação da biblioteca do twilio (já instalada por default na IBM) var twilio = require('twilio'); async function main(parametros) { try { await callTwilio(parametros); console.log('finalizada chamada ao whatsapp'); } catch (err) { console.log(err) return Promise.reject({ statusCode: 500, headers: { 'Content-Type': 'application/json' }, body: { message: err.message }, }); } } async function callTwilio(parametros){ console.log('entrou no twilio'); var client = new twilio(parametros.accountSID, parametros.authToken); await client.messages.create({ body: parametros.mensagem, to: 'whatsapp:+' + parametros.to, from: 'whatsapp:+' + parametros.from }) .then((message) => console.log(message.sid)); console.log('saiu do twilio'); }
O que está sendo feito no código acima é o seguinte
- Os parâmetros de entrada do serviço são recebidos na variável parametros na chamada da função principal async function main(parametros).
- na linha var client = new twilio(parametros.accountSID, parametros.authToken);, estamos instanciando o objeto que importamos da biblioteca do twilio com a nossa conta.
- Em client.messages.create estamos executando a chamada a API do Twilio para enviar a mensagem recebida pela função ao numero do whatsapp
Apos salvar o código, clique em Invoke e voce deve receber a mensagem no whatasapp.
agora, podemos montar uma chamada a função e remover os parâmetros dinamicos. Volte ao menu de parâmetros e remova os parâmetros to e mensagem.
no teste abaixo, estamos usando o postman para fazer chamada a URL. Faça uma requisição passando somente os parâmetros que foram removidos (to e mensagem).
com esse teste, fechamos o endpoint one-way-message. Caso queira enviar uma mensagem para o whatsapp, basta chamar a API que construímos informando a mensagem e o numero de telefone.
Lembrando que estamos em um ambiente de sandbox e que as mensagens enviadas neste modelo one-way, precisam ser aprovadas pelo whatsapp.
two-way-message
Vamos criar agora uma nova cloud functions. Siga os mesmos passos do modelo one-way-message, apenas modifique o nome da função. Faça a mesma configuração do endpoint feita anteriormente.
Nós temos uma nova função e um novo endpoint, copie a URL gerada para o web action.
O valor desta URL, deve ser informado na configuração de sandbox do Twilio, no primeiro campo texto conforme imagem abaixo. Apos informar a URL no campo, clique em Save.
O que estamos configurando é o seguinte:
- A sua conta tem um numero de telefone do whatsapp associado a ela. Em nossos testes, esse numero é o +14155238886. Ele foi Gerado automaticamente quando criamos a conta no Twilio e fizemos nosso tour por ele no inicio deste artigo.
- Sempre que um usuário enviar uma mensagem pra esse número, o Twilio vai receber a requisição.
- Apos receber a requisição, o Twilio vai encaminhar pra URL que acabamos de configurar esta requisição.
- O Fluxo natural da nossa API apos receber a mensagem do Twilio é encaminhar para uma outra API que deve implementar um chatbot.
Antes de prosseguir para o nosso código, precisamos entender o que recebemos do twilio quando o usuário envia uma mensagem e o que devemos retornar.
entrada
- AccountSid: ID da conta que recebeu a mensagem
- Body: mensagem enviada pelo usuário
- From: telefone do whatsapp do usuário que enviou a mensagem
- NumMedia: numero de arquivos enviados. Caso o usuário tenha enviado uma foto esse numero será igual a 1.
- MediaContentType0: mime type do arquivo enviado pelo usuario para o primeiro arquivo. Caso tenha enviado duas fotos, serão dois mime types: MediaContentType0 e MediaContentType1
- MediaUrl0: comportamento igual ao MediaContentType0, porem neste caso é exibida a URL para download do arquivo.
saida
A saída deve retornar um código http 200 e o retorno não será exibido ao usuário no whatsapp. Para responder a mensagem dele, você deve chamar a mesma API de envio de mensagem utilizado no one-way-message.
vamos então atualizar o código da função two-way-message
//importação da biblioteca do twilio (já instalada por default na IBM) var twilio = require('twilio'); async function main(parametros) { try { //printando valores recebidos pelo twilio (mensagem enviada pelo usuario) console.log('parametros recebidos do twilio:', parametros); console.log('AccountSid: ' + parametros.AccountSid); console.log('Body: ' + parametros.Body); console.log('From: ' + parametros.From); console.log('NumMedia: ' + parametros.NumMedia); console.log('MediaContentType0: ' + parametros.MediaContentType0); console.log('MediaUrl0: ' + parametros.MediaUrl0); //informa o usuario que recebeu a sua mensagem //esta linha é somente para teste, num cenario real deveria ser chamada uma integração com chatbot parametros.mensagem = "Ola recebi a sua mensagem: " + parametros.Body await callTwilio(parametros); console.log('finalizada chamada ao whatsapp'); return { statusCode: 200, headers: { 'Content-Type': 'application/json' }, body: { Body: 'sucesso' }, }; } catch (err) { console.log(err) return Promise.reject({ statusCode: 500, headers: { 'Content-Type': 'application/json' }, body: { message: err.message }, }); } } async function callTwilio(parametros){ console.log('entrou no twilio'); var client = new twilio(parametros.AccountSid, parametros.authToken); await client.messages.create({ body: parametros.mensagem, to: parametros.From, from: 'whatsapp:+' + parametros.telefoneOrigem }) .then((message) => console.log(message.sid)); console.log('saiu do twilio'); }
O código é muito parecido com o da primeira função, exceto pelos parâmetros recebidos, onde printamos os campos enviados pelo Twilio e nas variáveis AccountSid, From e telefoneOrigem, onde usamos valores recebidos pelo Twilio e mesclamos com os parâmetros configurados para a função.
Os parâmetros da função devem ser registrados conforme tela abaixo
O telefone de origem deixamos fixo no parâmetro, mesmo recebendo ele pelo Twilio. O authtoken por motivos óbvios, continua sendo informado nos parâmetros fixos da função.
Agora é só enviar mensagem do seu whatsapp para o número do Twilio e receber a resposta informada no código. Este é o fluxo esperado para um chatbot no whatsapp
Monitoramento
Neste ponto, nós já temos a API para enviar e receber informações do whatsapp funcionando, mas precisamos de uma forma de acompanhar o trafego de mensagens.
IBM Cloud Monitor
O primeiro monitoramento é sobre o que entra e sai das IBM functions que criamos, especialmente a two-way-message que é um webhook do Twilio e é um pouco mais complicada para testar.
Na pagina principal da IBM Cloud Function, temos o menu Monitor
ao clicar neste item do menu você será apresentado a um dashboard que exibe a quantidade de chamadas para cada função, quantas retornaram com sucesso, uma timeline com os horários de execução e um quadro de logs.
Ao clicar no log da execução no widget Activity Log, será exibido um JSON com o resultado da execução daquela requisição, inclusive exibindo o console.log.
IBM Cloud CLI
Existe uma outra forma de monitorar a sua cloud function que é através do client da IBM Cloud. A sua instalação e configuração está descrita no artigo IBM Cloud alem do Watson.
Alem da sua instalação padrão, é necessário instalar pacotes adicionais do client. Execute o login na sua conta através do comando ibmcloud login e execute o comando ibmcloud plugin install cloud-functions na sequencia.
Ao efetuar o login é feita uma pergunta sobre qual região deseja conectar. A zona que estou utilizando é a Dallas, que é o código us-south. Caso não tenha certeza do código da sua região, veja na pagina oficial da IBM sobre as regiões de disponibilidade
Apos a instalação, execute o comando ibmcloud plugin list cloud-functions para verificar se o plugin foi instalado corretamente. Deve ser exibida uma tela conforme abaixo
execute o comando ibmcloud target –cf para conectar na sua ORG e SPACE.
esta tudo pronto, agora execute o comando ibmcloud fn activation poll e o seu prompt vai ficar escutando qualquer entrada de log para as funções que você criou, parecido com o comando tail do linux. Basta enviar uma mensagem pelo whatsapp e o log será exibido
Twilio DashBoard
Saindo agora da cloud da IBM e voltando para interface do Twilio. Clique no dashboard para visualizar o histórico de mensagem trafegadas.
É possível acompanhar cada interação one-way e two-way. Até mesmo as imagens anexadas são exibidas no painel de detalhes clicando na mensagem
Proximos Passos
Fechamos a parte um rapaziada. No nosso próximo artigo da série, vamos subir o nosso ambiente para produção, no Twilio e no Whatsapp, mas para isso ainda dependemos da liberação do whatsapp que está em fase beta, assim que for aprovado, vamos cair dentro.
Como devem ter percebido, não abordamos o assunto chatbot nesse artigo, mas claro que para usar mensagens do tipo two-way-message, você vai querer implementar um chatbot. Temos um excelente artigo onde criamos um chatbot do zero usando o watson da IBM.
Caso queira ser informado sobre a parte 2 ou sobre outros artigos, eventos e novidades aqui no codechain, assine nossa newsletter ou acompanhe a gente nas redes sociais.
enquanto isso, seguimos …