Vrwb.
Alle Tools
zum Selbst-Hosten

Für die Arbeit

Sync

Google-Kalender spiegeln, ohne Chaos.

Unser Team arbeitet mit mehreren Google-Kalendern: private Termine, Team-Kalender, Projekte. Ich wollte, dass belegte Zeiten überall sichtbar sind, ohne Details offenzulegen — und ohne die Fehler, die Kalender-Sync sonst kaputtmachen: Duplikate, Endlos-Schleifen, versehentlich verschickte Einladungen.

Mit Sync meldest du dich mit Google an und legst gerichtete Sync-Paare an: Quelle → Ziel, wahlweise als anonymer „Belegt“-Block oder mit vollen Details. Mehrbenutzer-fähig und auf Wunsch auf deine Workspace-Domain beschränkt.

Was es kann

  • Gerichtete Sync-Paare mit Detailgrad pro Paar — Gegenrichtung legst du per Klick mit an
  • Loop-Schutz: Spiegel-Events sind markiert und werden nie erneut gespiegelt, auch wenn ein Kalender Quelle und Ziel zugleich ist
  • Idempotente Updates: Änderungen treffen dasselbe Ziel-Event, Duplikate entstehen nicht
  • Lösch-Propagation: abgesagte oder gelöschte Termine räumen ihren Spiegel-Block ab
  • Als „frei“ markierte und abgelehnte Termine blockieren im Ziel keine Zeit
  • Serientermine inklusive Ausnahmen und Einzelabsagen
  • Keine Einladungs-Mails: jeder Schreibvorgang läuft mit sendUpdates=none
  • Pro Paar einstellbar: Titel-Präfix, Event-Farbe, Vertraulich-Schalter
  • Google-Tokens liegen Fernet-verschlüsselt in der Datenbank
  • Rate-Limit-Backoff, manueller Sofort-Sync, Sync-Historie und Admin-Übersicht

Wie der Sync arbeitet

Ein Scheduler pollt alle drei Minuten (konfigurierbar) und holt über Googles syncToken nur die Änderungen seit dem letzten Lauf — kein Voll-Abgleich bei jedem Durchgang. Läuft ein Token ab, fällt die Engine automatisch auf einen Full-Sync mit 30 Tagen Backfill zurück.

Jedes Spiegel-Event trägt seine Herkunft in den extendedProperties: Paar, Quell-Kalender, Quell-Event. Das ist der Loop-Schutz — und zusammen mit der Mapping-Tabelle der Grund, warum Updates idempotent sind. Niemand bekommt je eine Einladung zu einem Spiegel-Termin.

Selbst hosten

Dein Server, deine Daten.

Das brauchst du

  • Server mit Docker und Docker Compose, eine Domain mit A-Record, Ports 80/443 — das mitgelieferte Caddy holt sich das TLS-Zertifikat selbst
  • Ein Google-Cloud-Projekt: Calendar API aktivieren, OAuth-Client (Typ „Web application“) mit zwei Redirect-URIs anlegen — /api/auth/google/callback und /calendar/callback
  • Scopes: openid email profile plus calendar.events und calendar.readonly. Wenn du auf eine Workspace-Domain beschränkst, reicht Publishing-Status „Internal“

So läuft es an

  1. 1

    Klonen und konfigurieren

    git clone https://github.com/laarsv/sync.git && cd sync
    cp .env.example .env
  2. 2

    Secrets erzeugen

    openssl rand -hex 32          # APP_SECRET
    python -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())'
  3. 3

    .env füllen

    DOMAIN, APP_SECRET, die Google-Credentials und der Fernet-Key sind Pflicht. Optional: ALLOWED_EMAIL_DOMAIN beschränkt den Login auf deine Workspace-Domain, INITIAL_ADMIN_EMAIL bestimmt den Admin.

  4. 4

    Starten

    Danach läuft alles unter https://deine-domain. Wer schon einen Reverse-Proxy hat, nimmt stattdessen docker-compose.prod.yml am externen proxy-Netz.

    docker compose up -d --build

Steckbrief

Stack
FastAPI · SQLite (WAL) · React + Vite · APScheduler
Google-API
Calendar REST direkt über httpx — kein SDK
Lizenz
MIT