Como integrar a WAME API (WhatsApp) com o Chatwoot — passo a passo
Tutorial para integrar o WhatsApp ao Chatwoot usando a WAME API: conecte os dois sentidos (mensagens que chegam e respostas dos atendentes) com o API Channel do Chatwoot e os webhooks da WAME. Com código em Node.js.
Sim, dá para usar o WhatsApp da WAME API dentro do Chatwoot. Não existe um conector nativo, mas a integração é direta: uma ponte (middleware) liga os webhooks da WAME ao API Channel do Chatwoot. O resultado é atendimento omnichannel — mensagens do WhatsApp viram conversas no Chatwoot e as respostas dos atendentes voltam para o cliente.
WhatsApp ⇄ WAME API ⇄ (seu middleware) ⇄ Chatwoot (API Channel)
Neste tutorial você cria a inbox no Chatwoot, configura os webhooks dos dois lados e sobe uma ponte em Node.js.
Visão geral dos dois sentidos
| Sentido | Origem | Destino |
|---|---|---|
| Entrada | Webhook da WAME (webhookMessage) | API pública do Chatwoot |
| Saída | Webhook da inbox do Chatwoot | POST /{key}/message/text da WAME |
Passo 1 — Criar o API Channel no Chatwoot
No Chatwoot, vá em Configurações → Caixas de entrada → Adicionar inbox → API. Defina um nome e, no campo webhook_url, aponte para o endpoint de saída do seu middleware (ex.: https://sua-ponte.com/webhook/chatwoot).
Ao criar, guarde o inbox_identifier (identificador da inbox) — ele é usado nas chamadas da API pública.
Passo 2 — Configurar o webhook da WAME
Aponte o webhook de mensagens da WAME para o endpoint de entrada do seu middleware:
curl -X PUT "https://us.api-wa.me/SUA_KEY/instance" \
-H "Content-Type: application/json" \
-d '{
"allowWebhook": true,
"allowNumber": "all",
"webhookMessage": "https://sua-ponte.com/webhook/wame"
}'
Passo 3 — A ponte (middleware) em Node.js
O exemplo abaixo usa Express. Variáveis de ambiente:
CHATWOOT_URL=https://app.chatwoot.com
CHATWOOT_INBOX_IDENTIFIER=seu_inbox_identifier
WAME_SERVER=https://us.api-wa.me
WAME_KEY=SUA_KEY
Entrada: WhatsApp → Chatwoot
Quando chega uma mensagem, a WAME chama /webhook/wame. O middleware garante o contato e a conversa no Chatwoot e cria a mensagem como recebida:
import express from "express";
const app = express();
app.use(express.json());
const CW = process.env.CHATWOOT_URL!;
const INBOX = process.env.CHATWOOT_INBOX_IDENTIFIER!;
// Em produção, persista esse mapa (Redis/DB). Aqui, em memória para o exemplo.
const sessions = new Map<string, { sourceId: string; conversationId: number }>();
async function ensureConversation(phone: string, name: string) {
if (sessions.has(phone)) return sessions.get(phone)!;
// 1) Criar/identificar o contato (usamos o telefone como identifier)
const contact = await fetch(`${CW}/public/api/v1/inboxes/${INBOX}/contacts`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ identifier: phone, name, phone_number: `+${phone}` }),
}).then((r) => r.json());
const sourceId = contact.source_id;
// 2) Abrir uma conversa para esse contato
const conversation = await fetch(
`${CW}/public/api/v1/inboxes/${INBOX}/contacts/${sourceId}/conversations`,
{ method: "POST", headers: { "Content-Type": "application/json" }, body: "{}" }
).then((r) => r.json());
const data = { sourceId, conversationId: conversation.id };
sessions.set(phone, data);
return data;
}
app.post("/webhook/wame", async (req, res) => {
const evt = req.body; // estrutura do evento de mensagem da WAME
const phone = String(evt.from || evt.number || "").replace(/\D/g, "");
const text = evt.text || evt.message?.text || "";
if (!phone || !text) return res.sendStatus(200);
const { sourceId, conversationId } = await ensureConversation(phone, evt.name || phone);
await fetch(
`${CW}/public/api/v1/inboxes/${INBOX}/contacts/${sourceId}/conversations/${conversationId}/messages`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ content: text, message_type: "incoming" }),
}
);
res.sendStatus(200);
});
Saída: Chatwoot → WhatsApp
Quando um atendente responde, o Chatwoot chama o webhook_url da inbox. Filtramos só mensagens de saída (do atendente) e enviamos pela WAME:
const WAME = `${process.env.WAME_SERVER}/${process.env.WAME_KEY}`;
app.post("/webhook/chatwoot", async (req, res) => {
const evt = req.body;
// Só reage a mensagens criadas, de saída e não privadas
if (evt.event !== "message_created") return res.sendStatus(200);
if (evt.message_type !== "outgoing" || evt.private) return res.sendStatus(200);
// O telefone é o identifier que definimos ao criar o contato
const phone = (evt.conversation?.meta?.sender?.identifier || "").replace(/\D/g, "");
const text = evt.content || "";
if (!phone || !text) return res.sendStatus(200);
await fetch(`${WAME}/message/text`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ to: phone, text }),
});
res.sendStatus(200);
});
app.listen(3000, () => console.log("Ponte WAME ⇄ Chatwoot rodando na porta 3000"));
Ajuste os nomes dos campos do evento da WAME (
from,text, etc.) conforme o payload real do seu webhook — confira na documentação. Em produção, persista o mapa de sessões (telefone ↔ contato/conversa) em um banco ou Redis.
Sem código? Use o n8n
Se preferir não manter um serviço próprio, dá para montar os mesmos dois fluxos em uma ferramenta de automação como o n8n: um workflow recebe o webhook da WAME e chama a API do Chatwoot; outro recebe o webhook do Chatwoot e chama a WAME.
Dicas finais
- Envie e responda só para contatos com opt-in — veja as boas práticas para evitar bloqueio.
- Para mídia, use os endpoints específicos (imagem, documento) em vez de
/message/text— veja como enviar mídia e botões. - Precisa de uma visão geral dos endpoints? Veja o guia da API.
Com essa ponte, seu time atende o WhatsApp direto no Chatwoot, com todo o histórico centralizado. Comece criando sua conta na api-wa.me e configurando o webhook.
Pronto para automatizar seu WhatsApp?
Crie sua conta gratuita e comece a enviar mensagens pela API em minutos.
Começar grátisPerguntas frequentes
Dá para usar a WAME API com o Chatwoot?+
Sim. Não há um conector nativo, mas a integração é feita com uma ponte (middleware) que liga os webhooks da WAME ao API Channel do Chatwoot. As mensagens que chegam no WhatsApp aparecem no Chatwoot, e as respostas dos atendentes voltam para o WhatsApp.
O que é o API Channel do Chatwoot?+
É um tipo de caixa de entrada (inbox) do Chatwoot feito para conectar canais externos. Você empurra mensagens recebidas via API pública do Chatwoot e recebe as respostas dos atendentes em uma webhook_url configurada na inbox.
Preciso saber programar para integrar WAME e Chatwoot?+
É preciso um pequeno serviço (middleware) que traduz os dois formatos. Pode ser feito em Node.js ou PHP, ou com uma ferramenta de automação como o n8n, sem escrever muito código.
Funciona com Chatwoot self-hosted?+
Sim. Funciona tanto com o Chatwoot na nuvem (app.chatwoot.com) quanto com uma instância self-hosted — basta apontar a base URL da API do Chatwoot para o seu domínio.