Files
fn_registry/docs/capabilities/whatsapp.md
T
egutierrez 10bfb846a8 ahora si funciona
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-07 16:23:52 +02:00

5.0 KiB

WhatsApp — Operar WhatsApp Web por CDP sobre la sesión existente

Tag: whatsapp. Grupo de funciones para automatizar WhatsApp Web (buscar/abrir un chat, leer la conversación, enviar texto) operando por Chrome DevTools Protocol sobre la pestaña ya abierta y logueada del navegador diario, sin abrir ventana nueva ni darle foco.

Filtro MCP: mcp__registry__fn_search query="" tag="whatsapp".

Por qué CDP y no HTTP replay

WhatsApp Web no envía mensajes por HTTP requests REST: usa un WebSocket (wss) como transporte y cifrado extremo a extremo (Signal/Noise), con claves que rotan por mensaje y viven en el navegador. El tráfico capturable es binario cifrado e irreproducible — por eso el patrón flow-replay (grabar HTTP → reproducir) no aplica aquí. La única vía que opera la sesión existente sin ventana nueva es automatizar el DOM por CDP. (Baileys/whatsapp-web.js quedan descartados: emparejan un dispositivo nuevo por QR, o abren su propio navegador.)

Funciones del grupo

ID Firma corta Qué hace
whatsapp_open_chat_py_browser whatsapp_open_chat(name, *, port=9222) -> dict Busca y abre un chat por nombre exacto (ancla span[title] + click de ratón real). Verifica el destinatario. Base de read/send.
whatsapp_read_chat_py_browser whatsapp_read_chat(name, *, n=15, open_first=True) -> dict Lee los últimos N mensajes renderizados del chat ({text, outgoing}).
whatsapp_send_message_py_browser whatsapp_send_message(name, text, *, open_first=True) -> dict Envía un texto. Salvaguarda: verifica destinatario + contenido exacto del composer antes de pulsar Enter.

Primitivas CDP que componen (grupo navegator)

El transport está en 4 primitivas Python reutilizables (cualquier automatización de la sesión diaria):

ID Qué hace
cdp_eval_py_browser Evalúa JS en un target por substring de URL (leer DOM, focus(), resolver coords).
cdp_type_chars_py_browser Escribe char-by-char con key events reales (único método que funciona con el editor Lexical).
cdp_press_key_py_browser Pulsa una tecla nombrada (Enter, Escape, Backspace, Arrows...) con modificadores.
cdp_click_xy_py_browser Click de ratón real en coordenadas (necesario: element.click() JS no dispara los handlers de React).

Ejemplo canónico end-to-end

Requisito: WhatsApp Web abierto y logueado en un Chrome con --remote-debugging-port=9222 (en este equipo, el CDP global de chromium ya lo expone). No hace falta foco ni ventana visible.

import sys, os
sys.path.insert(0, os.path.join("python", "functions"))
from browser.whatsapp_read_chat import whatsapp_read_chat
from browser.whatsapp_send_message import whatsapp_send_message

# Leer los últimos mensajes de un chat
r = whatsapp_read_chat("NOTAS WASAP", n=5)
for m in r["messages"]:
    print(("→" if m["outgoing"] else "←"), m["text"])

# Enviar un mensaje (acción con efecto: envía de verdad)
res = whatsapp_send_message("NOTAS WASAP", "hola desde el registry")
print(res)   # {"sent": True, "last_row": "hola desde el registry 11:48"}

Fronteras y gotchas (leer antes de usar)

  • Viola los ToS de WhatsApp; riesgo de ban del número. Probar en un chat propio reduce molestia a terceros pero no elimina el riesgo de detección por patrón.
  • Envío irreversible: whatsapp_send_message envía de verdad y WhatsApp no permite des-enviar por esta vía. La función verifica destinatario (name exacto en el composer) y contenido antes de Enter, pero el name lo das tú: un nombre ambiguo abre el primer match.
  • Nombre exacto requerido (span[title] exacto). El buscador no filtra de forma fiable los contactos NO cargados en la lista lateral; funciona para chats recientes/visibles. Un contacto sin chat reciente puede no encontrarse (limitación conocida; mejora futura: scroll).
  • Lexical: escribir SOLO con cdp_type_chars (key events reales). execCommand/el.value meten texto fantasma y producen duplicación/intercalado.
  • Abrir chats: requiere click de ratón real (cdp_click_xy); element.click() JS no abre.
  • outgoing se infiere de .message-out (heurístico) y puede no marcar bien los mensajes propios en algunos grupos; el text siempre es fiable.
  • Solo lee lo renderizado en el viewport del chat; mensajes muy antiguos requieren scroll (no implementado).
  • Funciona con la ventana minimizada y sin foco (CDP no depende del foco del SO).

Prerequisitos

  • Chrome/Chromium con remote debugging en el puerto 9222 y WhatsApp Web logueado.
  • websocket-client en python/.venv (ya presente). Sin dependencias nuevas.