diff --git a/notes/trading/system-docs/modul-26-telegram-gateway.md b/notes/trading/system-docs/modul-26-telegram-gateway.md new file mode 100644 index 0000000..6ad5279 --- /dev/null +++ b/notes/trading/system-docs/modul-26-telegram-gateway.md @@ -0,0 +1,108 @@ +# Modul-26-Telegram-Gateway + +**Status:** FREIGEGEBEN (2026-08-21) +**Port:** 55026 (nur Docker-intern, kein öffentlicher Port) +**Container:** `Modul-26-Telegram-Gateway` +**Image:** `telegram-gateway:0.1.0` +**Netzwerk:** `trading-modules` + +## Zweck + +Dünner, **tool-loser** Adapter zwischen Telegram und M17 Hermes-Agent. Ermöglicht die Bedienung von Hermes vom Handy über einen eigenen Telegram-Bot. **KEINE Trading-Tools**, kein M09/M07/M08/M15-Control-Zugriff. Safety bleibt deterministisch in M17. + +## Architektur + +``` +Telegram Bot API + │ Polling (getUpdates) — KEIN Webhook, kein öffentlicher Port + ▼ +Modul-26-Telegram-Gateway (Port 55026 intern) + │ Auth-Allowlist, Rate-Limit, Audit — NUR HTTP-Calls an M17, KEINE Tools + ▼ +Modul-17-Hermes-Agent (POST /tasks llm=true) + │ Tool-Whitelist + Task-Gates (deterministisch, UNVERÄNDERT) + ▼ +LLM (Cloud deepseek-v4-flash:cloud Standard / Local llama3.1:8b explizit) +``` + +## Sicherheitsmodell + +- **Allowlist:** Nur explizit erlaubte User-/Chat-IDs (`TELEGRAM_ALLOWED_IDS`, kommagetrennt). Unbekannte User werden **hart abgelehnt** (kein Task, Log-Eintrag, Status `REJECTED`/`UNAUTHORIZED`). +- **Rate-Limit:** Sliding-Window pro User/Chat (Default 10/min). Überschreitung → `REJECTED`/`RATE_LIMITED`. +- **Idempotenz:** `update_id` als PK in `telegram_message`. Bereits verarbeitete Updates werden übersprungen. +- **Secrets:** Bot-Token NUR via ENV/Secret (`TELEGRAM_BOT_TOKEN`), nie im Code. Keine Secrets in DB/Logs/Doku. +- **Prompt-Injection:** M17 behandelt externe Eingaben als untrusted data. Tool-Whitelist + Task-Gates hart im Code. +- **Doppelte Barriere:** Gateway ist tool-los (nur HTTP-Calls an M17) + M17-Whitelist deterministisch. + +## Commands + +| Command | M17 task_type | Beschreibung | +|---------|---------------|--------------| +| `/status` | — | Hermes-Health (synchron) | +| `/research` | research | Markt-/Regime-Analyse | +| `/analytics` | analytics | Portfolio-/Strategie-Analyse | +| `/backtest` | backtest | Backtest starten | +| `/optimize` | optimization | Optimierung starten | +| `/monitoring` | monitoring | Monitoring-Status | +| `/tasks` | — | Letzte Tasks (synchron) | +| `/help` | — | Hilfe | +| Freitext | research | Wird als Research-Analyse behandelt | + +## Asynchrone Task-Abwicklung + +Lange Tasks (Cloud 5-23s, explizit lokale Analyse bis zu Minuten) laufen asynchron: +1. Sofortige Bestätigung an denselben Chat ("⏳ *task* gestartet…"). +2. Task wird in Background-Thread an M17 gesendet (`POST /tasks` mit `llm=true`). +3. Ergebnis wird später an denselben Chat zurückgesendet. + +## Audit + +DB-Tabelle `telegram_message` (Migration `001_telegram_gateway.sql`): +- `update_id` (PK), `chat_id`, `user_id`, `username`, `text`, `command` +- `task_id`, `run_id`, `status`, `error_code`, `created_at` + +Nachvollziehbarkeit: **update_id → task_id → run_id → LLM-run → Tool-Calls** (via M17 hermes_llm_run + hermes_tool_call). + +## API (Port 55026 intern) + +- `GET /health` — Liveness +- `GET /health/ready` — Readiness (Telegram-Token + Allowlist) +- `GET /messages/recent` — Letzte Messages (Audit) +- `GET /messages/{update_id}` — Einzelne Message +- `POST /messages/test` — Test-Nachricht an konfigurierte Destination + +## Konfiguration (ENV) + +| Variable | Beschreibung | +|----------|--------------| +| `TELEGRAM_BOT_TOKEN` | Bot-Token (Secret, NUR ENV) | +| `TELEGRAM_ALLOWED_IDS` | Kommagetrennte erlaubte User-/Chat-IDs | +| `TELEGRAM_API_BASE` | Telegram API-Base (Default `https://api.telegram.org`; für E2E Fake-Server) | +| `M17_BASE_URL` | M17 Hermes-Agent (Default `http://Modul-17-Hermes-Agent:55017`) | +| `PG_HOST/PORT/USER/PASSWORD/DB` | PostgreSQL (Modul-01) | + +## E2E-Tests + +`tests/e2e_m26.py` (20/20 grün, 2026-08-21): +1. Unknown user reject +2. /status +3. /research (+ Ergebnis) +4. /analytics (+ Ergebnis) +5. /backtest (+ Ergebnis) +6. /optimize (+ Ergebnis) +7. /monitoring (+ Ergebnis) +8. /tasks +9. /help +10. Freitext → research (+ Ergebnis) +11. Safety: place_order im Prompt → keine Order +12. Rate-Limit +13. Audit: update_id → task_id → run_id + +Test-Infrastruktur: `tests/fake_telegram.py` (Fake-Telegram Bot API Server mit Steuer-API für E2E). + +## Wichtige Hinweise + +- **M20 bleibt reserviert für Universe-Scheduler** — M26 ist separat. +- **M14 NICHT verändern** — M26 nutzt nur das FAIL-SAFE-Muster als Vorlage, koppelt nicht an M14. +- **M17 Safety-Gates unverändert** — M26 fügt nur einen dünnen Adapter hinzu. +- **Kein öffentlicher Port** — nur `expose` im Compose.