O que vamos construir

Ao final desse tutorial, você vai ter:

  • Envio de mensagens de template (confirmação de pedido, código de verificação, etc.)
  • Envio de mensagens livres (texto, imagem, documento) dentro da janela de 24h
  • Recebimento de mensagens via webhook (Express.js)
  • Status de entrega em tempo real (sent, delivered, read)

Tudo usando TypeScript com tipos completos — sem any em lugar nenhum.

Pré-requisitos

  • Node.js 18+ instalado
  • Uma conta na AraraHQ (grátis pra começar)
  • Sua API key (você pega no dashboard após o cadastro)

1. Setup do projeto

Inicializar projeto e instalar dependências
mkdir meu-bot-whatsapp && cd meu-bot-whatsapp
npm init -y
npm install @ararahq/sdk express dotenv
npm install -D typescript @types/express @types/node tsx
.env
ARARA_API_KEY=sua_chave_aqui
WEBHOOK_SECRET=um_segredo_qualquer
PORT=3000

2. Enviando mensagens

Existem dois tipos de mensagens na API oficial: templates (podem ser enviados a qualquer momento) e mensagens livres (só dentro da janela de 24h após o cliente te enviar algo).

src/send.ts — Exemplos de envio
import { Arara } from '@ararahq/sdk';
import 'dotenv/config';

const arara = new Arara(process.env.ARARA_API_KEY!);

// ---- Template com variáveis ----
// Use para: confirmações, códigos, avisos de entrega
async function enviarConfirmacao(telefone: string, nome: string, pedido: string) {
  const res = await arara.messages.send({
    to: telefone,
    type: "template",
    template: {
      name: "confirmacao_pedido",
      language: "pt_BR",
      components: [
        {
          type: "body",
          parameters: [
            { type: "text", text: nome },
            { type: "text", text: pedido }
          ]
        }
      ]
    }
  });

  console.log("Template enviado:", res.messageId);
  return res;
}

// ---- Texto livre (dentro da janela de 24h) ----
async function responderCliente(telefone: string, mensagem: string) {
  return arara.messages.send({
    to: telefone,
    type: "text",
    text: mensagem
  });
}

// ---- Enviar imagem ----
async function enviarComprovante(telefone: string, urlImagem: string) {
  return arara.messages.send({
    to: telefone,
    type: "image",
    image: {
      url: urlImagem,
      caption: "Comprovante de pagamento"
    }
  });
}

// ---- Enviar documento (PDF, etc) ----
async function enviarBoleto(telefone: string, urlPdf: string) {
  return arara.messages.send({
    to: telefone,
    type: "document",
    document: {
      url: urlPdf,
      filename: "boleto.pdf"
    }
  });
}

3. Recebendo mensagens (Webhooks)

Quando alguém manda mensagem pro seu número ou quando o status de uma mensagem muda (enviado, entregue, lido), a AraraHQ envia um POST pra URL que você configurou.

src/server.ts — Servidor com webhook
import express from 'express';
import { Arara } from '@ararahq/sdk';
import 'dotenv/config';

const app = express();
const arara = new Arara(process.env.ARARA_API_KEY!);

app.use(express.json());

// Webhook: receber mensagens e status updates
app.post("/webhook/whatsapp", async (req, res) => {
  const event = req.body;

  // Mensagem recebida do cliente
  if (event.type === "message") {
    const { from, text, timestamp } = event;
    console.log(`[${new Date(timestamp).toLocaleString()}] ${from}: ${text?.body}`);

    // Exemplo: responder automaticamente
    if (text?.body?.toLowerCase().includes("status")) {
      await arara.messages.send({
        to: from,
        type: "text",
        text: "Seu pedido está em rota de entrega!"
      });
    }
  }

  // Status update (sent -> delivered -> read)
  if (event.type === "status") {
    console.log(`Mensagem ${event.messageId}: ${event.status}`);
    // Aqui você pode atualizar o status no seu banco de dados
  }

  res.sendStatus(200); // Sempre retorne 200 rápido
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Servidor rodando na porta ${PORT}`);
});

Para testar localmente, use ngrok http 3000 e configure a URL do ngrok como webhook no dashboard da AraraHQ.

4. Dicas pra produção

Responda o webhook rápido
O webhook espera um 200 em até 5 segundos. Se você precisa processar algo pesado, coloque numa fila (BullMQ, SQS, etc.) e retorne o 200 imediatamente.
Trate duplicatas
Webhooks podem ser reenviados. Use o messageId como chave de idempotência no seu banco.
Respeite os rate limits
A Meta permite até 80 mensagens/segundo por número. Para disparos em massa, use batch com intervalos ou entre em contato pra aumentar o limite.
Use o sandbox pra testar
A AraraHQ tem um ambiente de sandbox grátis. Você pode testar envios e webhooks sem gastar créditos de produção.

Exemplo real: notificação de pedido num e-commerce

Aqui vai um exemplo completo de como integrar com seu sistema de pedidos. Quando o status do pedido muda, você notifica o cliente no WhatsApp:

src/notifications.ts
import { Arara } from '@ararahq/sdk';

const arara = new Arara(process.env.ARARA_API_KEY!);

type OrderStatus = "confirmed" | "shipped" | "delivered";

const TEMPLATES: Record<OrderStatus, string> = {
  confirmed: "pedido_confirmado",
  shipped: "pedido_enviado",
  delivered: "pedido_entregue",
};

export async function notifyOrderStatus(
  phone: string,
  customerName: string,
  orderId: string,
  status: OrderStatus,
  trackingCode?: string
) {
  const templateName = TEMPLATES[status];

  const parameters = [
    { type: "text" as const, text: customerName },
    { type: "text" as const, text: orderId },
  ];

  // Adiciona código de rastreio se for envio
  if (status === "shipped" && trackingCode) {
    parameters.push({ type: "text" as const, text: trackingCode });
  }

  try {
    const result = await arara.messages.send({
      to: phone,
      type: "template",
      template: {
        name: templateName,
        language: "pt_BR",
        components: [{
          type: "body",
          parameters
        }]
      }
    });

    return { success: true, messageId: result.messageId };
  } catch (error) {
    console.error(`Falha ao notificar ${phone}:`, error);
    return { success: false, error };
  }
}

Próximos passos

Com essa base, você consegue cobrir a maioria dos casos de uso: notificações transacionais, suporte ao cliente, e campanhas de marketing. Se quiser ir além:

Bora codar? Crie sua conta, pegue a API key e comece a enviar mensagens em menos de 5 minutos. Docs completas.

Criar conta