Guia rápido para enviar e receber mensagens de WhatsApp em node.js

Saiba como configurar a API de WhatsApp da Zenvia para troca de mensagens em node.js, de forma prática. Texto de Rafael Sousa, desenvolvedor na Zenvia.

Por Rafael Sousa, desenvolvedor sênior na Zenvia

Pré-requisitos

  • Para seguir esse guia, é necessário já ter instalado no sistema tanto o node.js quanto o npm.
  • Também é necessário saber acessar o console (linha de comando) do seu sistema.
  • Por último, é necessário ter um número de WhatsApp habilitado na Zenvia. Futuramente, disponibilizaremos um ambiente de testes onde será possível realizar esses testes mesmo sem ter contratado um número com a gente.

Etapas

Caso esteja familiar com desenvolvimento em node.js, pode ir direto para o passo Criando o token da API.

Caso além disso, já tenha criado um token de API, pode ir direto para o passo Instalando o SDK da Zenvia.

  1. Validando a instalação
  2. Criando o projeto
  3. Criando o token da API
  4. Instalando o SDK da Zenvia
  5. Definindo a URL da aplicação
  6. Escrevendo a aplicação
  7. Executando a aplicação

Validando a instalação

Só pra verificar se você tem o node.js e o npm instalados.

node.js

node -v

Exemplo de saída:

v10.16.3

npm

npm -v

Exemplo de saída:

6.9.0

Criando o projeto

Isso você já deve saber, mas tá aqui caso precise.

Criando diretório

mkdir zenvia-sdk-quick-start
cd zenvia-sdk-quick-start

Inicializando o projeto (opcional)

npm init -y

Exemplo de saída:

Wrote to /home/rafael.souza/git/zenvia-sdk-quick-start/package.json:
{
  "name": "zenvia-sdk-quick-start",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Criando o token da API

Para usar nossa API, é necessário a criação de um token. Isso é feito em nosso console de API.

Basta clicar em “Create New” (ou “Criar Novo” dependendo do idioma).

Daí dar um nome pro token pra quando quiser revogá-lo achar mais facilmente o token, e então clicar em “Salvar” (ou “Salvar” dependendo do idioma).

Para copiar o token basta clicar em “Copy token” (ou “Copiar token” dependendo do idioma).

Esse token será usado durante a criação da aplicação.

Opcionalmente também, poderia já ser configurada a subscription (webhook) para receber as mensagens dos usuários. Contudo, nosso SDK já faz isso caso uma URL seja fornecida na configuração. Como vamos usar nosso SDK nesse guia, não precisamos realizar essa configuração.

Instalando o SDK da Zenvia

npm install @zenvia/sdk

Exemplo de saída:

npm install @zenvia/sdk
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN [email protected] No description
npm WARN [email protected] No repository field.
+ @zenvia/[email protected]
added 100 packages from 95 contributors and audited 198 packages in 5.558s
found 0 vulnerabilities

Definindo a URL da aplicação

A URL da aplicação é a URL que nossa plataforma irá chamar cada vez que houver uma nova mensagem enviada ao seu número. Portando, essa URL precisa ser acessível na internet.

Assim sendo, se você estiver fazendo essa aplicação na sua máquina local, ela precisa ser acessível na internet. Se sua máquina for acessível na internet, a URL da sua aplicação deve seguir o formato:

http://<IP DA SUA MÁQUINA>:3000/

Nesse guia usaremos a porta 3000, por isso usamos 3000 na URL, mas se preferir (ou necessitar) basta alterar a porta que a aplicação irá ouvir e usar essa porta na construção da URL.

Contudo, hoje em dia, dificilmente as máquinas são acessíveis na internet, pois quem é acessível na internet é o roteador. Felizmente existem serviços que nos ajudam a contornar isso criando um túnel para alguma porta da nossa máquina. Aqui nesse guia vamos usar o ngrok para isso. É bem simples usá-lo.

Primeiramente, precisamos instalá-lo em nosso projeto:

npm install --save-dev ngrok

Aí, quando escrevermos nossa aplicação, usaremos o trecho abaixo pra gerar a URL da aplicação:

const ngrok = require( 'ngrok' );
const url = (async function() {
  return await ngrok.connect( port );
})();

Escrevendo a aplicação

Nesse guia vamos escrever o código da aplicação no arquivo app.js, assim como fizemos durante a inicialização do package.json durante a inicialização do projeto.

Nossa aplicação será bem simples: ela irá imprimir no console a mensagem recebida, e irá enviar de volta pra o usuário uma mensagem agradecendo o usuário pela mensagem.

Deixamos no início do arquivo as variáveis que precisam ser alteradas para que nossa aplicação funcione: url e token.

app.js:

const port = 3000;
const token = '<O SEU TOKEN DE API VEM AQUI>';
const url = `http://<IP DA SUA MÁQUINA>:${port}/`;
// Comentar a linha acima e descomentar o trecho abaixo para usar ngrok.
/*
const ngrok = require( 'ngrok' );
const url = (async function() {
  return await ngrok.connect( port );
})();
*/
const channel = 'whatsapp';
// Criando a função main pra facilitar embutir o ngrok pra testar localmente.
async function main( url , token ) {
  // Esse await é só pro caso de ngrok ter sido usado.
  url = await url;
  console.log( `Iniciando a aplicação na porta ${port}, usando para webhook a URL: ${url}` );
  // Importando nosso SDK.
  const { Client, WebhookController, TextContent } = require( '@zenvia/sdk' );
  // Classe do nosso SDK usada para realizar chamadas de API.
  const client = new Client( token );
  // Classe no nosso SDK usada para receber chamadas de webhooks.
  const webhook = new WebhookController( {
    // A porta que nossa aplicação ouvirá.
    port,
    // O client que será usado pra realizar chamadas de API.
    client,
    // O canal que será usado pra criar uma subscription (webhook) para nossa aplicação.
    channel,
    // A URL que será usada para criar uma subscription (webhook) para nossa aplicação.
    url,
    // A parte mais importa da nossa aplicação. Aqui que as mensagens são tratadas.
    messageEventHandler: ( messageEvent ) => {
      const phone = messageEvent.message.from;
      const senderId = messageEvent.message.to;
      let firstName;
      let reply;
      /* É importante fazer um loop em contents porque normalmente vem dois:
        - O primeiro, que pode não vir, do tipo "json", com dados do usuário
        - E o segundo, do tipo do conteúdo enviado pelo usuário, normalmente "text" */
      messageEvent.message.contents.forEach( content => {
        switch( content.type ) {
          // Caso o usuário tenha enviado uma mensagem texto
          case 'text':
            const text = content.text;
            console.log( `O número "${phone}" enviou a mensagem: "${text}"` );
            // Tendo o nome do usuário disponível, personalizamos a resposta
            if( firstName ) {
              reply = `${firstName}, obrigado pela mensagem enviada!`;
            } else {
              reply = 'Obrigado pela mensagem enviada!';
            }
            break;
          // Caso o usuário tenha enviado um arquivo, imagem, vídeo ou áudio
          case 'file':
            const url = content.fileUrl;
            const type = content.fileType;
            console.log( `O número "${phone}" enviou um arquivo do tipo "${type}": "${url}"` );
            // Tendo o nome do usuário disponível, personalizamos a resposta
            if( firstName ) {
              reply = `${firstName}, obrigado pelo arquivo enviado!`;
            } else {
              reply = 'Obrigado pelo arquivo enviado!';
            }
            break;
          /* Caso tenha dados do usuário disponível.
            Normalmente tem, mas o usuário pode desabilitar isso. */
          case 'json':
            if( content.payload.visitor ) {
              firstName = content.payload.visitor.firstName;
            }
            break;
          default:
            console.log( `Ignorando conteúdo do tipo "${content.type}" do número "${phone}"` );
        }
        // Envia uma resposta ao usuário
        if( reply ) {
          client.getChannel( channel ).sendMessage( senderId, phone, new TextContent( reply ) );
        }
      } );
    },
  } );
  // Só para logar qualquer possível problema pra realizando chamadas
  webhook.on( 'error', ( error ) => {
    console.error( 'Erro:', error );
  } );
  // Aqui nossa aplicação sobe no ar
  webhook.init();
}
// Executando a função que criamos acima
main( url, token );

Executando a aplicação

Por último, basta executar a aplicação criada usando o node.

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>node app.js
</code></pre></div></div>

Agora é só enviar alguma mensagem para o seu número e ver sua aplicação te responder.

Dúvidas? É só deixar nos comentários!

Zenvia API's
Escrito por

Zenvia