11 KiB
11 KiB
Análise Atendeon → XOS
Projeto: https://github.com/JonasRodriguesPachceo/atendeon
Stack: Node.js (TypeScript) + React + PostgreSQL + Baileys
Data: 29/01/2026
Resumo do Projeto Atendeon
O Atendeon é uma central de atendimento WhatsApp multi-empresa (SaaS) completa com:
- 477 arquivos TypeScript no backend
- 41 Models (Sequelize/PostgreSQL)
- 35+ Services organizados por domínio
- Integração completa com Baileys (WhatsApp não-oficial)
- Suporte a Typebot, N8N e OpenAI
Funcionalidades do Atendeon vs XOS Atual
✅ O que o Atendeon tem que NOS FALTA
| Funcionalidade | Atendeon | XOS Atual | Prioridade |
|---|---|---|---|
| Filas de Atendimento (Queues) | ✅ Completo | ⚪ Não existe | 🔴 Alta |
| Distribuição Round-Robin | ✅ Por fila/equipe | ⚪ Não existe | 🔴 Alta |
| Notas Internas (TicketNote) | ✅ Model dedicado | ⚪ Não existe | 🔴 Alta |
| Mensagens Rápidas (QuickMessage) | ✅ Com atalhos | ⚪ Não existe | 🟠 Média |
| Agendamento de Mensagens | ✅ Schedule model | ⚪ Não existe | 🟠 Média |
| Tracking de Ticket | ✅ TicketTraking | ⚪ Não existe | 🟠 Média |
| Horário de Funcionamento | ✅ outOfHoursMessage | ⚪ Não existe | 🟡 Baixa |
| Rating/Avaliação | ✅ UserRating | ⚪ Não existe | 🟡 Baixa |
| Campos Customizados | ✅ ContactCustomField | ✅ customFields JSONB | ✅ OK |
| Multi-WhatsApp | ✅ Whatsapp model | ⚪ Não integrado | 🔴 Alta |
| Chatbot/Typebot | ✅ Integração nativa | ⚪ Não existe | 🟠 Média |
| Integração N8N | ✅ QueueIntegrations | ⚪ Não existe | 🟠 Média |
| Prompts OpenAI | ✅ Prompt model | ✅ Manus Agent | ✅ OK |
| Campanhas com 5 msgs | ✅ message1-5 | 🟡 content único | 🟠 Média |
| Disparo em massa | ✅ CampaignShipping | 🟡 Estrutura só | 🔴 Alta |
| Listas de Contatos | ✅ ContactList/Item | ⚪ Não existe | 🟠 Média |
| Tags em Tickets | ✅ TicketTag M:N | 🟡 Array no ticket | ✅ OK |
| Importação de Contatos | ✅ ImportService | ⚪ Não existe | 🟠 Média |
Models do Atendeon que Devemos Criar
1. Filas de Atendimento (Queue)
// Atendeon: Queue.ts
{
name: string,
color: string,
greetingMessage: string, // Mensagem de boas-vindas
outOfHoursMessage: string, // Fora do expediente
schedules: JSONB, // Horários de funcionamento
orderQueue: number, // Ordem na distribuição
}
// Relacionamentos:
// - BelongsToMany → Users (UserQueue)
// - BelongsToMany → Whatsapps (WhatsappQueue)
Sugestão para XOS:
CREATE TABLE xos_queues (
id SERIAL PRIMARY KEY,
tenant_id INTEGER REFERENCES tenants(id),
name VARCHAR(100) NOT NULL,
color VARCHAR(20),
greeting_message TEXT,
out_of_hours_message TEXT,
schedules JSONB, -- [{dayOfWeek: 1, startTime: "09:00", endTime: "18:00"}]
order_priority INTEGER DEFAULT 0,
is_active BOOLEAN DEFAULT true
);
CREATE TABLE xos_queue_users (
queue_id INTEGER REFERENCES xos_queues(id),
user_id VARCHAR REFERENCES users(id),
is_active BOOLEAN DEFAULT true,
PRIMARY KEY (queue_id, user_id)
);
2. Notas Internas (TicketNote)
// Atendeon: TicketNote.ts
{
note: string,
userId: number, // Quem escreveu
contactId: number, // Sobre qual contato
ticketId: number, // Em qual ticket
}
Sugestão para XOS:
CREATE TABLE xos_internal_notes (
id SERIAL PRIMARY KEY,
conversation_id INTEGER REFERENCES xos_conversations(id),
contact_id INTEGER REFERENCES xos_contacts(id),
user_id VARCHAR REFERENCES users(id),
content TEXT NOT NULL,
is_pinned BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT NOW()
);
3. Mensagens Rápidas (QuickMessage)
// Atendeon: QuickMessage.ts
{
shortcode: string, // Ex: "/preco", "/horario"
message: string,
mediaPath: string, // Anexo opcional
mediaName: string,
userId: number, // Dono da msg rápida
}
Sugestão para XOS:
CREATE TABLE xos_quick_messages (
id SERIAL PRIMARY KEY,
tenant_id INTEGER REFERENCES tenants(id),
shortcode VARCHAR(50) NOT NULL, -- "/preco"
title VARCHAR(200),
content TEXT NOT NULL,
media_url TEXT,
media_type VARCHAR(30), -- image, file, audio
scope VARCHAR(20) DEFAULT 'personal', -- personal, team, company
user_id VARCHAR REFERENCES users(id),
usage_count INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW()
);
4. Agendamento de Mensagens (Schedule)
// Atendeon: Schedule.ts
{
body: string, // Conteúdo da mensagem
sendAt: Date, // Quando enviar
sentAt: Date, // Quando foi enviada
status: string, // pending, sent, failed
contactId: number,
ticketId: number,
mediaPath: string,
}
Sugestão para XOS:
CREATE TABLE xos_scheduled_messages (
id SERIAL PRIMARY KEY,
tenant_id INTEGER REFERENCES tenants(id),
contact_id INTEGER REFERENCES xos_contacts(id),
conversation_id INTEGER REFERENCES xos_conversations(id),
content TEXT NOT NULL,
media_url TEXT,
media_type VARCHAR(30),
scheduled_at TIMESTAMP NOT NULL,
sent_at TIMESTAMP,
status VARCHAR(20) DEFAULT 'pending', -- pending, sent, failed, cancelled
error_message TEXT,
created_by VARCHAR REFERENCES users(id),
created_at TIMESTAMP DEFAULT NOW()
);
5. Tracking de Atendimento (TicketTraking)
// Atendeon: TicketTraking.ts
{
ticketId: number,
startedAt: Date, // Início do atendimento
queuedAt: Date, // Quando entrou na fila
finishedAt: Date, // Quando finalizou
ratingAt: Date, // Quando foi avaliado
chatbotAt: Date, // Quando passou pelo bot
rated: boolean,
}
Sugestão para XOS:
CREATE TABLE xos_conversation_tracking (
id SERIAL PRIMARY KEY,
conversation_id INTEGER REFERENCES xos_conversations(id) UNIQUE,
queued_at TIMESTAMP,
first_response_at TIMESTAMP,
assigned_at TIMESTAMP,
chatbot_ended_at TIMESTAMP,
human_started_at TIMESTAMP,
resolved_at TIMESTAMP,
rated_at TIMESTAMP,
rating_score INTEGER, -- 1-5
rating_comment TEXT,
total_duration_seconds INTEGER, -- calculado
response_time_seconds INTEGER -- calculado
);
6. Conexões WhatsApp (Whatsapp)
// Atendeon: Whatsapp.ts
{
name: string,
session: string, // Dados da sessão Baileys
qrcode: string, // QR code atual
status: string, // CONNECTED, DISCONNECTED, QR
greetingMessage: string,
farewellMessage: string,
complationMessage: string, // Ao finalizar ticket
ratingMessage: string,
expiresTicket: number, // Minutos para expirar
expiresInactiveMessage: string,
maxUseBotQueues: number,
}
Sugestão para XOS:
CREATE TABLE xos_whatsapp_connections (
id SERIAL PRIMARY KEY,
tenant_id INTEGER REFERENCES tenants(id),
name VARCHAR(100) NOT NULL,
phone_number VARCHAR(20),
status VARCHAR(30) DEFAULT 'disconnected', -- connected, disconnected, qr_pending
qr_code TEXT,
session_data JSONB, -- Dados Baileys
greeting_message TEXT,
farewell_message TEXT,
completion_message TEXT,
rating_message TEXT,
out_of_hours_message TEXT,
ticket_expires_minutes INTEGER DEFAULT 1440, -- 24h
inactive_message TEXT,
is_default BOOLEAN DEFAULT false,
last_seen_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE xos_whatsapp_queue_links (
whatsapp_id INTEGER REFERENCES xos_whatsapp_connections(id),
queue_id INTEGER REFERENCES xos_queues(id),
PRIMARY KEY (whatsapp_id, queue_id)
);
Services do Atendeon para Referência
Distribuição de Tickets
O Atendeon usa o conceito de Filas para distribuir leads:
// FindOrCreateTicketService.ts (simplificado)
const ticket = await Ticket.create({
contactId,
whatsappId,
status: "pending", // Aguardando na fila
queueId: defaultQueue.id,
// NÃO atribui userId ainda - fica na fila
});
// UpdateTicketService.ts - Quando atendente pega o ticket
ticket.userId = attendantId;
ticket.status = "open";
Lógica de Round-Robin
// Distribui entre usuários da fila
const usersInQueue = await UserQueue.findAll({
where: { queueId },
include: [{ model: User, where: { online: true }}]
});
// Pega o próximo da lista (round-robin)
const nextUser = usersInQueue[currentIndex % usersInQueue.length];
Chatbot com Opções
// QueueOption.ts - Menu do chatbot
{
title: string, // "Vendas"
option: string, // "1"
message: string, // Resposta quando selecionar
parentId: number, // Para sub-menus
queueId: number,
}
Plano de Implementação
Fase 1: Estrutura Base (1-2 semanas)
- ✅ Criar tabelas:
xos_queues,xos_queue_users - ✅ Criar tabelas:
xos_internal_notes,xos_quick_messages - ✅ Criar tabelas:
xos_scheduled_messages - ✅ Criar tabelas:
xos_conversation_tracking - ✅ Atualizar APIs XOS com novos endpoints
Fase 2: Distribuição de Leads (1 semana)
- Implementar lógica de filas
- Round-robin entre atendentes
- Status: pending → open → resolved
Fase 3: Integração WhatsApp (2-3 semanas)
- Criar
xos_whatsapp_connections - Integrar Baileys existente do projeto
- Sincronizar mensagens com
xos_messages - QR Code e gestão de sessões
Fase 4: Features Avançadas (2 semanas)
- Chatbot com menu de opções
- Horário de funcionamento
- Mensagens automáticas
- Sistema de avaliação
Código que Podemos Reutilizar
1. wbotMessageListener.ts (62KB)
- Lógica completa de recebimento de mensagens
- Tratamento de mídia (áudio, imagem, vídeo)
- Integração com OpenAI
- Fluxo de chatbot
2. providers.ts (79KB)
- Abstração do Baileys
- Gestão de sessões
- Envio de mensagens
3. UpdateTicketService.ts
- Lógica de transferência entre filas
- Tracking de tempos
- Notificações
4. CampaignService/
- Disparo em massa
- Agendamento
- Estatísticas
Comparativo Final
| Aspecto | Atendeon | XOS |
|---|---|---|
| Foco | WhatsApp CRM puro | Plataforma multi-propósito |
| Multi-tenant | Por company | Por tenant |
| ORM | Sequelize | Drizzle |
| Real-time | Socket.IO | Socket.IO |
| Baileys integrado | Baileys separado | |
| AI | OpenAI básico | Manus Agent completo |
| Código | ~500 arquivos | Integrado na Suite |
Vantagens do Atendeon
- Sistema maduro e testado
- Lógica de filas pronta
- Chatbot funcional
Vantagens do XOS
- Arquitetura mais moderna
- IA mais avançada (Manus)
- Integração com ERP
- Multi-canal nativo
Recomendação
Estratégia: Não copiar código diretamente, mas usar como referência para:
- Schema de dados → Adaptar models do Atendeon para Drizzle/PostgreSQL
- Lógica de negócio → Implementar distribuição de leads similar
- Fluxos de chatbot → Replicar QueueOption para menus
- Tracking → Copiar conceito de TicketTraking
Estimativa de Desenvolvimento:
- Estrutura básica: 2-3 semanas
- Integração WhatsApp: 2-3 semanas
- Features completas: 4-6 semanas
Total: ~2 meses para paridade com Atendeon