O WhatsApp é, sem dúvida, o canal de comunicação mais utilizado no Brasil para atendimento ao cliente e vendas. No entanto, as soluções oficiais (Meta Business API) podem ser custosas para pequenas e médias empresas devido às taxas por conversa. A alternativa whatsapp self-hosted surge como uma poderosa estratégia de redução de custos, permitindo que organizações controlem sua própria infraestrutura de mensagens. Ao combinar a biblioteca Baileys com a plataforma de atendimento Chatwoot, é possível criar um sistema robusto, escalável e totalmente personalizado para gerenciar interações em tempo real.
Neste guia técnico, detalhamos o processo de integração entre o Chatwoot e uma instância do WhatsApp rodando localmente ou em sua VPS. Utilizaremos a biblioteca Baileys, conhecida por ser leve e manter-se atualizada com as últimas mudanças da API do WhatsApp Web. O objetivo é fornecer um ambiente seguro para disparos seguros, automação de fluxos e integração com chatbots IA, tudo isso sem depender de gateways de terceiros que cobram por mensagem enviada.
1. Pré-requisitos e Arquitetura do Sistema
Antes de iniciar a instalação, é fundamental entender os componentes que compõem esta arquitetura. Não se trata apenas de instalar um software, mas de configurar um ambiente estável que suporte a conexão WebSocket com os servidores do WhatsApp.
- Servidor Linux (Ubuntu/Debian): Recomendamos uma VPS com mínimo de 2 vCPUs e 4GB de RAM para garantir estabilidade durante o processamento de mídia e picos de tráfego.
- Node.js (v18 ou superior): A biblioteca Baileys é escrita em JavaScript/TypeScript, exigindo um ambiente Node.js moderno e otimizado.
- Banco de Dados SQLite: Para simplificar a instalação inicial, utilizaremos o SQLite. Em ambientes de alta produção, considere migrar para PostgreSQL ou MySQL posteriormente.
- Nginx (Opcional): Utilizado como proxy reverso caso você queira expor a interface web do Chatwoot via HTTPS em um domínio próprio.
A lógica central funciona da seguinte maneira: o script Baileys inicia uma sessão de WhatsApp Web, gera um QR Code para autenticação e mantém o canal aberto. Simultaneamente, o Chatwoot atua como o painel de controle, enviando comandos (respostas manuais ou disparos automatizados) que são traduzidos pela biblioteca em mensagens reais para o número do destinatário.
2. Instalação do Ambiente Node.js
O primeiro passo é preparar o servidor com as dependências necessárias. Execute os comandos abaixo no terminal do seu servidor com privilégios de root ou usuário sudo.
curl -fsSL https://deb.nodesource.com/setup_18.x | bash -
apt-get install -y nodejs git build-essential
Verifique se as versões foram instaladas corretamente:
node -v
npm -v
Agora, crie um diretório dedicado para sua aplicação de automação. Isso mantém seu servidor organizado e facilita backups futuros.
mkdir -p /opt/whatsapp-selfhosted
cd /opt/whatsapp-selfhosted
3. Configuração do Conector Baileys
Aqui, criaremos o script que faz a ponte entre o WhatsApp e o Chatwoot. A biblioteca Baileys é o motor que mantém a conexão viva. Para facilitar a integração com o Chatwoot via Webhooks, utilizaremos uma abordagem baseada em eventos.
Crie um arquivo chamado index.js no diretório criado:
nano index.js
Insira o código base abaixo. Este script configura a conexão, lida com a autenticação via QR Code e prepara os ganchos para receber eventos de mensagens.
const { default: makeWASocket, useMultiFileAuthState, DisconnectReason } = require('@whiskeysockets/baileys')
const qrcode = require('qrcode')
const fs = require('fs')
const path = require('path')
// Configuração de persistência de credenciais
const { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys')
// Configuração do Socket
const sock = makeWASocket({
auth: state,
printQRInTerminal: true, // Mostra o QR Code no terminal para leitura inicial
browser: ['Chatwoot Bot', 'Chrome', '1.0.0']
})
// Evento de salvamento de credenciais
sock.ev.on('creds.update', saveCreds)
// Evento de conexão encerrada
sock.ev.on('connection.update', async (update) => {
const { connection, lastDisconnect } = update
if (connection === 'close') {
const shouldReconnect = (lastDisconnect.error)?.output?.statusCode !== DisconnectReason.loggedOut
console.log('Conexão encerrada. Reconectando:', shouldReconnect)
if (shouldReconnect) {
await sock.connect()
}
} else if (connection === 'open') {
console.log('WhatsApp conectado com sucesso!')
}
})
// Handler de mensagens recebidas
sock.ev.on('messages.upsert', async (m) => {
const message = m.messages[0]
if (!message.message) return
// Aqui você integraria com o Webhook do Chatwoot
// Exemplo: Enviar dados para uma API local que atualiza o Chatwoot
console.log('Mensagem recebida:', JSON.stringify(message))
// Lógica para responder via webhook ou API interna
// await sendToChatwootWebhook(message)
})
// Função auxiliar para envio de mensagens (exemplo)
async function sendMessage(to, text) {
await sock.sendMessage(to, { text: text })
}
module.exports = { sock, sendMessage }
Instale as dependências necessárias para este script:
npm init -y
npm install @whiskeysockets/baileys qrcode
4. Integração com o Chatwoot via Webhooks
O Chatwoot não se conecta diretamente ao Baileys por padrão. A integração ocorre através de Webhooks. O fluxo ideal é: o usuário responde no WhatsApp -> o script recebe -> o script dispara um webhook para o Chatwoot -> o atendente responde no Chatwoot -> o Chatwoot dispara um webhook para seu script -> o script envia a mensagem via Baileys.
Para gerenciar isso de forma eficiente, recomenda-se criar uma API Node.js simples (usando Express) que receba os webhooks do Chatwoot e chame as funções do Baileys. Crie um arquivo server.js:
nano server.js
Instale o Express e o Body-Parser:
npm install express body-parser cors
No server.js, configure o endpoint que o Chatwoot chamará quando uma nova mensagem chegar ou quando um atendente responder:
const express = require('express')
const { sock } = require('./index') // Importa a instância do socket
const app = express()
app.use(express.json())
// Endpoint chamado pelo Chatwoot quando o atendente responde
app.post('/chatwoot/response', (req, res) => {
const { content, message_id } = req.body
// Lógica para identificar o número do destinatário baseada no message_id ou contexto
// Por simplicidade, assumiremos que a lógica de roteamento é feita externamente
sock.sendMessage('[email protected]', { text: content })
res.status(200).send('OK')
})
// Endpoint para receber mensagens do WhatsApp e enviar ao Chatwoot
app.post('/whatsapp/incoming', (req, res) => {
const message = req.body
// Disparar webhook para o URL do seu Chatwoot
// fetch('https://seu-chatwoot.com/inbox_api/v1/integrations/whatsapp', ...)
res.status(200).send('Received')
})
app.listen(3000, () => {
console.log('Servidor de integração rodando na porta 3000')
})
Com esta estrutura, você centraliza o tráfego. O Chatwoot configura um Webhook Inbound apontando para http://seu-servidor:3000/whatsapp/incoming e o Bot do WhatsApp (se estiver usando automação) pode acionar /chatwoot/response.
5. Automatização com Typebot e Chatbots IA
Uma das maiores vantagens do ambiente self-hosted é a flexibilidade para conectar ferramentas de automação. O Typebot é uma ferramenta open-source excelente para criar fluxos de conversa visuais. Ao invés de escrever código complexo para cada resposta, você pode desenhar o fluxo no Typebot e usar seus webhooks para enviar as mensagens via seu servidor Baileys.
Para integrar chatbots IA, como um modelo LLM local (ex: Ollama) ou uma API de IA, você intercepta a mensagem recebida no endpoint /whatsapp/incoming. Antes de enviar ao Chatwoot, o script verifica se é um gatilho de automação. Se for, envia o texto para a IA, recebe a resposta e utiliza a função sock.sendMessage para entregar a mensagem ao usuário final.
Exemplo de fluxo lógico para IA:
- Usuário envia "Quero saber preços".
- Seu servidor Node.js intercepta no
/whatsapp/incoming. - O script consulta a API do Typebot ou da IA com o contexto da conversa.
- A IA retorna: "Nossos planos começam em R$ 50,00".
- O script chama
sock.sendMessage(numero_usuario, { text: "Nossos planos..." }).
Essa abordagem permite que você mantenha o histórico de conversas no Chatwoot (para fins de compliance e análise humana) enquanto a máquina cuida das respostas iniciais e triagem.
6. Segurança e Boas Práticas
Ao implementar whatsapp self-hosted, a segurança é crítica. Você está lidando com credenciais de sessão que, se vazarem, permitem o acesso total à conta do WhatsApp.
- Proteja as Credenciais: O diretório
auth_info_baileyscontém os dados de autenticação. Garanta permissões restritas:chmod -R 700 auth_info_baileys. Nunca faça commit desse diretório em repositórios públicos como GitHub. - Firewall e UFW: Bloqueie a porta 3000 (ou a que você usar para sua API) externamente. Utilize Nginx ou um proxy reverso com HTTPS se precisar expor endpoints publicamente. Se a comunicação for apenas local, use localhost.
- Rate Limiting: Implemente limites de requisições em seus webhooks para evitar ataques de negação de serviço (DDoS) que possam derrubar sua instância do Chatwoot ou seu servidor de mensagens.
- Monitoramento: Utilize ferramentas como PM2 para manter o processo Node.js rodando e monitorar reinicializações. O WhatsApp frequentemente desconecta sessões inativas; ter um sistema de reconnection robusto é vital.
Além disso, evite o uso de números novos ou não verificados para automação em massa sem cuidado. O WhatsApp possui algoritmos de detecção de spam agressivos. Para disparos seguros, respeite as janelas de tempo entre mensagens e utilize templates aprovados se houver interação comercial formal.
7. Execução e Testes Finais
Para colocar seu sistema em produção, recomenda-se o uso do pm2, um gerenciador de processos para Node.js que garante alta disponibilidade.
npm install -g pm2
pm2 start server.js --name "whatsapp-integration"
Para verificar os logs e garantir que a conexão foi estabelecida:
pm2 logs whatsapp-integration
No primeiro início, o QR Code aparecerá no terminal. Escaneie-o com seu celular dentro de 60 segundos. Após a leitura, a sessão será salva no disco e as reconexões futuras serão automáticas.
Realize um teste completo: envie uma mensagem para o número conectado. Verifique se ela aparece no Chatwoot via webhook. Em seguida, responda diretamente no Chatwoot (se a integração de resposta estiver configurada) ou use sua API para enviar uma mensagem proativa. Confirme que a mensagem chega ao WhatsApp do usuário.
Conclusão
A configuração de um ambiente Chatwoot + WhatsApp Self-Hosted oferece controle total sobre os dados dos seus clientes e custos operacionais reduzidos. Ao utilizar o Baileys como motor de conexão, você ganha uma base leve e moderna que se integra perfeitamente com ecossistemas de automação como Typebot e IAs generativas.
Lembre-se: a manutenção é contínua. A API do WhatsApp Web muda frequentemente. Mantenha suas dependências Node.js atualizadas e monitore os logs para garantir que sua infraestrutura de atendimento permaneça estável e eficiente. Esta solução é ideal para empresas que buscam escala, privacidade e personalização profunda em seu canal de comunicação principal.