Files
2026-05-24 18:10:11 -04:00

58 lines
1.8 KiB
Python

"""
utils/email.py — SMTP email helper.
Reads server settings from app_settings (email.smtp_*) with .env fallbacks.
"""
import logging
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from config import get_setting
logger = logging.getLogger("utils.email")
def send_email(to, subject: str, body_text: str, body_html: str = None) -> None:
"""Send email via configured SMTP. `to` may be a str or list[str]. Raises on failure."""
host = get_setting("email.smtp_host", "").strip()
port = get_setting("email.smtp_port", "587").strip()
user = get_setting("email.smtp_user", "").strip()
passwd = get_setting("email.smtp_password", "").strip()
from_ = get_setting("email.smtp_from", "").strip() or user
if not host:
raise ValueError("SMTP host not configured. Add it via Admin → Settings.")
try:
port = int(port)
except (ValueError, TypeError):
port = 587
recipients = [to] if isinstance(to, str) else list(to)
if not recipients:
raise ValueError("No recipients specified.")
if body_html:
msg = MIMEMultipart("alternative")
msg.attach(MIMEText(body_text, "plain"))
msg.attach(MIMEText(body_html, "html"))
else:
msg = MIMEText(body_text, "plain")
msg["Subject"] = subject
msg["From"] = from_
msg["To"] = ", ".join(recipients)
with smtplib.SMTP(host, port, timeout=15) as smtp:
smtp.ehlo()
try:
smtp.starttls()
smtp.ehlo()
except smtplib.SMTPException:
pass # server may not support STARTTLS
if user and passwd:
smtp.login(user, passwd)
smtp.sendmail(from_, recipients, msg.as_string())
logger.info("Email sent to %s: %r", recipients, subject)