Files
INFRAESTRUCTURA/scripts/monitor_estado/fuentes/correo.py
2026-10-03 17:13:39 +02:00

74 lines
2.6 KiB
Python

# -*- coding: utf-8 -*-
"""correo.py — Fuente de correo de empresa del monitor (RF-2, RF-6, RF-25).
Recoge los correos de las ultimas 24 h (o los de hoy) de `jminguez@prolongo.es`
usando la API de Gmail con el OAuth ya existente (repositorio de negocio).
SOLO LECTURA: usa `messages().list()` y `messages().get()`; nunca marca correos
como leidos ni modifica nada (RF-25).
"""
from __future__ import annotations
import sys
from .. import config # noqa: F401 (asegura sys.path con scripts/)
import infra_paths # ya disponible en sys.path (lo anade config.py)
def _bootstrap_google() -> None:
"""Deja importable el paquete `common` del repo de negocio (google/)."""
repo = infra_paths.bootstrap_biblioteca_paths()
google_dir = repo / "google"
if google_dir.exists() and str(google_dir) not in sys.path:
sys.path.insert(0, str(google_dir))
def construir_servicio():
"""Devuelve el servicio de Gmail autenticado (OAuth existente)."""
_bootstrap_google()
import common # google/common.py
return common.gmail_service()
def _consulta(horas: int) -> str:
"""Consulta Gmail para la ventana pedida (granularidad en dias)."""
dias = max(1, int(horas) // 24)
return f"in:inbox newer_than:{dias}d"
def recoger_recientes(gmail=None, horas: int = 24, limite: int = 50) -> list[dict]:
"""Devuelve los correos de la ventana, con {id, fecha, de, asunto, snippet}.
No modifica el estado de los correos (no marca leido).
"""
gmail = gmail or construir_servicio()
res = gmail.users().messages().list(userId="me", q=_consulta(horas), maxResults=limite).execute()
salida: list[dict] = []
for m in res.get("messages", []):
full = gmail.users().messages().get(
userId="me", id=m["id"], format="metadata",
metadataHeaders=["Subject", "From", "Date"],
).execute()
headers = {h["name"].lower(): h["value"] for h in full.get("payload", {}).get("headers", [])}
salida.append({
"id": m["id"],
"fecha": headers.get("date", ""),
"de": headers.get("from", "?"),
"asunto": headers.get("subject", "(sin asunto)"),
"snippet": full.get("snippet", ""),
})
return salida
def render_correo(m: dict) -> str:
"""Render Markdown de un correo para el fichero del dia."""
asunto = m.get("asunto", "(sin asunto)")
de = m.get("de", "?")
fecha = m.get("fecha", "")
snippet = (m.get("snippet") or "").strip()
linea = f"- **{fecha}** — **{de}:** {asunto}"
return f"{linea}\n {snippet}" if snippet else linea