generalbots/botbook/src/attendance.md
Rodrigo Rodriguez (Pragmatismo) 037db5c381 feat: Major workspace reorganization and documentation update
- Add comprehensive documentation in botbook/ with 12 chapters
- Add botapp/ Tauri desktop application
- Add botdevice/ IoT device support
- Add botlib/ shared library crate
- Add botmodels/ Python ML models service
- Add botplugin/ browser extension
- Add botserver/ reorganized server code
- Add bottemplates/ bot templates
- Add bottest/ integration tests
- Add botui/ web UI server
- Add CI/CD workflows in .forgejo/workflows/
- Add AGENTS.md and PROD.md documentation
- Add dependency management scripts (DEPENDENCIES.sh/ps1)
- Remove legacy src/ structure and migrations
- Clean up temporary and backup files
2026-04-19 08:14:25 -03:00

103 KiB

Attendance Suite - Plano Completo

Visão Geral

O módulo Attendance (Atendimento) é o sistema central de gestão de conversas humano-bot que permite transfers smooth entre o assistente IA e atendentes humanos. Integra nativamente com WhatsApp (inclui voice calls), Telegram, Teams, CRM, Marketing, Email e o motor Basic.

┌─────────────────────────────────────────────────────────────────────────────────┐
│                              ATTENDANCE SUITE                                    │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│   ┌─────────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────────┐   │
│   │   WHATSAPP  │     │  TELEGRAM   │     │     SMS     │     │  INSTAGRAM  │   │
│   │   +Voice    │     │   +Voice    │     │             │     │             │   │
│   └──────┬──────┘     └──────┬──────┘     └──────┬──────┘     └──────┬──────┘   │
│          │                   │                   │                   │           │
│          └───────────────────┴─────────┬─────────┴───────────────────┘           │
│                                          │                                       │
│                                          ▼                                       │
│   ┌─────────────┐               ┌─────────────────┐                             │
│   │  MESSENGER  │               │  LIVEKIT + SIP  │                             │
│   └──────┬──────┘               │  Video/Audio    │                             │
│          │                       │  STT/TTS        │                             │
│          │                       └────────┬────────┘                             │
│          │                                │                                       │
│          │                                ▼                                       │
│   ┌──────┴──────┐               ┌─────────────────┐                             │
│   │    WEB      │               │  ATTENDANCE     │                             │
│   │   Chat      │──────────────►│    ENGINE       │◄────────────               │
│   └─────────────┘               └────────┬────────┘    │                          │
│                                          │             │                          │
│          ┌──────────────────────────────┼─────────────┴───────────┐              │
│          │                              │                         │              │
│          ▼                              ▼                         ▼              │
│   ┌─────────────┐          ┌─────────────────────┐     ┌────────────────────┐ │
│   │     CRM     │          │  DESTINATION CHANNELS│     │    EMAIL           │ │
│   │   MODULE    │          │  ┌────────┐ ┌───────┐│     │    MODULE          │ │
│   └─────────────┘          │  │ TEAMS │ │Google ││     └────────────────────┘ │
│                             │  │       │ │ Chat ││                            │
│   ┌─────────────┐          │  └────────┘ └───────┘│                            │
│   │  MARKETING  │          │  ┌───────┐ ┌───────┐│                            │
│   │   MODULE    │          │  │WhatsApp│ │ Web  ││                            │
│   └─────────────┘          │  │       │ │Console│                            │
│                            │  └───────┘ └───────┘│                            │
│                            └─────────────────────┘                              │
└─────────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────────┐ │ ATTENDANCE SUITE │ ├─────────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ WHATSAPP │ │ TELEGRAM │ │ SMS │ │ INSTAGRAM │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ │ │ │ │ │ └───────────────────┴─────────┬─────────┴───────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────┐ ┌─────────────────┐ ┌────────────┐│ │ │ MESSENGER │ │ LIVEKIT + SIP │ │ TEAMS ││ │ └──────┬──────┘ │ Video/Audio │ └─────┬──────┘│ │ │ │ Screen Share │ │ │ │ ┌──────┴──────┐ └────────┬────────┘ ┌─────┴─────┐│ │ │ SLACK │ │ │ WEB ││ │ └─────────────┘ ▼ └───────────┘│ │ ┌─────────────────────────────────────────────────────────────────────────┐ │ │ │ CHANNEL ROUTER │ │ │ │ • Detecção de canal (whatsapp/telegram/sms/web/instagram/slack/teams) │ │ │ │ • Normalização de mensagens │ │ │ │ • Comandos de atendente (/queue, /take, /resolve, /video, /call) │ │ │ └────────────────────────────────┬────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────────────────┐ │ │ │ ATTENDANCE ENGINE │ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │ QUEUE │ │ ATTENDANT │ │ LLM │ │ MEETING │ │ │ │ │ │ MANAGER │ │ MANAGER │ │ ASSIST │ │ (LiveKit) │ │ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ └────────────────────────────────┬────────────────────────────────────────┘ │ │ │ │ │ ┌─────────────────────────┼─────────────────────────┐ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ CRM │ │ MARKETING │ │ EMAIL │ │ │ │ MODULE │ │ MODULE │ │ MODULE │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────────┘


---

## 1. Integração com Canais (WhatsApp/Telegram/SMS/Web/Instagram/LiveKit/SIP)

### 1.0 Arquitetura de Canais Suportados

┌──────────────────────────────────────────────────────────────────────────────────┐ │ CANAIS DE ATENDIMENTO │ ├──────────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ WHATSAPP │ │ TELEGRAM │ │ SMS │ │ INSTAGRAM │ │ │ │ (Voice) │ │ │ │ (Twilio) │ │ Direct │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ │ │ │ │ │ └────────────────┼─────────────────┼────────────────┘ │ │ │ │ │ │ ▼ ▼ ┌──────────────────────────┐ │ │ ┌────────────────────┐ │ │ DESTINOS ATENDIMENTO │ │ │ │ LIVEKIT + SIP │ │ │ (Teams / Google Chat) │ │ │ │ Video/Audio Calls │ │ │ │ │ │ │ Screen Sharing │────────┼────│ ┌──────────┐ ┌────────┐ │ │ │ │ Voice STT/TTS │ │ │ │ TEAMS │ │GOOGLE │ │ │ │ └────────────────────┘ │ │ │ │ │ CHAT │ │ │ │ │ │ └──────────┘ └────────┘ │ │ │ ┌─────────────┐ │ └──────────────────────────┘ │ │ │ MESSENGER │──────────────────────────┘ │ │ │ Facebook │ │ │ │ └─────────────┘ ┌──────┴──────┐ │ │ │ CHANNEL │ │ │ ┌─────────────┐ │ ROUTER │ │ │ │ WEB │─────────────────────┤ │ │ │ │ Chat │ └───────────────┘ │ │ └─────────────┘ │ └──────────────────────────────────────────────────────────────────────────────────┘


### 1.0.1 Canais de Entrada

| Canal | Tipo | Status | Suporte a Videochamada | Voice (STT/TTS) |
|-------|------|--------|------------------------|-----------------|
| **WhatsApp** | Mensageria | ✅ Estável | ❌ Não | ✅ Sim |
| **Telegram** | Mensageria | ✅ Estável | ✅ Botões | ✅ Sim |
| **SMS** | Mensageria | ✅ Estável | ❌ Não | ❌ Não |
| **Instagram** | Mensageria | ✅ Estável | ❌ Não | ❌ Não |
| **Messenger** | Mensageria | ✅ Parcial | ❌ Não | ❌ Não |
| **Teams** | Mensageria | ✅ Parcial | ✅ Embed | ✅ Sim |
| **Web Chat** | Mensageria | ✅ Estável | ✅ LiveKit | ✅ Sim |
| **LiveKit/SIP** | Video/Audio | ✅ Estável | ✅ Completo | ✅ Completo |

### 1.0.2 Destinos de Atendimento Humano

| Destino | Descrição | Status |
|---------|-----------|--------|
| **Teams** | Atendente recebe no Microsoft Teams | ✅ Implementado |
| **Google Chat** | Atendente recebe no Google Chat | 🔜 Planejado |
| **WhatsApp** | Atendente responde via WhatsApp | ✅ Implementado |
| **Web Console** | Atendente via interface web | ✅ Implementado |

### 1.1 Arquitetura de Mensagens

O Attendance actúa como **middleware** entre os canais de entrada e o motor Basic:

MENSAGEM ENTRADA │ ▼ ┌──────────────────┐ │ CHANNEL ADAPTER │ ──► Detecta canal de origem │ (WhatsApp/TG/ │ │ SMS/Web) │ └────────┬─────────┘ │ ▼ ┌──────────────────┐ │ NEEDS_HUMAN? │ ──► Verifica flag na sessão │ │ │ • false → BASIC │ ──► Processa via motor Basic │ • true → ATD │ ──► Encaminha para atendimento humano └────────┬─────────┘ │ ▼ ┌──────────────────┐ │ RESPONSE │ ──► Retorna resposta ao canal │ ROUTER │ original └──────────────────┘


### 1.2 Fluxo WhatsApp

```python
# Quando cliente envia mensagem via WhatsApp:

1. WhatsAppAdapter recebe webhook
2. SessionLoader verifica needs_human:
   
   IF session.needs_human == true:
       # Routing para Attendance
       attendance_handler.process(session, message, "whatsapp")
   ELSE:
       # Routing para Basic Engine
       basic_engine.execute(session, message)

3. Se attendente responde:
   WhatsAppAdapter.send_message(attendant_response)

1.2.1 WhatsApp Voice (Chamadas de Voz)

O WhatsApp suporta chamadas de voz com STT (Speech-to-Text) e TTS (Text-to-Speech):

┌─────────────────────────────────────────────────────────────────────────────┐
│                    WHATSAPP VOICE CALL FLOW                                  │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   Cliente ──[Liga]──► WhatsApp ──[Webhook]──► BotServer                    │
│                                              │                              │
│                                              ▼                              │
│                                    ┌──────────────────┐                    │
│                                    │  Voice Handler   │                    │
│                                    │  ┌────────────┐  │                    │
│                                    │  │ STT (Whisper)│ │ ──► Texto        │
│                                    │  └────────────┘  │                    │
│                                    └────────┬─────────┘                    │
│                                             │                              │
│                                             ▼                              │
│                                    ┌──────────────────┐                    │
│                                    │  Basic Engine   │                    │
│                                    │  ou Attendance  │                    │
│                                    └────────┬─────────┘                    │
│                                             │                              │
│                                             ▼                              │
│                                    ┌──────────────────┐                    │
│                                    │  TTS (BotModels) │                    │
│                                    │  ┌────────────┐  │                    │
│                                    │  │Coqui/OpenAI│ │ ──► Áudio         │
│                                    │  └────────────┘  │                    │
│                                    └────────┬─────────┘                    │
│                                             │                              │
│                                             ▼                              │
│                              WhatsApp ◄──[Audio]── BotServer               │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Configuração

name,value
whatsapp-voice-response,true
botmodels-url,http://localhost:5000
botmodels-api-key,

Componente BotModels (STT/TTS)

O sistema usa botmodels para processamento de voz:

# botmodels/src/services/speech_service.py

class SpeechService:
    def stt(self, audio_url: str) -> str:
        # Whisper para transcrição
        # Groq como fallback rápido
        pass
    
    def tts(self, text: str, voice: str = "alloy") -> str:
        # Coqui TTS (local)
        # OpenAI TTS
        # Google Translate TTS (fallback)
        pass

Fluxo de Voz no Attendance

1. Cliente liga no WhatsApp
2. WhatsApp envia webhook de chamada
3. Sistema atende e inicia gravação
4. Áudio é processado via STT → Texto
5. Texto é processado:
   
   SE needs_human = true:
       → Attendente recebe transcrição
       → Attendente responde (texto ou voz)
       → Resposta → TTS → Áudio → WhatsApp
   
   SE needs_human = false:
       → Basic Engine processa
       → Resposta → TTS → Áudio → WhatsApp

Comandos de Voz

Comando Descrição
/voice on Ativar respostas de voz
/voice off Desativar respostas de voz
/call Solicitar chamada de volta

Exemplos

' Ativar resposta de voz
SET SESSION "voice_response", true

' Desativar
SET SESSION "voice_response", false

' Verificar se é chamada de voz
IF session.call_type = "voice" THEN
    TALK "Entendi. Deixe-me verificar."
    ' Gera resposta em áudio automaticamente
END IF

1.3 Fluxo: Cliente Diz "Oi" no WhatsApp → Attendente

Este é o cenário mais comum. Quando um cliente inicia conversa com "Oi" no WhatsApp:

┌─────────────────────────────────────────────────────────────────────────────┐
│            FLUXO: CLIENTE DIZ "OI" NO WHATSAPP                            │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  1. CLIENTE ENVIA "Oi"                                                      │
│     │                                                                       │
│     ▼                                                                       │
│  2. WHATSAPP ADAPTER RECEBE WEBHOOK                                        │
│     │                                                                       │
│     ▼                                                                       │
│  3. SESSION LOADER VERIFICA needs_human                                     │
│     │                                                                       │
│     ├─────────────────────────────┬─────────────────────────────────────┐  │
│     │                             │                                     │  │
│     ▼                             ▼                                     │  │
│  needs_human = false          needs_human = true                        │  │
│     │                             │                                     │  │
│     ▼                             ▼                                     │  │
│  BASIC ENGINE              ATTENDANCE QUEUE                               │
│  processa "Oi"              ├── Adiciona à fila                          │  │
│  (bot responde)             ├── Define priority                          │  │
│                             └── Notifica attendants (WebSocket)          │  │
│                                    │                                      │  │
│                                    ▼                                      │  │
│                             ATTENDANTE VÊ NOTIFICAÇÃO                      │  │
│                                    │                                      │  │
│                                    ▼                                      │  │
│                             /take ou clica em "Aceitar"                   │  │
│                                    │                                      │  │
│                                    ▼                                      │  │
│                             CHAT ATIVO                                     │  │
│                             └── Attendente digita resposta                 │  │
│                                    │                                      │  │
│                                    ▼                                      │  │
│                             RESPOSTA → WHATSAPP → CLIENTE                  │  │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

1.3.1 Passo a Passo Detalhado

Passo 1: Cliente envia "Oi" → WhatsApp API → Webhook → BotServer

Passo 2: Sistema verifica needs_human:

fn check_needs_human(session: &UserSession) -> bool {
    session.context_data.get("needs_human")
        .and_then(|v| v.as_bool())
        .unwrap_or(false)
}

Passo 3: Se needs_human = false → Basic Engine processa → Bot responde

Passo 4: Se needs_human = true:

  1. Adiciona à fila de atendimento
  2. Notifica attendants online (WebSocket)
  3. Attendente vê notificação
  4. Attendente clica "Aceitar" ou /take
  5. Attendente digita resposta
  6. Resposta → WhatsApp → Cliente

1.3.2 Attendant Recebe via WhatsApp

Configuração em attendant.csv:

id,name,channel,phone
att-001,Maria Santos,whatsapp,+5511999990001

Notificação:

📱 *Nova conversa*
De: +5511988887777 (João Silva)
Mensagem: Oi

Digite: /take para aceitar

Attendente responde → WhatsApp → Cliente

1.3.3 Attendants via Interface (Users Table)

Não usa mais attendant.csv. Usa a tabela users existente:

┌─────────────────────────────────────────────────────────────────────────────┐
│              ATTENDANTS VIA INTERFACE - users table                          │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │                    CRIAÇÃO DE FILA (UI)                             │   │
│  │  ┌─────────────────────────────────────────────────────────────┐    │   │
│  │  │ Nome da Fila: Suporte WhatsApp                               │    │   │
│  │  │ Descrição: Atendimentos via WhatsApp                        │    │   │
│  │  │                                                              │    │   │
│  │  │ Canais: ☑ WhatsApp ☐ Telegram ☐ Web ☐ Instagram           │    │   │
│  │  │                                                              │    │   │
│  │  │ Usuários (atendentes):                                     │    │   │
│  │  │   ☑ Maria Santos (maria@empresa.com)                       │    │   │
│  │  │   ☑ João Silva (joao@empresa.com)                          │    │   │
│  │  │   ☐ Ana Costa (ana@empresa.com)                            │    │   │
│  │  │                                                              │    │   │
│  │  │ [Criar Fila]                                                │    │   │
│  │  └─────────────────────────────────────────────────────────────┘    │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │                    FILAS CONFIGURADAS                               │   │
│  │  ────────────────────────────────────────────────────────────────   │   │
│  │  📋 Fila                  │ Canais        │ Atendentes │ Status      │   │
│  │  ────────────────────────────────────────────────────────────────   │   │
│  │  Suporte WhatsApp         │ WhatsApp      │ 3 ativos   │ Ativa      │   │
│  │  Vendas                  │ Web, WhatsApp │ 2 ativos   │ Ativa      │   │
│  │  Técnica                 │ Telegram      │ 1 ativo    │ Ativa      │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────────────┘

1.3.4 Modelo de Dados - Filas

-- Tabela de Filas de Atendimento
CREATE TABLE attendance_queues (
    id UUID PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    description TEXT,
    channels JSONB DEFAULT '["whatsapp"]',
    is_active BOOLEAN DEFAULT true,
    priority_order INTEGER DEFAULT 0,
    max_wait_seconds INTEGER DEFAULT 600,
    auto_assign BOOLEAN DEFAULT true,
    bot_id UUID REFERENCES bots(id),
    created_by UUID REFERENCES users(id),
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Membros da Fila (users ↔ queue)
CREATE TABLE attendance_queue_members (
    id UUID PRIMARY KEY,
    queue_id UUID REFERENCES attendance_queues(id),
    user_id UUID REFERENCES users(id),
    is_active BOOLEAN DEFAULT true,
    max_conversations INTEGER DEFAULT 5,
    priority INTEGER DEFAULT 0,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

1.3.5 API de Filas

// Criar fila
POST /api/attendance/queues
{
    "name": "Suporte WhatsApp",
    "channels": ["whatsapp"],
    "user_ids": ["uuid-1", "uuid-2"]
}

// Adicionar usuário à fila
POST /api/attendance/queues/{id}/members
{"user_id": "uuid", "max_conversations": 5}

1.3.6 Atender Cliente Existente do CRM

// 1. Busca cliente no CRM
let customer = crm_contacts::table
    .filter(crm_contacts::phone.eq(phone))
    .first::<CrmContact>(conn)?;

// 2. Seleciona fila pelo canal
let queue = attendance_queues::table
    .filter(attendance_queues::channels.contains("whatsapp"))
    .filter(attendance_queues::is_active.eq(true))
    .first::<AttendanceQueue>(conn)?;

// 3. Seleciona próximo atendente (round-robin)
let member = attendance_queue_members::table
    .filter(attendance_queue_members::queue_id.eq(queue.id))
    .filter(attendance_queue_members::is_active.eq(true))
    .order(attendance_queue_members::priority.asc())
    .first::<QueueMember>(conn)?;

// 4. Associa ao usuário
let session = UserSession {
    needs_human: true,
    assigned_to: Some(member.user_id),  // ← users.id
    queue_id: Some(queue.id),
    customer_id: Some(customer.id),  // ← CRM contact
    ..
};

1.3.7 Fluxo com Cliente CRM

Cliente CRM existente
    │
    ▼
Envia mensagem WhatsApp
    │
    ▼
Identifica canal → fila específica
    │
    ▼
Seleciona próximo atendente (users)
    │
    ▼
Attendant vê dados do CRM:
  "João Silva - joao@email.com"
  "Cliente desde: 2022"
  "Total compras: R$ 5.000"
    │
    ▼
Responde
    │
    ▼
Ticket.assigned_to = users.id
Ticket.customer_id = crm_contacts.id

1.3.8 Console Web

┌─────────────────────────────────────────────────────────────────┐
│                    FILA DE ATENDIMENTO                          │
├─────────────────────────────────────────────────────────────────┤
│  🎫 #1 - Maria Santos (Você)                                    │
│     WhatsApp • João Silva (+55 11 98888-7777)                  │
│     "Oi" • 30s                                                  │
│     [Resolver] [Transferir]                                     │
│                                                                 │
│  🎫 #2 - João Silva                                             │
│     WhatsApp • Cliente Novo                                     │
│     "Preciso de ajuda" • 2min                                  │
│     [Aceitar]                                                   │
└─────────────────────────────────────────────────────────────────┘

1.3.5 WebSocket Notificação

{
  "type": "new_conversation",
  "session_id": "abc-123",
  "channel": "whatsapp",
  "customer": {"name": "João Silva", "phone": "+5511988887777"},
  "message": "Oi"
}

1.4 Fluxo Telegram

Mesma lógica do WhatsApp, com comandos específicos:

/start - Iniciar conversa
/agent - Solicitar atendente humano
/queue - Ver fila (atendente)
/resolve - Encerrar atendimento (atendente)

1.4 Fluxo SMS

SMS recebido → Normalizar → Verificar needs_human →
  → Se true: Attendance (com limite de 160 chars)
  → Se false: Basic Engine

1.5 Modo Bypass (Midleman)

O Attendance pode actuar como midleman puro (sem IA):

┌────────────┐     ┌────────────┐     ┌────────────┐
│  CLIENTE   │────►│   BOT      │────►│ ATENDENTE  │
│  (WhatsApp)│     │ (Attendance│     │  HUMANO    │
│            │◄────│   Bypass)  │◄────│            │
└────────────┘     └────────────┘     └────────────┘

Configuração:

name,value
attendance-bypass-mode,true
attendance-auto-transfer,true
attendance-transfer-keywords,human,atendente,pessoa,atendimento

1.6 Transferência para Teams

O attendance pode enviar a conversa para Microsoft Teams onde o atendente recebe a mensagem:

┌─────────────────────────────────────────────────────────────────────────────┐
│                  TRANSFER TO TEAMS FLOW                                      │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   Cliente        Bot                     Attendance      Microsoft Teams      │
│   (WhatsApp)                                                       (Atendente)  │
│       │             │                         │                  │           │
│       │────────────►│                         │                  │           │
│       │  Mensagem  │                         │                  │           │
│       │             │                         │                  │           │
│       │  (precisa  │                         │                  │           │
│       │   humano)  │                         │                  │           │
│       │             │                         │                  │           │
│       │             ├────────────────────────►│                  │           │
│       │             │  TRANSFER TO HUMAN      │                  │           │
│       │             │  destination=teams      │                  │           │
│       │             │                         │                  │           │
│       │             │                         ├─────────────────►│           │
│       │             │                         │  Mensagem Teams │           │
│       │             │                         │                  │           │
│       │◄────────────┤◄────────────────────────┤  Resposta       │           │
│       │  Resposta  │   (forwarded back)      │                  │           │
│       │             │                         │                  │           │
└─────────────────────────────────────────────────────────────────────────────┘

Configuração Teams

name,value
teams-enabled,true
teams-app-id,
teams-app-password,
teams-tenant-id,
teams-bot-id,
attendance-default-destination,teams

Transferir para Teams

' Transferir para Teams
TRANSFER TO HUMAN "support", "normal", "Cliente precisa de ajuda", "teams"

' Ou especificar o destino
result = TRANSFER TO HUMAN({
    department: "support",
    destination: "teams"
})

Comandos no Teams

O atendente pode usar comandos no Teams:

/resolve - Encerrar atendimento
/transfer @nome - Transferir para outro atendente
/queue - Ver fila
/context - Ver contexto do cliente

1.7 Transferência para Google Chat

Planejado para futuras implementações:

┌─────────────────────────────────────────────────────────────────────────────┐
│              GOOGLE CHAT DESTINATION (PLANEJADO)                             │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   Cliente ──► WhatsApp ──► Bot ──► Attendance ──► Google Chat ──► Atendente │
│                                                                           │
│   Configuração futura:                                                     │
│   name,value                                                              │
│   google-chat-enabled,true                                                │
│   google-chat-bot-token,                                                  │
│   google-chat-space-id,                                                   │
│                                                                           │
└─────────────────────────────────────────────────────────────────────────────┘

1.6.1 Teams Voice Calls

O Teams suporta chamadas de voz e vídeo diretamente:

name,value
teams-voice-enabled,true
teams-meeting-enabled,true
' Criar reunião Teams para atendimento
result = CREATE MEETING({
    "type": "teams",
    "title": "Suporte - " + customer.name,
    "participants": [customer.email]
})

TALK "Vou iniciar uma reunião Teams com você."
TALK result.join_url

1.10 Instagram Direct

1.10.1 Configuração

name,value
instagram-enabled,true
instagram-access-token,
instagram-app-secret,
instagram-webhook-verify-token,

1.10.2 Fluxo

Instagram User → Instagram API → Webhook → Channel Router → Attendance
                                                                    ↓
                                              needs_human=true → Fila de Atendimento
                                                                    ↓
                                              Atendente responde → Instagram API → User

1.10.3 Limitações do Instagram

Recurso Suporte Observação
Texto Suportado
Imagens Download e reenvio
Vídeos Download e reenvio
Áudio ⚠️ Limitado
Videochamada Não disponível na API
Compartilhamento de tela Não disponível

1.10.4 Workaround para Videochamada

Quando cliente Instagram precisa de videochamada:

' Instagram não suporta videochat nativo
' Ofereça alternativas:

TALK "Para melhor atendê-lo, gostaria de fazer uma videochamada?"
TALK "Posso criar uma sala de reunião agora. Clique no link:"
TALK meeting_link

' Attendente cria reunião via comando
' /video ou /call

1.11 LiveKit + SIP (Videochamadas)

1.11.1 Arquitetura LiveKit

O sistema já possui integração com LiveKit para videochamadas:

┌─────────────────────────────────────────────────────────────────────────────┐
│                          LIVEKIT INTEGRATION                                 │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ┌─────────────┐    ┌──────────────┐    ┌─────────────────────────────┐  │
│  │  Attendance │───►│ Meeting      │───►│ LiveKit Room                 │  │
│  │   Queue     │    │   Service    │    │ ┌─────────────────────────┐ │  │
│  └─────────────┘    └──────────────┘    │ │ • Video (WebRTC)         │ │  │
│                                           │ │ • Audio                  │ │  │
│  ┌─────────────┐    ┌──────────────┐    │ │ • Screen Sharing         │ │  │
│  │  Atendente  │───►│ Token        │───►│ │ • Transcription (AI)     │ │  │
│  │  Browser    │    │   Generator  │    │ │ • Recording              │ │  │
│  └─────────────┘    └──────────────┘    │ │ • Whiteboard             │ │  │
│                                           │ └─────────────────────────┘ │  │
│  ┌─────────────┐    ┌──────────────┐    │ │                           │  │
│  │   Cliente   │───►│ Join URL     │───►│ │ SIP Gateway (futuro)     │  │
│  │  Browser    │    │              │    │ │ • PSTN inbound           │  │
│  └─────────────┘    └──────────────┘    │ │ • PSTN outbound          │  │
│                                           │ │ • SIP trunk              │  │
│                                           └───────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────────────┘

1.11.2 Configuração LiveKit

name,value

# LiveKit Core
livekit-url,wss://livekit.yourserver.com
livekit-api-key,
livekit-api-secret,
livekit-room-prefix,attendance-

# SIP Configuration (futuro)
sip-enabled,false
sip-trunk-name,
sip-phone-number,
sip-inbound-route,
sip-outbound-route,

# Recording
livekit-recording-enabled,true
livekit-storage-bucket,recordings

# Transcription
livekit-transcription-enabled,true
transcription-language,pt-BR

1.11.3 Iniciar Videochamada no Attendance

Comando do Atendente:

/video - Iniciar videochamada
/video link - Gerar link para cliente
/video invite @cliente - Convidar para sala ativa
/video end - Encerrar videochamada

Comando BASIC:

' Criar sala de reunião para atendimento
result = CREATE MEETING({
    "title": "Atendimento - " + customer.name,
    "type": "support",
    "expires_in": 3600,
    "max_participants": 2,
    "recording": false,
    "transcription": true
})

IF result.success THEN
    SET SESSION "meeting_room", result.room_id
    SET SESSION "meeting_url", result.join_url
    
    TALK "Vou iniciar uma videochamada para melhor atendê-lo."
    TALK result.join_url
    
    ' Notifica atendente
    NOTIFY attendant, "Cliente entrou na sala: " + result.join_url
END IF

1.11.4 Compartilhamento de Tela

Durante videochamada:

' Atendente pode compartilhar tela
' Cliente pode compartilhar tela

' Detectar compartilhamento
IF meeting.participant.shared_screen THEN
    TALK "Cliente está compartilhando a tela"
END IF

' Solicitar compartilhamento
meeting.request_screen_share(participant_id)

1.11.5 Fluxo de Videochamada no Attendance

1. Cliente entra em contato (qualquer canal)
2. Atendente aceita o atendimento
3. Atendente decide fazer videochamada:
   /video

4. Sistema cria sala LiveKit
5. Sistema gera link de acesso
6. Envia link para cliente (mesmo canal ou email)

7. Cliente clica no link
8. Navegador abre → Permissões de câmera/microfone
9. Entra na sala de videochamada

10. Ambos (atendente + cliente) podem:
    • Ver vídeo
    • Ouvir áudio
    • Compartilhar tela
    • Ver transcrição ao vivo
    • Usar whiteboard

11. /resolve → Encerrar atendimento
12. Sala é fechada ou arquivada

1.11.6 API de Meeting

// Endpoints disponíveis em botserver/src/meet/mod.rs

POST /api/meet/create           // Criar sala
GET  /api/meet/rooms            // Listar salas
GET  /api/meet/rooms/{id}       // Obter sala
POST /api/meet/rooms/{id}/join  // Entrar na sala
POST /api/meet/token            // Gerar token
POST /api/meet/transcription    // Iniciar transcrição
POST /api/meet/invite           // Enviar convite

// WebSocket
WS  /api/meet/ws               // WebSocket de meeting

// Conversations
POST /api/meet/conversations/create
POST /api/meet/conversations/{id}/join
POST /api/meet/conversations/{id}/calls/start

1.12 SIP Gateway (Futuro)

1.12.1 Arquitetura SIP

┌─────────────────────────────────────────────────────────────────────────────┐
│                           SIP GATEWAY (PLANEJADO)                           │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   PSTN Network                                                             │
│        │                                                                    │
│        ▼                                                                    │
│  ┌─────────────┐      ┌──────────────┐      ┌─────────────────────────┐   │
│  │   SIP       │─────►│   LiveKit    │─────►│   Attendance           │   │
│  │   Trunk     │      │   Gateway    │      │   Queue                │   │
│  └─────────────┘      └──────────────┘      └─────────────────────────┘   │
│                              │                                              │
│                     ┌────────┴────────┐                                    │
│                     │                 │                                    │
│                     ▼                 ▼                                    │
│              ┌────────────┐    ┌────────────┐                            │
│              │   Inbound  │    │  Outbound  │                            │
│              │   Calls    │    │   Calls    │                            │
│              └────────────┘    └────────────┘                            │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

1.12.2 Casos de Uso SIP

Cenário Descrição
Inbound Cliente liga para número fixo → Direcionado para fila de atendimento
Outbound Atendente faz ligação para cliente → ID do atendimento
Callback Cliente agenda retorno → Sistema liga na hora marcada
IVR Menu de opções antes de entrar na fila

1.12.3 Comandos SIP

/call - Iniciar ligação
/call back - Ligar de volta
/callback 5511999999999 - Agendar retorno
/hangup - Desligar
/hold - Colocar em espera
/transfer - Transferir ligação

2. Integração com CRM Module

2.1 Dados do Cliente em Tempo Real

O Attendance partilha dados com CRM para contexto do atendente:

// attendance/queue.rs - dados do cliente disponíveis
struct QueueItem {
    session_id: Uuid,
    user_id: Uuid,
    bot_id: Uuid,
    channel: String,
    // Campos CRM
    user_name: String,
    user_email: Option<String>,
    user_phone: Option<String>,
    // Contexto adicional
    last_message: String,
    priority: i32,
    assigned_to: Option<Uuid>,
}

2.2 Busca Automática de Dados CRM

' Quando transfer para humano, busca dados do CRM
TRANSFER TO HUMAN "support"

' O sistema automaticamente busca:
customer = FIND "customers", "phone='" + session.phone + "'"
IF customer FOUND THEN
    SET SESSION "customer_name", customer.name
    SET SESSION "customer_tier", customer.tier
    SET SESSION "customer_lifetime_value", customer.ltv
END IF

2.3 Campos CRM Disponíveis

Campo Descrição Exemplo
customer_id ID único do cliente cust-001
name Nome completo João Silva
email Email joao@email.com
phone Telefone +5511999999999
tier Tier do cliente premium, gold, standard
ltv Lifetime Value 15000.00
last_purchase Última compra 2024-01-15
tags Tags do cliente vip,dev,nps-9

2.4 Automação CRM via Attendance

' Regra: Se cliente premium, transfere com alta prioridade
customer = FIND "customers", "phone='" + session.phone + "'"

IF customer.tier = "premium" THEN
    TRANSFER TO HUMAN "vip-support", "high", "Cliente premium"
ELSE
    TRANSFER TO HUMAN "support"
END IF

2.5 Logging de Atendimento

name,value
attendance-crm-logging,true
attendance-log-fields,session_id,customer_id,attendant_id,start_time,end_time,sentiment

3. Integração com Marketing Module

3.1 Campanhas de Proactive Outreach

O Attendance pode iniciar conversas via Marketing:

# Marketing module.trigger_attendance()
# Envia mensagem proativa e marca needs_human=true

MENSAGEM: "Olá João! Temos uma oferta especial para você."
           "[Atendente disponível para conversar]"

SET SESSION "needs_human", true
SET SESSION "campaign_id", "summer-sale-2024"
SET SESSION "lead_source", "marketing-campaign"

3.2 Dados de Campanha em Attendance

Campo Descrição
campaign_id ID da campanha营销
campaign_name Nome da campanha
utm_source Fonte UTM
utm_medium Medio UTM
ad_id ID do anúncio
segment Segmento do lead

3.3 Qualification de Leads

' Após atendimento, marca lead como qualificationado
IF attendant.resolved THEN
    customer = FIND "customers", "phone='" + session.phone + "'"
    
    IF customer NOT FOUND THEN
        ' Cria novo lead
        CREATE "leads", {
            "name": session.user_name,
            "phone": session.phone,
            "source": session.lead_source,
            "status": "contacted",
            "attendant_id": attendant.id,
            "notes": conversation.summary
        }
    ELSE
        ' Atualiza existente
        UPDATE "customers", customer.id, {
            "status": "qualified",
            "last_contact": NOW(),
            "attendant_id": attendant.id
        }
    END IF
END IF

4. Integração com Email Module

4.1 Notifications por Email

O Attendance pode enviar emails de notificação:

name,value
attendance-email-notify,true
attendance-email-template,attendant-assignment
attendance-email-recipient,attendant
attendance-email-bcc,supervisor@empresa.com

4.2 Tipos de Notificação

Tipo Quando Destinatário
new_assignment Nova conversa atribuída Atendente
queue_alert Fila > 10 conversas Supervisor
customer_waiting Cliente aguardando > 5min Atendente
sla_breach SLA violado Gerente
resolved Atendimento encerrado Cliente (opcional)

4.3 Email como Canal de Resposta

# Se cliente não está no WhatsApp, pode responder por email

IF channel = "email" THEN
    # Renderiza template de resposta
    response = EMAIL.render(
        template="attendant-response",
        data={
            "customer_name": session.user_name,
            "message": attendant.message,
            "attendant_name": attendant.name,
            "company": config.company_name
        }
    )
    
    EMAIL.send(
        to=customer.email,
        subject=f"Resposta: {original_subject}",
        body=response
    )
END IF

5. Integração com Bot e Basic Engine

5.1 Palavra-chave TRANSFER TO HUMAN

' Transferência simples
TRANSFER TO HUMAN

' Transferência com destino específico
TRANSFER TO HUMAN "João Silva"
TRANSFER TO HUMAN "suporte técnico"
TRANSFER TO HUMAN "vendas", "high"

' Transferência com contexto
TRANSFER TO HUMAN "suporte", "normal", "Cliente com problema no pagamento"

5.2 Estados da Sessão

struct UserSession {
    id: Uuid,
    bot_id: Uuid,
    user_id: Uuid,
    // Flag principal de attendance
    needs_human: bool,
    
    // Dados do attendance
    context_data: HashMap<String, Value> {
        "attendant_id": "att-001",
        "attendant_name": "Maria",
        "queue_position": 3,
        "transfer_reason": "Problema técnico",
        "transfer_time": "2024-01-15T10:30:00Z",
    }
}
' Checar se precisa de humano
IF session.needs_human THEN
    TALK "Você está em atendimento humano."
END IF

' Obter posição na fila
position = session.queue_position

' Obter atendente atual
attendant = session.attendant_id

' Retornar para bot (apenas atendente)
SET SESSION "needs_human", false

5.4 API REST de Attendance

# Endpoints disponíveis

GET  /api/attendance/queue                 # Lista fila
GET  /api/attendance/attendants            # Lista atendentes
POST /api/attendance/assign                # Atribui conversa
POST /api/attendance/transfer              # Transfere entre atendentes
POST /api/attendance/resolve/<session_id>  # Resolve atendimento
GET  /api/attendance/insights              # Métricas

# Endpoints LLM Assist
POST /api/attendance/llm/tips              # Dicas IA
POST /api/attendance/llm/polish             # Polir mensagem
POST /api/attendance/llm/smart-replies     # Respostas sugeridas
GET  /api/attendance/llm/summary/<id>      # Resumo conversa
POST /api/attendance/llm/sentiment         # Análise sentimento

6. Arquitetura de Filas e Atendentes

6.1 Estrutura de Dados

// Queue Item - Item na fila de atendimento
struct QueueItem {
    session_id: Uuid,
    user_id: Uuid,
    bot_id: Uuid,
    channel: String,          // whatsapp, telegram, sms, web
    user_name: String,
    user_email: Option<String>,
    last_message: String,
    waiting_time_seconds: i64,
    priority: i32,          // 0=low, 1=normal, 2=high, 3=urgent
    status: QueueStatus,    // waiting, assigned, active, resolved
    assigned_to: Option<Uuid>,
    assigned_to_name: Option<String>,
}

// Attendant - Atendente humano
struct Attendant {
    id: String,             // att-001
    name: String,
    channel: String,        // all, whatsapp, telegram, web
    preferences: String,    // sales, support, technical
    department: Option<String>,
    status: AttendantStatus, // online, busy, away, offline
    active_conversations: i32,
}

6.2 Status de Atendentes

Status Descrição Recebe Novas Conversas?
online Disponível Sim
busy Em atendimento Não
away Temporariamente indisponível Não
offline 离线 Não

6.3 Prioridades de Conversa

Prioridade Valor Uso
low 0 Consultas gerais
normal 1 Padrão
high 2 Clientes VIP, tempo-sensível
urgent 3 Escalações, reclamações

6.4 Routing Inteligente

def route_to_attendant(session, attendants):
    # 1. Filtra por canal
    eligible = [a for a in attendants 
                if a.channel in ["all", session.channel]]
    
    # 2. Filtra por status
    eligible = [a for a in eligible if a.status == "online"]
    
    # 3. Ordena por carga de trabalho
    eligible.sort(key=lambda a: a.active_conversations)
    
    # 4. Aplica preferências
    if session.topic:
        preferred = [a for a in eligible 
                    if a.preferences == session.topic]
        if preferred:
            return preferred[0]
    
    # 5. Retorna menor carga
    return eligible[0] if eligible else None

7. Módulo LLM Assist

7.1 Funcionalidades

Funcionalidade Descrição Comando WhatsApp
tips Dicas para o atendente /tips
polish Polir mensagem antes de enviar /polish <msg>
smart-replies Respostas sugeridas /replies
summary Resumo da conversa /summary
sentiment Análise de sentimento Automático

7.2 Exemplo de Uso

Cliente: Preciso.cancelar meu pedido

Atendente: /tips
Bot: 💡 Dicas:
    • Cliente quer cancelar pedido
    • Pergunte o número do pedido
    • Verifique política de cancelamento

Atendente: /polish Gostaria de me ajudar com o cancelamento
Bot: ✨ Polido:
    "Olá! Ficarei feliz em ajudá-lo com o cancelamento."

Atendente: Olá! Ficarei feliz em ajudá-lo com o cancelamento.
[Enviado para cliente]

8. Configuração Completa

8.1 config.csv

name,value

# === ATENDIMENTO BÁSICO ===
crm-enabled,true
attendance-enabled,true

# === FILA ===
attendance-queue-size,50
attendance-max-wait-seconds,600
attendance-priority-default,normal

# === ATENDENTES ===
attendance-auto-assign,true
attendance-slack-webhook,

# === CANAIS ===
attendance-whatsapp-commands,true
attendance-telegram-commands,true

# === BYPASS MODE ===
attendance-bypass-mode,false
attendance-auto-transfer,false
attendance-transfer-keywords,human,atendente,pessoa,falar com

# === LLM ASSIST ===
attendant-llm-tips,true
attendant-polish-message,true
attendant-smart-replies,true
attendant-auto-summary,true
attendant-sentiment-analysis,true

# === CRM INTEGRATION ===
attendance-crm-logging,true
attendance-customer-fields,name,email,phone,tier,ltv

# === EMAIL NOTIFICATIONS ===
attendance-email-notify,false
attendance-email-template,attendant-response

8.2 attendant.csv

id,name,channel,preferences,department,aliases,phone,email
att-001,Maria Santos,all,sales,commercial,maria;mari,5511999990001,maria@empresa.com
att-002,João Silva,whatsapp;web,support,support,joao;js,5511999990002,joao@empresa.com
att-003,Ana Costa,telegram,technical,engineering,ana;anc,5511999990003,ana@empresa.com
att-004,Pedro Oliveira,all,collections,finance,pedro;po,5511999990004,pedro@empresa.com

9. Fluxos de Conversa

9.1 Fluxo 1: Cliente Solicita Humano

Cliente: Quero falar com uma pessoa
    │
    ▼
Bot detecta keyword "pessoa"
    │
    ▼
TRANSFER TO HUMAN
    │
    ├──► needs_human = true
    ├──► Adiciona à fila
    ├──► Notifica atendentes (WebSocket)
    └──► Envia "Aguarde, transferir para atendente..."
    │
    ▼
Atendente recebe notificação
    │
    ▼
Atendente aceita /take
    │
    ▼
Chat entre cliente e atendente
    │
    ▼
Atendente /resolve
    │
    ├──► needs_human = false
    └──► Volta para Bot

9.2 Fluxo 2: Bot Transfere Automaticamente

Cliente: Não consigo acessar minha conta
    │
    ▼
Bot tenta resolver (3 tentativas)
    │
    ├──► Falha → Analisa sentimento
    │
    ▼
IF sentiment.score < -0.5 OR intent = "escalate" THEN
    │
    ▼
    TRANSFER TO HUMAN "support", "high", "Tentativas=3, Sentimento=negativo"

9.3 Fluxo 3: Bypass Mode (Midleman)

Cliente: (mensagem WhatsApp)
    │
    ▼
Attendance detecta:
    needs_human = true (via config bypass)
    attendance-bypass-mode = true
    │
    ▼
SEM passar pelo Basic Engine
    │
    ├──► Direto para fila
    └──► Notifica atendentes
    │
    ▼
Atendente responde
    │
    ▼
Response enviada diretamente para WhatsApp

9.4 Fluxo 4: Videochamada (LiveKit)

Cliente: Preciso de ajuda com problema técnico
    │
    ▼
Bot tenta resolver (3 tentativas)
    │
    ▼
IF complexidade > threshold THEN
    │
    ▼
    TRANSFER TO HUMAN "suporte técnico"
    │
    ▼
Atendente aceita
    │
    ▼
Atendente: /video
    │
    ├──► Cria sala LiveKit
    ├──► Gera link de acesso
    └──► Envia link para cliente
    │
    ▼
Cliente acessa link
    │
    ├──► Pede permissão câmera/mic
    ├──► Entra na sala
    └──► Vídeochat dimulai
    │
    ├──► Compartilhamento de tela
    ├──► Whiteboard
    └──► Transcrição em tempo real
    │
    ▼
/resolve → Sala encerrada
    │
    ├──► Gravação disponível (se enabled)
    ├──► Transcrição salva
    └──► Retorna para Bot

9.5 Fluxo 5: Videochamada Direta (cliente inicia)

Cliente: (do WhatsApp)
Quero fazer videochamada
    
    │
    ▼
Bot detecta intent = "video_call"
    │
    ▼
TALK "Vou criar uma sala de videochamada para você."
    
    │
    ▼
CREATE MEETING({type: "support"})
    │
    ▼
TALK "Clique no link para entrar: " + meeting_url
    
    │
    ▼
Atendente já está na sala esperando
    │
    ▼
Cliente entra → Videochamada inicia

10. Métricas e Analytics

10.1 KPIs de Atendimento

KPI Descrição Meta
avg_wait_time Tempo médio de espera < 60s
first_response_time Tempo até 1ª resposta < 30s
resolution_rate Taxa de resolução > 85%
customer_satisfaction NPS pós-atendimento > 7
attendant_utilization Utilização dos atendentes > 70%
transfers_rate Taxa de transferência < 20%

10.1.1 KPIs de Videochamada

KPI Descrição Meta
video_call_requests Solicitações de videochamada -
video_calls_completed Videochamadas completadas > 80%
avg_video_duration Duração média de videochamadas < 15min
screen_share_usage Uso de compartilhamento de tela > 40%
transcription_accuracy Acurácia da transcrição > 90%

10.2 Dashboard

┌────────────────────────────────────────────┐
│         ATTENDANCE DASHBOARD               │
├────────────────────────────────────────────┤
│                                            │
│  FILA: 5 │ ATENDENTES: 8/10 │ ONLINE: 6    │
│                                            │
│  ┌─────────────┐ ┌─────────────┐          │
│  │ TEMPO MÉDIO │ │ RESOLUÇÃO   │          │
│  │   45s       │ │   92%       │          │
│  └─────────────┘ └─────────────┘          │
│                                            │
│  POR CANAL:                                │
│  WhatsApp  ████████████ 65%                │
│  Web       ██████ 25%                      │
│  Telegram  ██ 10%                          │
│                                            │
└────────────────────────────────────────────┘

11. Casos de Uso

11.1 E-commerce - Suporte

  1. Cliente pergunta sobre pedido
  2. Bot tenta resolver com informações do pedido
  3. Se não conseguir após 3 tentativas → TRANSFER TO HUMAN "suporte"
  4. Atendente recebe contexto completo (pedido, cliente)
  5. Atendente resolve → /resolve
  6. Sistema cria/atualiza ticket no CRM

11.2 Vendas - Qualificação

  1. Lead entra via WhatsApp (campanha)
  2. Bot faz qualificação inicial
  3. Se lead = "quente" → TRANSFER TO HUMAN "vendas", "high"
  4. Atendente de vendas recebe com dados do lead
  5. Atendente fecha venda → /resolve
  6. Sistema cria oportunidade no CRM

11.3 Cobrança - Negociação

  1. Cliente em atraso recebe mensagem proativa
  2. Se cliente responde → needs_human = true
  3. Atendente de cobrança recebe
  4. Negocia dívida → registra no CRM
  5. /resolve → cliente volta para fluxo de cobrança

11.4 Suporte Técnico - Escalação

  1. Cliente reporta problema técnico
  2. Bot tenta solução básica
  3. Se complexidade > threshold → TRANSFER TO HUMAN "técnico"
  4. Atendente técnico com acesso a sistema
  5. Resolve ou escala para equipe de TI

12. Troubleshooting

12.1 Problemas Comuns

Problema Causa Solução
Mensagem não vai para atendente crm-enabled=false Ativar em config.csv
Atendente não recebe notificação Status != online Verificar attendant.csv
Transfer não encontra ninguém Nenhum atendente online Configurar horário ou fallback
Cliente preso em modo humano /resolve não executado Executar manualmente
WhatsApp não entrega resposta Phone inválido Verificar país + número

12.2 Problemas de Videochamada

Problema Causa Solução
Link de videochamada não funciona Sala expirada Gerar novo link
Cliente sem câmera/mic Permissão negada Orientar cliente
Videochamada trava Rede instável Reduzir qualidade
Transcrição não funciona API key inválida Verificar config
Gravação não inicia Storage cheio Limpar espaço

12.3 Debug

# Ver fila de atendimento
GET /api/attendance/queue

# Ver atendentes
GET /api/attendance/attendants

# Ver sessão específica
GET /api/session/<session_id>

# Logs de attendance
grep "attendance" botserver.log

13. Evolução Futura

13.1 Features Planejadas

  • Multi-tenant - Múltiplas empresas
  • Skills-based routing - Routing por habilidade
  • SLA alerts - Alertas de SLA
  • Chatbot cobros - Chatbot para cobrança
  • Video call - Implementado (LiveKit)
  • Screen sharing - Implementado
  • Co-browse - Compartilhamento de tela
  • Knowledge base - Base de conhecimento
  • Canned responses - Respostas pré-definidas

13.2 Integrações Atuais e Futuras

Canais de Entrada (Implementados)

Canal Status Voice (STT/TTS)
WhatsApp Estável Implementado
Telegram Estável Implementado
Instagram Parcial Não
Messenger Parcial Não
Teams Parcial Implementado
Web Chat Estável Implementado
SMS Estável Não
LiveKit/SIP Estável Completo

Destinos de Atendimento Humano

Destino Status Descrição
Teams Implementado Atendente recebe no MS Teams
Google Chat 🔜 Planejado Atendente recebe no Google Chat
WhatsApp Implementado Atendente responde via WA
Web Console Implementado Interface web

Features Planejadas

  • Multi-tenant - Múltiplas empresas
  • Skills-based routing - Routing por habilidade
  • SLA alerts - Alertas de SLA
  • Chatbot cobros - Chatbot para cobrança
  • Video call - Implementado (LiveKit)
  • Screen sharing - Implementado
  • WhatsApp Voice - Implementado (STT/TTS)
  • Teams Voice - Implementado
  • Co-browse - Compartilhamento de tela
  • Knowledge base - Base de conhecimento
  • Canned responses - Respostas pré-definidas
  • SIP Gateway - Planejado
  • PSTN Calls - Planejado

15. Kanban View para Fila de Atendimento

15.1 Visão Geral

O Kanban é uma view visual para gerenciar a fila de atendimento, permitindo arrastar cards entre colunas.

┌─────────────────────────────────────────────────────────────────────────────┐
│                         KANBAN - FILA DE ATENDIMENTO                        │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐       │
│  │   NOVOS     │  │  EM ATEND.  │  │  AGUARDANDO │  │  RESOLVIDOS │       │
│  │  (New)      │  │  (Active)   │  │  (Pending)  │  │  (Done)     │       │
│  ├─────────────┤  ├─────────────┤  ├─────────────┤  ├─────────────┤       │
│  │ ┌─────────┐ │  │ ┌─────────┐ │  │ ┌─────────┐ │  │ ┌─────────┐ │       │
│  │ │ Card #1 │ │  │ │ Card #3 │ │  │ │ Card #5 │ │  │ │ Card #7 │ │       │
│  │ │ João    │ │  │ │ Maria   │ │  │ │ Ana     │ │  │ │ Resolv. │ │       │
│  │ │ WhatsApp │ │  │ │ WhatsApp│ │  │ │ Telegram│ │  │ │ 15min   │ │       │
│  │ └────┬────┘ │  │ └────┬────┘ │  │ └────┬────┘ │  │ └─────────┘ │       │
│  │      ▼      │  │      │      │  │      ▼      │  │             │       │
│  │ ┌─────────┐ │  │      └──────┼──►│             │  │             │       │
│  │ │ Card #2 │ │  │             │  │             │  │             │       │
│  │ │ Carlos  │ │  │             │  │             │  │             │       │
│  │ │ Instagram│ │  │             │  │             │  │             │       │
│  │ └─────────┘ │  │             │  │             │  │             │       │
│  └─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘       │
│                                                                             │
│ drag & drop → mover cards entre colunas                                    │
└─────────────────────────────────────────────────────────────────────────────┘

15.2 Colunas do Kanban

Coluna Status Descrição
new Novos Clientes aguardando primeiro atendimento
active Em Atendimento Já aceitos por attendant
pending Aguardando Cliente não respondeu
resolved Resolvidos Atendimento concluído

15.3 Estrutura do Card

┌────────────────────────────────────────┐
│ #ID - João Silva                    │
│ ─────────────────────────────────────  │
│ 📱 WhatsApp • +55 11 98888-7777       │
│ 💬 "Preciso de ajuda com meu pedido"  │
│ ─────────────────────────────────────  │
│ ⏱️ 5min │ Prioridade: Alta │ Att: Maria │
│ Tags: [vip] [pedido]                   │
└────────────────────────────────────────┘

15.4 Implementação

API Endpoints

// GET - Listar com grouping por status
GET /api/attendance/kanban?bot_id={id}

// PUT - Mover card entre colunas
PUT /api/attendance/kanban/move
{
    "session_id": "uuid",
    "from_status": "new",
    "to_status": "active"
}

Frontend (attendant.js)

// Renderizar Kanban
function renderKanban(queueItems) {
    const columns = {
        new: queueItems.filter(i => i.status === 'waiting'),
        active: queueItems.filter(i => i.status === 'active'),
        pending: queueItems.filter(i => i.status === 'pending'),
        resolved: queueItems.filter(i => i.status === 'resolved')
    };
    
    columns.forEach((items, status) => {
        renderColumn(status, items);
    });
}

// Drag & Drop
function setupDragDrop() {
    document.querySelectorAll('.kanban-card').forEach(card => {
        card.draggable = true;
        card.addEventListener('dragend', handleDragEnd);
    });
}

16. Tickets (Issues) Integrados ao Atendimento

16.1 Conceito

Cada atendimento pode gerar um Ticket/Issue que é rastreado e relacionado ao CRM.

┌─────────────────────────────────────────────────────────────────────────────┐
│                    TICKET INTEGRATION FLOW                                   │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  Cliente (WhatsApp)                                                        │
│       │                                                                     │
│       ▼                                                                     │
│  Attendance Queue ─────► Criar Ticket                                       │
│       │                  │                                                  │
│       │                  ▼                                                  │
│       │            ┌─────────────┐                                         │
│       │            │   Ticket    │                                         │
│       │            │  #TIC-001   │                                         │
│       │            │ Status: Open│                                         │
│       │            │ Priority: H │                                         │
│       │            └──────┬──────┘                                         │
│       │                   │                                                │
│       ▼                   ▼                                                │
│  Attendente           assigned_to (users table)                            │
│       │                   │                                                │
│       │                   ▼                                                │
│       │            CRM / Compliance Issues                                 │
│       │                                                                     │
│       ▼                                                                     │
│  /resolve → Ticket status = resolved                                       │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

16.2 Modelo de Dados

Tabela: attendance_tickets (nova) ou usar compliance_issues

-- Opção 1: Nova tabela
CREATE TABLE attendance_tickets (
    id UUID PRIMARY KEY,
    session_id UUID NOT NULL,
    ticket_number SERIAL,
    subject TEXT NOT NULL,
    description TEXT,
    status VARCHAR(50) DEFAULT 'open',  -- open, in_progress, pending, resolved, closed
    priority VARCHAR(20) DEFAULT 'normal',  -- low, normal, high, urgent
    category VARCHAR(50),  -- sales, support, billing, technical
    
    -- Relacionamento com users
    assigned_to UUID REFERENCES users(id),
    
    -- Relacionamento com atendente atual
    attendant_id VARCHAR(50),
    
    -- Campos de tempo
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    resolved_at TIMESTAMPTZ,
    
    -- Integração
    channel VARCHAR(20),  -- whatsapp, telegram, web
    customer_id UUID,  -- crm_contacts
    contact_phone VARCHAR(20),
    contact_email VARCHAR(100),
    
    -- Tags e custom fields
    tags JSONB,
    custom_fields JSONB
);

-- Opção 2: Usar compliance_issues existente (recomendado)
-- Já tem: id, bot_id, title, description, status, severity, assigned_to, created_at, updated_at

16.3 Relacionamento com Users

A tabela users já existe:

// Schema: users table
pub struct User {
    id: Uuid,           // PK - usar em assigned_to
    username: String,
    email: String,
    password_hash: String,
    is_active: bool,
    is_admin: bool,
    created_at: DateTime<Utc>,
    updated_at: DateTime<Utc>,
}

Workflow:

// 1. Attendant aceita atendimento
POST /api/attendance/assign
{
    "session_id": "uuid",
    "attendant_id": "att-001"
}

// 2. Sistema busca user pelo attendant
let user = users::table
    .filter(users::email.like("%attendant%"))
    .first::<User>(conn)
    .ok();

// 3. Cria/associa ticket
let ticket = AttendanceTicket {
    assigned_to: user.id,  // ← UUID da tabela users
    attendant_id: Some("att-001".to_string()),
    ..
};

16.4 Integração com CRM

O ticket pode criar/atualizar no CRM:

' Quando ticket é criado
ticket = CREATE "attendance_tickets", {
    "subject": "Problema com pedido",
    "priority": "high",
    "channel": "whatsapp",
    "customer_id": customer.id
}

' Quando resolvido
UPDATE "attendance_tickets", ticket.id, {
    "status": "resolved",
    "resolved_at": NOW()
}

' Sincroniza com CRM
CREATE "crm_deals", {
    "name": "Ticket #" + ticket.number,
    "stage": "closed_won",
    "contact_id": ticket.customer_id
}

16.5 API de Tickets

// Endpoints
GET    /api/attendance/tickets              // Listar tickets
GET    /api/attendance/tickets/{id}         // Detalhe ticket
POST   /api/attendance/tickets              // Criar ticket
PUT    /api/attendance/tickets/{id}         // Atualizar ticket
DELETE /api/attendance/tickets/{id}         // Deletar ticket

// Relacionar com atendimento
POST   /api/attendance/tickets/{id}/assign     // Atribuir a user
POST   /api/attendance/tickets/{id}/resolve    // Resolver
POST   /api/attendance/tickets/{id}/transfer   // Transferir

17. Integração com CRM (Pipeline de Vendas)

17.1 ModeloCRM Existente

O sistema já tem tables CRM:

// Estruturas existentes em contacts/crm.rs
pub struct CrmContact {
    id: Uuid,
    org_id: Uuid,
    bot_id: Uuid,
    first_name: Option<String>,
    last_name: Option<String>,
    email: Option<String>,
    phone: Option<String>,
    // ... outros campos
    owner_id: Option<Uuid>,  // ← Pode usar users.id
}

pub struct CrmDeal {
    id: Uuid,
    name: String,
    value: f64,
    stage: String,  // ← Pipeline stage
    contact_id: Option<Uuid>,
    owner_id: Option<Uuid>,
}

pub struct CrmPipelineStage {
    id: Uuid,
    name: String,
    order_index: i32,
    probability: f64,
}

17.2 Integração Attendance ↔ CRM

┌─────────────────────────────────────────────────────────────────────────────┐
│                    ATTENDANCE + CRM INTEGRATION                              │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐                │
│  │  Attendance │    │   Tickets    │    │     CRM      │                │
│  │   Queue     │    │              │    │  Pipeline    │                │
│  └──────┬───────┘    └──────┬───────┘    └──────┬───────┘                │
│         │                    │                    │                         │
│         │                    │                    │                         │
│         ▼                    ▼                    ▼                         │
│  ┌─────────────────────────────────────────────────────────────────┐       │
│  │                     shared users table                           │       │
│  │                     (assigned_to → users.id)                    │       │
│  └─────────────────────────────────────────────────────────────────┘       │
│                                                                             │
│  Fluxo:                                                                    │
│  1. Attendance cria Ticket                                                 │
│  2. Ticket.assigned_to = users.id                                         │
│  3. CRM Deal pode referenciar Contact do ticket                            │
│  4. Pipeline stages controlam status                                       │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

17.3 Pipeline de Vendas no Attendance

' Configurar pipeline stages
' already exists: crm_pipeline_stages table

' Criar Deal a partir do atendimento
IF intent = "comprar" OR intent = "interesse" THEN
    ' Identifica ou cria contato
    contact = FIND "crm_contacts", "phone='" + session.phone + "'"
    
    IF contact NOT FOUND THEN
        contact = CREATE "crm_contacts", {
            "first_name": session.user_name,
            "phone": session.phone,
            "source": "whatsapp"
        }
    END IF
    
    ' Cria deal no pipeline
    deal = CREATE "crm_deals", {
        "name": "Oportunidade - " + contact.first_name,
        "contact_id": contact.id,
        "stage": "qualification",
        "owner_id": ticket.assigned_to
    }
    
    TALK "Perfeito! Vou criar uma proposta para você."
END IF

17.4 Dashboard Unificado

┌─────────────────────────────────────────────────────────────────────────────┐
│                    ATTENDANCE + CRM DASHBOARD                                │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ┌─────────────────────┐  ┌──────────────────────────────────────────────┐  │
│  │   ATENDIMENTOS     │  │              PIPELINE CRM                    │  │
│  │   ─────────────    │  │  ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐  │  │
│  │   Hoje: 45         │  │  │New  │ │Qual │ │Prop │ │Neg  │ │Won  │  │  │
│  │   Resolvidos: 38   │  │  │ $5K │ │$12K│ │$20K│ │$8K │ │$15K│  │  │
│  │   Em aberto: 7     │  │  └─────┘ └─────┘ └─────┘ └─────┘ └─────┘  │  │
│  │   Tempo médio: 8min│  │                                                │  │
│  └─────────────────────┘  └──────────────────────────────────────────────┘  │
│                                                                             │
│  ┌──────────────────────────────────────────────────────────────────────┐  │
│  │  TICKETS RECENTES                                                     │  │
│  │  ─────────────────────────────────────────────────────────────────── │  │
│  │  #TIC-001 | João Silva | Suporte | Alta | Maria | Aberto           │  │
│  │  #TIC-002 | Ana Costa  | Vendas  | Média| João  | Pendente         │  │
│  │  #TIC-003 | Carlos     | Técnico | Baixa| Maria | Resolvido        │  │
│  └──────────────────────────────────────────────────────────────────────┘  │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

18. Resumo: O que Faltava

Feature Status Descrição
Kanban View 🔜 Planejado View visual da fila com drag-drop
Tickets (Issues) 🔜 Planejado Usar compliance_issues ou nova tabela
Filas via Interface 🔜 Planejado CRUD de filas + membros (users)
assigned_to → users Já existe users.id como FK
CRM Pipeline Já existe crm_deals + crm_pipeline_stages

18.1 Modelo Novo (Sem attendant.csv)

attendance_queues
  ├── name: "Suporte WhatsApp"
  ├── channels: ["whatsapp"]
  └── members: [user_id, ...]  ← users table

attendance_queue_members
  ├── queue_id: attendance_queues.id
  ├── user_id: users.id  ← Attendente
  └── max_conversations: 5

18.2 Fluxo Completo

Cliente WhatsApp "Oi"
    │
    ▼
Identifica cliente no CRM (por phone)
    │
    ▼
Busca fila pelo canal → "Suporte WhatsApp"
    │
    ▼
Seleciona próximo atendente (round-robin)
    │
    ▼
Session.assigned_to = users.id
Session.customer_id = crm_contacts.id
    │
    ▼
Kanban: Card em "Novos"
    │
    ▼
Attendente aceita → Card move para "Em Atendimento"
    │
    ▼
Attendente responde
    │
    ▼
resolve → Card move para "Resolvidos"
    │
    ▼
Ticket criado com:
  - assigned_to = users.id
  - customer_id = crm_contacts.id

18.3 Próximos Passos

  1. Criar tabelas attendance_queues e attendance_queue_members
  2. Criar UI para gerenciar filas e membros
  3. Criar API Kanban
  4. Adaptar Tickets para usar users.id
  5. Dashboard Unificado Attendance + CRM

19. Comparação com Enterprise Grade (Zendesk, Freshdesk, Intercom)

19.1 Matriz de Features

Feature Ours (Planned) Zendesk Freshdesk Intercom Priority
CANAIS
WhatsApp Alta
Telegram Alta
Instagram Alta
Web Chat Alta
Email Alta
SMS Média
Teams Alta
Voice/Phone 🔜 Alta
Facebook Messenger Média
TICKETING
Criação automática Alta
Status workflow Alta
Prioridades Alta
Categorias/Tags Alta
assigned_to → users Alta
Ticket relacional CRM Alta
ATENDIMENTO
Filas (Queues) Alta
Round-robin Alta
Skills-based routing 🔜 Alta
Kanban View 🔜 Alta
Chat em tempo real Alta
AI/AUTOMAÇÃO
Sentiment analysis Alta
Smart replies Alta
Auto-responder 🔜 Alta
Resumo IA Alta
Tips para atendente Alta
CRM
Integração CRM Alta
360° customer view Alta
Pipeline de vendas Alta
Criar Deal do ticket 🔜 Alta
SLA
SLA rules 🔜 Alta
Alerts de SLA 🔜 Alta
DASHBOARD
Métricas básicas Alta
Relatórios custom 🔜 Média
KNOWLEDGE
Base de conhecimento 🔜 Média
FAQ auto 🔜 Média
VIDEO
Videochamada Alta
Screen share Alta
INTEGRAÇÕES
Webhooks 🔜 Alta
API REST Alta

19.2 Gap Analysis - O que Faltando

Feature Complexidade Descrição
Skills-based routing Alta Route baseado em habilidade do atendente
Kanban View Média Drag-drop entre colunas
SLA Management Alta Regras, alertas, métricas
Auto-responder Média Respostas automáticas por IA
Knowledge Base Alta Artigos, FAQs, busca
Relatórios custom Média Queries, gráficos custom
Webhooks Média Notificações externas
Voice/Phone (PSTN) Alta Integração com telefonia

19.3 Comparação Detalhada

Ours vs Zendesk

┌─────────────────────────────────────────────────────────────────────────────┐
│                        ZENDESK FEATURES                                      │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ✅ Já temos:                      ❌ Faltando:                            │
│  ─────────────────                ──────────────                           │
│  • Multi-channel                  • SLA Management completo                 │
│  • Ticket creation               • Knowledge base                         │
│  • User assignment               • Auto-responder IA                      │
│  • Real-time chat                • Custom reporting                        │
│  • LLM assist (tips/replies)    • Webhooks                                │
│  • Video calls                   • Marketplace apps                        │
│  • CRM integration               • Customer portals                       │
│  • Kanban (planejado)                                                      │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Ours vs Freshdesk

┌─────────────────────────────────────────────────────────────────────────────┐
│                      FRESHDESK FEATURES                                      │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ✅是我们 (Planned):              ❌ Faltando:                            │
│  ─────────────────                ──────────────                           │
│  • Omnichannel                   • Freddy AI (auto-responder)             │
│  • Ticket lifecycle              • Knowledge base                         │
│  • Queue management              • Custom objects                         │
│  • Round-robin                   • Approval workflows                     │
│  • Skills-based (planejado)      • Portal self-service                   │
│  • CRM integration               • SLAs                                   │
│  • Video meetings                • Advanced analytics                      │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

19.4 Roadmap de Implementação

FASE 1 (Imediato - 2 semanas)
├── ✅ Filas via Interface (users)
├── ✅ assigned_to → users.id
├── 🔜 Kanban View
└── 🔜 Tickets integrados

FASE 2 (1 mês)
├── 🔜 Skills-based routing
├── 🔜 SLA Management
└── 🔜 Auto-responder IA

FASE 3 (2 meses)
├── 🔜 Knowledge Base
├── 🔜 Custom Reporting
└── 🔜 Webhooks

FASE 4 (3 meses)
├── 🔜 Voice/PSTN
├── 🔜 Portal Self-service
└── 🔜 Advanced Integrations

19.5 Conclusão

O plano atual cobre ~70% das features enterprise-grade:

Categoria Cobertura
Canais 90%
Ticketing 85%
Atendimento 80%
AI/Automação 75%
CRM 85%
SLA 30%
Dashboard 60%
Knowledge 20%
Video 90%
Integrações 50%

Próximas prioridades:

  1. Filas via UI + users (em desenvolvimento)
  2. 🔜 Kanban View
  3. 🔜 Skills-based routing
  4. 🔜 SLA Management
  5. 🔜 Knowledge Base

14. Arquivo de Referência

Ver também: