# Webhook-Automation Webhooks ermöglichen das Triggern externer Systeme, wenn Synapse-Events feuern. Dieser Guide behandelt häufige Automations-Patterns. ## Häufige Patterns ### Pattern 1: Bei kritischem Memory benachrichtigen Slack-Nachricht senden, wenn ein kritischer Memory gespeichert wird: ```python # Webhook handler (your server) @app.post("/webhook") async def handle(request): payload = await request.json() # Verify signature if not verify_signature(payload, request.headers): return 401 if payload["event"] == "memory.store": memory = payload["data"] if memory.get("priority") == "critical": # Send Slack notification await slack.post( f"🚨 Critical memory stored: {memory['key']}\n{memory['content'][:200]}" ) return 200 ``` Webhook registrieren: ```bash curl -X POST https://synapse.schaefer.zone/webhooks \ -H "Authorization: Bearer YOUR_MIND_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://my-app.com/webhook", "events": "memory.store", "secret": "my-hmac-secret" }' ``` ### Pattern 2: Zu externem System synchronisieren Memories zu Notion, Obsidian oder jede andere externe KB synchronisieren: ```python @app.post("/webhook") async def sync_to_notion(request): payload = await request.json() if payload["event"] == "memory.store": memory = payload["data"] # Create Notion page await notion.create_page( title=memory["key"], content=memory["content"], tags=memory.get("tags", []) ) elif payload["event"] == "memory.delete": # Delete from Notion await notion.delete_page(memory_id=payload["data"]["id"]) return 200 ``` ### Pattern 3: CI/CD triggern Ein Deployment auslösen, wenn ein „Release"-Memory gespeichert wird: ```python @app.post("/webhook") async def trigger_deploy(request): payload = await request.json() if payload["event"] == "memory.store": memory = payload["data"] if memory.get("key", "").startswith("release_"): # Trigger GitLab pipeline await gitlab.trigger_pipeline( project="synapse", ref="main", variables={"RELEASE_MEMORY_ID": memory["id"]} ) return 200 ``` ### Pattern 4: Agent bei Mensch-Nachricht aufwecken Einen LLM-Agent-Lauf triggern, wenn ein Mensch eine Chat-Nachricht sendet: ```python @app.post("/webhook") async def wake_agent(request): payload = await request.json() if payload["event"] == "chat.message_received": message = payload["data"] # Queue agent processing job await job_queue.enqueue( "process_message", message_id=message["id"], content=message["content"] ) return 200 ``` ### Pattern 5: Metriken aggregieren Memory-Wachstum, Chat-Aktivität, Task-Abschluss tracken: ```python @app.post("/webhook") async def track_metrics(request): payload = await request.json() event = payload["event"] metrics = { "memory.store": "memories_stored_total", "memory.delete": "memories_deleted_total", "chat.message_received": "messages_received_total", "task.created": "tasks_created_total", "task.completed": "tasks_completed_total", } if event in metrics: await prometheus.increment(metrics[event]) return 200 ``` ## Signatur-Verifikation Verifiziere immer Webhook-Signaturen, um Spoofing zu verhindern: ```python import hmac import hashlib def verify_signature(payload_body: bytes, headers, secret: str) -> bool: signature = headers.get("X-Synapse-Signature", "") if not signature.startswith("sha256="): return False expected = hmac.new( secret.encode(), payload_body, hashlib.sha256 ).hexdigest() return hmac.compare_digest(f"sha256={expected}", signature) ``` ## Retry-Logik Synapse wiederholt fehlgeschlagene Webhooks mit exponentiellem Backoff. Dein Handler sollte: 1. **Schnell 200 zurückgeben** — keine schwere Arbeit synchron erledigen 2. **Arbeit in Queue stellen** — ein Hintergrund-Job-System verwenden 3. **Idempotent sein** — dasselbe Event kann zweimal zugestellt werden ```python @app.post("/webhook") async def handle(request): payload = await request.json() # Queue for async processing await job_queue.enqueue("process_webhook", payload) # Return immediately return 200 ``` ## Webhooks debuggen ### Zustellhistorie prüfen Webhook-Zustellungen werden protokolliert. Prüfe die letzten Zustellungen deines Webhooks: ```bash # Get webhook details including recent deliveries curl -H "Authorization: Bearer YOUR_MIND_KEY" \ https://synapse.schaefer.zone/webhooks/wh_001 ``` ### Webhook manuell testen ```bash # Trigger a test event curl -X POST https://synapse.schaefer.zone/webhooks/wh_001/test \ -H "Authorization: Bearer YOUR_MIND_KEY" ``` ### Häufige Probleme | Issue | Fix | |-------|-----| | 4xx-Antworten | Prüfen, dass dein Handler 200 liefert | | 5xx-Antworten | Server-Fehler — App-Logs prüfen | | Timeout | 200 schnell zurückgeben, Arbeit async stellen | | Duplikate | Handler idempotent machen | | Signatur-Fehler | Secret auf Korrektheit prüfen | ## Best Practices > [!TIP] > - **Immer Signaturen verifizieren** — niemals überspringen > - **Schnell 200 zurückgeben** — Synapse nicht blockieren > - **Idempotent sein** — Duplikat-Zustellungen behandeln > - **Spezifische Events verwenden** — `memory.store` nicht `*` > - **Zustellfehler überwachen** — Alerting einrichten ## Nächste Schritte - [Webhooks-API](/docs/api/webhooks) - [Cron & Scheduler](/docs/api/cron) - [Persistenter LLM-Agent](/docs/guides/persistent-llm-agent) ## Conditional Trigger Patterns (v1.18.14) Register a webhook that fires **only** when the event payload satisfies a category/tag/priority combination — e.g. alert only on critical security facts: ```bash curl -X POST https://synapse.schaefer.zone/webhooks \ -H "Authorization: Bearer $MIND_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/hook", "events": "memory.created,memory.updated", "secret": "signing-secret-32chars", "filter": { "categories": ["fact", "project"], "tags": ["sec", "crit"], "tag_mode": "any", "priority_min": "high" } }' ``` Filter fields (all optional, but at least one required): | Field | Meaning | |---|---| | `categories` | fire only if `data.category` is one of these | | `tags` | fire only if `data.tags` contains the given tag(s) | | `tag_mode` | `any` (default) = at least one tag matches; `all` = every listed tag must be present | | `priority_min` | fire only if payload priority rank ≥ this (`low < normal < high < critical`) | Safe defaults: events whose payload has no category/tags (e.g. `memory.deleted`, chat events) never fire filtered webhooks; a corrupt `filter` JSON is treated as unfiltered (the webhook stays active); `/webhooks/:id/test` ignores the filter on purpose. Note: only `memory.created` / `memory.updated` payloads carry `category`/`tags`/`priority` — including the GET alternatives (`GET /memory/store`, `GET /memory/:id/update`), which fire webhooks since v1.18.14.