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