Summary
Add email notifications via Resend for vehicle document expiry reminders. Email uses its own custom schedule — it fires only at -5 days and -1 day before expiry, independent of the existing Discord/Telegram reminder schedule (-7/-3/-1/0/+1/+3/+7/+15/+30). Single-owner (email goes to the owner).
Scope
1. Self-contained Resend sender
- New
utils/email.py exposing send_email(to, subject, html, text=None) -> bool.
- POSTs to
https://api.resend.com/emails using RESEND_API_KEY.
- Fully self-contained (each repo owns its copy).
- Never blocks or breaks the primary path: wrapped in try/except, failures logged and swallowed, existing Discord/Telegram delivery unaffected.
2. Custom email offsets in the cron sweep
- In
cron/reminder_sweep.py, add a separate email offset set [-5, -1] evaluated independently of the existing notify offsets.
- When a document's days-to-expiry equals -5 or -1, send an email to the owner in addition to whatever the normal schedule does.
- Deduplicate email sends the same way reminders are deduped (extend
reminder_log, or add an email-specific dedupe, so the same (vehicle, field, expiry_date, offset) email isn't sent twice).
3. Job-run logging (shared ops table)
- The daily sweep writes one row to the shared
ops.job_runs table (defined in the OneRingToRuleThemAll weekly-report issue): job name, started/finished, status, error, counts (vehicles checked, reminders sent, emails sent).
Config / env
RESEND_API_KEY — Resend key.
EMAIL_FROM — e.g. Pitstop <reminders@yourdomain>.
OWNER_EMAIL — recipient address for reminder emails.
- Add to
.env.example, README, and the cron GitHub Actions secrets.
Out of scope
- Per-user email (this app is single-owner).
- Changing the existing Discord/Telegram reminder schedule.
Summary
Add email notifications via Resend for vehicle document expiry reminders. Email uses its own custom schedule — it fires only at -5 days and -1 day before expiry, independent of the existing Discord/Telegram reminder schedule (
-7/-3/-1/0/+1/+3/+7/+15/+30). Single-owner (email goes to the owner).Scope
1. Self-contained Resend sender
utils/email.pyexposingsend_email(to, subject, html, text=None) -> bool.https://api.resend.com/emailsusingRESEND_API_KEY.2. Custom email offsets in the cron sweep
cron/reminder_sweep.py, add a separate email offset set[-5, -1]evaluated independently of the existing notify offsets.reminder_log, or add an email-specific dedupe, so the same(vehicle, field, expiry_date, offset)email isn't sent twice).3. Job-run logging (shared ops table)
ops.job_runstable (defined in the OneRingToRuleThemAll weekly-report issue): job name, started/finished, status, error, counts (vehicles checked, reminders sent, emails sent).Config / env
RESEND_API_KEY— Resend key.EMAIL_FROM— e.g.Pitstop <reminders@yourdomain>.OWNER_EMAIL— recipient address for reminder emails..env.example, README, and the cron GitHub Actions secrets.Out of scope