diff --git a/.env.example b/.env.example
index e19e05b..c63e971 100644
--- a/.env.example
+++ b/.env.example
@@ -24,3 +24,6 @@ MAIL_SEND_HOUR=7
AUTH_REMOTE_USER_HEADER=Remote-User
API_HOST=0.0.0.0
API_PORT=8000
+
+# --- Web-URL (optional, wird in Geburtstags-Mails verlinkt) ---
+WEB_URL=https://kontakte.example.de
diff --git a/docker-compose.yml b/docker-compose.yml
index 0dd1056..a2f4920 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -22,6 +22,7 @@ services:
MAIL_FROM: "${MAIL_FROM}"
MAIL_TO: "${MAIL_TO}"
MAIL_SEND_HOUR: "${MAIL_SEND_HOUR:-7}"
+ WEB_URL: "${WEB_URL:-}"
volumes:
- ./config/accounts.json:/app/config/accounts.json:ro
logging:
@@ -49,6 +50,7 @@ services:
AUTH_REMOTE_USER_HEADER: "${AUTH_REMOTE_USER_HEADER:-Remote-User}"
API_HOST: "${API_HOST:-0.0.0.0}"
API_PORT: "${API_PORT:-8000}"
+ WEB_URL: "${WEB_URL:-}"
volumes:
- ./config/accounts.json:/app/config/accounts.json:ro
ports:
diff --git a/src/config.py b/src/config.py
index db7724d..246eecd 100644
--- a/src/config.py
+++ b/src/config.py
@@ -42,6 +42,7 @@ class Config:
API_HOST = os.environ.get("API_HOST", "0.0.0.0")
API_PORT = int(os.environ.get("API_PORT", "8000"))
+ WEB_URL = os.environ.get("WEB_URL", "")
@classmethod
def validate_db(cls):
diff --git a/src/mailer.py b/src/mailer.py
index 3f2bb4b..7604072 100644
--- a/src/mailer.py
+++ b/src/mailer.py
@@ -20,7 +20,7 @@ def fetch_todays_birthdays(conn) -> list[dict]:
today = date.today()
with conn.cursor() as cur:
cur.execute(
- """SELECT account, full_name, birthday
+ """SELECT id, account, full_name, birthday
FROM contacts
WHERE birthday IS NOT NULL
AND MONTH(birthday) = %s
@@ -60,11 +60,81 @@ def build_message(birthdays: list[dict]) -> EmailMessage:
return msg
msg["Subject"] = f"Geburtstage heute ({today.isoformat()}): {len(birthdays)}"
- lines = [f"Heutige Geburtstage ({today.isoformat()}):", ""]
+
+ plain_lines = [f"Heutige Geburtstage ({today.isoformat()}):", ""]
for b in birthdays:
age = today.year - b["birthday"].year
- lines.append(f"- {b['full_name']} (wird {age}, Account: {b['account']})")
- msg.set_content("\n".join(lines))
+ line = f"- {b['full_name']} (wird {age}, Account: {b['account']})"
+ if Config.WEB_URL:
+ line += f" โ {Config.WEB_URL.rstrip('/')}/contacts/{b['id']}"
+ plain_lines.append(line)
+ if Config.WEB_URL:
+ plain_lines.extend(["", f"Alle Kontakte ansehen: {Config.WEB_URL}"])
+ msg.set_content("\n".join(plain_lines))
+
+ cards_html = ""
+ for b in birthdays:
+ age = today.year - b["birthday"].year
+ contact_link = f"{Config.WEB_URL.rstrip('/')}/contacts/{b['id']}" if Config.WEB_URL else ""
+ name_html = f'{b["full_name"]}' if contact_link else b["full_name"]
+ cards_html += f"""
+
+
+
+
+ {name_html}
+ Account: {b['account']}
+
+
+ ๐ wird {age}
+
+
+ |
+
+ |
"""
+
+ link_html = ""
+ if Config.WEB_URL:
+ link_html = f"""
+
+ |
+ Alle Kontakte ansehen
+ |
+
"""
+
+ html = f"""
+
+
+
+
+
+
+
+
+
+
+
+
+ Geburtstage heute
+ {today.strftime('%d.%m.%Y')} ยท {len(birthdays)} Kontakte
+ |
+
+
+ |
+
+ |
+
+ {link_html}
+
+ |
+
+
+
+"""
+
+ msg.add_alternative(html, subtype="html")
return msg