ahora si funciona
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
"""Lee los ultimos N mensajes de un chat de WhatsApp Web via Chrome DevTools Protocol.
|
||||
|
||||
Compone dos funciones del registry para extraer la conversacion reciente del chat
|
||||
abierto en una pestana ya logueada del navegador, SIN abrir ventana nueva ni darle
|
||||
foco al sistema:
|
||||
|
||||
1. (Opcional) Abre el chat por su nombre exacto con `whatsapp_open_chat`.
|
||||
2. Evalua una expresion JS via `cdp_eval` que recoge los ultimos `n` `[role="row"]`
|
||||
del panel principal (`#main`), normaliza su texto y detecta si cada mensaje es
|
||||
saliente comprobando la presencia de `.message-out` en el row.
|
||||
|
||||
Devuelve la lista de mensajes mas recientes con su direccion (entrante/saliente).
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
||||
|
||||
from browser.cdp_eval import cdp_eval
|
||||
from browser.whatsapp_open_chat import whatsapp_open_chat
|
||||
|
||||
|
||||
def whatsapp_read_chat(
|
||||
name: str,
|
||||
*,
|
||||
n: int = 15,
|
||||
port: int = 9222,
|
||||
target_url_substr: str = "whatsapp",
|
||||
open_first: bool = True,
|
||||
) -> dict:
|
||||
"""Lee los ultimos n mensajes renderizados de un chat de WhatsApp Web via CDP.
|
||||
|
||||
Args:
|
||||
name: Nombre EXACTO del chat/grupo tal y como aparece en la lista lateral
|
||||
(se pasa a `whatsapp_open_chat` cuando `open_first=True`).
|
||||
n: Numero maximo de mensajes recientes a leer (los ultimos del viewport).
|
||||
Default 15.
|
||||
port: Puerto de remote debugging de Chrome. Default 9222.
|
||||
target_url_substr: Substring que debe contener la URL del target (pestana).
|
||||
Default "whatsapp".
|
||||
open_first: Si True, abre el chat con `whatsapp_open_chat` antes de leer.
|
||||
Si el chat ya esta abierto y enfocado, puede pasarse False para ahorrar
|
||||
el paso de apertura. Default True.
|
||||
|
||||
Returns:
|
||||
dict con claves:
|
||||
ok: bool — True si se pudo leer el chat.
|
||||
name: str — el nombre solicitado.
|
||||
messages: list[dict] — mensajes recientes, cada uno {text: str,
|
||||
outgoing: bool}. Lista vacia si no hay mensajes o fallo la apertura.
|
||||
count: int — numero de mensajes leidos (solo si ok).
|
||||
reason: str — motivo del fallo (solo si ok=False).
|
||||
"""
|
||||
substr = target_url_substr
|
||||
|
||||
if open_first:
|
||||
o = whatsapp_open_chat(name, port=port, target_url_substr=substr)
|
||||
if not o.get("opened"):
|
||||
return {
|
||||
"ok": False,
|
||||
"name": name,
|
||||
"messages": [],
|
||||
"reason": o.get("reason", "no se pudo abrir el chat"),
|
||||
}
|
||||
|
||||
# Leer los ultimos n rows del panel principal. Detecta mensaje saliente por
|
||||
# la presencia de .message-out en el row. Normaliza el texto (colapsa espacios)
|
||||
# y lo trunca a 500 caracteres para acotar el payload.
|
||||
expr = (
|
||||
"(() => { const rows=[...document.querySelectorAll('#main [role=\"row\"]')]"
|
||||
".slice(-" + str(int(n)) + ");"
|
||||
"return JSON.stringify(rows.map(r=>({"
|
||||
"text: r.innerText.replace(/\\s+/g,' ').trim().slice(0,500),"
|
||||
"outgoing: !!r.querySelector('.message-out')"
|
||||
"})));})()"
|
||||
)
|
||||
r = cdp_eval(expr, port=port, target_url_substr=substr)
|
||||
msgs = json.loads(r.get("value") or "[]")
|
||||
return {"ok": True, "name": name, "messages": msgs, "count": len(msgs)}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
chat = sys.argv[1] if len(sys.argv) > 1 else "NOTAS WASAP"
|
||||
count = int(sys.argv[2]) if len(sys.argv) > 2 else 15
|
||||
out = whatsapp_read_chat(chat, n=count, port=9222, target_url_substr="whatsapp")
|
||||
print(json.dumps(out, ensure_ascii=False, indent=2))
|
||||
Reference in New Issue
Block a user