# Blueprint: Kalender-Bridge

Version 1.0 · denzer.ai · Lizenz: frei nutzbar mit Quellenangabe

Eine Brücke zwischen deinem Agent und Google Calendar (oder iCloud, Outlook), mit der du Termine in natürlicher Sprache eintragen kannst. "Trag Mittwoch 14 Uhr Friseur ein" — fertig, sofort auf allen Geräten sichtbar.

**Fallbeispiel.** Du jonglierst sechs verschiedene Sub-Kalender (privat, Studio, AI-Workshops, AI-Beratung, Personal Training, Familie). Termine kommen oft mündlich rein, zwischen zwei Telefonaten. Du sagst deinem Agent "AI-Beratung mit Schmidt am Freitag 11 Uhr", er erkennt die Kategorie aus dem Wortlaut, legt den Termin im richtigen Sub-Kalender an, du siehst ihn 5 Sekunden später auf dem iPhone.

---

## Teil B — Für dich (Operator)

### Was ist das?

Eine kleine Brücke zur Kalender-API deines Anbieters (Google am häufigsten, iCloud und Outlook gehen auch). Dein Agent versteht Sprache wie "Mittwoch 14 Uhr" oder "übermorgen früh", legt den Termin im richtigen Sub-Kalender an, schreibt Titel und Notizen sauber.

### Warum so und nicht anders?

Du könntest Termine ins Chat-Modell tippen und dir den ICS-Block ausgeben lassen. Funktioniert für Einzelfälle, taugt aber nicht für deinen Alltag — du müsstest jedesmal den Block manuell ins richtige Tool kopieren, und Sub-Kalender-Auswahl bleibt Handarbeit.

Direkte Google-Calendar-API ist der einzige saubere Weg, sofort auf allen Geräten zu sehen, was angelegt wurde. Vorteil von Google gegenüber iCloud: stabilere API, breiter Tool-Support. iCloud geht über CalDAV, ist aber spröde. Outlook über Microsoft Graph möglich, aber mehr Setup.

**Kategorien-Routing** statt einem riesigen Kalender, weil dein Leben Schichten hat (privat, Studio, Beratung) und du eine sichtbare Trennung willst — auf dem Handy reicht ein Blick. Keyword-Mapping plus LLM-Fallback, damit du nicht jeden Trigger handpflegen musst.

Konflikt-Puffer von 30 Minuten, weil ein Termin selten nahtlos in den nächsten geht — wer immer back-to-back bucht, vergisst die Übergangszeit.

### Was brauchst du dafür?

- Ein Google-Konto mit Calendar (oder Apple ID für iCloud, Microsoft 365 für Outlook)
- Wenige Sub-Kalender, die du sauber benennst (z. B. "Privat", "Studio", "AI-Beratung")
- Einmaliger OAuth-Klick im Browser

### Wie startest du?

1. Starter laden, deinem Agent geben
2. Sagen: "richte mir die Kalender-Bridge ein, Google Calendar, mit den Sub-Kalendern Privat, Studio, AI-Beratung"
3. OAuth-Klick im Browser
4. Erster Test: "trag morgen 10 Uhr Kaffee mit Anna ein" — Termin sollte 5 Sekunden später auf dem Handy stehen

### Wo sind die Grenzen?

- Verschiebungen sind möglich, aber der Agent muss den Termin eindeutig identifizieren — wenn du nur "verschieb den Friseur" sagst und drei Friseur-Termine im Kalender stehen, fragt der Agent nach
- Einladungen an andere Personen brauchen die Adressen — ohne Adresse kein Send
- Wiederkehrende Termine (jeden Dienstag) sind möglich, aber lass den Agent erst den ersten Termin anlegen und mach die Wiederholung dann manuell im Kalender, das ist weniger fehleranfällig

### Was kostet das?

- Google Calendar API: kostenlos
- Keine zusätzlichen Modell-Kosten für die Termin-Anlage (paar Cent pro Auftrag)

### Wann lohnt es sich, wann nicht?

Lohnt sich, wenn du täglich mehrere Termine eintippst und Sub-Kalender hast. Lohnt sich nicht, wenn du nur einen Kalender mit zwei Terminen pro Woche pflegst.

### Wie weißt du, dass es funktioniert?

- Termin in 5 Sekunden im richtigen Sub-Kalender sichtbar
- Erinnerung kommt zur richtigen Zeit
- Verschiebungen landen wieder im richtigen Sub-Kalender

### Stolpersteine

- **Zeitzonen.** Wenn du reist, immer absolute Zeitzone angeben oder Agent fragen lassen
- **Kategorie-Erkennung.** Wenn dein Wortlaut mehrere Kategorien zulässt ("Coaching mit Max" — privat oder business?), muss der Agent nachfragen, statt zu raten
- **Doppelt-Buchungen.** Der Agent sollte nicht stumpf eintragen, sondern auf Konflikt prüfen und dich fragen
- **Sub-Kalender-IDs.** Diese sind lange, kryptische Strings (`abc123@group.calendar.google.com`). Lass den Agent sie einmal aus deiner Kalender-Liste lesen und in `.env` speichern

---

## Teil A — Für deinen Agent

### Agent-Triggersätze

- "Richte mir die Kalender-Bridge ein"
- "Verbinde Klaus mit Google Calendar"
- "Mach dass ich Termine per Sprache eintragen kann"

### Ziel

Brücke zu Google Calendar mit Sub-Kalender-Routing per Kategorie. Natural-Language-Input wird zu strukturiertem Termin (start_iso, duration, calendar_id, title, notes). Konflikt-Check vor Anlage.

### Erfolgskriterien

- POST-Endpoint nimmt `{text, category?, start_iso?, duration_min?, attendees?}`
- Wenn `text` allein kommt: NLP-Schritt extrahiert Kategorie, Zeit, Titel
- Konflikt-Check 30 Minuten Puffer um angefragten Slot
- Anlage in 1–3 Sekunden, ID zurückgeben
- Verschieben und Löschen über separate Endpoints
- Niemals stumm eintragen wenn Kategorie oder Zeit unklar

### Eingabe-Schema

```yaml
provider:          "google"
oauth_creds:       "<root>/.config/gcal-oauth.json"
calendars:
  - slug:          "privat"
    name:          "Privat"
    id:            "primary"
  - slug:          "studio"
    name:          "Fitnesscentrum Husum"
    id:            "xyz@group.calendar.google.com"
  - slug:          "ai-beratung"
    name:          "AI-Beratung"
    id:            "abc@group.calendar.google.com"
default_duration:  60                    # Minuten
default_timezone:  "Europe/Berlin"
keywords_to_category:
  studio:          ["FCH", "Studio", "Fitness"]
  ai-beratung:     ["Beratung", "AI-Sprint", "Sprint"]
  privat:          ["Friseur", "Arzt", "Familie"]
```

### Verarbeitung

1. **Input** — Operator sagt z. B. "Mittwoch 14 Uhr Friseur"
2. **NLP** — Modell extrahiert `{start_iso, duration, title, category?}`
3. **Kategorie-Routing** — wenn `category` fehlt: Keywords matchen, sonst Rückfrage
4. **Konflikt-Check** — bestehende Termine im 30-min-Puffer prüfen
5. **Anlage** — Google Calendar API, ID zurück
6. **Bestätigung** — Operator-Hinweis: "Friseur, Mittwoch 14:00–15:00, Kalender Privat"

### Endpoints

| Methode | Pfad | Zweck |
|---|---|---|
| POST | `/api/calendar` | Termin anlegen, `{text?, category?, start_iso?, ...}` |
| GET | `/api/calendar?from=...&to=...` | Termine im Zeitraum |
| PATCH | `/api/calendar/<event_id>` | Verschieben/ändern |
| DELETE | `/api/calendar/<event_id>` | Löschen |

### Sicherheit

- OAuth-Token chmod 600
- Lösch-Endpoint verlangt User-Bestätigung im Aufrufer-Log
- Eingaben sanitisieren (keine HTML in Titel/Notes)

### Fehler-/Edge-Cases

- Kategorie unklar → Rückfrage statt Default
- Zeit unklar ("morgen früh") → Rückfrage mit Vorschlag
- Konflikt im Puffer → Operator-Hinweis mit Option "trotzdem anlegen"
- API down → Lokales Pending-Queue, beim nächsten Sync nachreichen
- OAuth abgelaufen → Refresh, sonst Re-Auth-Hinweis

### Verzeichnisstruktur

```
<root>/calendar-bridge/
├── gcal_client.py
├── nlp_extract.py        # Zeit/Titel/Kategorie aus Freitext
├── conflict_check.py
├── config.yaml           # Kalender-Liste, Keywords
└── .env.example
```

### Code-Snippets

Im Starter findest du `gcal_client.py` (Google Calendar API), `nlp_extract.py` (LLM-Aufruf zur Strukturextraktion), eine Konfliktprüfung und ein FastAPI-Wrapper.

---

## Teil C — Was du als Nächstes tust

1. Starter laden, Agent geben
2. Sagen: "richte mir die Kalender-Bridge mit folgenden Sub-Kalendern ein"
3. OAuth-Klick durchlaufen
4. Sub-Kalender-IDs in `config.yaml` füllen (Agent kann sie aus deiner Kalender-Liste auslesen)
5. Erster Test: "trag morgen 10 Uhr Kaffee mit Anna ein"
6. Wenn Kategorie nicht erkannt: Keyword in `keywords_to_category` ergänzen

### Lern-Checkliste

- Welche Sub-Kalender habe ich freigegeben?
- Wie wird ein Termin in eine Kategorie einsortiert?
- Was passiert, wenn ich einen mehrdeutigen Satz sage?
- Wie verschiebe ich einen bestehenden Termin?
- Wo finde ich die Liste der ID-Strings meiner Sub-Kalender?

Fragen: christian@denzer.ai
