Skip to content

About

Bot que envía un mensaje por WhatsApp Web indicando que la tarea fue finalizada y qué patrones de diseño se utilizaron

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

10 Commits

Folders and files

Repository files navigation

WhatsApp Bot con Playwright

Bot de automatización para WhatsApp Web que envía mensajes, implementado con Playwright y tres patrones de diseño fundamentales: Factory Method, Page Object Model y Template Method.

✨ Novedades v1.2.0

  • 🎯 Browser siempre visible: WhatsApp Web requiere browser visible; eliminado headless que causaba fallos
  • 🔔 Auto-dismiss popups: "Novedades en WhatsApp Web" (clic en "Continuar") + "Sincronización en pausa"
  • 🔄 Retry inteligente: 3 intentos con limpieza gradual (state.json → persistent context → full reset)
  • 🚀 Envío múltiple en una instancia: Un solo browser para todos los contactos (sin abrir/cerrar por contacto)
  • ⚙️ Rate limiting configurable: --delay segundos entre envíos (default 2.5s)
  • 🔧 Selectores robustos: Fallbacks para botón enviar (aria-label, data-testid, data-icon)

🏗️ Arquitectura y Patrones de Diseño

1. Page Object Model (POM) — src/whatsapp_bot/pages/whatsapp_page.py

Encapsula todos los selectores DOM y acciones de WhatsApp Web en una sola clase:

  • Selectores basados en data-testid para máxima estabilidad
  • Métodos: search_contact(), type_message(), click_send(), wait_for_qr(), is_logged_in()
  • Separa la lógica de UI de la lógica de negocio

2. Factory Method — src/whatsapp_bot/factories/browser_factory.py

Centraliza la creación del contexto de navegador:

  • BrowserFactory.create_context(config) retorna BrowserContext configurado
  • Usa launch_persistent_context() para persistir cookies, IndexedDB, Service Workers
  • Si NO hay sesión → crea contexto limpio con headless=False para escaneo QR manual

3. Template Method — src/whatsapp_bot/flows/base_bot_flow.py

Define el algoritmo esqueleto del bot en BaseBotFlow.run():

def run(self):
    self.setup()
    self.init_browser()
    self.authenticate_or_load_session()
    self.execute_task()
    self.cleanup()
  • WhatsAppBotFlow implementa los pasos concretos usando WhatsAppPage

📦 Instalación

Requisitos previos

  • Python 3.10+
  • PDM instalado

Pasos

# Clonar repositorio
git clone https://github.com/AngBan2x/whatsapp-playwright-bot.git
cd whatsapp-playwright-bot

# Instalar dependencias con PDM
pdm install

# Instalar navegador Chromium
pdm run playwright install chromium

🔐 Configuración de Credenciales (Keyring)

El bot usa Windows Credential Manager (via keyring) para almacenar números de forma segura.

Número por defecto (target_phone)

# Configurar número por defecto (usado por `run.bat` o `send` sin argumentos)
pdm run python -c "
import keyring
keyring.set_password('whatsapp-bot', 'target_phone', '+584120000000')
print('Número por defecto guardado')
"

Verificar número guardado

pdm run python -c "
import keyring
print(keyring.get_password('whatsapp-bot', 'target_phone'))
"

▶️ Ejecución

Opción 1: Script Windows (usa número por defecto + mensaje predeterminado)

run.bat

Mantiene la consola abierta al finalizar para ver logs.

Opción 2: CLI Completa (nuevas capacidades v1.2.0)

# Ver ayuda general
pdm run python main.py --help

# Ver ayuda de subcomando send
pdm run python main.py send --help

# Ver ayuda de subcomando contacts
pdm run python main.py contacts --help

📋 Comandos CLI

send — Enviar mensajes

# Enviar mensaje predeterminado al número por defecto (keyring target_phone)
pdm run python main.py send

# Enviar a número específico con mensaje personalizado
pdm run python main.py send --to "+58 424-0000000" --message "Hola desde el bot"

# Enviar a múltiples números
pdm run python main.py send --to +584120000000 --to +584240000000

# Enviar a contactos guardados por alias
pdm run python main.py send --contact josh --contact andres

# Combinar números directos y contactos
pdm run python main.py send --to +584120000000 --contact juan --message "Mensaje grupal"

# Simular envío sin abrir navegador (dry-run)
pdm run python main.py send --to +584120000000 --dry-run

# Cambiar delay entre envíos (default: 2.5s)
pdm run python main.py send --to +584120000000 --to +584240000000 --delay 3.0

Opciones de send:

Opción Descripción
--to NUMBER Número destino (E.164). Repetible para múltiples.
--contact, -c ALIAS Alias de contacto guardado. Repetible. Case-insensitive.
--message, -m TEXT Mensaje personalizado. Si no se usa, usa el predeterminado.
--dry-run Simula sin abrir navegador ni enviar real.
--delay SECONDS Segundos entre envíos múltiples (default: 2.5).

Nota: Si usas --message, se añade automáticamente: \nRepo: https://github.com/AngBan2x/whatsapp-playwright-bot

contacts — Gestión de contactos

# Agregar contacto (alias case-insensitive, número se normaliza)
pdm run python main.py contacts add josh "+58 414-0000000"
pdm run python main.py contacts add andres "+58 412-0000001"

# Listar contactos
pdm run python main.py contacts list

# Ver número de un contacto
pdm run python main.py contacts show josh

# Eliminar contacto
pdm run python main.py contacts remove josh

🔄 Persistencia de Sesión

Ejecución Comportamiento
Primera Abre Chromium visible (headless=False), muestra QR, espera escaneo manual, guarda sesión en session/
Subsecuentes Reutiliza sesión persistente desde session/, omite QR, envía mensaje directamente
Fallo de sesión Retry inteligente: 3 intentos (reintento → limpiar state.json → limpiar context → full reset + QR)

La carpeta session/ está en .gitignore — nunca se sube el estado de autenticación al repositorio.


📨 Mensajes

Predeterminado (sin --message)

Tarea finalizada.
Patrones utilizados: Factory Method, Page Object Model, Template Method.

Personalizado (con --message "texto")

texto
Repo: https://github.com/AngBan2x/whatsapp-playwright-bot

🛡️ Manejo Automático de Popups (v1.2.0)

Popup Detección Acción
Novedades en WhatsApp Web Texto exacto + botón "Continuar" Auto-clic en "Continuar"
Sincronización en pausa Textos: "Entendido", "Continuar", "OK", "Aceptar", "Cerrar", "Got it", "Continue" Auto-clic y espera desaparición

Ambos popups se detectan y dismissan automáticamente antes de verificar login y antes de enviar cada mensaje.


📁 Estructura del Proyecto

.
├── .gitignore
├── LICENSE
├── README.md
├── pyproject.toml
├── run.bat
├── session/
└── src/
    └── whatsapp_bot/
        ├── __init__.py
        ├── main.py                 # Punto de entrada + CLI
        ├── config.py               # Keyring + contactos + normalización
        ├── cli.py                  # Argument parser
        ├── pages/
        │   └── whatsapp_page.py    # POM
        ├── factories/
        │   └── browser_factory.py  # Factory Method
        └── flows/
            ├── base_bot_flow.py    # Template Method (base)
            └── whatsapp_bot_flow.py # Implementación concreta

🛠️ Desarrollo

Formato de números

Se aceptan formatos flexibles y se normalizan automáticamente:

  • +58 412-0000000 → +584120000000
  • +58 (414) 000-0000 → +584140000000
  • +584120000000 → +584120000000 (ya normalizado)

Rate Limiting

Entre envíos múltiples hay un delay configurable (default 2.5s) para evitar bloqueos de WhatsApp Web.

Manejo de errores

Si falla un destinatario en envío múltiple: se loggea warning y continúa con los siguientes.

Dry-run

--dry-run simula toda la ejecución sin abrir navegador ni enviar mensajes reales.


📄 Licencia

MIT License — ver LICENSE para detalles.


📦 Release Notes

v1.2.0 (2026-08-27)

  • Browser siempre visible: WhatsApp Web requiere browser visible; eliminado modo headless
  • Popup "Novedades en WhatsApp Web": Auto-clic en "Continuar" (aparece tras primer login)
  • Popup "Sincronización en pausa": Auto-dismiss con textos "Entendido", "Continuar", "OK", "Aceptar", "Cerrar", "Got it", "Continue"
  • Retry inteligente de sesión: 3 intentos con limpieza gradual (state_only → gradual → full)
  • Envío múltiple en una instancia: Un solo browser para todos los contactos (elimina abrir/cerrar Chromium por contacto)
  • Rate limiting configurable: --delay segundos entre envíos (default 2.5s)
  • Selectores robustos para botón enviar: Fallbacks aria-label="Enviar/Send", data-testid="wds-ic-send-filled", data-icon="send"
  • Detección de sesión mejorada: Verifica cookies + IndexedDB de WhatsApp en persistent context
  • Compatibilidad retro: target_phone (string) + target_phones (lista) coexisten

v1.1.0 (2026-08-26)

  • CLI completo con subcomandos send y contacts
  • Múltiples destinatarios via --to repetido y/o --contact repetido
  • Contactos predefinidos con alias case-insensitive (contacts add/list/show/remove)
  • Mensaje personalizable via --message (añade link del repo automáticamente)
  • Normalización de números (acepta espacios, guiones, paréntesis)
  • Rate limiting configurable entre envíos (--delay)
  • Dry-run para testing sin envío real (--dry-run)
  • Error handling robusto: continúa en fallos parciales
  • Backward compatibility: run.bat sigue funcionando igual

v1.0.0 (2026-08-26)

  • Implementación base con 3 patrones: Factory Method, POM, Template Method
  • Persistencia de sesión con storage_state
  • Gestión de credenciales con keyring
  • Script run.bat para Windows

About

Bot que envía un mensaje por WhatsApp Web indicando que la tarea fue finalizada y qué patrones de diseño se utilizaron

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages