--- name: whatsapp_read_chat kind: function lang: py domain: browser version: "1.0.0" purity: impure signature: "def whatsapp_read_chat(name: str, *, n: int = 15, port: int = 9222, target_url_substr: str = 'whatsapp', open_first: bool = True) -> dict" description: "Lee los ultimos N mensajes de un chat de WhatsApp Web en una pestana ya logueada del navegador via CDP, sin abrir ventana nueva ni darle foco. Opcionalmente abre el chat primero con whatsapp_open_chat, luego extrae los ultimos n [role=row] del panel #main, normaliza su texto y detecta si cada mensaje es saliente por la presencia de .message-out. Compone whatsapp_open_chat + cdp_eval." tags: [whatsapp, cdp, browser, automation, python, navegator] uses_functions: [whatsapp_open_chat_py_browser, cdp_eval_py_browser] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: ["os", "sys", "time", "json"] params_schema: params: - name: name desc: "Nombre EXACTO del chat o grupo tal y como aparece en la lista lateral. Se pasa a whatsapp_open_chat cuando open_first=True." - name: n desc: "Numero maximo de mensajes recientes a leer (los ultimos del viewport renderizado). Default 15." - name: port desc: "Puerto de remote debugging de Chrome. Default 9222." - name: target_url_substr desc: "Substring que debe contener la URL del target (pestana). Default 'whatsapp'." - name: open_first desc: "Si True, abre el chat con whatsapp_open_chat antes de leer. Si el chat ya esta abierto, puede pasarse False para saltar la apertura. Default True." output: "dict {ok: bool, name: str, messages: list[{text: str, outgoing: bool}], count: int (si ok), reason: str (si no ok)}. messages son los ultimos n mensajes renderizados, mas reciente al final. outgoing=True si el mensaje es saliente (.message-out). Nunca lanza: los fallos de apertura se reportan en 'ok'=False + 'reason'." tested: true tests: ["test_golden_lee_mensajes_y_detecta_outgoing", "test_edge_open_first_falla_no_lee_y_devuelve_reason", "test_open_first_false_no_llama_open_chat"] test_file_path: "python/functions/browser/whatsapp_read_chat_test.py" file_path: "python/functions/browser/whatsapp_read_chat.py" --- ## Ejemplo ```python import sys, os sys.path.insert(0, os.path.join("python", "functions")) from browser.whatsapp_read_chat import whatsapp_read_chat # Requiere WhatsApp Web abierto y logueado en un Chrome lanzado con # --remote-debugging-port=9222. res = whatsapp_read_chat("NOTAS WASAP", n=5) print(res) # -> {"ok": True, # "name": "NOTAS WASAP", # "messages": [{"text": "hola", "outgoing": False}, # {"text": "que tal", "outgoing": True}, ...], # "count": 5} ``` O directo por CLI: `python3 python/functions/browser/whatsapp_read_chat.py "NOTAS WASAP" 5`. ## Cuando usarla Cuando necesites **leer la conversacion reciente** de un chat de WhatsApp Web — resumir el hilo, recuperar contexto, ver el ultimo mensaje recibido o saber quien escribio que— sin abrir ventana nueva ni robar el foco al usuario. Pasa `open_first=False` si el chat ya esta abierto para ahorrar el paso de apertura. ## Gotchas - **Viola los ToS de WhatsApp**: automatizar la web tiene riesgo de ban del numero. Usar con cautela y bajo tu responsabilidad. - **`outgoing` es heuristico**: se infiere de la presencia de `.message-out` en el row. Si WhatsApp cambia sus clases CSS, la deteccion entrante/saliente puede fallar. - **Solo lee mensajes RENDERIZADOS en el viewport** del chat. Los mensajes muy antiguos requieren scroll del panel, que esta funcion NO implementa: solo recoge los ultimos `n` rows visibles del DOM. - **Depende de `whatsapp_open_chat`** para localizar el chat (cuando `open_first=True`): hereda sus limitaciones (nombre EXACTO, contacto no cargado en la lista lateral puede no encontrarse, chat fuera de viewport). Si la apertura falla devuelve `ok=False` con `reason` y NO intenta leer. - **Funciona con la ventana minimizada o sin foco**: CDP opera la pestana sin necesidad de que Chrome este en primer plano.