Files
2026-09-13 20:15:10 +01:00

4.6 KiB
Raw Permalink Blame History

Birthday Manager

Self-hosted birthday reminder application that automatically e-mails people on their birthday.

© 2026 Martinhal IT - Joao Vaz - Version 1.2

Features

Page 1 — Dashboard

  • Three panels at the top: Yesterday's Birthdays, Today's Birthdays (with the Force Send button to resend the e-mail) and Tomorrow's Birthdays
  • Add / remove birthday entries: First Name, Last Name, Date of Birth, Gender, E-mail address
  • Yearly calendar overview of all entries (hover a marked day to see the names; browse other years)

Page 2 — Administration

  • Add / remove application users
  • Every user can enable/disable MFA (TOTP — Google Authenticator, Authy, etc.) and change their own password
  • Full e-mail log: who received mail, at what date & time, and whether it succeeded
  • Setting for the time of day the automatic birthday e-mails are sent (applies immediately, no restart needed)
  • Two template zones: E-mail Template Male and E-Mail Template Female, with placeholders {first_name}, {last_name}, {age}
  • Image upload — select multiple files at once (15 MB total per upload); each image shows its ready-to-copy <img src="/uploads/…"> command, and images are embedded inline in the outgoing e-mail

Automatic sending: a scheduler runs every day at SEND_HOUR (default 08:00) and e-mails everyone whose birthday it is, using the template matching their gender. Duplicates are avoided (one automatic mail per person per day); Force Send always resends. February 29 birthdays are celebrated on February 28 in non-leap years.

Every successfully sent e-mail is also copied to the mailbox's Sent folder via IMAP, so it shows up in your normal mail client.

Mail provider

The app comes pre-configured for Purelymail:

Server Port Security
Outgoing (SMTP) smtp.purelymail.com 465 SSL/TLS
Incoming (IMAP, Sent-folder copy) imap.purelymail.com 993 SSL/TLS

You only need to fill in SMTP_USER, SMTP_PASS and SMTP_FROM with your Purelymail mailbox credentials. If your network only supports STARTTLS for SMTP, set SMTP_PORT=587 and SMTP_SECURITY=starttls instead. Any other provider works too — just override the host/port variables.

  1. Edit docker-compose.yml and fill in your Purelymail credentials (SMTP_USER, SMTP_PASS, SMTP_FROM) plus a random SECRET_KEY and your timezone.
  2. Run:
docker compose up -d --build
  1. Open http://localhost:8080 and log in with admin / admin — then change the password on the Administration page immediately.

All data (SQLite database + uploaded images) lives in ./data, so back up that folder.

Quick start (plain Python)

pip install -r requirements.txt

# Purelymail servers are the built-in defaults - only credentials are needed
export SMTP_USER=you@yourdomain.com
export SMTP_PASS=your-purelymail-password
export SMTP_FROM=you@yourdomain.com
export SEND_HOUR=8
export SECRET_KEY=$(python -c "import secrets;print(secrets.token_hex(32))")

python app.py

The app listens on port 8080 (PORT env var to change). Data is stored in ./data (DATA_DIR env var to change).

Environment variables

Variable Default Purpose
SMTP_HOST smtp.purelymail.com SMTP server
SMTP_PORT 465 SMTP port
SMTP_USER SMTP username / mailbox
SMTP_PASS SMTP password
SMTP_FROM SMTP_USER From address
SMTP_SECURITY ssl ssl, starttls or none
IMAP_HOST imap.purelymail.com IMAP server for the Sent-folder copy
IMAP_PORT 993 IMAP port (SSL/TLS)
IMAP_USER SMTP_USER IMAP username
IMAP_PASS SMTP_PASS IMAP password
IMAP_SENT_FOLDER Sent Mailbox folder sent mail is stored in
SEND_HOUR 8 Default hour for the daily send — the time picked on the Administration page overrides this
SECRET_KEY random Flask session key — set it so logins survive restarts
PORT 8080 HTTP port
DATA_DIR ./data Where the database and uploads are stored

Notes

  • The e-mail address field on entries is required because it is where the birthday greeting is sent.
  • Failed sends (e.g. SMTP misconfigured) are also recorded in the e-mail log with the error as tooltip on the "Failed" status. If a mail is delivered but the IMAP copy to the Sent folder fails, the mail is still logged as Sent and the IMAP error appears as a tooltip.
  • Run behind a reverse proxy (nginx / Caddy / Traefik) with HTTPS if you expose it beyond your LAN.