Files
descarga_factura_transporte/docs/outlook_utilities.md
T
GeorgeandClaude Sonnet 5.5 d4c1e0a264 se agrega README y se completa y corrige la documentación
README en la raíz con instalación, uso, estructura e índice de docs. Nuevos
docs/hana_manager.md y docs/outlook_utilities.md. Se renombran los .mkd a .md
y se corrigen construir_draft y validar_precios, que describían lógica ya
inexistente (CUADRO_VALOR_REFERENCIAL, use_sap_prices). Se actualizan los
docstrings obsoletos y las cifras de líneas del inventario.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 22:03:38 -05:00

2.8 KiB
Raw Blame History

outlook_utilities.py — Microsoft Graph (Outlook)

Cliente mínimo de Microsoft Graph para leer la bandeja de entrada, bajar adjuntos y enviar las notificaciones. Autenticación con MSAL (client credentials, permisos de aplicación).

Estructura

outlook_utilities.py
├── CONFIG (.env): CLIENT_ID, CLIENT_SECRET, TENANT_ID, VERIFY_SSL (false por defecto)
├── get_access_token() → str
├── get_emails(user_email, token, fecha_inicio, fecha_fin) → list[dict]
├── download_attachments(user_email, message_id, token, download_path) → list[str]
└── send_email(access_token, from_email, to_recipients, subject, html_body,
               attachment_paths=None, cc_recipients=None) → bool

Funciones

Función Endpoint Graph Qué hace
get_access_token login.microsoftonline.com/{TENANT_ID} (scope .default) Obtiene el token de aplicación. Lanza Exception si MSAL devuelve error.
get_emails GET /users/{user}/mailFolders/Inbox/messages Correos de la bandeja de entrada del rango, con paginación ($top=50, sigue @odata.nextLink). Devuelve id, fecha, sender, subject, has_attach. Lanza Exception si el status no es 200.
download_attachments GET /users/{user}/messages/{id}/attachments Guarda en download_path los adjuntos tipo archivo y devuelve sus nombres. Crea la carpeta si no existe.
send_email POST /users/{from}/sendMail Envía HTML con adjuntos y CC; guarda copia en Enviados. Devuelve True si Graph responde 202; False (con ERROR en el log) en cualquier otro caso. No lanza excepciones.

Zona horaria

get_emails asume UTC-5 (Perú, sin horario de verano): el rango fecha_inicio–fecha_fin se convierte a UTC sumando 5 h (el fin incluye todo el día), y el campo fecha devuelto resta 5 h a receivedDateTime.

Adjuntos de send_email

Los adjuntos se leen de las rutas indicadas. Una ruta inexistente se omite con un WARNING. El contentType se deduce de la extensión (.pdf, .xml, .json; cualquier otra, application/octet-stream).

Notas

  • download_attachments solo guarda adjuntos tipo fileAttachment con contenido; los adjuntos de tipo mensaje o referencia se ignoran.
  • Dos correos con un adjunto del mismo nombre se sobrescriben entre sí si comparten download_path (el pipeline usa una única carpeta, DOWNLOAD_FOLDER).
  • VERIFY_SSL se respeta en get_access_token, get_emails y download_attachments, pero send_email tiene verify_ssl = False fijo y lo ignora.
  • El módulo ejecuta warnings.filterwarnings("ignore"), lo que silencia todas las advertencias de Python del proceso (incluidas las de certificado SSL).
  • get_access_token retorna None (sin lanzar error) si MSAL devuelve un resultado vacío.