Umgebungsvariable EVENT_YEARS für konfigurierbaren Event-Horizont hinzugefügt
This commit is contained in:
@@ -133,7 +133,7 @@ func (d *Daemon) syncBirthdaysToCal(ctx context.Context, httpClient webdav.HTTPC
|
||||
return err
|
||||
}
|
||||
slog.DebugContext(ctx, "queried existing calendar events", "user", user, "count", len(events))
|
||||
bevs := generateBirthdayEvents(birthdays)
|
||||
bevs := generateBirthdayEvents(birthdays, d.eventYears)
|
||||
slog.DebugContext(ctx, "generated birthday events", "user", user, "count", len(bevs))
|
||||
bevsInSync := make([]int, 0)
|
||||
driftedEvents := make([]string, 0)
|
||||
@@ -185,11 +185,11 @@ type birthdayEvent struct {
|
||||
DateTimeEnd string
|
||||
}
|
||||
|
||||
func generateBirthdayEvents(birthdays []BirthdayContact) []birthdayEvent {
|
||||
func generateBirthdayEvents(birthdays []BirthdayContact, eventYears int) []birthdayEvent {
|
||||
cyear := time.Now().Year()
|
||||
bb := make([]birthdayEvent, 0)
|
||||
for _, v := range birthdays {
|
||||
for year := cyear; year <= 10+cyear; year++ {
|
||||
for year := cyear; year <= eventYears+cyear; year++ {
|
||||
yearshift := year - v.Date.Year()
|
||||
prefix := "\U0001F382 " // 🎂
|
||||
if v.Type == ContactTypeAnniversary {
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
@@ -39,6 +40,7 @@ type Daemon struct {
|
||||
oldCalendarName string
|
||||
notificationEnabled bool
|
||||
notificationTrigger string
|
||||
eventYears int
|
||||
syncInterval time.Duration
|
||||
excludeMailboxes map[string]bool
|
||||
health *healthState
|
||||
@@ -120,6 +122,11 @@ func run() error {
|
||||
calendarName = "Birthdays"
|
||||
}
|
||||
notificationEnabled := strings.EqualFold(os.Getenv("NOTIFICATION_ENABLED"), "true")
|
||||
eventYears, err := parseEventYears()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
slog.Info("event horizon configured", "years", eventYears)
|
||||
syncInterval, err := parseSyncInterval()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -129,6 +136,7 @@ func run() error {
|
||||
"MAILCOW_BASE", mailcowBase,
|
||||
"CALENDAR_NAME", calendarName,
|
||||
"NOTIFICATION_ENABLED", notificationEnabled,
|
||||
"EVENT_YEARS", eventYears,
|
||||
"MAILCOW_RESOLVE_HOST", os.Getenv("MAILCOW_RESOLVE_HOST"),
|
||||
"STATEFILE", os.Getenv("STATEFILE"),
|
||||
"MAILBOX_EXCLUDE", os.Getenv("MAILBOX_EXCLUDE"),
|
||||
@@ -166,6 +174,7 @@ func run() error {
|
||||
calendarName: calendarName,
|
||||
notificationEnabled: notificationEnabled,
|
||||
notificationTrigger: notificationTrigger,
|
||||
eventYears: eventYears,
|
||||
syncInterval: syncInterval,
|
||||
excludeMailboxes: excludeMailboxes,
|
||||
}
|
||||
@@ -420,6 +429,24 @@ func parseSyncInterval() (time.Duration, error) {
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// parseEventYears liest EVENT_YEARS aus der Umgebung und gibt die Anzahl
|
||||
// der Jahre zurück, für die Geburtstags-Events im Voraus erzeugt werden.
|
||||
// Standard: 10. Gültige Werte: 1–30.
|
||||
func parseEventYears() (int, error) {
|
||||
raw := os.Getenv("EVENT_YEARS")
|
||||
if raw == "" {
|
||||
return 10, nil
|
||||
}
|
||||
n, err := strconv.Atoi(raw)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("invalid EVENT_YEARS %q: %w", raw, err)
|
||||
}
|
||||
if n < 1 || n > 30 {
|
||||
return 0, fmt.Errorf("EVENT_YEARS must be between 1 and 30, got %d", n)
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// buildTransport erstellt einen http.Transport.
|
||||
// Wenn MAILCOW_RESOLVE_HOST gesetzt ist (z. B. "nginx-mailcow"), wird der
|
||||
// tatsächliche TCP-Connect auf diesen Host umgeleitet, während TLS-SNI und
|
||||
|
||||
@@ -17,7 +17,7 @@ Der Mailcow Birthday Daemon synchronisiert automatisch Geburtstagskalender für
|
||||
- Die daraus resultierenden Kalendereinträge werden im Voraus berechnet.
|
||||
|
||||
> **Hinweis zu Jahrestagen:** Die SOGo-Weboberfläche bietet kein Feld zum Anzeigen oder Bearbeiten von Jahrestagen. Das `ANNIVERSARY`-Feld muss über einen externen Client (z. B. Thunderbird, Android- oder iOS-Kontakte-App) gepflegt und per CardDAV synchronisiert werden. Das SOGo-CardDAV-Backend speichert und liefert das Feld korrekt – es fehlt lediglich die Unterstützung in der Web-UI.
|
||||
- Aktuell fest eingestellt: 1 Jahr in der Vergangenheit, 10 Jahre in der Zukunft.
|
||||
- Aktuell standardmäßig: 1 Jahr in der Vergangenheit, 10 Jahre in der Zukunft (konfigurierbar über `EVENT_YEARS`).
|
||||
- Selbstverständlich pro Mailbox isoliert – ein Benutzer sieht nur die Geburtstage seiner eigenen Kontakte.
|
||||
|
||||
## Mailbox-Filter
|
||||
|
||||
@@ -28,6 +28,7 @@ services:
|
||||
# - NOTIFICATION_ENABLED=true
|
||||
# - NOTIFICATION_TIME=08:00
|
||||
# - SYNC_INTERVAL=15m
|
||||
# - EVENT_YEARS=10
|
||||
# - MAILBOX_EXCLUDE=user1@example.com,user2@example.com
|
||||
# - LOG_LEVEL=info
|
||||
volumes:
|
||||
@@ -66,6 +67,7 @@ docker compose pull birthdaydaemon && docker compose up -d --no-deps birthdaydae
|
||||
| `NOTIFICATION_TIME` | Nein | `08:00` | Uhrzeit der Benachrichtigung im Format `HH:MM` (nur wirksam wenn `NOTIFICATION_ENABLED=true`) |
|
||||
| `STATEFILE` | Nein | `state.json` (im Container: `/data/state.json`) | Pfad zur Zustandsdatei, in der App-Passwörter und der aktuelle Kalendername gespeichert werden |
|
||||
| `SYNC_INTERVAL` | Nein | `15m` | Intervall zwischen den Synchronisationsläufen im Go-Duration-Format (z. B. `10m`, `30m`, `1h`). Mindestwert: `1m`. |
|
||||
| `EVENT_YEARS` | Nein | `10` | Anzahl der Jahre, für die Geburtstags-Events im Voraus erzeugt werden. Gültige Werte: `1`–`30`. Kleinere Werte können die Performance in Kalender-Clients verbessern. |
|
||||
| `MAILBOX_EXCLUDE` | Nein | – | Kommagetrennte Liste von Mailadressen, die von der Synchronisation ausgeschlossen werden (z. B. `admin@example.com,noreply@example.com`). Standardmäßig erhalten alle aktiven Mailboxen einen Geburtstagskalender. |
|
||||
| `LOG_LEVEL` | Nein | `info` | Log-Verbosity: `debug`, `info`, `warn` oder `error`. Im `debug`-Modus werden einzelne Kalendereinträge (hinzugefügt/entfernt) und Kontaktdetails geloggt. |
|
||||
## API-Key erstellen
|
||||
|
||||
Reference in New Issue
Block a user