Webhooks
Webhooks senden HTTP POST-Requests an deine URL, wenn in deinem Workspace Ereignisse auftreten. Nutze sie mit n8n, Zapier, Make oder eigenen Servern.
Voraussetzungen
Abschnitt betitelt „Voraussetzungen“- Zugriff Einstellungen → Entwickler (Capability Webhooks oder Team-Admin)
- Ein öffentlich erreichbarer HTTPS-Endpunkt (localhost funktioniert nur mit einem Tunnel wie ngrok)
- Server-Env:
PUBLISHING_ENCRYPTION_KEYmuss gesetzt sein (siehe Installation)
Webhook anlegen
Abschnitt betitelt „Webhook anlegen“- Gehe zu Einstellungen → Entwickler → Webhooks
- Klicke auf Webhook hinzufügen
- Gib einen Namen und eine URL ein (HTTPS empfohlen)
- Wähle die zu abonnierenden Events (oder alle)
- Speichern — das Signatur-Geheimnis wird einmal angezeigt. Bewahre es sicher auf.
Event-Typen
Abschnitt betitelt „Event-Typen“| Event | Wird ausgelöst bei |
|---|---|
document.created | Neues Dokument |
document.updated | Dokument-Inhalt oder -Metadaten geändert |
document.deleted | Dokument entfernt |
document.published | Dokument in einen Kanal veröffentlicht |
collection.created | Neue Collection |
collection.updated | Collection umbenannt oder verschoben |
collection.deleted | Collection entfernt |
notification.created | In-App-Benachrichtigung erstellt (pro Empfänger) |
Payload-Format
Abschnitt betitelt „Payload-Format“Jede Zustellung ist JSON:
{ "id": "delivery-uuid", "createdAt": "2026-05-22T10:00:00.000Z", "event": "document.updated", "payload": { "id": "document-uuid", "model": {} }}Das model-Objekt enthält einen bereinigten Snapshot der betroffenen Ressource.
Signaturen prüfen
Abschnitt betitelt „Signaturen prüfen“Jeder Request enthält:
| Header | Wert |
|---|---|
Content-Type | application/json |
X-Orimora-Event | Event-Name (z. B. document.updated) |
X-Orimora-Signature | t=<unix_seconds>,v=<hex_hmac> |
User-Agent | Orimora-Webhooks/1.0 |
Die Signatur ist HMAC-SHA256 über den String "<timestamp>.<raw_body>" mit deinem Webhook-Secret.
Prüfschritte:
- Lies den rohen Request-Body (vor dem JSON-Parsing)
- Parse
X-Orimora-Signature— extrahieretundv - Ablehnen, wenn
tzu alt ist (Replay-Schutz — z. B. ±5 Minuten) - Berechne
HMAC-SHA256(secret, t + "." + body)als Hex - Vergleiche mit
vüber einen timing-sicheren Vergleich
import { createHmac, timingSafeEqual } from 'crypto';
function verifyOrimoraWebhook(secret, signatureHeader, rawBody, maxAgeSec = 300) { const parts = Object.fromEntries(signatureHeader.split(',').map((p) => p.split('='))); const t = Number(parts.t); const v = parts.v; if (!t || !v || Math.abs(Date.now() / 1000 - t) > maxAgeSec) return false;
const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
try { return timingSafeEqual(Buffer.from(v, 'hex'), Buffer.from(expected, 'hex')); } catch { return false; }}import hashlibimport hmacimport time
def verify_orimora_webhook(secret: str, signature_header: str, raw_body: bytes, max_age_sec: int = 300) -> bool: parts = dict(part.split("=", 1) for part in signature_header.split(",")) t = int(parts.get("t", 0)) v = parts.get("v", "")
if not t or not v or abs(time.time() - t) > max_age_sec: return False
expected = hmac.new( secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256, ).hexdigest()
return hmac.compare_digest(v, expected)function verifyOrimoraWebhook(string $secret, string $signatureHeader, string $rawBody, int $maxAgeSec = 300): bool { $parts = []; foreach (explode(',', $signatureHeader) as $part) { [$k, $v] = explode('=', $part, 2); $parts[$k] = $v; }
$t = (int) ($parts['t'] ?? 0); $v = $parts['v'] ?? '';
if (!$t || !$v || abs(time() - $t) > $maxAgeSec) { return false; }
$expected = hash_hmac('sha256', "{$t}.{$rawBody}", $secret); return hash_equals($expected, $v);}SECRET="your_webhook_secret"BODY='{"event":"document.updated","data":{}}'T=$(date +%s)SIG=$(echo -n "${T}.${BODY}" | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $2}')
curl -X POST https://your-endpoint.example.com/webhook \ -H "Content-Type: application/json" \ -H "X-Orimora-Signature: t=${T},v=${SIG}" \ -H "X-Orimora-Event: document.updated" \ -d "$BODY"Zustellungsverhalten
Abschnitt betitelt „Zustellungsverhalten“- Zustellungen laufen asynchron über eine Hintergrund-Queue
- Fehlgeschlagene Zustellungen werden mit Backoff erneut versucht
- Webhooks mit hoher Fehlerrate werden automatisch deaktiviert (konfigurierbar über
WEBHOOK_FAILURE_*-Env-Vars) - Zustellungsprotokolle werden zum Debuggen aufbewahrt (siehe Einstellungs-UI)
URLs dürfen nicht auf private IPs oder Cloud-Metadaten-Endpunkte zeigen (SSRF-Schutz).
Mit n8n testen
Abschnitt betitelt „Mit n8n testen“Orimora bringt einen n8n-Community-Node mit (packages/n8n-nodes-orimora). Alternativ kannst du einen n8n-Webhook-Trigger-Node verwenden und die Test-URL beim Anlegen des Orimora-Webhooks einfügen.
Siehe auch
Abschnitt betitelt „Siehe auch“- Konfiguration —
WEBHOOK_FAILURE_*-Schwellenwerte - Publishing-Kanäle — anderes Outbound-Sync-Modell
- Berechtigungen & Gruppen — Capability Webhooks