"""Transport selection for CRM-originated email (daily digest, admin test sends). Prefers Gmail-over-DWD — it reuses the service account that already powers email capture (the grant includes gmail.compose, which can send), so there's no extra credential to manage — and falls back to SMTP (`smtp_send`) when DWD isn't available. One entry point so the digest and the admin test endpoint share the same routing. Stdlib only. """ import os class NoTransport(Exception): """Neither Gmail DWD nor SMTP is configured.""" def transport(): """Return the active transport: 'gmail-dwd', 'smtp', or None.""" try: from email_integration import gmail_send if gmail_send.gmail_available(): return "gmail-dwd" except Exception: pass try: import smtp_send if smtp_send.smtp_configured(): return "smtp" except Exception: pass return None def default_sender(conn): """Domain user to send as for the DWD path. `CRM_DIGEST_SENDER` if set, else the first active admin's email.""" s = os.environ.get("CRM_DIGEST_SENDER", "").strip() if s: return s if conn is None: return None row = conn.execute( "SELECT email FROM users WHERE role='admin' AND is_active=1 " "AND email IS NOT NULL AND TRIM(email)!='' ORDER BY created_at LIMIT 1" ).fetchone() return row["email"].strip() if row and row["email"] else None def send_digest(conn, to_addrs, subject, body, sender_email=None): """Send via the active transport. Returns the transport's result dict with a 'transport' key added; raises NoTransport if neither is configured.""" t = transport() if t == "gmail-dwd": from email_integration import gmail_send sender = sender_email or default_sender(conn) result = gmail_send.send_via_gmail(sender, to_addrs, subject, body, conn=conn) result["transport"] = "gmail-dwd" return result if t == "smtp": import smtp_send result = smtp_send.send_email(to_addrs, subject, body) result["transport"] = "smtp" return result raise NoTransport("No email transport configured: enable Gmail (DWD) or set " "SMTP via the 'Configure Digest SMTP' action.")