initial
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,303 @@
|
||||
# openclaw-mailbox-cal
|
||||
|
||||
**OpenClaw Skill-Repository** — mailbox.org Kalender und Aufgaben auf dem Raspberry Pi
|
||||
Telegram-Bot-Befehle für Kalendertermine (khal), Tasks (todoman) und automatischen CalDAV-Sync (vdirsyncer).
|
||||
|
||||
---
|
||||
|
||||
## Schnellstart
|
||||
|
||||
```bash
|
||||
# 1. .env befüllen
|
||||
cp assets/.env.example .env && nano .env
|
||||
|
||||
# 2. Installation
|
||||
chmod +x scripts/install.sh && bash scripts/install.sh
|
||||
|
||||
# 3. Selbsttest
|
||||
bash scripts/test_setup.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Projektstruktur
|
||||
|
||||
```
|
||||
openclaw-mailbox-cal/
|
||||
├── SKILL.md ← OpenClaw Skill-Definition
|
||||
├── README.md ← Diese Datei
|
||||
├── assets/
|
||||
│ └── .env.example ← Umgebungsvariablen-Vorlage
|
||||
├── config/
|
||||
│ ├── vdirsyncer.conf ← vdirsyncer CalDAV-Konfiguration
|
||||
│ ├── khal.conf ← khal Kalender-Konfiguration
|
||||
│ └── todoman.conf ← todoman Aufgaben-Konfiguration
|
||||
├── scripts/
|
||||
│ ├── install.sh ← Installations-Script (Raspi)
|
||||
│ ├── test_setup.sh ← Selbsttest aller Komponenten
|
||||
│ └── openclaw_skill.py ← OpenClaw/Telegram Bot Handler
|
||||
└── systemd/
|
||||
├── vdirsyncer-sync.service ← systemd Service Unit
|
||||
├── vdirsyncer-sync.timer ← systemd Timer (alle 15 Min.)
|
||||
└── vdirsyncer-sync.env ← Umgebungsvariablen für systemd
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Setup-Schritte (detailliert)
|
||||
|
||||
### Schritt 1 — Voraussetzungen
|
||||
|
||||
- Raspberry Pi mit Raspberry Pi OS Bookworm (64-bit empfohlen) oder Ubuntu 22.04+ ARM
|
||||
- mailbox.org-Konto
|
||||
- App-Passwort in mailbox.org anlegen:
|
||||
`Einstellungen → Sicherheit → App-Passwörter → Neu erstellen`
|
||||
- OpenClaw installiert: [openclaw.dev](https://openclaw.dev)
|
||||
- Telegram Bot-Token via [@BotFather](https://t.me/BotFather)
|
||||
|
||||
### Schritt 2 — .env konfigurieren
|
||||
|
||||
```bash
|
||||
cp assets/.env.example .env
|
||||
nano .env
|
||||
```
|
||||
|
||||
Mindestens diese Werte setzen:
|
||||
|
||||
```dotenv
|
||||
MAILBOX_USER=vorname.nachname@mailbox.org
|
||||
MAILBOX_PASS=app-passwort-xyz
|
||||
```
|
||||
|
||||
### Schritt 3 — install.sh ausführen
|
||||
|
||||
```bash
|
||||
chmod +x scripts/install.sh
|
||||
bash scripts/install.sh
|
||||
```
|
||||
|
||||
Das Script installiert automatisch:
|
||||
- `vdirsyncer` — CalDAV-Sync-Tool
|
||||
- `khal` — CLI-Kalender
|
||||
- `todoman` — CLI-Aufgabenverwaltung
|
||||
- `pass` — GNU Password Store
|
||||
- `python3-keyring` — Python-Keyring-Integration
|
||||
- `gettext-base` — envsubst für Konfigurationen
|
||||
|
||||
Anschließend:
|
||||
- Alle Konfigurationsdateien werden deployed
|
||||
- systemd User-Timer wird aktiviert
|
||||
- Initialer Sync wird durchgeführt
|
||||
|
||||
### Schritt 4 — OpenClaw Skill registrieren
|
||||
|
||||
OpenClaw erkennt Skills **automatisch** wenn sie in einem der Skill-Verzeichnisse liegen.
|
||||
Kein manueller Eintrag in `openclaw.json` nötig — das `install.sh` legt bereits einen Symlink an.
|
||||
|
||||
```bash
|
||||
# Manuell (falls install.sh den Symlink nicht angelegt hat):
|
||||
mkdir -p ~/.openclaw/skills
|
||||
ln -s ~/mailbox-cal ~/.openclaw/skills/mailbox-cal
|
||||
```
|
||||
|
||||
Optional — Zugangsdaten direkt in `~/.openclaw/openclaw.json` hinterlegen
|
||||
(Alternative zur `.env`-Datei). **Immer zuerst Backup anlegen:**
|
||||
|
||||
```bash
|
||||
cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.bak
|
||||
```
|
||||
|
||||
Dann im `"skills"`-Block den `"entries"`-Unterblock ergänzen:
|
||||
|
||||
```json
|
||||
"skills": {
|
||||
"install": {
|
||||
"nodeManager": "npm"
|
||||
},
|
||||
"entries": {
|
||||
"mailbox-cal": {
|
||||
"enabled": true,
|
||||
"env": {
|
||||
"MAILBOX_USER": "dein.name@mailbox.org",
|
||||
"MAILBOX_PASS": "app-passwort-xyz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Nach jeder Änderung an `openclaw.json` validieren und Gateway neu starten:
|
||||
|
||||
```bash
|
||||
openclaw doctor --fix
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
### Schritt 5 — Telegram testen
|
||||
|
||||
Sende an deinen Bot:
|
||||
```
|
||||
/termine
|
||||
/aufgaben
|
||||
/sync
|
||||
/status
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Test-Befehle
|
||||
|
||||
### Vollständiger Selbsttest
|
||||
```bash
|
||||
bash scripts/test_setup.sh
|
||||
```
|
||||
|
||||
### vdirsyncer
|
||||
```bash
|
||||
# Verbindung testen und Sammlungen entdecken
|
||||
vdirsyncer discover calendars
|
||||
vdirsyncer discover tasks
|
||||
|
||||
# Synchronisation manuell starten
|
||||
vdirsyncer sync
|
||||
|
||||
# Nur Kalender synchronisieren
|
||||
vdirsyncer sync calendars
|
||||
|
||||
# Verbose-Ausgabe
|
||||
vdirsyncer -v DEBUG sync
|
||||
```
|
||||
|
||||
### khal
|
||||
```bash
|
||||
# Termine heute
|
||||
khal list
|
||||
|
||||
# Termine nächste 7 Tage
|
||||
khal list today 7d
|
||||
|
||||
# Agenda-Ansicht
|
||||
khal agenda
|
||||
|
||||
# Interaktiver Kalender
|
||||
ikhal
|
||||
|
||||
# Ereignis hinzufügen (interaktiv)
|
||||
khal new
|
||||
|
||||
# Ereignis direkt anlegen
|
||||
khal new 2025-06-15 14:00 15:00 "Arzttermin" --calendar mailbox_kalender
|
||||
|
||||
# Cache neu aufbauen
|
||||
khal rebuild-cache
|
||||
|
||||
# Konfiguration anzeigen
|
||||
khal printformats
|
||||
```
|
||||
|
||||
### todoman
|
||||
```bash
|
||||
# Alle offenen Aufgaben
|
||||
todo list
|
||||
|
||||
# Alle Aufgaben inkl. erledigt
|
||||
todo list --all
|
||||
|
||||
# Neue Aufgabe
|
||||
todo new "Bericht schreiben"
|
||||
|
||||
# Aufgabe mit Fälligkeitsdatum
|
||||
todo new --due 2025-06-30 "Bericht abgeben"
|
||||
|
||||
# Aufgabe mit Priorität (1=hoch, 9=niedrig)
|
||||
todo new --priority 1 "Dringend: Server patchen"
|
||||
|
||||
# Aufgabe als erledigt markieren (ID aus 'todo list')
|
||||
todo done 1
|
||||
|
||||
# Aufgabe löschen
|
||||
todo delete 2
|
||||
|
||||
# Aufgaben-Listen anzeigen
|
||||
todo lists
|
||||
```
|
||||
|
||||
### systemd
|
||||
```bash
|
||||
# Timer-Status
|
||||
systemctl --user status vdirsyncer-sync.timer
|
||||
|
||||
# Service manuell starten (einmaliger Sync)
|
||||
systemctl --user start vdirsyncer-sync.service
|
||||
|
||||
# Alle User-Timer anzeigen
|
||||
systemctl --user list-timers
|
||||
|
||||
# Live-Log verfolgen
|
||||
journalctl --user -u vdirsyncer-sync.service -f
|
||||
|
||||
# Log der letzten 50 Zeilen
|
||||
journalctl --user -u vdirsyncer-sync.service -n 50
|
||||
|
||||
# Timer deaktivieren
|
||||
systemctl --user disable --now vdirsyncer-sync.timer
|
||||
```
|
||||
|
||||
### Python-Skill direkt testen
|
||||
```bash
|
||||
python3 scripts/openclaw_skill.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## mailbox.org CalDAV-Endpunkte
|
||||
|
||||
| Zweck | URL |
|
||||
|---|---|
|
||||
| CalDAV-Basis | `https://dav.mailbox.org/caldav/<USER>/` |
|
||||
| Kalender-Sammlung | `https://dav.mailbox.org/caldav/<USER>/Kalender/` |
|
||||
| Aufgaben-Sammlung | `https://dav.mailbox.org/caldav/<USER>/Aufgaben/` |
|
||||
| CardDAV (Kontakte) | `https://dav.mailbox.org/carddav/<USER>/` |
|
||||
|
||||
Entdeckung aller Sammlungen:
|
||||
```bash
|
||||
curl -u "USER:PASS" -X PROPFIND https://dav.mailbox.org/caldav/ \
|
||||
-H "Depth: 1" -H "Content-Type: application/xml"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Sicherheit
|
||||
|
||||
| Maßnahme | Status |
|
||||
|---|---|
|
||||
| App-Passwort statt Hauptpasswort | ✅ Empfohlen |
|
||||
| vdirsyncer-Config: chmod 600 | ✅ Automatisch via install.sh |
|
||||
| .env nicht in Git | ✅ In .gitignore eingetragen |
|
||||
| HTTPS für CalDAV | ✅ dav.mailbox.org erzwingt TLS |
|
||||
| pass(1)-Integration | Optional via `pass` + `python3-keyring` |
|
||||
|
||||
---
|
||||
|
||||
## Fehlerbehebung
|
||||
|
||||
**vdirsyncer: `[Errno 111] Connection refused`**
|
||||
→ Netzwerkverbindung prüfen: `ping dav.mailbox.org`
|
||||
|
||||
**vdirsyncer: `Conflict!`**
|
||||
→ Beide Seiten wurden geändert. Konflikt manuell lösen oder `conflict_resolution = "b wins"` in vdirsyncer.conf setzen.
|
||||
|
||||
**khal: `No calendars configured`**
|
||||
→ `khal rebuild-cache` ausführen; Pfad in `~/.config/khal/config` prüfen.
|
||||
|
||||
**todoman: `Error: No lists found`**
|
||||
→ `path`-Eintrag in `~/.config/todoman/config.cfg` prüfen; Verzeichnis `~/.local/share/vdirsyncer/tasks/` muss existieren und `.ics`-Dateien enthalten.
|
||||
|
||||
**systemd-Timer läuft nach Reboot nicht**
|
||||
→ `sudo loginctl enable-linger $USER` ausführen (User-Session ohne Login).
|
||||
|
||||
---
|
||||
|
||||
## Lizenz
|
||||
|
||||
MIT — Freie Nutzung, Veränderung und Weitergabe.
|
||||
@@ -0,0 +1,226 @@
|
||||
---
|
||||
name: mailbox-cal
|
||||
description: "OpenClaw Telegram-Bot-Skill für mailbox.org Kalender und Aufgaben auf dem Raspberry Pi. Synchronisiert CalDAV-Kalender und VTODO-Aufgaben via vdirsyncer, zeigt Termine mit khal und verwaltet Tasks mit todoman. Befehle: /termine, /aufgaben, /neu_aufgabe, /sync, /status. Lade diesen Skill wenn: der Nutzer Kalender-Einträge oder Aufgaben aus mailbox.org per Telegram abfragen, anlegen oder synchronisieren möchte."
|
||||
license: MIT
|
||||
compatibility: "Raspberry Pi OS Bookworm / Ubuntu 22.04+ ARM. Benötigt: vdirsyncer >= 0.19, khal >= 0.11, todoman >= 4.3, python3 >= 3.10. mailbox.org CalDAV-Zugang erforderlich."
|
||||
metadata:
|
||||
author: lonely.wolf.64
|
||||
version: '1.0'
|
||||
platform: Raspberry Pi
|
||||
caldav_server: mailbox.org
|
||||
---
|
||||
|
||||
# mailbox.org Kalender + Aufgaben Skill
|
||||
|
||||
## Übersicht
|
||||
|
||||
Dieser OpenClaw-Skill synchronisiert deinen mailbox.org-Kalender und deine Aufgaben über CalDAV auf einen Raspberry Pi und stellt sie über Telegram-Bot-Befehle bereit. Die Synchronisation läuft automatisch alle 15 Minuten via systemd-Timer.
|
||||
|
||||
**Architektur:**
|
||||
```
|
||||
mailbox.org (CalDAV)
|
||||
│
|
||||
vdirsyncer (Sync)
|
||||
│
|
||||
┌───┴───────────┐
|
||||
│ │
|
||||
khal todoman
|
||||
(Kalender) (Aufgaben)
|
||||
│ │
|
||||
└───────┬───────┘
|
||||
│
|
||||
openclaw_skill.py
|
||||
│
|
||||
Telegram Bot
|
||||
```
|
||||
|
||||
## Unterstützte Befehle
|
||||
|
||||
| Telegram-Befehl | Beschreibung | Beispiel |
|
||||
|---|---|---|
|
||||
| `/termine` | Heutige Termine | `/termine heute` |
|
||||
| `/termine morgen` | Morgige Termine | `/termine morgen` |
|
||||
| `/termine woche` | Termine nächste 7 Tage | `/termine woche` |
|
||||
| `/aufgaben` | Offene Aufgaben | `/aufgaben` |
|
||||
| `/aufgaben alle` | Alle Aufgaben inkl. erledigt | `/aufgaben alle` |
|
||||
| `/neu_aufgabe` | Neue Aufgabe anlegen | `/neu_aufgabe Arzt anrufen` |
|
||||
| `/sync` | Manuellen Sync auslösen | `/sync` |
|
||||
| `/status` | Sync-Timer-Status | `/status` |
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
- Raspberry Pi mit Raspberry Pi OS Bookworm oder Ubuntu 22.04+ ARM
|
||||
- mailbox.org-Konto mit CalDAV-Zugang
|
||||
- OpenClaw installiert und konfiguriert
|
||||
- Telegram Bot-Token (via @BotFather)
|
||||
- Internetverbindung vom Raspberry Pi
|
||||
|
||||
## Installation
|
||||
|
||||
### 1. Repository klonen
|
||||
|
||||
```bash
|
||||
git clone https://github.com/DEIN_USER/openclaw-mailbox-cal.git
|
||||
cd openclaw-mailbox-cal
|
||||
```
|
||||
|
||||
### 2. .env befüllen
|
||||
|
||||
```bash
|
||||
cp assets/.env.example .env
|
||||
nano .env
|
||||
# MAILBOX_USER und MAILBOX_PASS setzen
|
||||
```
|
||||
|
||||
**Empfehlung:** Lege in mailbox.org ein App-Passwort an:
|
||||
Einstellungen → Sicherheit → App-Passwörter → Neu erstellen
|
||||
|
||||
### 3. Installation ausführen
|
||||
|
||||
```bash
|
||||
chmod +x scripts/install.sh
|
||||
bash scripts/install.sh
|
||||
```
|
||||
|
||||
Das Script führt folgende Schritte aus:
|
||||
1. Pakete installieren: `vdirsyncer khal todoman pass python3-keyring gettext-base`
|
||||
2. Konfigurationsdateien deployen (mit envsubst)
|
||||
3. systemd User-Timer aktivieren
|
||||
4. Initialen Sync durchführen
|
||||
5. khal-Datenbank aufbauen
|
||||
6. OpenClaw Skill verknüpfen
|
||||
|
||||
### 4. Skill in OpenClaw registrieren
|
||||
|
||||
OpenClaw erkennt Skills automatisch aus diesen Verzeichnissen (höchste Priorität zuerst):
|
||||
- `<workspace>/skills/`
|
||||
- `~/.openclaw/skills/`
|
||||
- bundled skills
|
||||
|
||||
Skill-Verzeichnis ins OpenClaw-Skills-Verzeichnis kopieren oder verlinken:
|
||||
|
||||
```bash
|
||||
# Option A: Symlink (empfohlen — Updates wirken sofort)
|
||||
mkdir -p ~/.openclaw/skills
|
||||
ln -s ~/mailbox-cal ~/.openclaw/skills/mailbox-cal
|
||||
|
||||
# Option B: Kopieren
|
||||
cp -r ~/mailbox-cal ~/.openclaw/skills/mailbox-cal
|
||||
```
|
||||
|
||||
Optional: Skill in `~/.openclaw/openclaw.json` aktivieren/konfigurieren
|
||||
(nur nötig für env-Variablen oder explizites enable/disable):
|
||||
|
||||
```json
|
||||
"skills": {
|
||||
"install": {
|
||||
"nodeManager": "npm"
|
||||
},
|
||||
"entries": {
|
||||
"mailbox-cal": {
|
||||
"enabled": true,
|
||||
"env": {
|
||||
"MAILBOX_USER": "dein.name@mailbox.org",
|
||||
"MAILBOX_PASS": "app-passwort-xyz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Wichtig:** Unbekannte Keys lassen den OpenClaw-Gateway nicht starten.
|
||||
Vor dem Bearbeiten immer ein Backup anlegen:
|
||||
```bash
|
||||
cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.bak
|
||||
# Nach der Bearbeitung validieren:
|
||||
openclaw doctor --fix
|
||||
```
|
||||
|
||||
Danach Gateway neu starten:
|
||||
```bash
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
## Test-Befehle
|
||||
|
||||
Nach der Installation Setup validieren:
|
||||
|
||||
```bash
|
||||
# Vollständiger Selbsttest
|
||||
bash scripts/test_setup.sh
|
||||
|
||||
# Einzeltests
|
||||
vdirsyncer sync # Sync testen
|
||||
khal list today tomorrow # Termine heute + morgen
|
||||
khal list --format "{start} {title}" 2025-01-01 2025-12-31 # Jahresübersicht
|
||||
todo list # Aufgaben anzeigen
|
||||
todo list --all # Alle inkl. erledigt
|
||||
todo new "Test-Aufgabe" # Aufgabe anlegen
|
||||
|
||||
# systemd Timer
|
||||
systemctl --user status vdirsyncer-sync.timer # Timer-Status
|
||||
systemctl --user list-timers # Alle Timer
|
||||
journalctl --user -u vdirsyncer-sync.service -f # Live-Log
|
||||
|
||||
# Python-Skill direkt testen (ohne OpenClaw/Telegram)
|
||||
python3 scripts/openclaw_skill.py
|
||||
```
|
||||
|
||||
## Konfigurationsdateien
|
||||
|
||||
| Datei | Ziel-Pfad | Beschreibung |
|
||||
|---|---|---|
|
||||
| `config/vdirsyncer.conf` | `~/.config/vdirsyncer/config` | CalDAV-Sync-Konfiguration |
|
||||
| `config/khal.conf` | `~/.config/khal/config` | Kalender-Anzeige-Konfiguration |
|
||||
| `config/todoman.conf` | `~/.config/todoman/config.cfg` | Aufgaben-Konfiguration |
|
||||
| `systemd/vdirsyncer-sync.service` | `~/.config/systemd/user/` | Sync-Service Unit |
|
||||
| `systemd/vdirsyncer-sync.timer` | `~/.config/systemd/user/` | 15-Minuten-Timer |
|
||||
| `scripts/openclaw_skill.py` | (in-place) | OpenClaw/Telegram-Integration |
|
||||
|
||||
## Sicherheitshinweise
|
||||
|
||||
- Die vdirsyncer-Config (`~/.config/vdirsyncer/config`) enthält das Passwort — Berechtigungen sind `chmod 600`
|
||||
- Verwende ein mailbox.org App-Passwort statt des Hauptpassworts
|
||||
- Für produktive Umgebungen: `pass`-Integration (GNU Password Store) via `pass` + `python3-keyring`
|
||||
- `.env`-Datei niemals in Git committen (ist in `.gitignore` eingetragen)
|
||||
|
||||
## Fehlerbehebung
|
||||
|
||||
### vdirsyncer discover schlägt fehl
|
||||
```bash
|
||||
# Verbindung testen
|
||||
curl -u "USER:PASS" https://dav.mailbox.org/caldav/
|
||||
# SSL-Zertifikate prüfen
|
||||
openssl s_client -connect dav.mailbox.org:443
|
||||
```
|
||||
|
||||
### khal zeigt keine Termine
|
||||
```bash
|
||||
# Cache neu aufbauen
|
||||
khal rebuild-cache
|
||||
# Config validieren
|
||||
khal printformats
|
||||
```
|
||||
|
||||
### systemd-Timer läuft nicht
|
||||
```bash
|
||||
# Lingering aktivieren (damit User-Units ohne Login laufen)
|
||||
sudo loginctl enable-linger pi
|
||||
# Timer manuell starten
|
||||
systemctl --user start vdirsyncer-sync.service
|
||||
```
|
||||
|
||||
### Todoman findet keine Aufgaben
|
||||
```bash
|
||||
# Pfad in config prüfen
|
||||
cat ~/.config/todoman/config.cfg
|
||||
# Verzeichnis prüfen
|
||||
ls ~/.local/share/vdirsyncer/tasks/
|
||||
```
|
||||
|
||||
## Erweiterungen
|
||||
|
||||
- **Mehrere Kalender:** Weitere `[[kalender_name]]`-Sektionen in `khal.conf` hinzufügen
|
||||
- **Push-Sync:** mailbox.org unterstützt CalDAV-Push — XMPP-Trigger via `vdirsyncer`
|
||||
- **Erinnerungen:** Integration mit `khal-remind` oder `at`-Daemon
|
||||
- **Verschlüsselung:** `.env` via `gpg-agent` verschlüsseln
|
||||
@@ -0,0 +1,26 @@
|
||||
# Secrets — niemals committen!
|
||||
.env
|
||||
*.env
|
||||
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*.pyo
|
||||
.venv/
|
||||
venv/
|
||||
|
||||
# Editor
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
*~
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
/logs/
|
||||
|
||||
# vdirsyncer Status (lokal)
|
||||
status/
|
||||
@@ -0,0 +1,279 @@
|
||||
# openclaw-mailbox-cal
|
||||
|
||||
**OpenClaw Skill-Repository** — mailbox.org Kalender und Aufgaben auf dem Raspberry Pi
|
||||
Telegram-Bot-Befehle für Kalendertermine (khal), Tasks (todoman) und automatischen CalDAV-Sync (vdirsyncer).
|
||||
|
||||
---
|
||||
|
||||
## Schnellstart
|
||||
|
||||
```bash
|
||||
# 1. .env befüllen
|
||||
cp assets/.env.example .env && nano .env
|
||||
|
||||
# 2. Installation
|
||||
chmod +x scripts/install.sh && bash scripts/install.sh
|
||||
|
||||
# 3. Selbsttest
|
||||
bash scripts/test_setup.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Projektstruktur
|
||||
|
||||
```
|
||||
openclaw-mailbox-cal/
|
||||
├── SKILL.md ← OpenClaw Skill-Definition
|
||||
├── README.md ← Diese Datei
|
||||
├── assets/
|
||||
│ └── .env.example ← Umgebungsvariablen-Vorlage
|
||||
├── config/
|
||||
│ ├── vdirsyncer.conf ← vdirsyncer CalDAV-Konfiguration
|
||||
│ ├── khal.conf ← khal Kalender-Konfiguration
|
||||
│ └── todoman.conf ← todoman Aufgaben-Konfiguration
|
||||
├── scripts/
|
||||
│ ├── install.sh ← Installations-Script (Raspi)
|
||||
│ ├── test_setup.sh ← Selbsttest aller Komponenten
|
||||
│ └── openclaw_skill.py ← OpenClaw/Telegram Bot Handler
|
||||
└── systemd/
|
||||
├── vdirsyncer-sync.service ← systemd Service Unit
|
||||
├── vdirsyncer-sync.timer ← systemd Timer (alle 15 Min.)
|
||||
└── vdirsyncer-sync.env ← Umgebungsvariablen für systemd
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Setup-Schritte (detailliert)
|
||||
|
||||
### Schritt 1 — Voraussetzungen
|
||||
|
||||
- Raspberry Pi mit Raspberry Pi OS Bookworm (64-bit empfohlen) oder Ubuntu 22.04+ ARM
|
||||
- mailbox.org-Konto
|
||||
- App-Passwort in mailbox.org anlegen:
|
||||
`Einstellungen → Sicherheit → App-Passwörter → Neu erstellen`
|
||||
- OpenClaw installiert: [openclaw.dev](https://openclaw.dev)
|
||||
- Telegram Bot-Token via [@BotFather](https://t.me/BotFather)
|
||||
|
||||
### Schritt 2 — .env konfigurieren
|
||||
|
||||
```bash
|
||||
cp assets/.env.example .env
|
||||
nano .env
|
||||
```
|
||||
|
||||
Mindestens diese Werte setzen:
|
||||
|
||||
```dotenv
|
||||
MAILBOX_USER=vorname.nachname@mailbox.org
|
||||
MAILBOX_PASS=app-passwort-xyz
|
||||
```
|
||||
|
||||
### Schritt 3 — install.sh ausführen
|
||||
|
||||
```bash
|
||||
chmod +x scripts/install.sh
|
||||
bash scripts/install.sh
|
||||
```
|
||||
|
||||
Das Script installiert automatisch:
|
||||
- `vdirsyncer` — CalDAV-Sync-Tool
|
||||
- `khal` — CLI-Kalender
|
||||
- `todoman` — CLI-Aufgabenverwaltung
|
||||
- `python3-pass` — Passwort-Store-Integration
|
||||
- `gettext-base` — envsubst für Konfigurationen
|
||||
|
||||
Anschließend:
|
||||
- Alle Konfigurationsdateien werden deployed
|
||||
- systemd User-Timer wird aktiviert
|
||||
- Initialer Sync wird durchgeführt
|
||||
|
||||
### Schritt 4 — OpenClaw Skill registrieren
|
||||
|
||||
Füge in `~/.config/openclaw/config.yaml` hinzu:
|
||||
|
||||
```yaml
|
||||
skills:
|
||||
- name: mailbox-cal
|
||||
path: ~/openclaw-mailbox-cal
|
||||
entry: scripts/openclaw_skill.py
|
||||
commands:
|
||||
- termine
|
||||
- aufgaben
|
||||
- neu_aufgabe
|
||||
- sync
|
||||
- status
|
||||
```
|
||||
|
||||
```bash
|
||||
systemctl --user restart openclaw
|
||||
```
|
||||
|
||||
### Schritt 5 — Telegram testen
|
||||
|
||||
Sende an deinen Bot:
|
||||
```
|
||||
/termine
|
||||
/aufgaben
|
||||
/sync
|
||||
/status
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Test-Befehle
|
||||
|
||||
### Vollständiger Selbsttest
|
||||
```bash
|
||||
bash scripts/test_setup.sh
|
||||
```
|
||||
|
||||
### vdirsyncer
|
||||
```bash
|
||||
# Verbindung testen und Sammlungen entdecken
|
||||
vdirsyncer discover calendars
|
||||
vdirsyncer discover tasks
|
||||
|
||||
# Synchronisation manuell starten
|
||||
vdirsyncer sync
|
||||
|
||||
# Nur Kalender synchronisieren
|
||||
vdirsyncer sync calendars
|
||||
|
||||
# Verbose-Ausgabe
|
||||
vdirsyncer -v DEBUG sync
|
||||
```
|
||||
|
||||
### khal
|
||||
```bash
|
||||
# Termine heute
|
||||
khal list
|
||||
|
||||
# Termine nächste 7 Tage
|
||||
khal list today 7d
|
||||
|
||||
# Agenda-Ansicht
|
||||
khal agenda
|
||||
|
||||
# Interaktiver Kalender
|
||||
ikhal
|
||||
|
||||
# Ereignis hinzufügen (interaktiv)
|
||||
khal new
|
||||
|
||||
# Ereignis direkt anlegen
|
||||
khal new 2025-06-15 14:00 15:00 "Arzttermin" --calendar mailbox_kalender
|
||||
|
||||
# Cache neu aufbauen
|
||||
khal rebuild-cache
|
||||
|
||||
# Konfiguration anzeigen
|
||||
khal printformats
|
||||
```
|
||||
|
||||
### todoman
|
||||
```bash
|
||||
# Alle offenen Aufgaben
|
||||
todo list
|
||||
|
||||
# Alle Aufgaben inkl. erledigt
|
||||
todo list --all
|
||||
|
||||
# Neue Aufgabe
|
||||
todo new "Bericht schreiben"
|
||||
|
||||
# Aufgabe mit Fälligkeitsdatum
|
||||
todo new --due 2025-06-30 "Bericht abgeben"
|
||||
|
||||
# Aufgabe mit Priorität (1=hoch, 9=niedrig)
|
||||
todo new --priority 1 "Dringend: Server patchen"
|
||||
|
||||
# Aufgabe als erledigt markieren (ID aus 'todo list')
|
||||
todo done 1
|
||||
|
||||
# Aufgabe löschen
|
||||
todo delete 2
|
||||
|
||||
# Aufgaben-Listen anzeigen
|
||||
todo lists
|
||||
```
|
||||
|
||||
### systemd
|
||||
```bash
|
||||
# Timer-Status
|
||||
systemctl --user status vdirsyncer-sync.timer
|
||||
|
||||
# Service manuell starten (einmaliger Sync)
|
||||
systemctl --user start vdirsyncer-sync.service
|
||||
|
||||
# Alle User-Timer anzeigen
|
||||
systemctl --user list-timers
|
||||
|
||||
# Live-Log verfolgen
|
||||
journalctl --user -u vdirsyncer-sync.service -f
|
||||
|
||||
# Log der letzten 50 Zeilen
|
||||
journalctl --user -u vdirsyncer-sync.service -n 50
|
||||
|
||||
# Timer deaktivieren
|
||||
systemctl --user disable --now vdirsyncer-sync.timer
|
||||
```
|
||||
|
||||
### Python-Skill direkt testen
|
||||
```bash
|
||||
python3 scripts/openclaw_skill.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## mailbox.org CalDAV-Endpunkte
|
||||
|
||||
| Zweck | URL |
|
||||
|---|---|
|
||||
| CalDAV-Basis | `https://dav.mailbox.org/caldav/<USER>/` |
|
||||
| Kalender-Sammlung | `https://dav.mailbox.org/caldav/<USER>/Kalender/` |
|
||||
| Aufgaben-Sammlung | `https://dav.mailbox.org/caldav/<USER>/Aufgaben/` |
|
||||
| CardDAV (Kontakte) | `https://dav.mailbox.org/carddav/<USER>/` |
|
||||
|
||||
Entdeckung aller Sammlungen:
|
||||
```bash
|
||||
curl -u "USER:PASS" -X PROPFIND https://dav.mailbox.org/caldav/ \
|
||||
-H "Depth: 1" -H "Content-Type: application/xml"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Sicherheit
|
||||
|
||||
| Maßnahme | Status |
|
||||
|---|---|
|
||||
| App-Passwort statt Hauptpasswort | ✅ Empfohlen |
|
||||
| vdirsyncer-Config: chmod 600 | ✅ Automatisch via install.sh |
|
||||
| .env nicht in Git | ✅ In .gitignore eingetragen |
|
||||
| HTTPS für CalDAV | ✅ dav.mailbox.org erzwingt TLS |
|
||||
| pass(1)-Integration | Optional via python3-pass |
|
||||
|
||||
---
|
||||
|
||||
## Fehlerbehebung
|
||||
|
||||
**vdirsyncer: `[Errno 111] Connection refused`**
|
||||
→ Netzwerkverbindung prüfen: `ping dav.mailbox.org`
|
||||
|
||||
**vdirsyncer: `Conflict!`**
|
||||
→ Beide Seiten wurden geändert. Konflikt manuell lösen oder `conflict_resolution = "b wins"` in vdirsyncer.conf setzen.
|
||||
|
||||
**khal: `No calendars configured`**
|
||||
→ `khal rebuild-cache` ausführen; Pfad in `~/.config/khal/config` prüfen.
|
||||
|
||||
**todoman: `Error: No lists found`**
|
||||
→ `path`-Eintrag in `~/.config/todoman/config.cfg` prüfen; Verzeichnis `~/.local/share/vdirsyncer/tasks/` muss existieren und `.ics`-Dateien enthalten.
|
||||
|
||||
**systemd-Timer läuft nach Reboot nicht**
|
||||
→ `sudo loginctl enable-linger $USER` ausführen (User-Session ohne Login).
|
||||
|
||||
---
|
||||
|
||||
## Lizenz
|
||||
|
||||
MIT — Freie Nutzung, Veränderung und Weitergabe.
|
||||
@@ -0,0 +1,197 @@
|
||||
---
|
||||
name: mailbox-cal
|
||||
description: "OpenClaw Telegram-Bot-Skill für mailbox.org Kalender und Aufgaben auf dem Raspberry Pi. Synchronisiert CalDAV-Kalender und VTODO-Aufgaben via vdirsyncer, zeigt Termine mit khal und verwaltet Tasks mit todoman. Befehle: /termine, /aufgaben, /neu_aufgabe, /sync, /status. Lade diesen Skill wenn: der Nutzer Kalender-Einträge oder Aufgaben aus mailbox.org per Telegram abfragen, anlegen oder synchronisieren möchte."
|
||||
license: MIT
|
||||
compatibility: "Raspberry Pi OS Bookworm / Ubuntu 22.04+ ARM. Benötigt: vdirsyncer >= 0.19, khal >= 0.11, todoman >= 4.3, python3 >= 3.10. mailbox.org CalDAV-Zugang erforderlich."
|
||||
metadata:
|
||||
author: lonely.wolf.64
|
||||
version: '1.0'
|
||||
platform: Raspberry Pi
|
||||
caldav_server: mailbox.org
|
||||
---
|
||||
|
||||
# mailbox.org Kalender + Aufgaben Skill
|
||||
|
||||
## Übersicht
|
||||
|
||||
Dieser OpenClaw-Skill synchronisiert deinen mailbox.org-Kalender und deine Aufgaben über CalDAV auf einen Raspberry Pi und stellt sie über Telegram-Bot-Befehle bereit. Die Synchronisation läuft automatisch alle 15 Minuten via systemd-Timer.
|
||||
|
||||
**Architektur:**
|
||||
```
|
||||
mailbox.org (CalDAV)
|
||||
│
|
||||
vdirsyncer (Sync)
|
||||
│
|
||||
┌───┴───────────┐
|
||||
│ │
|
||||
khal todoman
|
||||
(Kalender) (Aufgaben)
|
||||
│ │
|
||||
└───────┬───────┘
|
||||
│
|
||||
openclaw_skill.py
|
||||
│
|
||||
Telegram Bot
|
||||
```
|
||||
|
||||
## Unterstützte Befehle
|
||||
|
||||
| Telegram-Befehl | Beschreibung | Beispiel |
|
||||
|---|---|---|
|
||||
| `/termine` | Heutige Termine | `/termine heute` |
|
||||
| `/termine morgen` | Morgige Termine | `/termine morgen` |
|
||||
| `/termine woche` | Termine nächste 7 Tage | `/termine woche` |
|
||||
| `/aufgaben` | Offene Aufgaben | `/aufgaben` |
|
||||
| `/aufgaben alle` | Alle Aufgaben inkl. erledigt | `/aufgaben alle` |
|
||||
| `/neu_aufgabe` | Neue Aufgabe anlegen | `/neu_aufgabe Arzt anrufen` |
|
||||
| `/sync` | Manuellen Sync auslösen | `/sync` |
|
||||
| `/status` | Sync-Timer-Status | `/status` |
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
- Raspberry Pi mit Raspberry Pi OS Bookworm oder Ubuntu 22.04+ ARM
|
||||
- mailbox.org-Konto mit CalDAV-Zugang
|
||||
- OpenClaw installiert und konfiguriert
|
||||
- Telegram Bot-Token (via @BotFather)
|
||||
- Internetverbindung vom Raspberry Pi
|
||||
|
||||
## Installation
|
||||
|
||||
### 1. Repository klonen
|
||||
|
||||
```bash
|
||||
git clone https://github.com/DEIN_USER/openclaw-mailbox-cal.git
|
||||
cd openclaw-mailbox-cal
|
||||
```
|
||||
|
||||
### 2. .env befüllen
|
||||
|
||||
```bash
|
||||
cp assets/.env.example .env
|
||||
nano .env
|
||||
# MAILBOX_USER und MAILBOX_PASS setzen
|
||||
```
|
||||
|
||||
**Empfehlung:** Lege in mailbox.org ein App-Passwort an:
|
||||
Einstellungen → Sicherheit → App-Passwörter → Neu erstellen
|
||||
|
||||
### 3. Installation ausführen
|
||||
|
||||
```bash
|
||||
chmod +x scripts/install.sh
|
||||
bash scripts/install.sh
|
||||
```
|
||||
|
||||
Das Script führt folgende Schritte aus:
|
||||
1. Pakete installieren: `vdirsyncer khal todoman python3-pass gettext-base`
|
||||
2. Konfigurationsdateien deployen (mit envsubst)
|
||||
3. systemd User-Timer aktivieren
|
||||
4. Initialen Sync durchführen
|
||||
5. khal-Datenbank aufbauen
|
||||
6. OpenClaw Skill verknüpfen
|
||||
|
||||
### 4. Skill in OpenClaw registrieren
|
||||
|
||||
In OpenClaw-Konfiguration (`~/.config/openclaw/config.yaml`):
|
||||
|
||||
```yaml
|
||||
skills:
|
||||
- name: mailbox-cal
|
||||
path: /home/pi/openclaw-mailbox-cal
|
||||
entry: scripts/openclaw_skill.py
|
||||
commands:
|
||||
- termine
|
||||
- aufgaben
|
||||
- neu_aufgabe
|
||||
- sync
|
||||
- status
|
||||
```
|
||||
|
||||
Danach OpenClaw neu starten:
|
||||
```bash
|
||||
systemctl --user restart openclaw
|
||||
```
|
||||
|
||||
## Test-Befehle
|
||||
|
||||
Nach der Installation Setup validieren:
|
||||
|
||||
```bash
|
||||
# Vollständiger Selbsttest
|
||||
bash scripts/test_setup.sh
|
||||
|
||||
# Einzeltests
|
||||
vdirsyncer sync # Sync testen
|
||||
khal list today tomorrow # Termine heute + morgen
|
||||
khal list --format "{start} {title}" 2025-01-01 2025-12-31 # Jahresübersicht
|
||||
todo list # Aufgaben anzeigen
|
||||
todo list --all # Alle inkl. erledigt
|
||||
todo new "Test-Aufgabe" # Aufgabe anlegen
|
||||
|
||||
# systemd Timer
|
||||
systemctl --user status vdirsyncer-sync.timer # Timer-Status
|
||||
systemctl --user list-timers # Alle Timer
|
||||
journalctl --user -u vdirsyncer-sync.service -f # Live-Log
|
||||
|
||||
# Python-Skill direkt testen (ohne OpenClaw/Telegram)
|
||||
python3 scripts/openclaw_skill.py
|
||||
```
|
||||
|
||||
## Konfigurationsdateien
|
||||
|
||||
| Datei | Ziel-Pfad | Beschreibung |
|
||||
|---|---|---|
|
||||
| `config/vdirsyncer.conf` | `~/.config/vdirsyncer/config` | CalDAV-Sync-Konfiguration |
|
||||
| `config/khal.conf` | `~/.config/khal/config` | Kalender-Anzeige-Konfiguration |
|
||||
| `config/todoman.conf` | `~/.config/todoman/config.cfg` | Aufgaben-Konfiguration |
|
||||
| `systemd/vdirsyncer-sync.service` | `~/.config/systemd/user/` | Sync-Service Unit |
|
||||
| `systemd/vdirsyncer-sync.timer` | `~/.config/systemd/user/` | 15-Minuten-Timer |
|
||||
| `scripts/openclaw_skill.py` | (in-place) | OpenClaw/Telegram-Integration |
|
||||
|
||||
## Sicherheitshinweise
|
||||
|
||||
- Die vdirsyncer-Config (`~/.config/vdirsyncer/config`) enthält das Passwort — Berechtigungen sind `chmod 600`
|
||||
- Verwende ein mailbox.org App-Passwort statt des Hauptpassworts
|
||||
- Für produktive Umgebungen: `pass`-Integration (GNU Password Store) via `python3-pass`
|
||||
- `.env`-Datei niemals in Git committen (ist in `.gitignore` eingetragen)
|
||||
|
||||
## Fehlerbehebung
|
||||
|
||||
### vdirsyncer discover schlägt fehl
|
||||
```bash
|
||||
# Verbindung testen
|
||||
curl -u "USER:PASS" https://dav.mailbox.org/caldav/
|
||||
# SSL-Zertifikate prüfen
|
||||
openssl s_client -connect dav.mailbox.org:443
|
||||
```
|
||||
|
||||
### khal zeigt keine Termine
|
||||
```bash
|
||||
# Cache neu aufbauen
|
||||
khal rebuild-cache
|
||||
# Config validieren
|
||||
khal printformats
|
||||
```
|
||||
|
||||
### systemd-Timer läuft nicht
|
||||
```bash
|
||||
# Lingering aktivieren (damit User-Units ohne Login laufen)
|
||||
sudo loginctl enable-linger pi
|
||||
# Timer manuell starten
|
||||
systemctl --user start vdirsyncer-sync.service
|
||||
```
|
||||
|
||||
### Todoman findet keine Aufgaben
|
||||
```bash
|
||||
# Pfad in config prüfen
|
||||
cat ~/.config/todoman/config.cfg
|
||||
# Verzeichnis prüfen
|
||||
ls ~/.local/share/vdirsyncer/tasks/
|
||||
```
|
||||
|
||||
## Erweiterungen
|
||||
|
||||
- **Mehrere Kalender:** Weitere `[[kalender_name]]`-Sektionen in `khal.conf` hinzufügen
|
||||
- **Push-Sync:** mailbox.org unterstützt CalDAV-Push — XMPP-Trigger via `vdirsyncer`
|
||||
- **Erinnerungen:** Integration mit `khal-remind` oder `at`-Daemon
|
||||
- **Verschlüsselung:** `.env` via `gpg-agent` verschlüsseln
|
||||
@@ -0,0 +1,39 @@
|
||||
# ============================================================
|
||||
# OpenClaw mailbox.org Kalender + Aufgaben — Umgebungsvariablen
|
||||
# Kopiere diese Datei nach .env und passe die Werte an.
|
||||
# ============================================================
|
||||
|
||||
# --- mailbox.org Zugangsdaten ---
|
||||
MAILBOX_USER=dein.name@mailbox.org
|
||||
MAILBOX_PASS=dein_passwort_hier
|
||||
|
||||
# Optional: App-Passwort statt Hauptpasswort (empfohlen)
|
||||
# Unter mailbox.org → Einstellungen → Sicherheit → App-Passwörter erstellen
|
||||
# MAILBOX_PASS=app-passwort-xyzabc
|
||||
|
||||
# --- Kalender-Konfiguration ---
|
||||
# Basis-URL des CalDAV-Servers von mailbox.org
|
||||
CALDAV_BASE_URL=https://dav.mailbox.org/caldav/
|
||||
|
||||
# Name des primären Kalenders (wie in mailbox.org angelegt)
|
||||
PRIMARY_CALENDAR=Kalender
|
||||
|
||||
# Name des Aufgaben-Kalenders (VTODO)
|
||||
TASKS_CALENDAR=Aufgaben
|
||||
|
||||
# --- Sync-Intervall (für systemd-Timer) ---
|
||||
# Format: systemd OnCalendar — z. B. *:0/15 = alle 15 Minuten
|
||||
SYNC_INTERVAL=*:0/15
|
||||
|
||||
# --- Lokale Verzeichnisse ---
|
||||
VDIR_BASE_DIR=/home/pi/.local/share/vdirsyncer
|
||||
KHAL_DB_PATH=/home/pi/.local/share/khal/db.db
|
||||
|
||||
# --- OpenClaw / Telegram ---
|
||||
OPENCLAW_SKILL_NAME=mailbox-cal
|
||||
# Telegram Bot Token (aus BotFather)
|
||||
TELEGRAM_BOT_TOKEN=123456789:AABBCCDDEEFFaabbccddeeff1234567890
|
||||
|
||||
# --- Logging ---
|
||||
LOG_LEVEL=INFO
|
||||
LOG_FILE=/var/log/openclaw-mailbox-cal/sync.log
|
||||
@@ -0,0 +1,60 @@
|
||||
# =============================================================
|
||||
# khal Konfiguration
|
||||
# Pfad: ~/.config/khal/config
|
||||
# Dokumentation: https://lostpackets.de/khal/
|
||||
# =============================================================
|
||||
|
||||
[calendars]
|
||||
|
||||
# Primärer Kalender (VEVENT)
|
||||
[[mailbox_kalender]]
|
||||
path = ~/.local/share/vdirsyncer/calendars/Kalender/
|
||||
color = light cyan
|
||||
readonly = False
|
||||
|
||||
# Weitere Kalender-Sammlungen — füge bei Bedarf weitere hinzu
|
||||
# [[mailbox_privat]]
|
||||
# path = ~/.local/share/vdirsyncer/calendars/Privat/
|
||||
# color = light blue
|
||||
# readonly = False
|
||||
|
||||
|
||||
[sqlite]
|
||||
# SQLite-Datenbank für khal-Index
|
||||
path = ~/.local/share/khal/db.db
|
||||
|
||||
|
||||
[locale]
|
||||
# Zeitzone und Spracheinstellungen (Österreich/Deutschland)
|
||||
local_timezone = Europe/Vienna
|
||||
default_timezone = Europe/Vienna
|
||||
|
||||
# Datumsformat: DD.MM.YYYY (deutsches Format)
|
||||
dateformat = %d.%m.%Y
|
||||
|
||||
# Zeitformat: HH:MM (24h)
|
||||
timeformat = %H:%M
|
||||
|
||||
# Datum+Zeit-Format
|
||||
datetimeformat = %d.%m.%Y %H:%M
|
||||
|
||||
# Wochenbeginn: Montag
|
||||
firstweekday = 0
|
||||
|
||||
# Sprache (für Ausgabe)
|
||||
# khal nutzt die System-Locale; stelle sicher, dass de_AT.UTF-8 installiert ist:
|
||||
# sudo locale-gen de_AT.UTF-8
|
||||
|
||||
|
||||
[view]
|
||||
# Standard-Ansicht beim Starten von khal
|
||||
default_calendar = mailbox_kalender
|
||||
|
||||
# Agenda-Vorschau: Tage in die Zukunft
|
||||
days = 7
|
||||
|
||||
# Farbige Ausgabe
|
||||
color = True
|
||||
|
||||
# Zeilenumbruch bei langen Titeln
|
||||
event_format = {title} [{calendar}]
|
||||
@@ -0,0 +1,32 @@
|
||||
# =============================================================
|
||||
# todoman Konfiguration
|
||||
# Pfad: ~/.config/todoman/config.cfg
|
||||
# Dokumentation: https://todoman.readthedocs.io/
|
||||
# =============================================================
|
||||
|
||||
[main]
|
||||
|
||||
# Verzeichnis mit den synchronisierten VTODO-Dateien (vdirsyncer output)
|
||||
path = ~/.local/share/vdirsyncer/tasks/*
|
||||
|
||||
# Standard-Liste für neue Aufgaben (muss einem Unterverzeichnis entsprechen)
|
||||
default_list = Aufgaben
|
||||
|
||||
# Datum/Zeit-Format (deutsches Format)
|
||||
date_format = %d.%m.%Y
|
||||
time_format = %H:%M
|
||||
datetime_format = %d.%m.%Y %H:%M
|
||||
|
||||
# Farbige Ausgabe aktivieren
|
||||
color = auto
|
||||
|
||||
# Abgeschlossene Aufgaben ausblenden (true = nur offene anzeigen)
|
||||
# Kann via CLI mit --all überschrieben werden
|
||||
humanize = true
|
||||
|
||||
# Priorität anzeigen
|
||||
show_private = true
|
||||
|
||||
# Dateierweiterung für VTODO-Dateien
|
||||
# (muss mit vdirsyncer fileext übereinstimmen)
|
||||
# fileext = .ics ← Standard, nicht ändern
|
||||
@@ -0,0 +1,80 @@
|
||||
# =============================================================
|
||||
# vdirsyncer Konfiguration für mailbox.org (CalDAV)
|
||||
# Pfad: ~/.config/vdirsyncer/config
|
||||
#
|
||||
# Ersetze MAILBOX_USER / MAILBOX_PASS durch echte Werte
|
||||
# oder nutze das install.sh-Script, das .env einliest und
|
||||
# diese Datei mit envsubst befüllt.
|
||||
# =============================================================
|
||||
|
||||
[general]
|
||||
# Statusverzeichnis für vdirsyncer-Metadaten
|
||||
status_path = "~/.local/share/vdirsyncer/status/"
|
||||
|
||||
|
||||
# -----------------------------------------------------------
|
||||
# STORAGE: Lokale CalDAV-Verzeichnisse (filesystem)
|
||||
# -----------------------------------------------------------
|
||||
|
||||
[storage local_calendars]
|
||||
type = "filesystem"
|
||||
path = "~/.local/share/vdirsyncer/calendars/"
|
||||
fileext = ".ics"
|
||||
|
||||
[storage local_tasks]
|
||||
type = "filesystem"
|
||||
path = "~/.local/share/vdirsyncer/tasks/"
|
||||
fileext = ".ics"
|
||||
|
||||
|
||||
# -----------------------------------------------------------
|
||||
# STORAGE: mailbox.org CalDAV-Server (Remote)
|
||||
#
|
||||
# mailbox.org CalDAV-Endpunkte:
|
||||
# Kalender: https://dav.mailbox.org/caldav/<USERNAME>/
|
||||
# Aufgaben: https://dav.mailbox.org/caldav/<USERNAME>/Aufgaben/
|
||||
#
|
||||
# Für die Entdeckung aller Sammlungen:
|
||||
# vdirsyncer discover calendars
|
||||
# -----------------------------------------------------------
|
||||
|
||||
[storage remote_calendars]
|
||||
type = "caldav"
|
||||
url = "https://dav.mailbox.org/caldav/${MAILBOX_USER}/"
|
||||
username = "${MAILBOX_USER}"
|
||||
password = "${MAILBOX_PASS}"
|
||||
|
||||
# Nur VEVENT-Einträge (Kalender-Ereignisse)
|
||||
item_types = ["VEVENT"]
|
||||
|
||||
[storage remote_tasks]
|
||||
type = "caldav"
|
||||
url = "https://dav.mailbox.org/caldav/${MAILBOX_USER}/"
|
||||
username = "${MAILBOX_USER}"
|
||||
password = "${MAILBOX_PASS}"
|
||||
|
||||
# Nur VTODO-Einträge (Aufgaben / Tasks)
|
||||
item_types = ["VTODO"]
|
||||
|
||||
|
||||
# -----------------------------------------------------------
|
||||
# PAIR: Kalender-Synchronisierung
|
||||
# -----------------------------------------------------------
|
||||
|
||||
[pair calendars]
|
||||
a = "local_calendars"
|
||||
b = "remote_calendars"
|
||||
collections = ["from b"]
|
||||
|
||||
# Konflikt-Lösung: Remote gewinnt (mailbox.org ist die Quelle der Wahrheit)
|
||||
conflict_resolution = "b wins"
|
||||
|
||||
# Metadaten-Sync (Kalender-Farbe, Anzeigename)
|
||||
metadata = ["color", "displayname"]
|
||||
|
||||
[pair tasks]
|
||||
a = "local_tasks"
|
||||
b = "remote_tasks"
|
||||
collections = ["from b"]
|
||||
conflict_resolution = "b wins"
|
||||
metadata = ["color", "displayname"]
|
||||
@@ -0,0 +1,157 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================
|
||||
# install.sh — OpenClaw mailbox.org Kalender + Aufgaben
|
||||
# Zielplattform: Raspberry Pi (Raspberry Pi OS / Ubuntu ARM)
|
||||
# Ausführen als: pi-Nutzer (sudo-Rechte erforderlich)
|
||||
# =============================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
ENV_FILE="$REPO_ROOT/.env"
|
||||
|
||||
# --- Farben ---
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
|
||||
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }
|
||||
|
||||
# =============================================================
|
||||
# 1. .env laden
|
||||
# =============================================================
|
||||
if [[ ! -f "$ENV_FILE" ]]; then
|
||||
warn ".env nicht gefunden — kopiere .env.example nach .env"
|
||||
cp "$REPO_ROOT/assets/.env.example" "$ENV_FILE"
|
||||
error "Bitte .env mit deinen mailbox.org-Zugangsdaten befüllen und install.sh erneut ausführen."
|
||||
fi
|
||||
# shellcheck source=/dev/null
|
||||
source "$ENV_FILE"
|
||||
info ".env geladen (Benutzer: ${MAILBOX_USER:-NICHT GESETZT})"
|
||||
|
||||
[[ -z "${MAILBOX_USER:-}" ]] && error "MAILBOX_USER in .env nicht gesetzt!"
|
||||
[[ -z "${MAILBOX_PASS:-}" ]] && error "MAILBOX_PASS in .env nicht gesetzt!"
|
||||
|
||||
# =============================================================
|
||||
# 2. Systempakete installieren
|
||||
# =============================================================
|
||||
info "Installiere Systempakete..."
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y \
|
||||
vdirsyncer \
|
||||
khal \
|
||||
todoman \
|
||||
python3-pass \
|
||||
gettext-base \
|
||||
curl \
|
||||
jq \
|
||||
python3-pip \
|
||||
python3-venv
|
||||
|
||||
# Locale sicherstellen
|
||||
sudo locale-gen de_AT.UTF-8 2>/dev/null || true
|
||||
info "Pakete installiert."
|
||||
|
||||
# =============================================================
|
||||
# 3. Verzeichnisse anlegen
|
||||
# =============================================================
|
||||
info "Lege Verzeichnisse an..."
|
||||
|
||||
VDIR_BASE="${VDIR_BASE_DIR:-$HOME/.local/share/vdirsyncer}"
|
||||
mkdir -p "$VDIR_BASE/status"
|
||||
mkdir -p "$VDIR_BASE/calendars"
|
||||
mkdir -p "$VDIR_BASE/tasks"
|
||||
mkdir -p "${KHAL_DB_PATH:-$HOME/.local/share/khal}"
|
||||
mkdir -p "$HOME/.config/vdirsyncer"
|
||||
mkdir -p "$HOME/.config/khal"
|
||||
mkdir -p "$HOME/.config/todoman"
|
||||
sudo mkdir -p /var/log/openclaw-mailbox-cal
|
||||
sudo chown "$USER:$USER" /var/log/openclaw-mailbox-cal
|
||||
|
||||
# =============================================================
|
||||
# 4. Konfigurationsdateien deployen (envsubst für Variablen)
|
||||
# =============================================================
|
||||
info "Deploye Konfigurationsdateien..."
|
||||
|
||||
# vdirsyncer config — Variablen ersetzen
|
||||
export MAILBOX_USER MAILBOX_PASS
|
||||
envsubst '${MAILBOX_USER} ${MAILBOX_PASS}' \
|
||||
< "$REPO_ROOT/config/vdirsyncer.conf" \
|
||||
> "$HOME/.config/vdirsyncer/config"
|
||||
chmod 600 "$HOME/.config/vdirsyncer/config"
|
||||
info " → ~/.config/vdirsyncer/config"
|
||||
|
||||
# khal config
|
||||
cp "$REPO_ROOT/config/khal.conf" "$HOME/.config/khal/config"
|
||||
info " → ~/.config/khal/config"
|
||||
|
||||
# todoman config
|
||||
cp "$REPO_ROOT/config/todoman.conf" "$HOME/.config/todoman/config.cfg"
|
||||
info " → ~/.config/todoman/config.cfg"
|
||||
|
||||
# =============================================================
|
||||
# 5. systemd Units installieren (User-Session)
|
||||
# =============================================================
|
||||
info "Installiere systemd Units (User-Session)..."
|
||||
|
||||
SYSTEMD_USER_DIR="$HOME/.config/systemd/user"
|
||||
mkdir -p "$SYSTEMD_USER_DIR"
|
||||
|
||||
# Variablen in systemd-Units ersetzen
|
||||
for unit_file in "$REPO_ROOT/systemd/"*.{service,timer}; do
|
||||
[[ -f "$unit_file" ]] || continue
|
||||
unit_name="$(basename "$unit_file")"
|
||||
envsubst '${SYNC_INTERVAL}' < "$unit_file" > "$SYSTEMD_USER_DIR/$unit_name"
|
||||
info " → $SYSTEMD_USER_DIR/$unit_name"
|
||||
done
|
||||
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now vdirsyncer-sync.timer
|
||||
info "systemd Timer aktiviert."
|
||||
|
||||
# Lingering aktivieren (damit User-Units ohne Login laufen)
|
||||
loginctl enable-linger "$USER" 2>/dev/null || \
|
||||
warn "loginctl enable-linger fehlgeschlagen — bitte manuell ausführen: sudo loginctl enable-linger $USER"
|
||||
|
||||
# =============================================================
|
||||
# 6. Erst-Synchronisation
|
||||
# =============================================================
|
||||
info "Führe initialen vdirsyncer discover + sync durch..."
|
||||
vdirsyncer discover calendars || warn "discover calendars hatte Warnungen — prüfe Ausgabe"
|
||||
vdirsyncer discover tasks || warn "discover tasks hatte Warnungen — prüfe Ausgabe"
|
||||
vdirsyncer sync || warn "sync hatte Warnungen — prüfe Ausgabe"
|
||||
info "Erst-Sync abgeschlossen."
|
||||
|
||||
# =============================================================
|
||||
# 7. khal-Index aufbauen
|
||||
# =============================================================
|
||||
info "Baue khal-Index auf..."
|
||||
khal --config "$HOME/.config/khal/config" rebuild-cache || true
|
||||
|
||||
# =============================================================
|
||||
# 8. OpenClaw Skill-Verknüpfung
|
||||
# =============================================================
|
||||
OPENCLAW_SKILLS_DIR="${OPENCLAW_SKILLS_DIR:-$HOME/.config/openclaw/skills}"
|
||||
if [[ -d "$OPENCLAW_SKILLS_DIR" ]]; then
|
||||
info "Verknüpfe OpenClaw Skill..."
|
||||
ln -sf "$REPO_ROOT" "$OPENCLAW_SKILLS_DIR/mailbox-cal" 2>/dev/null || true
|
||||
info " → $OPENCLAW_SKILLS_DIR/mailbox-cal"
|
||||
else
|
||||
warn "OpenClaw Skills-Verzeichnis nicht gefunden ($OPENCLAW_SKILLS_DIR)."
|
||||
warn "Bitte Skill manuell in OpenClaw registrieren (siehe README.md)."
|
||||
fi
|
||||
|
||||
# =============================================================
|
||||
# Fertig
|
||||
# =============================================================
|
||||
echo ""
|
||||
echo -e "${GREEN}╔══════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${GREEN}║ Installation abgeschlossen! ║${NC}"
|
||||
echo -e "${GREEN}╚══════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo " Nächste Schritte:"
|
||||
echo " 1. khal agenda # Termine anzeigen"
|
||||
echo " 2. todo list # Aufgaben anzeigen"
|
||||
echo " 3. systemctl --user status vdirsyncer-sync.timer"
|
||||
echo " 4. tail -f /var/log/openclaw-mailbox-cal/sync.log"
|
||||
echo ""
|
||||
@@ -0,0 +1,178 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
openclaw_skill.py — OpenClaw Telegram-Bot-Skill: mailbox.org Kalender + Aufgaben
|
||||
Registrierung in OpenClaw: /register skill mailbox-cal
|
||||
|
||||
Unterstützte Befehle (via Telegram-Chat an den Bot):
|
||||
/termine [heute|morgen|woche] — Kalender-Ereignisse anzeigen
|
||||
/aufgaben [offen|alle] — Aufgabenliste anzeigen
|
||||
/neu_aufgabe <Text> — Neue Aufgabe anlegen
|
||||
/sync — manuellen vdirsyncer-Sync auslösen
|
||||
/status — Sync-Status abfragen
|
||||
|
||||
Voraussetzungen:
|
||||
- khal, todoman, vdirsyncer installiert (install.sh ausgeführt)
|
||||
- OpenClaw mit Python-Skill-API >= 0.4
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
import shlex
|
||||
import logging
|
||||
from datetime import datetime, date, timedelta
|
||||
from typing import Optional
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────
|
||||
# Hilfsfunktionen
|
||||
# ─────────────────────────────────────────────
|
||||
|
||||
def _run(cmd: list[str], timeout: int = 30) -> tuple[str, str, int]:
|
||||
"""Führt einen Subprozess aus und gibt (stdout, stderr, returncode) zurück."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
cmd,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=timeout,
|
||||
)
|
||||
return result.stdout.strip(), result.stderr.strip(), result.returncode
|
||||
except subprocess.TimeoutExpired:
|
||||
return "", "Timeout nach {}s".format(timeout), 1
|
||||
except FileNotFoundError as e:
|
||||
return "", str(e), 127
|
||||
|
||||
|
||||
def _khal_agenda(days: int = 1, start: Optional[date] = None) -> str:
|
||||
"""Gibt khal-Agenda als String zurück."""
|
||||
start_str = (start or date.today()).strftime("%Y-%m-%d")
|
||||
end_str = (date.today() + timedelta(days=days)).strftime("%Y-%m-%d")
|
||||
stdout, stderr, rc = _run(
|
||||
["khal", "list", "--format", "{start-time} {title}", start_str, end_str]
|
||||
)
|
||||
if rc != 0:
|
||||
logger.warning("khal list Fehler: %s", stderr)
|
||||
return "⚠️ khal Fehler: " + stderr
|
||||
return stdout or "Keine Termine gefunden."
|
||||
|
||||
|
||||
def _todo_list(all_tasks: bool = False) -> str:
|
||||
"""Gibt todoman-Aufgabenliste als String zurück."""
|
||||
cmd = ["todo", "list"]
|
||||
if all_tasks:
|
||||
cmd.append("--all")
|
||||
stdout, stderr, rc = _run(cmd)
|
||||
if rc != 0:
|
||||
return "⚠️ todoman Fehler: " + stderr
|
||||
return stdout or "Keine Aufgaben."
|
||||
|
||||
|
||||
def _todo_new(title: str) -> str:
|
||||
"""Legt eine neue Aufgabe an."""
|
||||
if not title.strip():
|
||||
return "⚠️ Kein Aufgabentitel angegeben."
|
||||
stdout, stderr, rc = _run(["todo", "new", "--", title])
|
||||
if rc != 0:
|
||||
return "⚠️ Fehler beim Anlegen: " + stderr
|
||||
return "✅ Aufgabe angelegt: " + title
|
||||
|
||||
|
||||
def _vdirsyncer_sync() -> str:
|
||||
"""Löst manuellen vdirsyncer-Sync aus."""
|
||||
stdout, stderr, rc = _run(["vdirsyncer", "sync"], timeout=60)
|
||||
if rc != 0:
|
||||
return "⚠️ Sync-Fehler:\n" + stderr
|
||||
return "✅ Sync erfolgreich.\n" + stdout
|
||||
|
||||
|
||||
def _sync_status() -> str:
|
||||
"""Prüft systemd-Timer-Status."""
|
||||
stdout, _, rc = _run(
|
||||
["systemctl", "--user", "status", "vdirsyncer-sync.timer", "--no-pager", "-l"]
|
||||
)
|
||||
if rc not in (0, 3):
|
||||
return "⚠️ Timer nicht gefunden oder Fehler."
|
||||
# Nur relevante Zeilen extrahieren
|
||||
lines = [
|
||||
line for line in stdout.splitlines()
|
||||
if any(kw in line for kw in ("Active:", "Trigger:", "Last trigger:"))
|
||||
]
|
||||
return "\n".join(lines) or stdout[:500]
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────
|
||||
# OpenClaw Skill-Handler
|
||||
# ─────────────────────────────────────────────
|
||||
|
||||
def handle(command: str, args: str, context: dict) -> str:
|
||||
"""
|
||||
Haupt-Einstiegspunkt für OpenClaw.
|
||||
|
||||
:param command: Befehlsname ohne führenden Slash, z. B. "termine"
|
||||
:param args: Argumente als String, z. B. "woche"
|
||||
:param context: OpenClaw-Kontext (user_id, chat_id, etc.)
|
||||
:return: Antwort-String für Telegram
|
||||
"""
|
||||
cmd = command.lower().strip()
|
||||
arg = args.lower().strip()
|
||||
|
||||
if cmd == "termine":
|
||||
if arg in ("morgen",):
|
||||
start = date.today() + timedelta(days=1)
|
||||
result = _khal_agenda(days=1, start=start)
|
||||
return "📅 *Termine morgen:*\n" + result
|
||||
elif arg in ("woche", "7"):
|
||||
result = _khal_agenda(days=7)
|
||||
return "📅 *Termine diese Woche:*\n" + result
|
||||
else:
|
||||
result = _khal_agenda(days=1)
|
||||
return "📅 *Termine heute:*\n" + result
|
||||
|
||||
elif cmd == "aufgaben":
|
||||
all_tasks = arg in ("alle", "all", "fertig")
|
||||
result = _todo_list(all_tasks=all_tasks)
|
||||
label = "alle Aufgaben" if all_tasks else "offene Aufgaben"
|
||||
return "📝 *{}:*\n{}".format(label.capitalize(), result)
|
||||
|
||||
elif cmd == "neu_aufgabe":
|
||||
return _todo_new(args.strip())
|
||||
|
||||
elif cmd == "sync":
|
||||
return "🔄 Starte Sync...\n" + _vdirsyncer_sync()
|
||||
|
||||
elif cmd == "status":
|
||||
return "⏱ *Sync-Status:*\n" + _sync_status()
|
||||
|
||||
else:
|
||||
return (
|
||||
"❓ Unbekannter Befehl. Verfügbare Befehle:\n"
|
||||
" /termine [heute|morgen|woche]\n"
|
||||
" /aufgaben [offen|alle]\n"
|
||||
" /neu_aufgabe <Text>\n"
|
||||
" /sync\n"
|
||||
" /status"
|
||||
)
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────
|
||||
# Standalone-Test (ohne OpenClaw)
|
||||
# ─────────────────────────────────────────────
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
tests = [
|
||||
("termine", "heute"),
|
||||
("termine", "woche"),
|
||||
("aufgaben", "offen"),
|
||||
("sync", ""),
|
||||
("status", ""),
|
||||
]
|
||||
for cmd, arg in tests:
|
||||
print("\n" + "=" * 50)
|
||||
print(f"CMD: {cmd!r} ARG: {arg!r}")
|
||||
print(handle(cmd, arg, {}))
|
||||
@@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================
|
||||
# test_setup.sh — Überprüft die Installation Schritt für Schritt
|
||||
# Ausführen nach install.sh: bash scripts/test_setup.sh
|
||||
# =============================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Farben
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
|
||||
ok() { echo -e "${GREEN} [✓] $*${NC}"; }
|
||||
fail() { echo -e "${RED} [✗] $*${NC}"; FAILED=$((FAILED+1)); }
|
||||
info() { echo -e "${CYAN} [i] $*${NC}"; }
|
||||
|
||||
FAILED=0
|
||||
|
||||
echo ""
|
||||
echo -e "${CYAN}══════════════════════════════════════════════════${NC}"
|
||||
echo -e "${CYAN} OpenClaw mailbox.org Kalender+Aufgaben — Selbsttest${NC}"
|
||||
echo -e "${CYAN}══════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
|
||||
# --- 1. Binaries vorhanden? ---
|
||||
echo "▶ 1. Programm-Verfügbarkeit"
|
||||
for bin in vdirsyncer khal todo python3; do
|
||||
if command -v "$bin" &>/dev/null; then
|
||||
ok "$bin → $(command -v $bin)"
|
||||
else
|
||||
fail "$bin nicht gefunden — install.sh ausführen"
|
||||
fi
|
||||
done
|
||||
|
||||
# --- 2. Konfigurationsdateien ---
|
||||
echo ""
|
||||
echo "▶ 2. Konfigurationsdateien"
|
||||
declare -A CONFIGS=(
|
||||
["vdirsyncer"]="$HOME/.config/vdirsyncer/config"
|
||||
["khal"]="$HOME/.config/khal/config"
|
||||
["todoman"]="$HOME/.config/todoman/config.cfg"
|
||||
)
|
||||
for name in "${!CONFIGS[@]}"; do
|
||||
path="${CONFIGS[$name]}"
|
||||
if [[ -f "$path" ]]; then
|
||||
ok "$name → $path"
|
||||
else
|
||||
fail "$name-Config fehlt: $path"
|
||||
fi
|
||||
done
|
||||
|
||||
# --- 3. Berechtigungen vdirsyncer-Config (enthält Passwort) ---
|
||||
echo ""
|
||||
echo "▶ 3. Sicherheit"
|
||||
VDIR_CONF="$HOME/.config/vdirsyncer/config"
|
||||
if [[ -f "$VDIR_CONF" ]]; then
|
||||
PERMS=$(stat -c "%a" "$VDIR_CONF")
|
||||
if [[ "$PERMS" == "600" ]]; then
|
||||
ok "vdirsyncer config Berechtigungen: $PERMS (korrekt)"
|
||||
else
|
||||
fail "vdirsyncer config Berechtigungen: $PERMS (sollte 600 sein) → chmod 600 $VDIR_CONF"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prüfe ob Klartext-Passwort in Config steht
|
||||
if grep -q 'password.*=.*"[^$]' "$VDIR_CONF" 2>/dev/null; then
|
||||
info "Passwort in Plaintext erkannt — Erwäge pass(1) oder python-keyring als Alternative"
|
||||
fi
|
||||
|
||||
# --- 4. Sync-Verzeichnisse ---
|
||||
echo ""
|
||||
echo "▶ 4. Sync-Verzeichnisse"
|
||||
for dir in \
|
||||
"$HOME/.local/share/vdirsyncer/status" \
|
||||
"$HOME/.local/share/vdirsyncer/calendars" \
|
||||
"$HOME/.local/share/vdirsyncer/tasks"; do
|
||||
if [[ -d "$dir" ]]; then
|
||||
COUNT=$(find "$dir" -name "*.ics" 2>/dev/null | wc -l)
|
||||
ok "$dir (${COUNT} .ics Dateien)"
|
||||
else
|
||||
fail "Verzeichnis fehlt: $dir"
|
||||
fi
|
||||
done
|
||||
|
||||
# --- 5. vdirsyncer Verbindungstest ---
|
||||
echo ""
|
||||
echo "▶ 5. vdirsyncer — Verbindungstest"
|
||||
info "Führe 'vdirsyncer sync' aus (Timeout: 30s)..."
|
||||
if timeout 30 vdirsyncer sync 2>&1 | tail -5; then
|
||||
ok "vdirsyncer sync erfolgreich"
|
||||
else
|
||||
fail "vdirsyncer sync fehlgeschlagen — Zugangsdaten und Netzwerk prüfen"
|
||||
fi
|
||||
|
||||
# --- 6. khal-Test ---
|
||||
echo ""
|
||||
echo "▶ 6. khal — Termine heute"
|
||||
if khal list --format "{start-time} {title}" today today 2>/dev/null; then
|
||||
ok "khal list ausgeführt"
|
||||
else
|
||||
fail "khal list fehlgeschlagen — khal.conf prüfen"
|
||||
fi
|
||||
|
||||
# --- 7. todoman-Test ---
|
||||
echo ""
|
||||
echo "▶ 7. todoman — Aufgabenliste"
|
||||
if todo list 2>/dev/null; then
|
||||
ok "todo list ausgeführt"
|
||||
else
|
||||
fail "todo list fehlgeschlagen — todoman.conf prüfen"
|
||||
fi
|
||||
|
||||
# --- 8. systemd-Timer ---
|
||||
echo ""
|
||||
echo "▶ 8. systemd Timer"
|
||||
if systemctl --user is-active vdirsyncer-sync.timer &>/dev/null; then
|
||||
ok "vdirsyncer-sync.timer: aktiv"
|
||||
NEXT=$(systemctl --user list-timers vdirsyncer-sync.timer --no-legend 2>/dev/null | awk '{print $1, $2}')
|
||||
info "Nächster Sync: $NEXT"
|
||||
else
|
||||
fail "vdirsyncer-sync.timer nicht aktiv → systemctl --user enable --now vdirsyncer-sync.timer"
|
||||
fi
|
||||
|
||||
# --- 9. Log-Datei ---
|
||||
echo ""
|
||||
echo "▶ 9. Log-Datei"
|
||||
LOG="/var/log/openclaw-mailbox-cal/sync.log"
|
||||
if [[ -f "$LOG" ]]; then
|
||||
SIZE=$(du -sh "$LOG" | cut -f1)
|
||||
ok "Log vorhanden: $LOG ($SIZE)"
|
||||
info "Letzte 5 Zeilen:"
|
||||
tail -5 "$LOG" | sed 's/^/ /'
|
||||
else
|
||||
info "Log noch nicht vorhanden (wird beim ersten Sync erstellt)"
|
||||
fi
|
||||
|
||||
# --- Zusammenfassung ---
|
||||
echo ""
|
||||
echo -e "${CYAN}══════════════════════════════════════════════════${NC}"
|
||||
if [[ $FAILED -eq 0 ]]; then
|
||||
echo -e "${GREEN} Alle Tests bestanden! Setup ist korrekt.${NC}"
|
||||
else
|
||||
echo -e "${RED} $FAILED Test(s) fehlgeschlagen — siehe Details oben.${NC}"
|
||||
fi
|
||||
echo -e "${CYAN}══════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
|
||||
exit $FAILED
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Konfiguration
|
||||
CAL_URL="https://dav.mailbox.org/caldav/Y2FsOi8vMC8zMg"
|
||||
USER="minitux@net-so.org"
|
||||
PASS="dbba-guvm-perd-pdhq"
|
||||
OUT_FILE="/home/hans/.openclaw/workspace/mailbox-calendar.ics"
|
||||
|
||||
# Temporäre Datei, um halb geschriebene Files zu vermeiden
|
||||
TMP_FILE="$(mktemp)"
|
||||
|
||||
# ICS/CalDAV-Daten holen
|
||||
curl -sS -u "$USER:$PASS" "$CAL_URL" -o "$TMP_FILE"
|
||||
|
||||
# Wenn curl erfolgreich war, Datei an Ziel verschieben
|
||||
mv "$TMP_FILE" "$OUT_FILE"
|
||||
chmod 644 "$OUT_FILE"
|
||||
@@ -0,0 +1,29 @@
|
||||
[Unit]
|
||||
Description=vdirsyncer — mailbox.org CalDAV Synchronisation
|
||||
Documentation=https://vdirsyncer.pimutils.org/
|
||||
# Netzwerk abwarten
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
|
||||
# Umgebungsvariablen aus .env laden (Pfad anpassen falls nötig)
|
||||
EnvironmentFile=%h/.config/openclaw-mailbox-cal/.env
|
||||
|
||||
# Erst-Sync: discover + sync
|
||||
# Bei erstem Lauf collect = auto, danach nur sync
|
||||
ExecStart=/usr/bin/vdirsyncer sync
|
||||
|
||||
# Fehler loggen
|
||||
StandardOutput=append:/var/log/openclaw-mailbox-cal/sync.log
|
||||
StandardError=append:/var/log/openclaw-mailbox-cal/sync.log
|
||||
|
||||
# Timeout: 120 Sekunden (ausreichend für langsame Verbindungen)
|
||||
TimeoutStartSec=120
|
||||
|
||||
# Nach erfolgreichem Sync khal-Cache neu aufbauen
|
||||
ExecStartPost=/usr/bin/khal rebuild-cache
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -0,0 +1,27 @@
|
||||
[Unit]
|
||||
Description=vdirsyncer Sync Timer — mailbox.org (alle 15 Minuten)
|
||||
Documentation=https://vdirsyncer.pimutils.org/
|
||||
Requires=vdirsyncer-sync.service
|
||||
|
||||
[Timer]
|
||||
# Sync-Intervall: alle 15 Minuten (aus .env SYNC_INTERVAL oder hier anpassen)
|
||||
# Beispiele:
|
||||
# *:0/15 → alle 15 Minuten
|
||||
# *:0/5 → alle 5 Minuten
|
||||
# hourly → stündlich
|
||||
# *-*-* 06,12,18,22:00:00 → 4x täglich
|
||||
OnCalendar=${SYNC_INTERVAL:-*:0/15}
|
||||
|
||||
# Beim Booten direkt starten (nicht auf den nächsten Interval warten)
|
||||
OnBootSec=60s
|
||||
|
||||
# Zufällige Verzögerung ±30s (verhindert Last-Spitzen)
|
||||
RandomizedDelaySec=30s
|
||||
|
||||
# Verpasste Runs nachholen (z. B. nach Schlafmodus)
|
||||
Persistent=true
|
||||
|
||||
Unit=vdirsyncer-sync.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
Reference in New Issue
Block a user