Zum Inhalt springen

Webhooks

Webhooks feuern HTTP-POSTs an konfigurierte URLs, sobald Content commitet oder gelöscht wird — typisch für Search-Index-Updates, Slack-Notifications, CDN-Cache-Invalidation oder Sync zu Downstream-Systemen.

Verfügbarkeit

Webhooks sind eine Pro- und Enterprise-Funktion. Free-Lizenzen sehen die Verwaltung im Admin, können sie aber nicht editieren — der bestehende deployHook aus der Astro-Integration bleibt für alle Tarife verfügbar.

Konfiguration

Im Admin: ⚙ Settings → Webhooks. Pro Webhook konfigurierbar: Name, URL, Events, optionales HMAC-Secret. Liste wird im _webhooks.json im Content-Repo (Single-Mode) bzw. pro Website-Repo (Multi-Mode) gespeichert.

Events

  • content.save — nach jedem erfolgreichen Section/Page-Commit
  • content.delete — nach Löschen einer Section
  • content.publish — reserviert für künftige Staging-Branches (v2.x)

Payload

POST body
{
  "event": "content.save",
  "timestamp": "2026-05-08T12:34:56.789Z",
  "website": {
    "id": "kunde-a",
    "repo": "kunde-a/website",
    "branch": "main"
  },
  "user": {
    "email": "redaktion@example.com",
    "name": "Maria Schmidt"
  },
  "commit": {
    "sha": "abc123…",
    "message": "content(hero): heading aktualisiert"
  },
  "files": [
    { "path": "content/_sections/hero.json" }
  ]
}

Headers

Setzkasten sendet vier Header. Die Signatur ist nur gesetzt, wenn ein Secret konfiguriert ist.

Request headers
Content-Type: application/json
X-Setzkasten-Event: content.save
X-Setzkasten-Delivery: 9c3f8a4d-1e2b-4f6a-9b7d-1234567890ab
X-Setzkasten-Signature: sha256=<64 chars hex>

Signatur verifizieren

HMAC-SHA256 über den UTF-8-Body, hex-encoded. Empfänger sollten den rohen Request-Body nutzen — JSON-Re-Stringify-Ergebnisse weichen ab und schlagen fehl. Pattern entspricht GitHub-Webhooks.

Node.js / Express
import { createHmac, timingSafeEqual } from 'node:crypto'

export function verify(req, secret) {
  const sigHeader = req.headers['x-setzkasten-signature']
  if (!sigHeader?.startsWith('sha256=')) return false

  const expected = sigHeader.slice('sha256='.length)
  const computed = createHmac('sha256', secret)
    .update(req.rawBody, 'utf8')
    .digest('hex')

  return timingSafeEqual(
    Buffer.from(expected, 'hex'),
    Buffer.from(computed, 'hex'),
  )
}
Python
import hmac
import hashlib

def verify(raw_body: bytes, signature_header: str, secret: str) -> bool:
    if not signature_header.startswith("sha256="):
        return False
    expected = signature_header[len("sha256="):]
    computed = hmac.new(
        secret.encode("utf-8"),
        raw_body,
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(expected, computed)

Idempotenz

Setzkasten retryt aktuell nicht. Empfänger sollten dennoch X-Setzkasten-Delivery als idempotency-key behandeln — falls eine künftige Version Retry nachzieht, ist das Empfänger-System dann schon korrekt.

Test-Fire

Im Admin per Klick auf das Pfeil-Icon: schickt einen synthetischen Payload (commit.sha = 0…0, leere files-Liste, zusätzlich X-Setzkasten-Test: true). Empfänger können diese Test-Fires auswerten oder ignorieren.

Timeout & Fehler

Pro Hook 5 Sekunden Timeout (10 s im Test-Fire). Schlägt der Request fehl, loggt der Server-Output den Fehler; der Save-Vorgang im Admin bleibt unbeeinflusst — Webhooks sind fire-and-forget.

Backwards-Compat: deployHook

Die ältere deployHook-Option in astro.config.mjs bleibt als 1-URL-Variante bestehen — feuert nach jedem Save mit leerem POST. Wer mehr braucht (mehrere Endpoints, Events trennen, Payload), nutzt die hier beschriebenen Webhooks.