Schema do Banco de Dados
O Disparador de Campanhas utiliza um banco de dados MySQL para armazenar informações sobre agentes, conversas, mensagens, webhooks e logs.
Diagrama ER
┌─────────────┐ ┌──────────────────┐
│ agent │────┬────<│ agent_contact │
└─────────────┘ │ └──────────────────┘
│
│ ┌──────────────────┐
└────<│ conversation │
└────────┬─────────┘
│
┌────────▼─────────┐
│ message │
└──────────────────┘
┌──────────────────────┐
│ webhook │
└──────────────────────┘
┌──────────────────────┐
│ logs │
└──────────────────────┘
┌──────────────────────┐
│ conversation_insights│
└──────────────────────┘
Tabelas
1. agent
Armazena configurações dos agentes de IA.
CREATE TABLE `agent` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
`instructions` longtext, -- Instruções/prompt do agente
`functions` json DEFAULT NULL, -- Funções disponíveis (JSON)
`inbox_id` int DEFAULT NULL, -- ID do inbox no Chatwoot
`status` int DEFAULT NULL, -- 0: inativo, 1: ativo
`team_id` int DEFAULT NULL, -- ID do time responsável
`assigned_contact_id` int DEFAULT NULL, -- Contato atribuído
`testword` text, -- Palavra-chave de teste
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Campos importantes:
instructions: Prompt base do agente (ex: "Você é um assistente de vendas...")functions: Lista de funções que o agente pode chamar (formato JSON)inbox_id: Qual inbox do Chatwoot esse agente gerenciastatus: Se o agente está ativo (1) ou inativo (0)
2. agent_contact
Relacionamento N:N entre agentes e contatos.
CREATE TABLE `agent_contact` (
`id` int NOT NULL AUTO_INCREMENT,
`contact_id` int NOT NULL,
`agent_id` int NOT NULL,
PRIMARY KEY (`id`),
KEY `contact_id` (`contact_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Uso: Permite que um contato seja gerenciado por múltiplos agentes ou que um agente gerencie múltiplos contatos.
3. conversation
Armazena conversas ativas e históricas.
CREATE TABLE `conversation` (
`id` int NOT NULL AUTO_INCREMENT,
`external_id` int DEFAULT NULL, -- ID da conversa no Chatwoot
`contact_id` int DEFAULT NULL, -- ID do contato
`inbox_id` int DEFAULT NULL, -- ID do inbox
`status` int DEFAULT NULL, -- Status da conversa
`last_interaction_at` datetime DEFAULT NULL,
`account_id` int DEFAULT NULL, -- ID da conta no Chatwoot
`retry_times` int DEFAULT '0', -- Tentativas de reprocessamento
`is_over` int DEFAULT NULL, -- Conversa finalizada?
`last_source_id` varchar(200) DEFAULT NULL, -- Source ID do último contato
`origin` varchar(50) DEFAULT NULL, -- Origem (whatsapp, instagram, etc)
PRIMARY KEY (`id`),
UNIQUE KEY `uk_external_contact_inbox` (`external_id`,`contact_id`,`inbox_id`),
KEY `account_id` (`account_id`),
KEY `status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Campos importantes:
external_id: ID da conversa no Chatwoot (para sincronização)status: Status atual (0: aberta, 1: resolvida, 2: pendente)retry_times: Quantas vezes tentou reprocessar (útil para erros)is_over: Flag se conversa foi finalizadaorigin: Canal de origem (whatsapp, instagram, webchat)
4. message
Armazena todas as mensagens processadas.
CREATE TABLE `message` (
`id` int NOT NULL AUTO_INCREMENT,
`payload` json DEFAULT NULL, -- Payload completo da mensagem
`content` longtext, -- Conteúdo da mensagem
`processed` int DEFAULT NULL, -- Status: 0: não processado, 1: processado
`grouping` varchar(100) DEFAULT NULL, -- Agrupamento (para campanhas)
`created_at` datetime DEFAULT NULL,
`source` varchar(100) DEFAULT NULL, -- Fonte da mensagem
`account_id` int DEFAULT NULL,
`inbox_id` int DEFAULT NULL,
`role` varchar(50) DEFAULT NULL, -- 'user' ou 'assistant'
`external_id` varchar(100) DEFAULT NULL, -- ID externo (Chatwoot)
`sub_external_id` varchar(100) DEFAULT NULL,
`type` varchar(30) DEFAULT NULL, -- Tipo de mensagem
`agent_id` int DEFAULT NULL,
`message_id` int DEFAULT NULL,
`execution_id` varchar(255) DEFAULT NULL, -- ID da execução no N8N
PRIMARY KEY (`id`),
KEY `processed` (`processed`),
KEY `account_id` (`account_id`),
KEY `inbox_id` (`inbox_id`),
KEY `agent_id` (`agent_id`),
KEY `external_id` (`external_id`),
KEY `sub_external_id` (`sub_external_id`),
KEY `grouping` (`grouping`),
KEY `source` (`source`),
KEY `execution_id` (`execution_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Campos importantes:
payload: JSON completo da mensagem (útil para debug)content: Texto da mensagemprocessed: Se foi processada pelo sistema (0: pendente, 1: processado)grouping: Identificador de campanha/loterole: Quem enviou ('user' = cliente, 'assistant' = IA/atendente)execution_id: ID da execução no N8N (rastreabilidade)
5. webhook
Armazena webhooks recebidos (auditoria).
CREATE TABLE `webhook` (
`id` int NOT NULL AUTO_INCREMENT,
`payload` json DEFAULT NULL, -- Payload completo do webhook
`created_at` datetime DEFAULT NULL,
`origin` varchar(100) DEFAULT NULL, -- Origem (chatwoot, meta, brevo)
`type` varchar(50) DEFAULT NULL, -- Tipo do evento
`external_id` varchar(200) DEFAULT NULL, -- ID externo único
PRIMARY KEY (`id`),
UNIQUE KEY `external_id` (`external_id`),
KEY `origin` (`origin`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Uso: Auditoria de todos os webhooks recebidos. Útil para:
- Debug de problemas
- Replay de eventos
- Análise de tráfego
6. logs
Logs gerais do sistema.
CREATE TABLE `logs` (
`id` int NOT NULL AUTO_INCREMENT,
`payload` json NOT NULL, -- Dados do log em JSON
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`status` int NOT NULL DEFAULT '0', -- Status do processamento
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Uso: Logs genéricos que não se encaixam em outras tabelas.
7. conversation_insights
Insights e métricas de conversas (campanhas).
CREATE TABLE `conversation_insights` (
`id` int NOT NULL AUTO_INCREMENT,
`conversation_id` int NOT NULL,
`name` varchar(200) NOT NULL, -- Nome do contato
`phone_number` varchar(50) NOT NULL,
`contact_id` int NOT NULL,
`has_reply` int NOT NULL, -- 0: não respondeu, 1: respondeu
PRIMARY KEY (`id`),
UNIQUE KEY `conversation_id` (`conversation_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Uso: Análise de campanhas
- Quantos responderam?
- Taxa de resposta por campanha
- Identificar contatos engajados
Queries Úteis
Contadores de Conversas por Status
SELECT
status,
COUNT(*) as total,
origin
FROM conversation
WHERE account_id = 1
GROUP BY status, origin;
Mensagens Não Processadas
SELECT
id,
content,
created_at,
inbox_id
FROM message
WHERE processed = 0
ORDER BY created_at DESC
LIMIT 50;
Taxa de Resposta de Campanha
SELECT
COUNT(*) as total_sent,
SUM(has_reply) as replied,
ROUND(SUM(has_reply) / COUNT(*) * 100, 2) as reply_rate_percent
FROM conversation_insights;
Últimos Webhooks Recebidos
SELECT
id,
origin,
type,
created_at
FROM webhook
ORDER BY created_at DESC
LIMIT 20;
Mensagens por Agente
SELECT
a.name as agent_name,
COUNT(m.id) as total_messages,
SUM(CASE WHEN m.role = 'assistant' THEN 1 ELSE 0 END) as sent_by_agent,
SUM(CASE WHEN m.role = 'user' THEN 1 ELSE 0 END) as received_from_user
FROM agent a
LEFT JOIN message m ON m.agent_id = a.id
GROUP BY a.id, a.name;
Índices Importantes
Os índices existentes garantem performance para:
- Busca por conversa:
external_id,contact_id,inbox_id - Filtragem de mensagens:
processed,account_id,inbox_id,grouping - Rastreabilidade:
execution_id,external_id - Auditoria:
origin(webhook),status(conversation)
Manutenção
Limpeza de Logs Antigos
-- Remover logs com mais de 30 dias
DELETE FROM logs
WHERE created_at < DATE_SUB(NOW(), INTERVAL 30 DAY);
-- Remover webhooks antigos (mais de 90 dias)
DELETE FROM webhook
WHERE created_at < DATE_SUB(NOW(), INTERVAL 90 DAY);
Backup Recomendado
# Dump diário
mysqldump -u user -p whatsapp > backup_$(date +%Y%m%d).sql
# Apenas estrutura (sem dados)
mysqldump -u user -p --no-data whatsapp > schema.sql
Próximos Passos
- Veja Exemplos de Uso práticos
- Consulte as Rotas da API para referência completa