caldav-email-reminders/dispatch.py
2025-05-01 17:04:01 -05:00

87 lines
3.1 KiB
Python

#!/usr/bin/env python3
import os
import sqlite3
import smtplib
import logging
from email.message import EmailMessage
from datetime import datetime, timezone
# ─── Environment & Logging ─────────────────────────────────────────────────────
DB_PATH = os.getenv("DB_PATH", "/data/sync_state.db")
# SMTP config from env; convert TLS/STARTTLS flags to real booleans
SMTP_HOST = os.getenv("SMTP_HOST")
SMTP_PORT = int(os.getenv("SMTP_PORT", "25"))
SMTP_USERNAME = os.getenv("SMTP_USERNAME")
SMTP_PASSWORD = os.getenv("SMTP_PASSWORD")
SMTP_USE_SSL = os.getenv("SMTP_USE_TLS", "false").lower() in ("1","true","yes")
SMTP_USE_STARTTLS = os.getenv("SMTP_USE_STARTTLS", "false").lower() in ("1","true","yes")
EMAIL_FROM = os.getenv("EMAIL_FROM")
EMAIL_TO = os.getenv("EMAIL_TO")
EMAIL_SUBJECT_PREFIX = os.getenv("EMAIL_SUBJECT_PREFIX", "")
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s"
)
logger = logging.getLogger(__name__)
# ─── Email sender ──────────────────────────────────────────────────────────────
def send_email(subject: str, body: str, to_addrs: str):
# 1) Choose SSL socket or plain
if SMTP_USE_SSL:
server = smtplib.SMTP_SSL(SMTP_HOST, SMTP_PORT)
else:
server = smtplib.SMTP(SMTP_HOST, SMTP_PORT)
if SMTP_USE_STARTTLS:
server.ehlo()
server.starttls()
server.ehlo()
# 2) Login if creds provided
if SMTP_USERNAME and SMTP_PASSWORD:
server.login(SMTP_USERNAME, SMTP_PASSWORD)
# 3) Build & send
msg = EmailMessage()
msg["Subject"] = subject
msg["From"] = EMAIL_FROM
msg["To"] = to_addrs
msg.set_content(body)
server.send_message(msg)
server.quit()
# ─── Dispatch loop ─────────────────────────────────────────────────────────────
def dispatch():
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
now_iso = datetime.now(timezone.utc).isoformat()
c.execute("""
SELECT id, event_uid, trigger_dt, summary, description
FROM reminders
WHERE trigger_dt <= ? AND sent_flag = 0
""", (now_iso,))
rows = c.fetchall()
for rid, uid, trigger_dt, summary, description in rows:
subject = f"{EMAIL_SUBJECT_PREFIX} {summary}"
body = (
f"{summary}\n\n"
f"{description}\n\n"
f"Scheduled at: {trigger_dt}"
)
try:
send_email(subject, body, EMAIL_TO)
c.execute("UPDATE reminders SET sent_flag = 1 WHERE id = ?", (rid,))
conn.commit()
logger.info(f"Sent reminder {rid} ({uid})")
except Exception as e:
logger.error(f"Failed to send reminder {rid}: {e}")
conn.close()
if __name__ == "__main__":
dispatch()