|
|
||
|---|---|---|
| .forgejo/workflows | ||
| deploy | ||
| tests | ||
| .env.example | ||
| .gitignore | ||
| bridge_ingestor.py | ||
| bridge_run.py | ||
| bridge_worker.py | ||
| create_task.py | ||
| deck_client.py | ||
| DEPLOY.md | ||
| due_time.py | ||
| healthcheck.py | ||
| ntfy_subscribe.py | ||
| OPERATIONS.md | ||
| pyproject.toml | ||
| queue_store.py | ||
| README.md | ||
| RELEASE_NOTES.md | ||
| requirements-dev.txt | ||
| requirements.txt | ||
| vikunja_lookup.py | ||
ntfy2vikunja
Vikunja ist obsolet. Das Projekt wurde eingestellt; es wird nur noch Nextcloud Deck als Backend unterstützt. Die Vikunja-Option bleibt aus Abwärtskompatibilität im Code, wird aber nicht mehr gepflegt.
Bridge von ntfy nach Nextcloud Deck (früher auch Vikunja):
- Nachrichten werden per WebSocket von
NTFY_TOPICgelesen - in einer lokalen SQLite-Queue zwischengespeichert
- vom Worker zuverlässig als Tasks (Vikunja) oder Karten (Deck) angelegt
Verwende BACKEND=deck (Standard). BACKEND=vikunja ist obsolet und wird nicht mehr gepflegt.
Features
- WebSocket-Subscriber (ntfy)
- Persistente Queue (SQLite)
- Retry mit Exponential Backoff
- Dead-letter Zustand (
dead) nach zu vielen Fehlversuchen - Entkoppelte Architektur (Ingestor/Worker) oder kombinierter Runner
Tests
Vor Aenderungen oder neuen Features: Tests ausfuehren, damit bestehende Funktionalitaet erhalten bleibt.
pip install -r requirements-dev.txt
pytest tests/ -v --cov=queue_store --cov=bridge_worker --cov=bridge_ingestor --cov=vikunja_lookup --cov=create_task --cov=deck_client
Die CI laeuft Tests vor jedem Deploy; der Deploy wird blockiert, wenn Tests fehlschlagen.
Security-Checks: pip-audit und bandit -r . -x ./tests
Projektstruktur
ntfy_subscribe.py– WebSocket-Client für ntfycreate_task.py– Vikunja Task-Erstellung (beiBACKEND=vikunja)vikunja_lookup.py– Projekt- und Bucket-Namen in IDs auflösendeck_client.py– Nextcloud Deck API (Karten anlegen, Board/Stack auflösen; beiBACKEND=deck)queue_store.py– SQLite Queue-Layerbridge_ingestor.py– ntfy -> Queuebridge_worker.py– Queue -> Vikunja oder Deck (je nachBACKEND)bridge_run.py– Ingestor + Worker in einem Prozess (lokal/dev)healthcheck.py– Queue-Status als JSON (Monitoring)deploy/systemd/*.service– Linux Services.forgejo/workflows/deploy.yml– Forgejo CI/CD Deploy Workflow
Voraussetzungen
- Python 3.11+ (3.10 sollte ebenfalls funktionieren)
- Abhängigkeiten aus
requirements.txt
Installation:
pip install -r requirements.txt
Konfiguration
Als Vorlage:
cp .env.example .env
Relevante ENV-Variablen:
BACKEND–deck(Standard; Vikunja ist obsolet)NTFY_BASE_URL,NTFY_TOPIC,NTFY_TOKEN(oderNTFY_USER/NTFY_PASSWORD)NTFY_FEEDBACK_TOPIC(optional: sendet "Task erstellt" als ntfy-Message)NTFY_FEEDBACK_BASE_URL/NTFY_FEEDBACK_TOKEN(optional)DUE_TIME(optional, Standard 10:00) – Tageszeit für Fälligkeitsdatum, wenn nur Datum angegeben wird (HH:MM oder HH:MM:SS, UTC)QUEUE_DB_PATH(z. B../state/queue.dboder/opt/ntfy2vikunja/state/queue.db)
Bei BACKEND=deck (Standard):
NEXTCLOUD_URL(z. B.https://nextcloud.example.com)NEXTCLOUD_USER,NEXTCLOUD_PASSWORD(oder App-Passwort)DECK_BOARD– Board-ID oder NameDECK_STACK– Stack-ID oder Name (Spalte, z. B.ToDo)DECK_STACK_HIGH_PRIO(optional: Stack fuer Nachrichten mit fuehrendem!ohnedue:)
Bei BACKEND=vikunja (obsolet, nicht mehr gepflegt):
VIKUNJA_URL,VIKUNJA_TOKEN,VIKUNJA_PROJECT,VIKUNJA_BUCKET_HIGH_PRIO
Lokal starten
Option A: Alles in einem Prozess
python bridge_run.py
Option B: Getrennt starten
Terminal 1:
python bridge_ingestor.py
Terminal 2:
python bridge_worker.py
Task-Mapping (aktuell)
title: erste Zeile vonmessage, sonst ntfytitlepriority: Parsing ausprio:/priority:oder fuehrendem!in Title/Bodydue_date: optional aus Title oder Body via Patterndue:YYYY-MM-DD- Android-Leer-Events wie
triggered(ohne Inhalt) werden ignoriert
Beispiel:
Server reboot prio:high due:2026-03-01
Beispiele Nachricht -> Task
Backup pruefen-> Task ohnedue_date, ohnepriorityBackup pruefen due:2026-03-10-> Task mitdue_date=2026-03-10Backup pruefen prio:5-> Task mitpriority=5Backup pruefen prio:high due:2026-03-10-> Task mitpriority=4,due_date=2026-03-10! Backup sofort pruefen due:2026-03-10-> Task mitpriority=5,due_date=2026-03-10! Backup sofort(ohnedue:) -> Task mitpriority=5,due_date= Erstellungstag (heute); führendes!wird aus dem Titel entfernt
Optional: Mit DECK_STACK_HIGH_PRIO landen Tasks mit fuehrendem ! (ohne due:) im angegebenen Stack (z. B. „Heute“). Normale Tasks landen in DECK_STACK (z. B. Inbox). Tasks mit Fälligkeitsdatum landen stets in der normalen Spalte.
Prioritaetsreihenfolge:
prio:/priority:Marker- fuehrender
!Marker (setztpriority=5)
Healthcheck
python healthcheck.py
Exit-Codes:
0: OK1: Queue erreichbar, aber Schwellwert überschritten (z. B. zu vieledead)2: Queue DB nicht gefunden
Queue-Zustände
pending– neuprocessing– gerade in Bearbeitungfailed– fehlgeschlagen, wird später erneut versuchtdone– erfolgreich in Deck erstelltdead– maximale Retry-Anzahl erreicht
Linux / systemd / Forgejo
Siehe:
DEPLOY.mdOPERATIONS.mddeploy/systemd/ntfy2vikunja-ingestor.servicedeploy/systemd/ntfy2vikunja-worker.servicedeploy/systemd/ntfy2vikunja-bridge-run.service
Hinweise
- Für Produktion sind zwei getrennte Services (Ingestor + Worker) empfohlen.
bridge_run.serviceist praktisch, aber weniger isoliert.