Chatwoot com API de WhatsApp: atendimento pela inbox do tipo API

Para atender WhatsApp no Chatwoot usando a D-API, crie uma inbox do tipo API e coloque um middleware entre os dois. As mensagens do cliente entram no Chatwoot pela API dele, e as respostas dos agentes saem pelo webhook do Chatwoot até a D-API.

Por que o caminho é a inbox do tipo API

O Chatwoot tem canais prontos para alguns provedores, e a D-API não está entre eles. Para esses casos ele oferece a inbox do tipo API: um canal genérico em que um sistema externo cria contatos, conversas e mensagens pela API do Chatwoot, e o Chatwoot avisa esse sistema por uma URL de callback quando o agente responde.

Nenhum dos dois lados fala o idioma do outro, então alguém precisa traduzir. Esse alguém é o middleware, um serviço pequeno que você hospeda. Não existe conector nativo entre D-API e Chatwoot, e a integração abaixo é feita inteiramente por HTTP e webhook.

O caminho de cada mensagem

Cliente escreve no WhatsApp

  1. O cliente manda mensagem para o número conectado na D-API.
  2. A D-API dispara messages.received para a URL de entrada do middleware.
  3. O middleware procura o contato pelo telefone. Se não existe, cria o contato na inbox API e guarda o source_id devolvido.
  4. Se não há conversa aberta para esse contato, cria uma e guarda o id.
  5. Cria a mensagem na conversa com message_type: "incoming". O agente vê a mensagem no painel.

Agente responde no Chatwoot

  1. O agente escreve na conversa.
  2. O Chatwoot chama a URL de callback da inbox com o evento message_created.
  3. O middleware descarta o que não é resposta ao cliente: mensagens incoming (as que ele mesmo criou) e notas com private verdadeiro.
  4. Pelo id da conversa, encontra o telefone e envia o texto para /api/v1/messages/send/text da D-API.

Configurando os dois lados

No Chatwoot, vá em Settings, Inboxes, Add Inbox e escolha API. Informe um nome para o canal e, no campo de webhook, a URL de saída do middleware. Depois adicione os agentes que vão atender a inbox. Para chamar a API do Chatwoot, o middleware usa um token de acesso gerado no perfil de um usuário, enviado no header api_access_token.

Na D-API, aponte o evento de mensagem recebida da conexão para a URL de entrada do middleware:

curl -X POST https://api.d-api.cloud/api/v1/sessions/suporte/webhook-config \
  -H "Authorization: SUA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true, "type": "single",
        "events": { "messages.received": { "enabled": true, "webhookUrl": "https://middleware.suaempresa.com/entrada" } } }'

As chamadas que o middleware faz no Chatwoot, todas com o header de token:

MomentoChamada no Chatwoot
Primeiro contato do clientePOST /api/v1/accounts/ID/contacts com inbox_id, nome e telefone
Sem conversa abertaPOST /api/v1/accounts/ID/conversations com source_id, inbox_id e contact_id
Cada mensagem recebidaPOST /api/v1/accounts/ID/conversations/ID/messages com content e message_type incoming

A saída: do callback do Chatwoot para a D-API

Este é o trecho que mais gera dúvida, então vale ver em código. A rota abaixo recebe o callback da inbox e responde ao cliente. O findConversation representa a sua tabela de mapeamento:

app.post('/saida', async (req, res) => {
  res.sendStatus(200)
  const ev = req.body
  if (ev.event !== 'message_created') return
  if (ev.message_type !== 'outgoing' || ev.private) return

  const link = await findConversation(ev.conversation.id)
  if (!link) return // conversa que não nasceu no WhatsApp

  await fetch('https://api.d-api.cloud/api/v1/messages/send/text', {
    method: 'POST',
    headers: { Authorization: process.env.DAPI_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ sessionId: link.sessionId, to: link.phone, text: ev.content }),
    signal: AbortSignal.timeout(10000),
  })
})

Repare no filtro de message_type. Sem ele, cada mensagem que o middleware cria como incoming dispara o callback de volta e pode virar envio duplicado para o cliente.

O que o middleware precisa fazer bem

  • Mapeamento persistente: telefone para contato e conversa, conversa para telefone e sessionId. Em banco, não em memória, para sobreviver a deploy e rodar em mais de uma instância.
  • Idempotência: a D-API reenvia o webhook quando a URL falha ou passa de 30 segundos. Use o data.id da mensagem como chave e ignore o que já foi registrado.
  • Resposta rápida: devolva 200 logo e processe em seguida, ou numa fila. Chamar o Chatwoot três vezes dentro do request do webhook é pedir timeout.
  • Mensagens do próprio celular: o evento de recebida também chega com fromMe verdadeiro quando alguém escreve pelo aparelho. Decida se isso entra no Chatwoot como nota ou se é ignorado.
  • Conexão caída: assine também connection.status para avisar o time quando o número desconectar, em vez de descobrir pela fila parada.

Quando esse desenho compensa

Se a sua empresa quer uma central de atendimento sem desenvolver tela, Chatwoot mais API de WhatsApp resolve com um serviço pequeno no meio. Com vários números, uma inbox por conexão mantém cada equipe no seu canal, como descrito em múltiplos números no WhatsApp.

Se você está construindo um produto de atendimento para vender a outras empresas, o caminho é outro: WhatsApp dentro do seu próprio sistema, uma conexão por cliente, como mostra a página de API de WhatsApp para helpdesk e a de API de WhatsApp para SaaS. Para entender cada evento que chega ao middleware, veja o guia de webhook de WhatsApp.

Perguntas frequentes

A D-API aparece como canal pronto no Chatwoot?

Não. O Chatwoot oferece a inbox do tipo API justamente para canais que ele não conhece. A D-API se liga a essa inbox por meio de um middleware que conversa com as duas APIs.

O que o middleware precisa guardar?

A relação entre o telefone do cliente, o contato e a conversa no Chatwoot, e a relação inversa entre a conversa e o número da D-API que a atende. Sem isso ele não sabe onde registrar a mensagem que chegou nem para quem enviar a resposta.

Notas privadas dos agentes vão para o cliente?

Não devem. O webhook do Chatwoot traz o campo private, e o middleware só repassa mensagens com message_type outgoing e private falso. Notas internas ficam no Chatwoot.

Consigo atender vários números no mesmo Chatwoot?

Sim. O desenho mais simples é uma inbox do tipo API por conexão da D-API. Cada inbox tem sua URL de callback, e o middleware sabe por ela de qual número a resposta deve sair.

Mensagens com imagem e áudio também funcionam?

Funcionam, mas exigem mais código. Na entrada, o webhook da D-API traz media_url para mídia recebida, que o middleware anexa à mensagem no Chatwoot. Na saída, os anexos do agente vão para as rotas de envio de mídia da D-API.

Teste a API de WhatsApp da D-API

Trial de 3 dias com acesso completo. Sem cartão, sem fidelidade.