Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

ComandoDescrição
/voice onAtivar respostas de voz
/voice offDesativar respostas de voz
/callSolicitar 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:

#![allow(unused)]
fn main() {
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

#![allow(unused)]
fn main() {
// 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

#![allow(unused)]
fn main() {
// 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

RecursoSuporteObservação
TextoSuportado
ImagensDownload e reenvio
VídeosDownload e reenvio
Áudio⚠️Limitado
VideochamadaNão disponível na API
Compartilhamento de telaNã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

#![allow(unused)]
fn main() {
// 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árioDescrição
InboundCliente liga para número fixo → Direcionado para fila de atendimento
OutboundAtendente faz ligação para cliente → ID do atendimento
CallbackCliente agenda retorno → Sistema liga na hora marcada
IVRMenu 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:

#![allow(unused)]
fn main() {
// 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

CampoDescriçãoExemplo
customer_idID único do clientecust-001
nameNome completoJoão Silva
emailEmailjoao@email.com
phoneTelefone+5511999999999
tierTier do clientepremium, gold, standard
ltvLifetime Value15000.00
last_purchaseÚltima compra2024-01-15
tagsTags do clientevip,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

CampoDescrição
campaign_idID da campanha营销
campaign_nameNome da campanha
utm_sourceFonte UTM
utm_mediumMedio UTM
ad_idID do anúncio
segmentSegmento 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

TipoQuandoDestinatário
new_assignmentNova conversa atribuídaAtendente
queue_alertFila > 10 conversasSupervisor
customer_waitingCliente aguardando > 5minAtendente
sla_breachSLA violadoGerente
resolvedAtendimento encerradoCliente (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

#![allow(unused)]
fn main() {
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

#![allow(unused)]
fn main() {
// 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

StatusDescriçãoRecebe Novas Conversas?
onlineDisponível✅ Sim
busyEm atendimento❌ Não
awayTemporariamente indisponível❌ Não
offline离线❌ Não

6.3 Prioridades de Conversa

PrioridadeValorUso
low0Consultas gerais
normal1Padrão
high2Clientes VIP, tempo-sensível
urgent3Escalaçõ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

FuncionalidadeDescriçãoComando WhatsApp
tipsDicas para o atendente/tips
polishPolir mensagem antes de enviar/polish <msg>
smart-repliesRespostas sugeridas/replies
summaryResumo da conversa/summary
sentimentAnálise de sentimentoAutomá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

KPIDescriçãoMeta
avg_wait_timeTempo médio de espera< 60s
first_response_timeTempo até 1ª resposta< 30s
resolution_rateTaxa de resolução> 85%
customer_satisfactionNPS pós-atendimento> 7
attendant_utilizationUtilização dos atendentes> 70%
transfers_rateTaxa de transferência< 20%

10.1.1 KPIs de Videochamada

KPIDescriçãoMeta
video_call_requestsSolicitações de videochamada-
video_calls_completedVideochamadas completadas> 80%
avg_video_durationDuração média de videochamadas< 15min
screen_share_usageUso de compartilhamento de tela> 40%
transcription_accuracyAcurá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

ProblemaCausaSolução
Mensagem não vai para atendentecrm-enabled=falseAtivar em config.csv
Atendente não recebe notificaçãoStatus != onlineVerificar attendant.csv
Transfer não encontra ninguémNenhum atendente onlineConfigurar horário ou fallback
Cliente preso em modo humano/resolve não executadoExecutar manualmente
WhatsApp não entrega respostaPhone inválidoVerificar país + número

12.2 Problemas de Videochamada

ProblemaCausaSolução
Link de videochamada não funcionaSala expiradaGerar novo link
Cliente sem câmera/micPermissão negadaOrientar cliente
Videochamada travaRede instávelReduzir qualidade
Transcrição não funcionaAPI key inválidaVerificar config
Gravação não iniciaStorage cheioLimpar 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)

CanalStatusVoice (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

DestinoStatusDescrição
Teams✅ ImplementadoAtendente recebe no MS Teams
Google Chat🔜 PlanejadoAtendente recebe no Google Chat
WhatsApp✅ ImplementadoAtendente responde via WA
Web Console✅ ImplementadoInterface 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

ColunaStatusDescrição
newNovosClientes aguardando primeiro atendimento
activeEm AtendimentoJá aceitos por attendant
pendingAguardandoCliente não respondeu
resolvedResolvidosAtendimento 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

#![allow(unused)]
fn main() {
// 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:

#![allow(unused)]
fn main() {
// 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:

#![allow(unused)]
fn main() {
// 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

#![allow(unused)]
fn main() {
// 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:

#![allow(unused)]
fn main() {
// 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

FeatureStatusDescrição
Kanban View🔜 PlanejadoView visual da fila com drag-drop
Tickets (Issues)🔜 PlanejadoUsar compliance_issues ou nova tabela
Filas via Interface🔜 PlanejadoCRUD de filas + membros (users)
assigned_to → users✅ Já existeusers.id como FK
CRM Pipeline✅ Já existecrm_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

FeatureOurs (Planned)ZendeskFreshdeskIntercomPriority
CANAIS
WhatsAppAlta
TelegramAlta
InstagramAlta
Web ChatAlta
EmailAlta
SMSMédia
TeamsAlta
Voice/Phone🔜Alta
Facebook MessengerMédia
TICKETING
Criação automáticaAlta
Status workflowAlta
PrioridadesAlta
Categorias/TagsAlta
assigned_to → usersAlta
Ticket relacional CRMAlta
ATENDIMENTO
Filas (Queues)Alta
Round-robinAlta
Skills-based routing🔜Alta
Kanban View🔜Alta
Chat em tempo realAlta
AI/AUTOMAÇÃO
Sentiment analysisAlta
Smart repliesAlta
Auto-responder🔜Alta
Resumo IAAlta
Tips para atendenteAlta
CRM
Integração CRMAlta
360° customer viewAlta
Pipeline de vendasAlta
Criar Deal do ticket🔜Alta
SLA
SLA rules🔜Alta
Alerts de SLA🔜Alta
DASHBOARD
Métricas básicasAlta
Relatórios custom🔜Média
KNOWLEDGE
Base de conhecimento🔜Média
FAQ auto🔜Média
VIDEO
VideochamadaAlta
Screen shareAlta
INTEGRAÇÕES
Webhooks🔜Alta
API RESTAlta

19.2 Gap Analysis - O que Faltando

FeatureComplexidadeDescrição
Skills-based routingAltaRoute baseado em habilidade do atendente
Kanban ViewMédiaDrag-drop entre colunas
SLA ManagementAltaRegras, alertas, métricas
Auto-responderMédiaRespostas automáticas por IA
Knowledge BaseAltaArtigos, FAQs, busca
Relatórios customMédiaQueries, gráficos custom
WebhooksMédiaNotificações externas
Voice/Phone (PSTN)AltaIntegraçã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:

CategoriaCobertura
Canais90%
Ticketing85%
Atendimento80%
AI/Automação75%
CRM85%
SLA30%
Dashboard60%
Knowledge20%
Video90%
Integrações50%

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: