New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

pywhatsweb

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pywhatsweb

Biblioteca Python para WhatsApp Web corporativo com sidecar Python integrado (padrão) ou Node.js (opcional)

pipPyPI
Version
0.5.3
Maintainers
1

🚀 PyWhatsWeb v0.5.1 - Guia para Desenvolvedores

📑 ÍNDICE RÁPIDO

  • 🚀 COMO FUNCIONA - Arquitetura e fluxo
  • 📁 ESTRUTURA - Pastas e arquivos
  • QUICK START - Começar em 5 minutos
  • 🔧 COMO USAR - Guia completo
  • 📊 FUNCIONALIDADES - Recursos avançados
  • 🚨 TROUBLESHOOTING - 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

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

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

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

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

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

# 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

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

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:

@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

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:

@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:

# 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

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

@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:

# 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

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

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)

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)

# 1. Instalar biblioteca
pip install pywhatsweb

# 2. Testar (sidecar inicia automaticamente)
python examples/basic_usage.py

📦 Sidecar Node.js (Opcional - Com Node.js)

# 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)

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)

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:

  • 0-5s: Sidecar inicia e cria sessão
  • 5-10s: QR Code aparece no console
  • 10-30s: Escanear QR no WhatsApp
  • 30s+: Receber/enviar mensagens!

📂 sidecar/ - SIDECAR NODE.JS

package.json - Dependências Node.js

{
  "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):

// 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

ComponenteVersão MínimaVersão RecomendadaVerificaçãoStatus
Node.js18.0.018.17.0+ (LTS)node --version✅ Verificado
whatsapp-web.js1.23.01.23.0+npm list whatsapp-web.js✅ Verificado
Python3.83.9+ (3.13+ recomendado)python --version✅ Verificado
Sidecarv0.5.1v0.5.1+Health check /health✅ Verificado
Puppeteer21.0.021.0.0+npm list puppeteer✅ Verificado

Verificação Python no import (v0.5.1+)

# 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

# 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:

// 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:

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)}`
    });
});
// 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

# 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

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:

# 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:

# 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

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

# Enviar mensagem
session.send_text("5511999999999", "Olá!")

django_complete_example.py - Exemplo Django completo

View Django com template completo
# views.py - Views Django para WhatsApp
from django.views.generic import TemplateView
from django.http import JsonResponse
from pywhatsweb import WhatsWebManager, DjangoORMStore

class WhatsAppDashboardView(TemplateView):
    template_name = 'whatsapp/dashboard.html'
    
    def get_context_data(self, **kwargs):
        # Inicializar manager e configurar models Django
        manager = WhatsWebManager(
            sidecar_host=settings.WHATSAPP_SIDECAR_HOST,
            sidecar_port=settings.WHATSAPP_SIDECAR_PORT,
            api_key=settings.WHATSAPP_API_KEY,
            storage=DjangoORMStore()
        )
        
        # Configurar models Django
        manager.storage.set_models(
            session_model=WhatsAppSession,
            message_model=WhatsAppMessage,
            contact_model=WhatsAppContact
        )
        
        # Buscar sessões ativas
        active_sessions = manager.get_active_sessions()
        
        context = super().get_context_data(**kwargs)
        context['active_sessions'] = active_sessions
        context['manager'] = manager
        return context

# API para enviar mensagens
def send_message_api(request):
    if request.method == 'POST':
        session_id = request.POST.get('session_id')
        to = request.POST.get('to')
        text = request.POST.get('text')
        
        manager = WhatsWebManager()
        session = manager.get_session(session_id)
        
        try:
            message_id = session.send_text(to, text)
            return JsonResponse({'success': True, 'message_id': message_id})
        except Exception as e:
            return JsonResponse({'success': False, 'error': str(e)})
Template HTML com QR Code e JavaScript
<!-- whatsapp/dashboard.html -->
{% extends 'base.html' %}

{% block content %}
<div class="whatsapp-dashboard">
    <h1>Dashboard WhatsApp</h1>
    
    <!-- Lista de sessões -->
    <div class="sessions-list">
        {% for session in active_sessions %}
        <div class="session-card" data-session-id="{{ session.session_id }}">
            <h3>Sessão: {{ session.session_id }}</h3>
            <div class="session-status">
                Status: <span class="status-{{ session.status }}">{{ session.status }}</span>
            </div>
            
            <!-- Container do QR Code -->
            <div class="qr-container" id="qr-{{ session.session_id }}">
                <img id="qr-code-{{ session.session_id }}" src="" alt="QR Code WhatsApp" style="display: none;">
                <div id="qr-status-{{ session.session_id }}">Aguardando QR Code...</div>
            </div>
            
            <!-- Controles da sessão -->
            <div class="session-controls">
                <button onclick="startSession('{{ session.session_id }}')">Iniciar</button>
                <button onclick="stopSession('{{ session.session_id }}')">Parar</button>
                <button onclick="showQR('{{ session.session_id }}')">Mostrar QR</button>
            </div>
            
            <!-- Envio de mensagens -->
            <div class="message-form">
                <input type="text" id="to-{{ session.session_id }}" placeholder="Número (ex: 5511999999999)">
                <input type="text" id="text-{{ session.session_id }}" placeholder="Mensagem">
                <button onclick="sendMessage('{{ session.session_id }}')">Enviar</button>
            </div>
        </div>
        {% endfor %}
    </div>
</div>

<script>
// WebSocket para receber eventos WhatsApp
const ws = new WebSocket('ws://localhost:8000/ws/whatsapp/');

ws.onmessage = function(e) {
    const data = JSON.parse(e.data);
    const sessionId = data.session_id;
    
    if (data.type === 'qr') {
        // Mostrar QR Code
        const qrImg = document.getElementById(`qr-code-${sessionId}`);
        const qrStatus = document.getElementById(`qr-status-${sessionId}`);
        
        qrImg.src = data.qr;
        qrImg.style.display = 'block';
        qrStatus.textContent = 'Escaneie o QR Code';
        
    } else if (data.type === 'ready') {
        // WhatsApp conectado
        const qrImg = document.getElementById(`qr-code-${sessionId}`);
        const qrStatus = document.getElementById(`qr-status-${sessionId}`);
        
        qrImg.style.display = 'none';
        qrStatus.textContent = 'WhatsApp conectado!';
        
    } else if (data.type === 'message') {
        // Nova mensagem recebida
        console.log('Nova mensagem:', data);
        // Aqui você pode atualizar a interface
    }
};

// Funções para controlar sessões
function startSession(sessionId) {
    fetch(`/whatsapp/session/${sessionId}/start/`, {method: 'POST'})
        .then(response => response.json())
        .then(data => console.log('Sessão iniciada:', data));
}

function stopSession(sessionId) {
    fetch(`/whatsapp/session/${sessionId}/stop/`, {method: 'POST'})
        .then(response => response.json())
        .then(data => console.log('Sessão parada:', data));
}

function sendMessage(sessionId) {
    const to = document.getElementById(`to-${sessionId}`).value;
    const text = document.getElementById(`text-${sessionId}`).value;
    
    fetch('/whatsapp/send-message/', {
        method: 'POST',
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        body: `session_id=${sessionId}&to=${to}&text=${text}`
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            console.log('Mensagem enviada:', data.message_id);
        } else {
            console.error('Erro ao enviar:', data.error);
        }
    });
}
</script>
{% endblock %}
Consumer WebSocket Django Channels
# consumers.py - Consumer WebSocket para Django Channels
import json
from channels.generic.websocket import AsyncWebsocketConsumer
from pywhatsweb import WhatsWebManager

class WhatsAppWebSocketConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        await self.accept()
        print("Cliente WebSocket conectado")
        
        # Conectar ao WebSocket da sessão WhatsApp
        self.whatsapp_manager = WhatsWebManager()
        
    async def disconnect(self, close_code):
        print(f"Cliente WebSocket desconectado: {close_code}")
        
    async def receive(self, text_data):
        # Processar mensagens do cliente
        data = json.loads(text_data)
        
        if data['action'] == 'send_message':
            session_id = data['session_id']
            to = data['to']
            text = data['text']
            
            try:
                session = self.whatsapp_manager.get_session(session_id)
                message_id = await session.send_text(to, text)
                
                # Confirmar envio para o cliente
                await self.send(text_data=json.dumps({
                    'type': 'message_sent',
                    'message_id': message_id,
                    'to': to
                }))
                
            except Exception as e:
                await self.send(text_data=json.dumps({
                    'type': 'error',
                    'error': str(e)
                }))
                
    async def whatsapp_event(self, event):
        # Enviar eventos WhatsApp para o cliente
        await self.send(text_data=json.dumps({
            'type': event['event_type'],
            'session_id': event['session_id'],
            'data': event['data']
        }))

Funcionalidades do exemplo Django:

  • ✅ Dashboard completo com sessões
  • ✅ QR Code em tempo real com template HTML
  • ✅ Sistema Kanban (NEW → ACTIVE → DONE)
  • ✅ Envio de mensagens via API
  • ✅ WebSocket para eventos em tempo real
  • ✅ Template HTML responsivo com JavaScript
  • ✅ Consumer WebSocket funcional
  • ✅ Integração completa com models Django

📂 tests/ - TESTES AUTOMATIZADOS

test_imports.py - Teste de imports

def test_imports():
    # Testa se todas as classes podem ser importadas
    from pywhatsweb import WhatsWebManager, Session
    from pywhatsweb import FileSystemStore, DjangoORMStore

def test_instanciacao():
    # Testa se as classes podem ser instanciadas
    manager = WhatsWebManager()
    storage = FileSystemStore("./test_data")

🚀 COMO USAR A BIBLIOTECA

1. INSTALAÇÃO

# Clonar repositório
git clone <repo>
cd pywhatsweb-lib

# Instalar dependências Python
pip install -r requirements.txt

# Instalar dependências Node.js
cd sidecar
npm install

2. CONFIGURAÇÃO

Configurar sidecar

cd sidecar
cp env.example .env
# Editar .env com suas configurações
npm start

Configurar Python

from pywhatsweb import WhatsWebManager, FileSystemStore

manager = WhatsWebManager(
    sidecar_host="localhost",      # Host do sidecar
    sidecar_port=3000,            # Porta HTTP
    sidecar_ws_port=3001,         # Porta WebSocket
    api_key="sua-api-key",        # Chave de API
    storage=FileSystemStore("./whatsapp_data")  # Storage
)

3. USO BÁSICO

# Criar sessão
session = manager.create_session("sessao_123")

# Configurar eventos
@session.on("qr")
def on_qr(data):
    # Renderizar QR no template Django/Flask
    qr_data_url = data['qr']
    # <img src="{{ qr_data_url }}">

@session.on("ready")
def on_ready(data):
    print("WhatsApp está pronto!")

@session.on("message")
def on_message(data):
    # Processar mensagem recebida
    sender = data['from']
    content = data['body']
    
    # Auto-resposta
    if "oi" in content.lower():
        session.send_text(sender, "Oi! Como posso ajudar?")

# Iniciar sessão
session.start()

4. MÚLTIPLAS SESSÕES COM MULTI-TENANT

# Criar múltiplas sessões com tenant
sessao1 = manager.create_session("sessao_1", tenant_id="empresa_a")
sessao2 = manager.create_session("sessao_2", tenant_id="empresa_b")

# Cada sessão é independente e isolada por tenant
sessao1.start()
sessao2.start()

# Listar sessões ativas por tenant
active_sessions = manager.get_active_sessions(tenant_id="empresa_a")
print(f"Sessões ativas empresa A: {active_sessions}")

5. VALIDAÇÃO E NORMALIZAÇÃO

# Criar múltiplas sessões
sessao1 = manager.create_session("sessao_1", phone_number="5511999999999")
sessao2 = manager.create_session("sessao_2", phone_number="5511888888888")

# Cada sessão é independente
sessao1.start()
sessao2.start()

# Listar sessões ativas
active_sessions = manager.get_active_sessions()
print(f"Sessões ativas: {active_sessions}")

6. ENVIO DE MENSAGENS COM VALIDAÇÃO

# Texto
message_id = session.send_text("5511999999999", "Olá! Como vai?")

# Mídia
message_id = session.send_media(
    to="5511999999999",
    media_path="./imagem.jpg",
    caption="Veja esta imagem!"
)

# Verificar status
if session.is_active():
    print("Sessão está ativa e pronta")

7. 🗃️ STORAGE E PERSISTÊNCIA AVANÇADA

Storage pluggable com múltiplas opções

# FileSystem (padrão) - armazena em JSON
from pywhatsweb import FileSystemStore
storage = FileSystemStore("./whatsapp_data")

# Django ORM (opcional) - integração com banco de dados
from pywhatsweb import DjangoORMStore
storage = DjangoORMStore()

# Redis (futuro) - para alta performance
# from pywhatsweb import RedisStore
# storage = RedisStore(redis_url="redis://localhost:6379")

# PostgreSQL (futuro) - para dados estruturados
# from pywhatsweb import PostgreSQLStore
# storage = PostgreSQLStore(connection_string="postgresql://...")

Configuração Django ORM com models + migrations

# models.py - Models Django para WhatsApp
from django.db import models
from pywhatsweb import KanbanStatus, MessageType

class WhatsAppSession(models.Model):
    session_id = models.CharField(max_length=100, unique=True)
    tenant_id = models.CharField(max_length=50, null=True)
    status = models.CharField(max_length=20, choices=KanbanStatus.choices())
    phone_number = models.CharField(max_length=20, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

class WhatsAppMessage(models.Model):
    message_id = models.CharField(max_length=100, unique=True)
    session = models.ForeignKey(WhatsAppSession, on_delete=models.CASCADE)
    content = models.TextField()
    sender = models.CharField(max_length=20)
    recipient = models.CharField(max_length=20)
    message_type = models.CharField(max_length=20, choices=MessageType.choices())
    status = models.CharField(max_length=20)
    trace_id = models.CharField(max_length=100)
    created_at = models.DateTimeField(auto_now_add=True)

# Configurar storage
storage.set_models(
    session_model=WhatsAppSession,
    message_model=WhatsAppMessage,
    contact_model=WhatsAppContact,
    chat_model=WhatsAppChat
)

📁 PIPELINE DE MÍDIA ROBUSTO

Validação e processamento de mídia

# Configurações de mídia
MEDIA_CONFIG = {
    'max_size': 16 * 1024 * 1024,  # 16MB (limite WhatsApp)
    'allowed_types': ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
    'timeout': 300,  # 5 minutos para upload
    'retry_count': 3,
    'storage_backend': 'local'  # 'local', 's3', 'minio'
}

# Envio com validação automática
try:
    message_id = session.send_media(
        to="5511999999999",
        media_path="./imagem.jpg",
        caption="Veja esta imagem!",
        validate_media=True,  # Validação automática
        compress_if_needed=True  # Compressão se necessário
    )
except MediaTooLargeError:
    print("Arquivo muito grande, comprimindo...")
    compressed_path = compress_image("./imagem.jpg")
    message_id = session.send_media(to="5511999999999", media_path=compressed_path)

Storage de mídia configurável

# Configurar storage de mídia
manager = WhatsWebManager(
    media_storage={
        'backend': 's3',  # 'local', 's3', 'minio'
        'bucket': 'whatsapp-media',
        'region': 'us-east-1',
        'retention_days': 30,  # Retenção automática
        'encryption': True,  # Criptografia em repouso
        'cdn_enabled': True  # CDN para entrega rápida
    }
)

# Upload para S3/MinIO
media_url = session.upload_media_to_storage(
    file_path="./imagem.jpg",
    mime_type="image/jpeg",
    metadata={'session_id': 'sessao_123'}
)

🔒 POLÍTICA LGPD E RETENÇÃO

Configurações de retenção e privacidade

# Configurar política LGPD
manager = WhatsWebManager(
    lgpd_compliance={
        'data_retention_days': 90,  # Retenção de mensagens
        'media_retention_days': 30,  # Retenção de mídia
        'log_redaction': True,  # Redação de dados sensíveis
        'media_encryption': True,  # Criptografia de anexos
        'audit_trail': True,  # Rastreamento de ações
        'right_to_forget': True,  # Direito ao esquecimento
        'data_export': True  # Exportação de dados
    }
)

# Excluir dados de um usuário
storage.delete_user_data(
    phone_number="5511999999999",
    reason="direito_ao_esquecimento",
    audit_user="admin"
)

# Exportar dados para LGPD
user_data = storage.export_user_data("5511999999999")
# Retorna JSON com todas as mensagens, contatos, etc.

Compliance e auditoria

# Logs sem conteúdo de mensagem (apenas metadados)
# [2024-12-19 10:30:00] [corr:req_456] [tenant:empresa_a] Mensagem enviada: ID=msg_123, Para=5511999999999, Tipo=texto

# Criptografia AES-256 em repouso para mídia
# Chaves gerenciadas por KMS ou variáveis de ambiente

# Rastreamento completo de acesso e modificações
audit_log = storage.get_audit_log(
    user_id="5511999999999",
    start_date="2024-12-01",
    end_date="2024-12-19"
)

🔧 FUNCIONALIDADES AVANÇADAS

🧱 SISTEMA KANBAN COM FLUXO INTELIGENTE

Estados do fluxo Kanban

from pywhatsweb import KanbanStatus

# Criar chat com status
chat = Chat(
    chat_id="5511999999999",
    status=KanbanStatus.NEW
)

# Atribuir para atendente
chat.assign_to("atendente_123", "sistema")
# Status muda para ACTIVE

# Marcar como concluído
chat.mark_as_done("atendente_123")
# Status muda para DONE

# Reabrir conversa
chat.reopen("sistema")
# Status volta para NEW

Políticas automáticas recomendadas

# Auto-NEW em mensagem nova
@session.on("message")
def on_message(data):
    if data['origin'] == 'inbound':
        chat = storage.get_or_create_chat(data['from'])
        if chat.status == KanbanStatus.DONE:
            # Cliente respondeu após conclusão, reabrir
            chat.reopen("sistema", reason="cliente_respondeu")
            storage.save_chat(chat)

# Auto-DONE após N horas de inatividade
def auto_close_inactive_chats():
    from datetime import timedelta
    
    active_chats = storage.get_chats_by_status(KanbanStatus.ACTIVE)
    cutoff_time = datetime.now() - timedelta(hours=24)
    
    for chat in active_chats:
        if chat.last_message_at < cutoff_time:
            chat.mark_as_done("sistema", reason="inatividade_24h")
            storage.save_chat(chat)

📱 NORMALIZAÇÃO E VALIDAÇÃO DE NÚMEROS

Utilitário E.164 com phonenumbers

from pywhatsweb.utils import normalize_phone_number, validate_phone_number

# Normalização automática para formato E.164
phone = normalize_phone_number("11999999999")  # +5511999999999
phone = normalize_phone_number("(11) 99999-9999")  # +5511999999999
phone = normalize_phone_number("+55 11 99999 9999")  # +5511999999999

# Validação completa
is_valid, normalized, country_code, region = validate_phone_number("11999999999")
# (True, "+5511999999999", 55, "BR")

# Informações detalhadas do número
info = get_phone_info("+5511999999999")
# {
#   'number': '+5511999999999',
#   'country_code': 55,
#   'region': 'BR',
#   'carrier': 'Vivo',
#   'timezone': 'America/Sao_Paulo',
#   'is_valid': True,
#   'is_mobile': True
# }

Formatação para exibição

# Formatação para diferentes regiões
display_national = format_phone_for_display("+5511999999999", "NATIONAL")   # (11) 99999-9999
display_international = format_phone_for_display("+5511999999999", "INTERNATIONAL")  # +55 11 99999-9999
display_e164 = format_phone_for_display("+5511999999999", "E164")  # +5511999999999

Context Manager e Tratamento de Erros

Context Manager

# Usar como context manager
with WhatsWebManager() as manager:
    session = manager.create_session("test")
    session.start()
    # ... usar sessão
    # Cleanup automático ao sair

Logging e Debug

import logging

# Configurar logging
logging.basicConfig(level=logging.DEBUG)

# Logs automáticos em todas as operações
manager = WhatsWebManager()
# Logs: "PyWhatsWeb Manager inicializado", "Sessão criada", etc.

🔄 RESILIÊNCIA E RECONEXÃO

Reconexão automática com backoff exponencial

# A sessão reconecta automaticamente com backoff exponencial
# Tentativa 1: 2s, Tentativa 2: 4s, Tentativa 3: 8s, etc.
# Máximo 5 tentativas

@session.on("disconnected")
def on_disconnected(data):
    print(f"Desconectado: {data['reason']}")
    # Reconexão automática em andamento

@session.on("ready")
def on_ready(data):
    print("Reconectado e pronto!")

Heartbeat WebSocket para manter conexões ativas

# Ping/pong automático a cada 30 segundos
# Se falhar 3 vezes consecutivas, reconecta automaticamente

@session.on("heartbeat")
def on_heartbeat(data):
    print(f"Heartbeat: {data['latency']}ms")

@session.on("heartbeat_failed")
def on_heartbeat_failed(data):
    print("Heartbeat falhou, reconectando...")

📨 IDEMPOTÊNCIA E DEDUPLICAÇÃO

Sistema de idempotência com chaves únicas

# Gerar chave de idempotência única
message_id = session.send_text_with_idempotency(
    to="5511999999999",
    text="Mensagem importante",
    idempotency_key="msg_123_v1"  # Chave única
)

# Verificar se mensagem já foi enviada
if session.is_message_sent("msg_123_v1"):
    print("Mensagem já enviada, ignorando...")

Marcar origem da mensagem para evitar loops

# Sistema anti-loop automático
@session.on("message")
def on_message(data):
    # data['origin'] = 'inbound' (recebida) ou 'outbound' (enviada)
    # data['fromSelf'] = True se enviada pelo próprio usuário
    
    if data['origin'] == 'inbound' and not data['fromSelf']:
        # Processar mensagem recebida
        process_incoming_message(data)
    else:
        # Ignorar mensagens próprias ou de saída
        print("Mensagem ignorada (loop prevention)")

📊 ESTADOS DE ENTREGA E MONITORAMENTO

Estados de envio/entrega quando suportado

# WhatsApp suporta alguns estados de entrega
@session.on("message_status")
def on_message_status(data):
    if data['status'] == 'sent':
        print("Mensagem enviada para servidor")
    elif data['status'] == 'delivered':
        print("Mensagem entregue ao destinatário")
    elif data['status'] == 'read':
        print("Mensagem lida pelo destinatário")
    elif data['status'] == 'failed':
        print(f"Mensagem falhou: {data['error']}")

Limites e timeouts de entrega

# Configurações de entrega
MESSAGE_TIMEOUT = 60        # Timeout de envio (segundos)
DELIVERY_TIMEOUT = 300      # Timeout de entrega (segundos)
MAX_RETRIES = 3             # Máximo de tentativas
RETRY_DELAY = 5             # Delay entre tentativas (segundos)

@session.on("disconnected") def on_disconnected(data): print(f"Desconectado: {data['reason']}") # Reconexão automática em andamento

@session.on("ready") def on_ready(data): print("Reconectado e pronto!")


---

## 📊 **STATUS E MONITORAMENTO**

### **Informações da Sessão**
```python
# Status básico
status = session.get_status()
print(f"Status: {status.value}")

# Informações detalhadas
info = session.get_status_info()
print(f"Conectado desde: {info['created_at']}")
print(f"Última atividade: {info['last_activity']}")
print(f"Autenticado: {info['is_authenticated']}")
print(f"WebSocket conectado: {info['ws_connected']}")
print(f"Tentativas de reconexão: {info['reconnection_attempts']}")

Informações do Manager

# Listar todas as sessões
sessions = manager.list_sessions()
print(f"Sessões: {sessions}")

# Contar sessões
count = manager.get_session_count()
print(f"Total: {count}")

# Informações do sidecar
sidecar_info = manager.get_sidecar_info()
print(f"Sidecar: {sidecar_info['base_url']}")

📊 OBSERVABILIDADE E MONITORAMENTO

Health Check e Métricas

# Health check básico
curl http://localhost:3000/health

# Métricas Prometheus (formato padrão)
curl -H "Authorization: Bearer sua-api-key" http://localhost:3000/metrics

# Métricas JSON (para dashboards customizados)
curl -H "Authorization: Bearer sua-api-key" http://localhost:3000/metrics.json

Métricas Prometheus com histogramas e percentis

# Métricas-chave disponíveis
METRICS = {
    # Contadores
    'messages_in_total': 'Total de mensagens recebidas',
    'messages_out_total': 'Total de mensagens enviadas',
    'reconnections_total': 'Total de reconexões',
    'errors_total': 'Total de erros por código',
    
    # Gauges
    'sessions_active': 'Sessões ativas no momento',
    'sessions_total': 'Total de sessões criadas',
    'websocket_connections': 'Conexões WebSocket ativas',
    
    # Histogramas
    'message_latency_seconds': 'Latência de envio (p50, p95, p99)',
    'reconnection_delay_seconds': 'Delay de reconexão',
    'media_upload_duration_seconds': 'Duração de upload de mídia'
}

# Exemplo de métricas Prometheus
# whatsapp_messages_in_total{tenant="empresa_a",session="sessao_123"} 150
# whatsapp_message_latency_seconds_bucket{le="0.1"} 45
# whatsapp_message_latency_seconds_bucket{le="0.5"} 120
# whatsapp_message_latency_seconds_bucket{le="1.0"} 150

Health checks por sessão e componente

# Health check completo do sistema
health_status = manager.get_health_status()
# {
#   'status': 'healthy',
#   'timestamp': '2024-12-19T10:30:00.000Z',
#   'uptime': 3600000,
#   'components': {
#     'sidecar': 'healthy',
#     'websocket': 'healthy',
#     'storage': 'healthy',
#     'sessions': 'healthy'
#   },
#   'sessions': {
#     'active': 2,
#     'total': 5,
#     'healthy': 2,
#     'unhealthy': 0
#   },
#   'metrics': {
#     'messagesIn': 150,
#     'messagesOut': 120,
#     'reconnections': 3,
#     'errors': 1
#   }
# }

# Health check de sessão específica
session_health = session.get_health_status()
# {
#   'status': 'healthy',
#   'websocket_connected': True,
#   'last_heartbeat': '2024-12-19T10:29:45.000Z',
#   'reconnection_attempts': 0,
#   'message_queue_size': 0
# }

Alertas e monitoramento proativo

# Configurar alertas automáticos
manager.setup_alerts({
    'max_reconnection_attempts': 5,
    'max_message_latency_ms': 5000,
    'min_active_sessions': 1,
    'max_error_rate': 0.05  # 5% de erro
})

# Handler para alertas
@manager.on("alert")
def on_alert(alert_data):
    if alert_data['type'] == 'high_latency':
        print(f"ALERTA: Latência alta: {alert_data['latency']}ms")
        # Notificar equipe, escalar, etc.
    elif alert_data['type'] == 'session_down':
        print(f"ALERTA: Sessão {alert_data['session_id']} caiu")
        # Tentar reconexão automática

Resposta do health check:

{
  "status": "healthy",
  "timestamp": "2024-12-19T10:30:00.000Z",
  "uptime": 3600000,
  "sessions": {
    "active": 2,
    "total": 5
  },
  "metrics": {
    "messagesIn": 150,
    "messagesOut": 120,
    "reconnections": 3,
    "errors": 1
  },
  "version": "0.3.2"
}

🚨 TRATAMENTO DE ERROS

Exceções comuns

try:
    session.start()
except SessionError as e:
    print(f"Erro de sessão: {e}")
except ConnectionError as e:
    print(f"Erro de conexão: {e}")
except AuthenticationError as e:
    print(f"Erro de autenticação: {e}")
except WebSocketError as e:
    print(f"Erro de WebSocket: {e}")

Verificação de status

if not session.is_connected():
    print("Sessão não está conectada")
    return

if not session.is_active():
    print("Sessão não está ativa")
    return

# Verificar reconexão
if session._reconnection_attempts > 0:
    print(f"Tentativas de reconexão: {session._reconnection_attempts}")

🔒 SEGURANÇA E CONTROLE DE ACESSO

🔐 AUTENTICAÇÃO E AUTORIZAÇÃO

API Key obrigatória

# Sempre use uma API key forte
manager = WhatsWebManager(
    api_key="sua-api-key-super-secreta-aqui"
)

Token/JWT no WebSocket (obrigatório)

// Autenticação no handshake de 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 imediatamente
        }
        
        // Validar tenant_id se fornecido
        const tenantId = info.req.headers['x-tenant-id'];
        if (tenantId && !isValidTenant(tenantId)) {
            return false;
        }
        
        return true;
    }
});

Multi-tenant com isolamento

# Criar sessão com tenant específico
session = manager.create_session(
    "sessao_123", 
    tenant_id="empresa_a",
    correlation_id="req_456"
)

# Headers de correlação automáticos
# X-Correlation-Id: req_456
# X-Tenant-Id: empresa_a
# X-Session-Id: sessao_123

🛡️ CONTROLE DE ACESSO E AUDITORIA

Headers de correlação padronizados

  • X-Correlation-Id: ID único para rastrear operação
  • X-Tenant-Id: Identificador do tenant (multi-tenancy)
  • X-Session-Id: ID da sessão WhatsApp
  • X-Request-Id: ID único da requisição HTTP

Logs com rastreamento completo

# Logs automáticos com correlation ID
# [2024-12-19 10:30:00] [corr:req_456] [tenant:empresa_a] Sessão criada: sessao_123
# [2024-12-19 10:30:05] [corr:req_456] [tenant:empresa_a] QR Code gerado
# [2024-12-19 10:30:30] [corr:req_456] [tenant:empresa_a] WhatsApp autenticado

API Key

# Sempre use uma API key forte
manager = WhatsWebManager(
    api_key="sua-api-key-super-secreta-aqui"
)

Configuração de rede

# Restringir acesso por IP se necessário
manager = WhatsWebManager(
    sidecar_host="127.0.0.1",  # Apenas localhost
    sidecar_port=3000
)

Rate Limiting

// Configuração no sidecar
const limiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15 minutos
    max: 100, // máximo 100 requisições por IP
    message: 'Muitas requisições deste IP, tente novamente mais tarde.'
});

📈 CASOS DE USO

1. Chatbot Automático

@session.on("message")
def auto_response(data):
    content = data['body'].lower()
    sender = data['from']
    
    if "preço" in content:
        session.send_text(sender, "Nossos preços: Produto A - R$ 50, Produto B - R$ 100")
    elif "contato" in content:
        session.send_text(sender, "Entre em contato: (11) 99999-9999")
    else:
        session.send_text(sender, "Como posso ajudar? Digite 'preço' ou 'contato'")

2. Sistema de Atendimento

# Atribuir chat para atendente
def assign_chat_to_attendant(chat_id, attendant_id):
    chat = storage.get_chat(chat_id)
    chat.assign_to(attendant_id, "sistema")
    storage.save_chat(chat)
    
    # Notificar atendente
    session.send_text(attendant_id, f"Novo chat atribuído: {chat_id}")

3. Monitoramento de Conversas

# Verificar conversas ativas
def monitor_active_chats():
    active_chats = storage.get_chats_by_status(KanbanStatus.ACTIVE)
    
    for chat in active_chats:
        # Verificar tempo de atendimento
        if chat.is_taking_too_long():
            # Escalar para supervisor
            escalate_chat(chat)

4. Sistema de Auditoria

# Rastrear todas as ações
def audit_action(action, user_id, details):
    event = SessionEvent(
        session_id=session.session_id,
        event_type=action,
        data=details,
        user_id=user_id,
        ip_address=request.META.get('REMOTE_ADDR'),
        user_agent=request.META.get('HTTP_USER_AGENT')
    )
    storage.save_event(event)

🧪 TESTES E DESENVOLVIMENTO

Executar testes

# Teste de imports
python test_imports.py

# Teste com pytest
pytest tests/

# Teste com tox
tox

Desenvolvimento local

# Instalar em modo desenvolvimento
pip install -e .

# Executar exemplos
python examples/basic_usage.py
python examples/django_complete_example.py

🖥️ CLI OPERACIONAL (pww)

Instalação e uso do CLI

# Instalar CLI globalmente
pip install pywhatsweb[cli]

# Ou usar via Python
python -m pywhatsweb.cli session start --id teste

# Verificar versão
pww --version

Comandos para suporte e diagnóstico

# Gerenciar sessões
pww session start --id sessao_123 --tenant empresa_a
pww session status --id sessao_123
pww session stop --id sessao_123
pww session list --active
pww session list --all

# Mostrar QR Code
pww session qr --id sessao_123

# Enviar mensagem de teste
pww session send --id sessao_123 --to 5511999999999 --text "Teste CLI"

# Diagnóstico completo
pww diag --session sessao_123
pww diag --sidecar
pww diag --storage

# Ver logs em tempo real
pww logs --follow --session sessao_123
pww logs --level debug --tenant empresa_a

# Health check completo
pww health --sidecar --sessions --storage
pww health --format json
pww health --format prometheus

Exemplos de uso do CLI

# Iniciar múltiplas sessões
pww session start --id atendente_1 --tenant empresa_a
pww session start --id atendente_2 --tenant empresa_a
pww session start --id suporte --tenant empresa_b

# Monitorar sessões ativas
pww session list --active --format table
# +-------------+-----------+--------+---------------------+
# | Session ID  | Tenant    | Status | Last Activity      |
# +-------------+-----------+--------+---------------------+
# | atendente_1 | empresa_a | ready  | 2024-12-19 10:30:00 |
# | atendente_2 | empresa_a | ready  | 2024-12-19 10:29:45 |
# | suporte     | empresa_b | qr     | 2024-12-19 10:25:00 |
# +-------------+-----------+--------+---------------------+

# Diagnóstico de problemas
pww diag --session atendente_1 --verbose
# Sessão: atendente_1
# Status: ready
# WebSocket: connected
# Heartbeat: 45ms
# Última mensagem: 2 minutos atrás
# Reconexões: 0
# Erros: 0

Testar sidecar

cd sidecar

# Instalar dependências
npm install

# Executar em modo desenvolvimento
npm run dev

# Testar endpoints
curl http://localhost:3000/health
curl -H "Authorization: Bearer sua-api-key" http://localhost:3000/metrics

📚 RECURSOS ADICIONAIS

Documentação

  • README.md: Visão geral para usuários
  • README-for-devs.md: Este arquivo (guia técnico)
  • examples/: Exemplos práticos
  • sidecar/README.md: Documentação do sidecar

Ferramentas

  • Makefile: Comandos de automação
  • requirements.txt: Dependências Python
  • sidecar/package.json: Dependências Node.js

Configurações de ambiente

# .env do sidecar
PORT=3000
WS_PORT=3001
API_KEY=sua-api-key-super-secreta
ALLOWED_ORIGINS=http://localhost:3000,http://127.0.0.1:3000
PUPPETEER_ARGS=--no-sandbox --disable-setuid-sandbox
LOG_LEVEL=info

🎯 PRÓXIMOS PASSOS

v0.5.1 (Atual)

  • Interface web para supervisão
  • Sistema de métricas e analytics avançado
  • Orquestração multi-instância
  • Integração com sistemas externos (CRM, ERP)
  • Suporte a múltiplos números por sessão
  • Sistema de templates de mensagem
  • Backup e restore de sessões

Contribuições

  • Testes unitários completos
  • Documentação adicional
  • Novos tipos de storage (Redis, PostgreSQL)
  • Melhorias de performance
  • Novos tipos de mensagem (botões, listas)
  • Sistema de webhooks

🚨 SUPORTE E TROUBLESHOOTING

🔍 PROBLEMAS COMUNS E SOLUÇÕES

1. Sidecar não inicia

# ❌ Erro: "Node.js version must be 18.0.0 or higher"
# ✅ Solução: Atualizar Node.js
node --version  # Deve ser ≥18.0.0
nvm install 18  # ou baixar do nodejs.org

# ❌ Erro: "Cannot find module 'whatsapp-web.js'"
# ✅ Solução: Reinstalar dependências
cd sidecar && rm -rf node_modules package-lock.json
npm install

2. QR Code não aparece

# ❌ Problema: Evento 'qr' não dispara
# ✅ Solução: Verificar WebSocket
import logging
logging.basicConfig(level=logging.DEBUG)

# Verificar se está conectando
@session.on("connecting")
def on_connecting(data):
    print("Conectando...")

@session.on("qr")
def on_qr(data):
    print(f"QR: {data['qr']}")  # Deve aparecer aqui

3. Mensagens não enviam

# ❌ Problema: "Session not ready"
# ✅ Solução: Aguardar evento 'ready'
@session.on("ready")
def on_ready(data):
    print("WhatsApp pronto! Agora pode enviar")
    session.send_text("5511999999999", "Teste")

# ❌ Problema: "Rate limit exceeded"
# ✅ Solução: Aguardar e tentar novamente
import time
time.sleep(60)  # Aguardar 1 minuto

4. WebSocket desconectado

# ❌ Problema: Eventos param de chegar
# ✅ Solução: Reconexão automática
@session.on("disconnected")
def on_disconnected(data):
    print(f"Desconectado: {data['reason']}")
    # Reconexão automática em andamento

@session.on("ready")
def on_ready(data):
    print("Reconectado!")

📊 DIAGNÓSTICO RÁPIDO

# 1. Verificar sidecar
curl http://localhost:3000/health

# 2. Verificar sessões ativas
curl -H "Authorization: Bearer ${API_KEY}" \
     http://localhost:3000/metrics

# 3. Ver logs do sidecar
cd sidecar && npm run dev

# 4. Ver logs Python
python -c "import logging; logging.basicConfig(level=logging.DEBUG)"

🚨 CENÁRIOS CRÍTICOS

Sessão expirada (QR não aparece)

# 1. Parar todas as sessões
curl -X POST -H "Authorization: Bearer ${API_KEY}" \
     http://localhost:3000/api/sessions/stop-all

# 2. Reiniciar sidecar
cd sidecar && npm restart

# 3. Recriar sessão
session = manager.create_session("nova_sessao")
session.start()

WhatsApp banido/limitado

# ❌ Erro: "Account banned" ou "Too many requests"
# ✅ Solução: Aguardar e usar número diferente
import time

# Aguardar 24h para ban
time.sleep(24 * 60 * 60)

# Ou usar número alternativo
session2 = manager.create_session("sessao_2", phone_number="5511888888888")

Logs e debug

import logging
logging.basicConfig(level=logging.DEBUG)

# Logs detalhados de todas as operações
manager = WhatsWebManager()

Verificar health do sidecar

# Health check
curl http://localhost:3000/health

# Ver logs do sidecar
cd sidecar
npm run dev

🎉 CONCLUSÃO

A PyWhatsWeb v0.5.1 é uma biblioteca completa e funcional que oferece:

Arquitetura moderna com sidecar Node.js
Multi-sessão para múltiplos atendentes
Eventos em tempo real via WebSocket
Storage pluggable (FileSystem ou Django)
Sistema Kanban para gestão de conversas
API Python limpa e fácil de usar
Sem dependências de navegador/Selenium
Funciona em qualquer projeto Python
Reconexão automática com backoff exponencial
Sistema de idempotência para deduplicação
Health check e métricas completas
Segurança robusta com rate limiting e CORS
Exemplo Django completo com dashboard funcional

Para começar agora:

  • Inicie o sidecar: cd sidecar && npm install && npm start
  • Use a biblioteca Python em seu projeto
  • Configure eventos e handlers
  • Gerencie múltiplas sessões
  • Implemente o sistema Kanban
  • Monitore com health check e métricas

A biblioteca está pronta para uso em produção com todas as funcionalidades essenciais implementadas! 🚀

🔑 FUNÇÕES PRINCIPAIS - RESUMO RÁPIDO

🚀 CORE FUNCTIONS

# 1. MANAGER - Gerenciador principal
manager = WhatsWebManager(api_key="sua-chave")
manager.create_session("id")      # Criar sessão
manager.list_sessions()           # Listar todas
manager.get_active_sessions()     # Sessões ativas

# 2. SESSION - Sessão individual
session = manager.get_session("id")
session.start()                   # Iniciar conexão
session.stop()                    # Parar sessão
session.send_text(to, text)      # Enviar texto
session.send_media(to, path)     # Enviar arquivo

# 3. EVENTS - Sistema de eventos
@session.on("qr", handler)       # QR Code
@session.on("message", handler)  # Mensagem recebida
@session.on("ready", handler)    # WhatsApp pronto
@session.on("disconnected", handler)  # Desconectado

💾 STORAGE - Persistência de dados

# FileSystem (padrão)
storage = FileSystemStore("./data")

# Django ORM (opcional)
storage = DjangoORMStore()
storage.set_models(WhatsAppSession, WhatsAppMessage)

# Operações básicas
storage.save_message(message)
storage.get_chat_messages(chat_id)
storage.save_contact(contact)

🔧 UTILITIES - Ferramentas auxiliares

from pywhatsweb.utils import *

# Números de telefone
normalize_phone_number("11999999999")  # +5511999999999
validate_phone_number("11999999999")   # (True, "+5511999999999")

# IDs e timestamps
generate_session_id("session", "tenant")  # session_tenant_1703000000_abc123
format_timestamp(datetime.now(), "America/Sao_Paulo")

🚨 ERROR HANDLING - Tratamento de erros

from pywhatsweb.errors import *

# Códigos de erro padronizados
ErrorCode.E_SESSION_NOT_FOUND      # 404
ErrorCode.E_AUTHENTICATION_FAILED  # 401
ErrorCode.E_MEDIA_TOO_LARGE       # 400

# Criar resposta de erro
error_response = create_error_response(ErrorCode.E_SESSION_NOT_FOUND)

📋 CHANGELOG v0.5.1

🔧 CORRIGIDO

  • Bug de compatibilidade Python 3.13: Corrigido erro TypeError: non-default argument follows default argument em dataclasses
  • Ordem de campos: Reordenados campos obrigatórios antes de campos opcionais em MediaMessage e Chat
  • Compatibilidade: Todas as classes dataclass agora funcionam perfeitamente com Python 3.13+

✨ ADICIONADO

  • Suporte explícito Python 3.13: Verificação automática e mensagens informativas
  • Verificação de compatibilidade: Detecta versão Python e dependências no import
  • Configurações centralizadas: Todas as configurações padrão em __default_config__
  • Informações de versão: Atributos __python_support__, __dependencies__, etc.

📚 DOCUMENTAÇÃO

  • Matriz de compatibilidade atualizada: Inclui Python 3.13 explicitamente
  • README atualizado: Versão e funcionalidades da v0.5.1
  • CHANGELOG completo: Todas as mudanças documentadas

🚀 MELHORIAS

  • Import otimizado: Verificação de compatibilidade automática
  • Mensagens informativas: Feedback sobre versões suportadas
  • Estrutura de dados: Dataclasses mais robustas e compatíveis

📋 CHANGELOG v0.4.1

✨ Novas Funcionalidades [LIB + README]

  • Autenticação WebSocket obrigatória com token + multi-tenant [LIB]
  • Endpoint /metrics Prometheus para monitoramento avançado [LIB]
  • Sistema de idempotência reforçado com outbox pattern [LIB]
  • Dockerfile e docker-compose otimizados para produção [LIB]
  • Runbooks ampliados para cenários críticos (2FA, ban, limites) [README]
  • CLI operacional para suporte e diagnóstico [LIB + README]
  • Webhooks e SSE fallback quando WebSocket não disponível [LIB + README]
  • Sistema de backpressure com filas Redis/memória [LIB + README]
  • Política LGPD com retenção configurável e criptografia [LIB + README]

🔧 Melhorias [LIB + README]

  • Normalização E.164 e validação de números de telefone [LIB]
  • Catálogo de erros padronizados com 50+ códigos HTTP [LIB]
  • Reconexão automática com backoff exponencial e heartbeat [LIB]
  • Sistema Kanban com rastreamento completo de conversas [LIB]
  • Exemplos Django com template HTML e consumer WebSocket [README]
  • Matriz de compatibilidade com verificação fail-fast [LIB + README]
  • Tabela de limites e timeouts centralizada [README]
  • Headers de correlação padronizados (X-Correlation-Id, X-Tenant-Id) [LIB + README]

🐛 Correções [LIB + README]

  • Consolidação de segurança (Helmet, CORS, Rate Limiting unificados) [LIB]
  • Ajustes de payloads de eventos e status de sessão [LIB]
  • Endpoints /metrics duplicados corrigidos (Prometheus + JSON) [LIB]
  • Dockerfile com usuário correto (node em vez de nodejs) [LIB]
  • Versões inconsistentes padronizadas para v0.5.1 [README]
  • WebSocket auth com compatibilidade entre versões do ws [LIB]

📚 Documentação [README]

  • README-for-devs.md completo e atualizado
  • Exemplos práticos para todos os casos de uso
  • Guia de configuração e troubleshooting
  • Documentação de segurança e boas práticas
  • Matriz de compatibilidade com verificação automática
  • CLI operacional com comandos de diagnóstico
  • Exemplo Django completo com template HTML funcional

📋 CHANGELOG v0.4.4

🔧 CORRIGIDO

  • Bug de compatibilidade websockets 15.0+: Corrigido erro AttributeError: module 'websockets' has no attribute 'version_tuple'
  • Verificação de versão: Implementado fallback robusto para diferentes versões de websockets
  • Compatibilidade: Suporte total a websockets 15.0+ e Python 3.13

✨ ADICIONADO

  • Suporte websockets modernos: Compatibilidade com versões 15.0+ que não possuem version_tuple
  • Fallback automático: Verificação de versão usando __version__ quando version_tuple não está disponível
  • Verificação robusta: Tratamento de erros para diferentes atributos de versão

🚀 MELHORIAS

  • Compatibilidade total: Python 3.13 + websockets 15.0+ funcionando perfeitamente
  • Verificação resiliente: Sistema de compatibilidade mais robusto
  • Fallback inteligente: Adaptação automática a diferentes versões de dependências

📋 CHANGELOG v0.5.1

🔧 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

Keywords

whatsapp

FAQs

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts