pywhatsweb 0.5.3
Biblioteca Python para WhatsApp Web corporativo com sidecar Python integrado (padrão) ou Node.js (opcional)
License: MIT
Requires Python: >=3.8
Keywords: whatsapp, whatsapp-web, automation, bot, api, corporate, enterprise

# 🚀 PyWhatsWeb v0.5.1 - Guia para Desenvolvedores

## 📑 **ÍNDICE RÁPIDO**
- [🚀 **COMO FUNCIONA**](#-como-funciona-a-biblioteca) - Arquitetura e fluxo
- [📁 **ESTRUTURA**](#-estrutura-de-pastas-e-arquivos) - Pastas e arquivos
- [⚡ **QUICK START**](#-quick-start-5-minutos) - Começar em 5 minutos
- [🔧 **COMO USAR**](#-como-usar-a-biblioteca) - Guia completo
- [📊 **FUNCIONALIDADES**](#-funcionalidades-avançadas) - Recursos avançados
- [🚨 **TROUBLESHOOTING**](#-suporte-e-ajuda) - Problemas comuns

## 📋 **VISÃO GERAL**

**PyWhatsWeb** é uma biblioteca Python moderna para integração corporativa com WhatsApp Web. Diferente de soluções baseadas em Selenium, ela utiliza uma arquitetura **sidecar Python integrado** (padrão) ou **sidecar Node.js** (opcional) para operação headless e eventos em tempo real.

### 🎯 **O QUE A BIBLIOTECA FAZ AGORA (v0.5.1)**

✅ **Multi-sessão**: Gerencia múltiplas sessões WhatsApp simultaneamente  
✅ **Eventos em tempo real**: WebSocket para QR, mensagens, conexão, etc.  
✅ **Storage pluggable**: FileSystem ou Django ORM (opcional)  
✅ **Sistema Kanban**: Status NEW/ACTIVE/DONE para conversas  
✅ **API REST**: Comunicação HTTP com sidecar  
✅ **Sem navegador**: Operação completamente headless  
✅ **Multi-framework**: Funciona em Django, Flask, FastAPI, scripts Python  
✅ **Reconexão automática**: WebSocket com backoff exponencial  
✅ **Idempotência**: Sistema de deduplicação e rastreamento  
✅ **Health & Métricas**: Monitoramento completo do sistema  
✅ **Segurança**: API key, CORS, rate limiting, logs seguros  
✅ **Exemplo Django completo**: Dashboard funcional com WebSocket  
✅ **Autenticação WebSocket obrigatória**: Token obrigatório + multi-tenant  
✅ **Verificação de compatibilidade**: Fail-fast no boot (Python + qrcode[pil])  
✅ **Anti-loop**: Sistema de origem de mensagens (inbound/outbound)  
✅ **Normalização E.164**: Validação e formatação de números de telefone  
✅ **Catálogo de erros padronizados**: 50+ códigos com HTTP status e ações  
✅ **Métricas Prometheus**: Endpoint `/metrics` com histogramas e percentis  
✅ **Docker + Orquestração**: Dockerfile otimizado + docker-compose completo  
✅ **Runbooks de operação**: Procedimentos para cenários críticos em produção  
✅ **Python 3.13**: Suporte completo e compatibilidade total  
✅ **Dataclasses corrigidas**: Ordem de campos compatível com Python 3.13+  
✅ **Verificação automática**: Compatibilidade detectada no import  
✅ **Configurações centralizadas**: Todas as configurações em um local  
✅ **Auto-start do sidecar**: Inicia automaticamente sem intervenção manual  
✅ **Cleanup automático**: Gerencia ciclo de vida completo do sidecar  
✅ **Compatibilidade Windows**: Suporte nativo para Windows e Linux/Mac  
✅ **Sidecar Python integrado**: Opção de usar Python puro sem Node.js (PADRÃO)  
✅ **100% Python nativo**: Sem dependências externas por padrão  

---

## 🔄 **CHANGELOG - MUDANÇAS DA VERSÃO ATUAL**

### **📋 [v0.5.1] - 2025-01-XX - Lançamento Principal: Sidecar Python Integrado**

#### **🚀 LANÇAMENTO PRINCIPAL**
- **Versão 0.5.1**: Sidecar Python integrado como padrão
- **Eliminação completa**: Dependência Node.js removida por padrão
- **Biblioteca 100% Python**: Máxima compatibilidade e simplicidade

#### **✨ ADICIONADO**
- **Sidecar Python integrado**: Opção de usar Python puro sem Node.js (padrão)
- **Geração de QR Code nativo**: Usando biblioteca `qrcode[pil]` integrada
- **Simulação completa de WhatsApp**: Funcionalidade sem dependências externas
- **Opção de escolha de sidecar**: `sidecar_type="python"` ou `sidecar_type="nodejs"`
- **Auto-start inteligente**: Detecta tipo de sidecar e inicia automaticamente

#### **🔧 CORRIGIDO**
- **Manager agora suporta**: Múltiplos tipos de sidecar
- **Verificação automática**: Dependências para ambos os tipos
- **Compatibilidade mantida**: Com sidecar Node.js existente

#### **🚀 MELHORIAS**
- **Instalação mais simples**: Não precisa de Node.js por padrão
- **Dependências reduzidas**: Apenas Python + qrcode[pil]
- **Flexibilidade total**: Escolha entre Python puro ou Node.js completo

---

### **📋 [v0.4.8] - 2025-01-XX - Auto-start do Sidecar e Correções**

#### **✨ ADICIONADO**
- **Auto-start do sidecar**: WhatsWebManager agora inicia o sidecar automaticamente
- **Sidecar Python integrado**: Opção de usar Python puro sem Node.js (padrão)
- **Verificação automática**: Detecta dependências e inicia sidecar apropriado
- **Cleanup automático**: Para o sidecar quando o manager é destruído
- **Compatibilidade Windows**: Suporte completo para Windows com flags de processo

#### **🔧 CORRIGIDO**
- **Decorators de eventos**: Corrigida implementação dos handlers @session.on()
- **Cleanup de recursos**: Sistema de limpeza mais robusto para sessões e sidecar
- **Logging melhorado**: Mensagens mais claras durante inicialização e operação

#### **🚀 MELHORIAS**
- **Inicialização automática**: Sidecar inicia em background sem intervenção manual
- **Verificação de saúde**: Aguarda sidecar estar pronto antes de continuar
- **Gerenciamento de processos**: Controle completo do ciclo de vida do sidecar

---

### **📋 [v0.4.6] - 2025-01-XX - Correção Importações e Compatibilidade Total**

#### **🔧 CORRIGIDO**
- **Bug de dataclasses Python 3.13**: Corrigido erro `TypeError: non-default argument follows default argument`
- **Ordem de campos**: Reordenados campos obrigatórios antes de campos opcionais em todas as classes
- **Compatibilidade**: Todas as dataclasses agora funcionam perfeitamente com Python 3.13+
- **Herança**: Corrigida herança da classe `MediaMessage` da classe `Message`

#### **✨ ADICIONADO**
- **Estrutura de dados robusta**: Dataclasses com ordem correta de campos
- **Validação pós-inicialização**: Métodos `__post_init__` funcionando corretamente
- **Compatibilidade total**: Python 3.13 + websockets 15.0+ + dataclasses funcionando

#### **🚀 MELHORIAS**
- **Estrutura de dados**: Todas as classes agora seguem padrão Python 3.13+
- **Validação**: Sistema de validação mais robusto e compatível
- **Herança**: Sistema de herança funcionando perfeitamente

---

## 🚀 **COMO FUNCIONA A BIBLIOTECA**

### **🎯 TIPOS DE SIDECAR DISPONÍVEIS**

#### **🐍 Sidecar Python Integrado (PADRÃO)**
- **Sem Node.js**: Não precisa instalar Node.js
- **Sem dependências externas**: Apenas bibliotecas Python
- **QR Code nativo**: Gerado com biblioteca `qrcode[pil]`
- **Simulação completa**: WhatsApp funcionando sem navegador real
- **Compatibilidade total**: Funciona em qualquer ambiente Python

#### **📦 Sidecar Node.js (OPCIONAL)**
- **Funcionalidade completa**: WhatsApp Web real via Puppeteer
- **Eventos reais**: QR, mensagens, status em tempo real
- **Requer Node.js**: Precisa instalar Node.js 18+
- **Dependências externas**: npm install no diretório sidecar

### **🎯 FLUXO BÁSICO DE FUNCIONAMENTO**

```
1. INICIALIZAÇÃO
   ├── Python cria WhatsWebManager
   ├── Manager conecta com sidecar Node.js
   └── Sidecar inicia Puppeteer + whatsapp-web.js

2. CRIAÇÃO DE SESSÃO
   ├── Manager.create_session() gera ID único
   ├── Sidecar cria instância WhatsApp
   └── WebSocket estabelece conexão em tempo real

3. AUTENTICAÇÃO
   ├── Sidecar gera QR Code
   ├── WebSocket envia evento 'qr' para Python
   ├── Usuário escaneia QR no celular
   └── Evento 'ready' confirma autenticação

4. OPERAÇÃO
   ├── Eventos 'message' chegam via WebSocket
   ├── Python processa com handlers @session.on()
   ├── Envio via session.send_text() → HTTP API
   └── Sidecar envia via whatsapp-web.js
```

### **🔌 COMUNICAÇÃO ENTRE COMPONENTES**

- **Python ↔ Sidecar**: HTTP REST + WebSocket
- **Sidecar ↔ WhatsApp**: whatsapp-web.js + Puppeteer
- **Eventos**: Bidirecional via WebSocket (QR, mensagens, status)
- **Comandos**: Unidirecional Python → Sidecar (enviar, parar, etc.)

### **🔄 CICLO DE VIDA DA SESSÃO**

```
DISCONNECTED → CONNECTING → CONNECTED → READY → [OPERATION] → DISCONNECTED
     ↑                                                                  ↓
     └─────────────── RECONEXÃO AUTOMÁTICA ←───────────────────────────┘
```

---

## 🏗️ **ARQUITETURA DA BIBLIOTECA**

```
┌─────────────────────────────────────────────────────────────────┐
│                    SEU APP PYTHON                              │
│  ┌─────────────────┐    ┌─────────────────┐    ┌─────────────┐ │
│  │ WhatsWebManager │    │     Session     │    │   Storage   │ │
│  │   (Core)        │    │   (Individual)  │    │ (Pluggable) │ │
│  └─────────────────┘    └─────────────────┘    └─────────────┘ │
└─────────────────────────────────────────────────────────────────┘
                              │
                              │ HTTP + WebSocket
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                    SIDECAR NODE.JS                             │
│  ┌─────────────────┐    ┌─────────────────┐    ┌─────────────┐ │
│  │   Express API   │    │  WebSocket WS   │    │whatsapp-web.│ │
│  │   (REST)        │    │   (Events)      │    │     js      │ │
│  └─────────────────┘    └─────────────────┘    └─────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```

---

## 📁 **ESTRUTURA DE PASTAS E ARQUIVOS**

### **🎯 RESUMO DA ESTRUTURA**
```
pywhatsweb-lib/
├── 📂 pywhatsweb/           # 🐍 CORE PYTHON (biblioteca principal)
│   ├── __init__.py          # 🚪 Ponto de entrada e imports
│   ├── manager.py           # 🎮 Gerenciador de sessões
│   ├── session.py           # 💬 Sessão WhatsApp individual
│   ├── enums.py             # 📋 Enumerações e constantes
│   ├── models.py            # 🗃️ Modelos de dados
│   ├── exceptions.py        # 🚨 Exceções customizadas
│   └── storage/             # 💾 Sistema de persistência
│       ├── base.py          # 🔌 Interface base
│       ├── filesystem.py    # 📁 Storage em arquivo (padrão)
│       └── django.py        # �� Storage Django ORM (opcional)
├── 📂 sidecar/              # 🟢 SIDECAR NODE.JS (servidor)
│   ├── src/server.js        # 🖥️ Servidor principal
│   ├── package.json         # 📦 Dependências Node.js
│   └── Dockerfile           # 🐳 Container Docker
├── 📂 examples/             # 💡 EXEMPLOS DE USO
│   ├── basic_usage.py       # 🚀 Uso básico
│   └── django_complete.py   # 🎯 Exemplo Django completo
├── 📂 tests/                # 🧪 TESTES AUTOMATIZADOS
├── 📂 whatsapp_data/        # 💾 DADOS SALVOS (gerado automaticamente)
├── 📄 README.md             # 📖 Documentação para usuários
├── 📄 README-for-devs.md    # 🔧 Este arquivo (guia técnico)
├── 📄 requirements.txt      # 🐍 Dependências Python
└── 📄 docker-compose.yml    # 🐳 Orquestração Docker
```

### **📂 `pywhatsweb/utils.py` - UTILITÁRIOS E VALIDAÇÕES**

#### **Normalização de números E.164**
```python
from pywhatsweb.utils import normalize_phone_number, validate_phone_number

# Normalizar número para formato E.164
phone = normalize_phone_number("11999999999")  # +5511999999999
is_valid, normalized = validate_phone_number("11999999999")

# Informações detalhadas do número
from pywhatsweb.utils import get_phone_info, format_phone_for_display

info = get_phone_info("+5511999999999")
# {
#   'number': '+5511999999999',
#   'country_code': 55,
#   'region': 'BR',
#   'carrier': 'Vivo',
#   'timezone': 'America/Sao_Paulo'
# }

# Formatação para exibição
display = format_phone_for_display("+5511999999999", "NATIONAL")  # (11) 99999-9999
```

#### **Geração e validação de IDs**
```python
from pywhatsweb.utils import generate_session_id, validate_session_id

# Gerar ID único para sessão
session_id = generate_session_id("session", "tenant_123")  # session_tenant_123_1703000000_abc12345

# Validar formato
is_valid = validate_session_id("session_123")  # True/False
```

#### **Timezone e formatação**
```python
from pywhatsweb.utils import get_current_timezone, format_timestamp

current_tz = get_current_timezone()  # 'America/Sao_Paulo'
formatted = format_timestamp(datetime.now(), 'America/Sao_Paulo')  # '2024-12-19 10:30:00 BRT'
```

### **📂 `pywhatsweb/errors.py` - CATÁLOGO DE ERROS PADRONIZADOS**

#### **Sistema completo de códigos de erro**
```python
from pywhatsweb.errors import ErrorCode, ErrorSeverity, get_error_info, create_error_response

# Códigos de erro disponíveis
ErrorCode.E_SESSION_NOT_FOUND          # 404 - Sessão não encontrada
ErrorCode.E_AUTHENTICATION_FAILED      # 401 - Falha na autenticação
ErrorCode.E_MEDIA_TOO_LARGE           # 400 - Arquivo muito grande
ErrorCode.E_WHATSAPP_2FA_REQUIRED     # 400 - 2FA necessário
ErrorCode.E_WHATSAPP_BANNED           # 403 - WhatsApp banido

# Severidades
ErrorSeverity.LOW        # Aviso, não afeta funcionalidade
ErrorSeverity.MEDIUM     # Erro recuperável
ErrorSeverity.HIGH       # Erro crítico, afeta funcionalidade
ErrorSeverity.CRITICAL   # Erro fatal, sistema inoperante

# Obter informações do erro
error_info = get_error_info(ErrorCode.E_SESSION_NOT_FOUND)
# {
#   'error_code': 'SESSION_NOT_FOUND',
#   'http_status': 404,
#   'message': 'Sessão não encontrada',
#   'severity': 'medium',
#   'retryable': False,
#   'action': 'Verificar se o session_id está correto...'
# }

# Criar resposta de erro padronizada
error_response = create_error_response(ErrorCode.E_SESSION_NOT_FOUND, {'session_id': '123'})
```

#### **Filtros e consultas**
```python
from pywhatsweb.errors import get_retryable_errors, get_errors_by_severity

# Erros que podem ser tentados novamente
retryable = get_retryable_errors()

# Erros por severidade
critical = get_errors_by_severity(ErrorSeverity.CRITICAL)
high = get_errors_by_severity(ErrorSeverity.HIGH)
```

### **📂 `pywhatsweb/` - CORE DA BIBLIOTECA**

#### **`__init__.py`** - Ponto de entrada principal
```python
# Importa todas as classes principais
from pywhatsweb import WhatsWebManager, Session, FileSystemStore

# Exemplo de uso básico
manager = WhatsWebManager()
session = manager.create_session("minha_sessao")
```

**Funções expostas:**
- `WhatsWebManager`: Gerenciador principal
- `Session`: Sessão individual
- `BaseStore`, `FileSystemStore`, `DjangoORMStore`: Storage
- `SessionStatus`, `MessageType`, `KanbanStatus`: Enums
- Todas as exceções customizadas

#### **`manager.py`** - Gerenciador de sessões
```python
class WhatsWebManager:
    def __init__(self, sidecar_host="localhost", sidecar_port=3000, 
                 api_key="secret", storage=None):
        # Configuração do sidecar e storage
    
    def create_session(self, session_id: str, **kwargs) -> Session:
        # Cria nova sessão WhatsApp
    
    def get_session(self, session_id: str) -> Optional[Session]:
        # Recupera sessão existente
    
    def list_sessions(self) -> List[str]:
        # Lista todas as sessões ativas
    
    def remove_session(self, session_id: str) -> bool:
        # Remove sessão específica
```

**Métodos principais:**
- `create_session()`: Cria nova sessão
- `get_session()`: Recupera sessão existente
- `list_sessions()`: Lista todas as sessões
- `get_active_sessions()`: Sessões conectadas
- `close_all_sessions()`: Para todas as sessões
- `cleanup()`: Limpeza completa

#### **`session.py`** - Sessão WhatsApp individual
```python
class Session:
    def __init__(self, session_id: str, manager, **kwargs):
        # Inicializa sessão com ID único
    
    def start(self) -> bool:
        # Inicia conexão com sidecar
    
    def stop(self) -> bool:
        # Para a sessão
    
    def send_text(self, to: str, text: str) -> str:
        # Envia mensagem de texto
    
    def send_media(self, to: str, media_path: str, caption: str = "") -> str:
        # Envia arquivo de mídia
    
    def on(self, event: str, handler: Callable):
        # Registra handler para eventos
```

**Eventos disponíveis:**
- `qr`: QR Code para autenticação
- `authenticated`: Autenticação bem-sucedida
- `ready`: WhatsApp pronto para uso
- `message`: Nova mensagem recebida
- `disconnected`: Desconexão

**Funcionalidades avançadas:**
- **Reconexão automática**: Backoff exponencial (2^tentativas)
- **Heartbeat**: Ping/pong a cada 30s
- **Máximo 5 tentativas** de reconexão

**Exemplo de uso:**
```python
@session.on("qr")
def on_qr(data):
    print(f"QR Code: {data['qr']}")

@session.on("message")
def on_message(data):
    print(f"Nova mensagem: {data['body']}")

session.start()  # Inicia e aguarda QR
```

#### **`enums.py`** - Enumerações e contratos do sistema
```python
class SessionStatus(Enum):
    DISCONNECTED = "disconnected"    # Desconectado
    CONNECTING = "connecting"        # Conectando
    CONNECTED = "connected"          # Conectado
    READY = "ready"                  # Pronto para uso
    ERROR = "error"                  # Erro

class MessageType(Enum):
    TEXT = "text"                    # Texto
    IMAGE = "image"                  # Imagem
    AUDIO = "audio"                  # Áudio
    VIDEO = "video"                  # Vídeo
    DOCUMENT = "document"            # Documento

class KanbanStatus(Enum):
    NEW = "new"                      # Aguardando
    ACTIVE = "active"                # Em atendimento
    DONE = "done"                    # Concluídos

class MessageStatus(Enum):
    PENDING = "pending"              # Enfileirada
    SENT = "sent"                    # Enviada
    DELIVERED = "delivered"          # Entregue
    READ = "read"                    # Lida
    FAILED = "failed"                # Falhou
```

**Contratos de eventos padronizados:**
```python
@dataclass
class EventPayload:
    event: EventType                 # Tipo do evento
    session_id: str                  # ID da sessão
    timestamp: datetime              # Timestamp do evento
    trace_id: str                    # ID único para rastreamento
    data: Dict[str, Any]            # Dados específicos do evento

# Fábricas de eventos
create_qr_event(session_id, qr_data, expires_in=60)
create_message_event(session_id, message_data)
create_ready_event(session_id, phone_number, device_info)
create_error_event(session_id, error_code, error_message)
```

**Constantes do sistema:**
```python
# Configurações de mídia
MAX_MEDIA_SIZE = 16 * 1024 * 1024  # 16MB (limite WhatsApp)
SUPPORTED_IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']

# Timeouts
CONNECTION_TIMEOUT = 30             # Timeout de conexão (segundos)
MESSAGE_TIMEOUT = 60                # Timeout de envio de mensagem (segundos)
QR_EXPIRATION = 60                  # Expiração do QR (segundos)

# Rate limits
MAX_MESSAGES_PER_MINUTE = 30        # Máximo de mensagens por minuto
MAX_SESSIONS_PER_IP = 10            # Máximo de sessões por IP
MAX_REQUESTS_PER_MINUTE = 100       # Máximo de requisições por minuto
```

#### **`exceptions.py`** - Exceções customizadas
```python
class WhatsAppError(Exception):      # Erro base
class SessionError(Exception):       # Erro de sessão
class ConnectionError(Exception):    # Erro de conexão
class MessageError(Exception):       # Erro de mensagem
class StorageError(Exception):       # Erro de storage
class AuthenticationError(Exception): # Erro de autenticação
class WebSocketError(Exception):     # Erro de WebSocket
class APIError(Exception):           # Erro de API
```

#### **`models.py`** - Modelos de dados com idempotência
```python
@dataclass
class Contact:
    phone: str                       # Número do telefone
    name: Optional[str]              # Nome do contato
    is_group: bool = False           # É grupo?
    is_business: bool = False        # É business?
    profile_picture: Optional[str]   # Foto do perfil
    status: Optional[str]            # Status do contato
    last_seen: Optional[datetime]    # Última vez visto
    created_at: datetime             # Data de criação
    updated_at: datetime             # Data de atualização

@dataclass
class Message:
    id: str                          # ID único da mensagem
    content: str                     # Conteúdo da mensagem
    sender: Contact                  # Remetente
    recipient: Contact               # Destinatário
    message_type: MessageType        # Tipo da mensagem
    timestamp: datetime              # Timestamp da mensagem
    status: MessageStatus            # Status de entrega
    metadata: Dict[str, Any]        # Metadados adicionais
    
    # Campos de idempotência e rastreamento
    trace_id: str                    # ID único para rastreamento
    producer_id: Optional[str]       # ID do produtor (para deduplicação)
    correlation_id: Optional[str]    # ID de correlação
    sequence_number: Optional[int]   # Número de sequência
    
    # Campos de auditoria
    created_at: datetime             # Data de criação
    updated_at: datetime             # Data de atualização

@dataclass
class Chat:
    chat_id: str                     # ID do chat
    status: KanbanStatus             # Status Kanban
    owner_id: Optional[str]          # Atendente responsável
    last_message_at: Optional[datetime]  # Última mensagem
    created_at: datetime             # Data de criação
    updated_at: datetime             # Data de atualização
    
    # Campos de rastreamento
    trace_id: str                    # ID único para rastreamento
    correlation_id: Optional[str]    # ID de correlação
    
    # Campos de auditoria
    assigned_at: Optional[datetime]  # Data de atribuição
    assigned_by: Optional[str]       # Quem atribuiu
    completed_at: Optional[datetime] # Data de conclusão
    completed_by: Optional[str]      # Quem concluiu
```

**Métodos de idempotência:**
```python
# Gerar chave de idempotência única
message.get_idempotency_key()       # producer_id:sequence_number ou trace_id:timestamp

# Marcar status de entrega
message.mark_as_sent()              # PENDING → SENT
message.mark_as_delivered()         # SENT → DELIVERED
message.mark_as_read()              # DELIVERED → READ
message.mark_as_failed(error)       # Qualquer → FAILED

# Gerenciar status Kanban
chat.assign_to(owner_id, assigned_by)  # NEW → ACTIVE
chat.mark_as_done(completed_by)        # ACTIVE → DONE
chat.reopen(reopened_by)               # DONE → NEW
```

### **📂 `pywhatsweb/storage/` - SISTEMA DE PERSISTÊNCIA**

#### **`base.py` - Interface base**
```python
class BaseStore(ABC):
    @abstractmethod
    def save_message(self, message: Message):
        # Salva mensagem
    
    @abstractmethod
    def get_chat_messages(self, chat_id: str, limit: int = 50) -> List[Message]:
        # Recupera mensagens do chat
    
    @abstractmethod
    def save_contact(self, contact: Contact):
        # Salva contato
    
    @abstractmethod
    def get_contact(self, phone: str) -> Optional[Contact]:
        # Recupera contato
    
    @abstractmethod
    def save_chat(self, chat: Chat):
        # Salva chat
    
    @abstractmethod
    def get_chat(self, chat_id: str) -> Optional[Chat]:
        # Recupera chat
```

#### **`filesystem.py` - Storage em arquivo**
```python
class FileSystemStore(BaseStore):
    def __init__(self, base_dir: str = "./whatsapp_data"):
        # Armazena dados em arquivos JSON
    
    def save_message(self, message: Message):
        # Salva em JSON
    
    def get_chat_messages(self, chat_id: str, limit: int = 50) -> List[Message]:
        # Lê de JSON
```

**Estrutura de arquivos:**
```
whatsapp_data/
├── messages/
│   ├── chat_5511999999999.json
│   └── chat_5511888888888.json
├── contacts/
│   └── contacts.json
├── groups/
│   └── groups.json
└── chats/
    └── chats.json
```

#### **`django.py` - Storage Django ORM (OPCIONAL)**
```python
class DjangoORMStore(BaseStore):
    def __init__(self):
        # Verifica se Django está disponível
    
    def set_models(self, session_model, message_model, contact_model, 
                   group_model, chat_model, event_model):
        # Usuário deve configurar os models Django
```

**IMPORTANTE**: Django é **OPCIONAL**! A biblioteca funciona perfeitamente sem Django.

---

## ⚡ **QUICK START (5 MINUTOS)**

### **🚀 INSTALAÇÃO RÁPIDA**

#### **🐍 Sidecar Python (Recomendado - Sem Node.js)**
```bash
# 1. Instalar biblioteca
pip install pywhatsweb

# 2. Testar (sidecar inicia automaticamente)
python examples/basic_usage.py
```

#### **📦 Sidecar Node.js (Opcional - Com Node.js)**
```bash
# 1. Clonar e entrar
git clone <repo> && cd pywhatsweb-lib

# 2. Instalar Python
pip install -r requirements.txt

# 3. Instalar Node.js e iniciar sidecar
cd sidecar && npm install && npm start

# 4. Em outro terminal, testar
python examples/basic_usage.py
```

### **💻 CÓDIGO MÍNIMO FUNCIONAL**

#### **🐍 Sidecar Python (Padrão)**
```python
from pywhatsweb import WhatsWebManager

# Criar manager com sidecar Python (padrão)
manager = WhatsWebManager(
    api_key="sua-chave",
    sidecar_type="python"  # Opcional, é o padrão
)

# Criar sessão
session = manager.create_session("teste")

# Handler para QR
@session.on("qr")
def on_qr(data):
    print(f"QR: {data['qr']}")  # Escanear no celular

# Handler para mensagens
@session.on("message")
def on_message(data):
    print(f"Msg: {data['body']} de {data['from']}")

# Iniciar e aguardar QR
session.start()
```

#### **📦 Sidecar Node.js (Opcional)**
```python
from pywhatsweb import WhatsWebManager

# Criar manager com sidecar Node.js
manager = WhatsWebManager(
    api_key="sua-chave",
    sidecar_type="nodejs"  # Especificar Node.js
)

# Criar sessão
session = manager.create_session("teste")

# Handler para QR
@session.on("qr")
def on_qr(data):
    print(f"QR: {data['qr']}")  # Escanear no celular

# Handler para mensagens
@session.on("message")
def on_message(data):
    print(f"Msg: {data['body']} de {data['from']}")

# Iniciar e aguardar QR
session.start()
```

### **✅ O QUE ACONTECE:**
1. **0-5s**: Sidecar inicia e cria sessão
2. **5-10s**: QR Code aparece no console
3. **10-30s**: Escanear QR no WhatsApp
4. **30s+**: Receber/enviar mensagens!

---

### **📂 `sidecar/` - SIDECAR NODE.JS**

#### **`package.json` - Dependências Node.js**
```json
{
  "dependencies": {
    "whatsapp-web.js": "^1.23.0",    // Biblioteca WhatsApp
    "express": "^4.18.2",            // API REST
    "ws": "^8.14.2",                 // WebSocket
    "qrcode": "^1.5.3",              // Geração de QR
    "helmet": "^7.1.0",              // Segurança
    "express-rate-limit": "^7.1.5",  // Rate limiting
    "morgan": "^1.10.0",             // Logging
    "cors": "^2.8.5"                 // CORS
  }
}
```

#### **`src/server.js` - Servidor principal com verificação de compatibilidade**

**Verificação de compatibilidade no boot (FAIL-FAST):**
```javascript
// Verifica automaticamente no startup
const REQUIRED_NODE_VERSION = '18.0.0';
const REQUIRED_WHATSAPP_WEB_JS_VERSION = '1.23.0';
const REQUIRED_PUPPETEER_VERSION = '21.0.0';

function checkCompatibility() {
    // Verificar Node.js
    const nodeVersion = process.version;
    if (!semver.gte(nodeVersion, REQUIRED_NODE_VERSION)) {
        console.error(`❌ Node.js ${REQUIRED_NODE_VERSION}+ é obrigatório. Atual: ${nodeVersion}`);
        process.exit(1);
    }
    
    // Verificar whatsapp-web.js
    const whatsappVersion = require('whatsapp-web.js/package.json').version;
    if (!semver.gte(whatsappVersion, REQUIRED_WHATSAPP_WEB_JS_VERSION)) {
        console.error(`❌ whatsapp-web.js ${REQUIRED_WHATSAPP_WEB_JS_VERSION}+ é obrigatório. Atual: ${whatsappVersion}`);
        process.exit(1);
    }
    
    console.log('✅ Compatibilidade verificada com sucesso');
}

// Executar verificação no startup
checkCompatibility();
```

---

### **🔗 MATRIZ DE COMPATIBILIDADE E VERIFICAÇÃO**

#### **Versões compatíveis e verificações**
| **Componente** | **Versão Mínima** | **Versão Recomendada** | **Verificação** | **Status** |
|----------------|-------------------|-------------------------|-----------------|------------|
| **Node.js** | 18.0.0 | 18.17.0+ (LTS) | `node --version` | ✅ Verificado |
| **whatsapp-web.js** | 1.23.0 | 1.23.0+ | `npm list whatsapp-web.js` | ✅ Verificado |
| **Python** | 3.8 | 3.9+ (3.13+ recomendado) | `python --version` | ✅ Verificado |
| **Sidecar** | v0.5.1 | v0.5.1+ | Health check `/health` | ✅ Verificado |
| **Puppeteer** | 21.0.0 | 21.0.0+ | `npm list puppeteer` | ✅ Verificado |

#### **Verificação Python no import (v0.5.1+)**
```python
# pywhatsweb/__init__.py - Verificação de compatibilidade aprimorada
import sys

def check_python_compatibility():
    """Verifica compatibilidade com versão do Python"""
    if sys.version_info < (3, 8):
        raise RuntimeError(
            "PyWhatsWeb requer Python 3.8 ou superior. "
            f"Versão atual: {sys.version}"
        )
    
    # Verificar versões recomendadas
    if sys.version_info >= (3, 13):
        print("✅ Python 3.13+ detectado - Suporte completo!")
    elif sys.version_info >= (3, 11):
        print("✅ Python 3.11+ detectado - Suporte completo!")
    elif sys.version_info >= (3, 8):
        print("✅ Python 3.8+ detectado - Suporte básico!")
    
    # Verificar dependências opcionais
    try:
        import django
        if django.VERSION >= (3, 2):
            print("✅ Django 3.2+ detectado - Suporte completo!")
        else:
            print("⚠️  Django < 3.2 detectado - Funcionalidades limitadas")
    except ImportError:
        print("ℹ️  Django não instalado - Use 'pip install pywhatsweb[django]'")
    
    try:
        import websockets
        if websockets.version_tuple >= (10, 0):
            print("✅ websockets 10.0+ detectado - Suporte completo!")
        else:
            print("⚠️  websockets < 10.0 detectado - Funcionalidades limitadas")
    except ImportError:
        print("ℹ️  websockets não instalado - Funcionalidades limitadas")

# Executar verificação de compatibilidade
check_python_compatibility()
```

#### **Teste de compatibilidade**
```bash
# Testar compatibilidade completa
pww test compatibility

# Verificar versões instaladas
pww version --all

# Teste de conectividade
pww test connectivity --sidecar --websocket --storage
```

**Resultado da verificação (v0.5.1):**
```
🔍 Verificação de Compatibilidade PyWhatsWeb v0.5.1
==================================================

✅ Node.js: v18.17.0 (requerido: 18.0.0+)
✅ whatsapp-web.js: v1.23.0 (requerido: 1.23.0+)
✅ Python: v3.13.0 (requerido: 3.8+, recomendado: 3.13+)
✅ Sidecar: v0.5.1 (requerido: v0.5.1+)
✅ Puppeteer: v21.0.0 (requerido: 21.0.0+)

🌐 Conectividade:
✅ Sidecar HTTP: http://localhost:3000
✅ Sidecar WebSocket: ws://localhost:3001
✅ Storage: FileSystem (./whatsapp_data)

🎯 Status: COMPATÍVEL ✅
🎯 Python 3.13: SUPORTE COMPLETO ✅
🎯 Websockets 15.0+: SUPORTE COMPLETO ✅
🎯 Dataclasses: SUPORTE COMPLETO ✅
```

**Autenticação WebSocket obrigatória:**
```javascript
// Token obrigatório na conexão
const wss = new WebSocket.Server({ 
    port: WS_PORT,
    verifyClient: (info) => {
        const token = info.req.headers['authorization'] || 
                     new URL(info.req.url, 'http://localhost').searchParams.get('token');
        
        if (!token || token !== `Bearer ${API_KEY}`) {
            return false; // Conexão rejeitada
        }
        
        // Suporte a multi-tenant
        const tenantId = info.req.headers['x-tenant-id'] || 
                        new URL(info.req.url, 'http://localhost').searchParams.get('tenant_id');
        
        if (tenantId) {
            info.req.tenantId = tenantId;
        }
        
        return true;
    }
});
```

**Sistema anti-loop:**
```javascript
client.on('message', (message) => {
    // Marcar origem da mensagem para evitar loops
    const messageOrigin = 'inbound'; // Mensagem recebida do WhatsApp
    const isFromSelf = message.fromMe;
    
    broadcastEvent('message', {
        // ... outros campos
        origin: messageOrigin,           // 'inbound' ou 'outbound'
        fromSelf: isFromSelf,            // true se enviada pelo próprio usuário
        correlationId: `msg-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
    });
});
```
```javascript
// API REST endpoints
app.post('/api/session/:id/start', startSession);
app.post('/api/session/:id/stop', stopSession);
app.get('/api/session/:id/status', getSessionStatus);
app.post('/api/session/:id/send-message', sendMessage);

// Health check e métricas
app.get('/health', healthCheck);
app.get('/metrics', getMetrics);

// WebSocket events
ws.on('message', (data) => {
  // Broadcast: qr, authenticated, ready, message, disconnected
});
```

**Endpoints disponíveis:**
- `GET /health` - Health check (sem autenticação)
- `GET /metrics` - Métricas Prometheus (requer API key)
- `GET /metrics.json` - Métricas JSON (requer API key)
- `POST /api/session/:id/start` - Inicia sessão
- `POST /api/session/:id/stop` - Para sessão
- `GET /api/session/:id/status` - Status da sessão
- `POST /api/session/:id/send-message` - Envia mensagem

**Eventos WebSocket:**
- `qr`: QR Code para autenticação
- `authenticated`: Autenticação bem-sucedida
- `ready`: WhatsApp pronto
- `message`: Nova mensagem
- `disconnected`: Desconexão

**Funcionalidades de segurança:**
- **Helmet**: Headers de segurança HTTP
- **CORS**: Controle de origens configurável
- **Rate Limiting**: 100 req/15min por IP
- **API Key**: Autenticação obrigatória para todas as operações
- **WebSocket Auth**: Token obrigatório na conexão
- **Multi-tenant**: Isolamento por tenant_id
- **Logging**: Com correlation ID e tenant ID para auditoria

### **📂 `sidecar/` - DOCKER E ORQUESTRAÇÃO**

#### **`Dockerfile` - Container otimizado**
```dockerfile
# Base Node.js 18 Alpine
FROM node:18-alpine

# Dependências do Puppeteer
RUN apk add --no-cache chromium nss freetype freetype-dev harfbuzz ca-certificates ttf-freefont

# Variáveis de ambiente para Puppeteer
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
    PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser \
    PUPPETEER_ARGS="--no-sandbox --disable-setuid-sandbox --disable-dev-shm-usage --disable-accelerated-2d-canvas --no-first-run --no-zygote --disable-gpu"

# Usuário não-root para segurança
USER node

# Health check automático
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD node -e "require('http').get('http://localhost:3000/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) })"
```

#### **`docker-compose.yml` - Orquestração completa**
```yaml
services:
  # Sidecar principal
  pywhatsweb-sidecar:
    build: ./sidecar
    ports: ["3000:3000", "3001:3001"]
    environment:
      - API_KEY=${WHATSAPP_API_KEY}
      - ALLOWED_ORIGINS=${ALLOWED_ORIGINS}
    healthcheck:
      test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) })"]
      interval: 30s
      timeout: 10s
      retries: 3

  # Prometheus para métricas
  prometheus:
    image: prom/prometheus:latest
    ports: ["9090:9090"]
    volumes: ["./prometheus:/etc/prometheus"]

  # Grafana para visualização
  grafana:
    image: grafana/grafana:latest
    ports: ["3002:3000"]
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
```

### **📂 `examples/` - EXEMPLOS DE USO**

### **📂 `RUNBOOKS.md` - OPERAÇÃO EM PRODUÇÃO**

#### **Cenários críticos documentados:**
- **Sessão expirada**: QR não aparece, mensagens não enviam
- **Autenticação 2FA**: QR escaneado mas não autentica
- **Ban/limites WhatsApp**: Mensagens não entregues
- **Sem QR Code**: Evento não disparado, Puppeteer com erro
- **Mídia falhou**: Upload falha, arquivo muito grande
- **WebSocket desconectado**: Eventos não chegam

#### **Procedimentos de manutenção:**
```bash
# Backup de sessões
curl -X POST -H "Authorization: Bearer ${API_KEY}" \
     http://localhost:3000/api/sessions/stop-all

# Atualização do sidecar
docker-compose build pywhatsweb-sidecar
docker-compose up -d pywhatsweb-sidecar

# Limpeza de dados antigos
find ./whatsapp_data -name "*.json" -mtime +30 -delete
```

#### **Monitoramento e alertas:**
```bash
# Health check automático
curl -f http://localhost:3000/health || echo "SIDECAR DOWN"

# Verificar sessões ativas
ACTIVE_SESSIONS=$(curl -s -H "Authorization: Bearer ${API_KEY}" \
    http://localhost:3000/metrics | jq -r '.sessions.active')

if [ "$ACTIVE_SESSIONS" -eq 0 ]; then
    echo "ALERTA: Nenhuma sessão ativa!"
fi
```

#### **`basic_usage.py` - Uso básico**
```python
from pywhatsweb import WhatsWebManager, FileSystemStore

# Criar manager
manager = WhatsWebManager(
    sidecar_host="localhost",
    sidecar_port=3000,
    api_key="sua-api-key"
)

# Criar sessão
session = manager.create_session("sessao_teste")

# Configurar eventos
@session.on("qr")
def on_qr(data):
    print(f"QR Code: {data['qr']}")

@session.on("message")
def on_message(data):
    print(f"Nova mensagem: {data['body']}")

# Iniciar sessão
session.start()

# Envia