Biblioteca Python para WhatsApp Web corporativo com sidecar Python integrado (padrão) ou Node.js (opcional)
Project description
🚀 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"ousidecar_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
MediaMessageda classeMessage
✨ 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 principalSession: Sessão individualBaseStore,FileSystemStore,DjangoORMStore: StorageSessionStatus,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ãoget_session(): Recupera sessão existentelist_sessions(): Lista todas as sessõesget_active_sessions(): Sessões conectadasclose_all_sessions(): Para todas as sessõescleanup(): 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çãoauthenticated: Autenticação bem-sucedidaready: WhatsApp pronto para usomessage: Nova mensagem recebidadisconnected: 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
| 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+)
# 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ãoPOST /api/session/:id/stop- Para sessãoGET /api/session/:id/status- Status da sessãoPOST /api/session/:id/send-message- Envia mensagem
Eventos WebSocket:
qr: QR Code para autenticaçãoauthenticated: Autenticação bem-sucedidaready: WhatsApp prontomessage: Nova mensagemdisconnected: 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 argumentem dataclasses - Ordem de campos: Reordenados campos obrigatórios antes de campos opcionais em
MediaMessageeChat - 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__quandoversion_tuplenã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
MediaMessageda classeMessage
✨ 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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pywhatsweb-0.5.3.tar.gz.
File metadata
- Download URL: pywhatsweb-0.5.3.tar.gz
- Upload date:
- Size: 121.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
84d6f8eb65e8dbb0ecd39bfa0aa63434b3c61d42e82ffc0bcf00b884b65301ef
|
|
| MD5 |
93519d1b6d6a67c42f98808966685607
|
|
| BLAKE2b-256 |
f359d12716f6cbd10d39776c1b595342aed7ba7552de4facf4a4e4567aa9f62c
|
File details
Details for the file pywhatsweb-0.5.3-py3-none-any.whl.
File metadata
- Download URL: pywhatsweb-0.5.3-py3-none-any.whl
- Upload date:
- Size: 63.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
abd5eaec7acb8119866deaf9d86f1536c5dbc7d8c7fac42cd6e75cfa4688ba77
|
|
| MD5 |
9c92235656bcad5b3e998c1a4f5110b7
|
|
| BLAKE2b-256 |
4db572c85f708fe748f4fb60724408733836eda2c6547bdb56ceacbfcd7691a7
|