Zum Inhalt

Webhooks

Webhooks ermöglichen es, externe Systeme automatisch über Ereignisse in enconf zu informieren. Bei jedem konfigurierten Ereignis sendet das Panel eine HTTP-POST-Anfrage mit den Ereignisdaten an Ihre URL.

Typische Anwendungsfälle:

  • Automatische Deployment-Pipelines nach Website-Erstellung
  • Benachrichtigungen an Chat-Systeme (Slack, Microsoft Teams, Discord)
  • Synchronisierung mit Billing-Systemen
  • Monitoring und Logging in externe Plattformen

Funktionsweise

Ereignis im Panel → Webhook-Service → HTTP POST an Ihre URL
                            Signatur (HMAC-SHA256) im Header
                            Ihr Server verifiziert und verarbeitet
  1. Ein Ereignis tritt im Panel auf (z. B. Website erstellt)
  2. Das Panel findet alle aktiven Webhook-Endpoints, die auf dieses Ereignis abonniert sind
  3. Für jeden Endpoint wird ein HTTP-POST mit dem JSON-Payload gesendet
  4. Der Payload wird mit HMAC-SHA256 signiert
  5. Bei Fehlschlag wird ein automatischer Retry durchgeführt

Webhook-Endpoint erstellen

Über die API

POST /api/v1/webhooks
Authorization: Bearer <token>
Content-Type: application/json

{
  "url": "https://ihr-server.de/webhook",
  "secret": "IhrGeheimesWebhookSecret",
  "events": "site.created,site.deleted,backup.completed",
  "active": true
}
Feld Pflicht Beschreibung
url Ja Die URL, an die Ereignisse gesendet werden (muss HTTPS sein)
secret Ja Geheimer Schlüssel für die HMAC-SHA256-Signatur
events Ja Komma-getrennte Liste der gewünschten Ereignisse (oder * für alle)
active Nein Endpoint aktivieren/deaktivieren (Standard: true)

Über das Panel

  1. Navigieren Sie zu EinstellungenWebhooks
  2. Klicken Sie auf Webhook erstellen
  3. Füllen Sie URL, Secret und Ereignisse aus
  4. Klicken Sie auf Erstellen

Verfügbare Ereignisse

Ereignis Beschreibung Payload-Daten
site.created Website wurde erstellt site_id, domain
site.deleted Website wurde gelöscht site_id, domain
domain.created Domain wurde hinzugefügt domain_id, name
domain.deleted Domain wurde entfernt domain_id, name
database.created Datenbank wurde erstellt database_id, name
database.deleted Datenbank wurde gelöscht database_id, name
email.created E-Mail-Postfach wurde erstellt mailbox_id, email
ftp.created FTP-Konto wurde erstellt ftp_account_id, username
backup.completed Backup wurde abgeschlossen schedule_id, name
subscription.created Abonnement wurde erstellt subscription_id, main_domain
subscription.suspended Abonnement wurde gesperrt subscription_id, main_domain
webhook.test Test-Ereignis (manuell ausgelöst) message

Wildcard-Abonnement

Verwenden Sie * als Ereignis, um alle Ereignisse zu empfangen:

{
  "events": "*"
}

Payload-Format

Jeder Webhook-Aufruf sendet einen JSON-Body mit folgendem Format:

{
  "event": "site.created",
  "timestamp": "2026-03-31T14:30:00Z",
  "data": {
    "site_id": 42,
    "domain": "meine-seite.de"
  }
}
Feld Typ Beschreibung
event String Name des Ereignisses
timestamp String Zeitpunkt des Ereignisses (RFC 3339, UTC)
data Object Ereignisspezifische Daten

HTTP-Header

Jede Webhook-Anfrage enthält folgende Header:

Header Beschreibung
Content-Type application/json
User-Agent NetCell-WebPanel-Webhook/1.0
X-Webhook-Event Name des Ereignisses (z. B. site.created)
X-Webhook-Signature HMAC-SHA256-Signatur (siehe unten)

HMAC-Signaturverifizierung

Jede Webhook-Anfrage wird mit HMAC-SHA256 signiert, damit Sie die Authentizität und Integrität des Payloads verifizieren können.

Signatur-Format

X-Webhook-Signature: sha256=<hex-encoded-hmac>

Verifizierungsschritte

  1. Lesen Sie den rohen Request-Body (als Byte-Array)
  2. Berechnen Sie HMAC-SHA256 mit Ihrem Secret als Schlüssel
  3. Vergleichen Sie das Ergebnis mit dem Wert aus X-Webhook-Signature
  4. Akzeptieren Sie die Anfrage nur bei Übereinstimmung

Beispiel: PHP

<?php
$secret = 'IhrGeheimesWebhookSecret';
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';

// Erwartete Signatur berechnen
$expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);

// Timing-sichere Vergleichsfunktion verwenden
if (!hash_equals($expected, $signature)) {
    http_response_code(403);
    die('Invalid signature');
}

// Payload verarbeiten
$data = json_decode($payload, true);
$event = $data['event'];

switch ($event) {
    case 'site.created':
        // Website wurde erstellt
        $siteId = $data['data']['site_id'];
        $domain = $data['data']['domain'];
        // Ihre Logik hier...
        break;

    case 'backup.completed':
        // Backup abgeschlossen
        break;
}

http_response_code(200);
echo json_encode(['status' => 'ok']);

Beispiel: Python

import hmac
import hashlib
import json
from flask import Flask, request, abort

app = Flask(__name__)
SECRET = 'IhrGeheimesWebhookSecret'

@app.route('/webhook', methods=['POST'])
def handle_webhook():
    # Signatur verifizieren
    signature = request.headers.get('X-Webhook-Signature', '')
    expected = 'sha256=' + hmac.new(
        SECRET.encode(),
        request.data,
        hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(expected, signature):
        abort(403, 'Invalid signature')

    # Payload verarbeiten
    data = request.json
    event = data['event']

    if event == 'site.created':
        site_id = data['data']['site_id']
        domain = data['data']['domain']
        # Ihre Logik hier...

    return {'status': 'ok'}, 200

Beispiel: Node.js

const crypto = require('crypto');
const express = require('express');
const app = express();

const SECRET = 'IhrGeheimesWebhookSecret';

app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-webhook-signature'] || '';
  const expected = 'sha256=' + crypto
    .createHmac('sha256', SECRET)
    .update(req.body)
    .digest('hex');

  if (!crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  )) {
    return res.status(403).json({ error: 'Invalid signature' });
  }

  const data = JSON.parse(req.body);
  console.log(`Event: ${data.event}`, data.data);

  res.json({ status: 'ok' });
});

app.listen(3000);

Signatur immer prüfen

Verarbeiten Sie Webhook-Payloads niemals ohne Signaturprüfung. Ohne Verifizierung könnte ein Angreifer gefälschte Ereignisse an Ihre URL senden.

Timing-sichere Vergleiche

Verwenden Sie immer timing-sichere Vergleichsfunktionen (hash_equals in PHP, hmac.compare_digest in Python, crypto.timingSafeEqual in Node.js), um Timing-Angriffe zu verhindern.


Retry-Verhalten

Wenn Ihr Server nicht mit einem HTTP-Statuscode im Bereich 2xx antwortet, führt das Panel automatisch einen Retry durch:

Versuch Zeitpunkt
1. Versuch Sofort
2. Versuch (Retry) 2 Sekunden nach dem ersten Fehlschlag

Nach zwei Fehlversuchen wird die Zustellung als fehlgeschlagen markiert und im Delivery-Log protokolliert.

Timeout

Ihr Server muss innerhalb von 10 Sekunden antworten. Anfragen, die länger dauern, werden als fehlgeschlagen gewertet.

Empfehlungen für Ihren Webhook-Server

  • Antworten Sie sofort mit HTTP 200 und verarbeiten Sie den Payload asynchron
  • Implementieren Sie Idempotenz — derselbe Event kann doppelt zugestellt werden
  • Loggen Sie eingehende Webhooks für Debugging-Zwecke

Delivery-Logs

Das Panel speichert die letzten 100 Zustellversuche pro Webhook-Endpoint.

Logs abrufen

GET /api/v1/webhooks/:id/deliveries
Authorization: Bearer <token>

Log-Einträge

Feld Beschreibung
id Eindeutige ID des Zustellversuchs
event Ausgelöstes Ereignis
payload Der gesendete JSON-Payload
status_code HTTP-Statuscode der Antwort (0 bei Verbindungsfehler)
response Antwort-Body Ihres Servers (max. 4 KB)
success Ob die Zustellung erfolgreich war
duration_ms Dauer der Anfrage in Millisekunden
created_at Zeitpunkt des Zustellversuchs

Logs im Panel einsehen

  1. Navigieren Sie zu EinstellungenWebhooks
  2. Klicken Sie auf einen Webhook-Endpoint
  3. Im Tab Zustellungen sehen Sie den Verlauf aller Zustellversuche

Test-Webhook senden

Um Ihre Integration zu testen, können Sie ein Test-Ereignis manuell auslösen:

POST /api/v1/webhooks/:id/test
Authorization: Bearer <token>

Dies sendet ein webhook.test-Ereignis mit Testdaten an die konfigurierte URL.

Oder im Panel:

  1. Öffnen Sie den Webhook-Endpoint
  2. Klicken Sie auf Test senden
  3. Prüfen Sie die Zustellung im Delivery-Log

Webhook verwalten

Endpoint aktualisieren

PUT /api/v1/webhooks/:id
Authorization: Bearer <token>
Content-Type: application/json

{
  "url": "https://neue-url.de/webhook",
  "events": "site.created,domain.created",
  "active": true
}

Endpoint löschen

DELETE /api/v1/webhooks/:id
Authorization: Bearer <token>

Endpoint deaktivieren

Setzen Sie active auf false, um einen Endpoint vorübergehend zu deaktivieren, ohne ihn zu löschen:

{
  "active": false
}

Best Practices

Empfehlung Beschreibung
HTTPS verwenden Nutzen Sie immer HTTPS für Ihre Webhook-URL
Signatur prüfen Verifizieren Sie jede Anfrage mit dem HMAC-Secret
Schnell antworten Antworten Sie innerhalb von 2 Sekunden, verarbeiten Sie asynchron
Idempotenz Rechnen Sie damit, dass Events doppelt zugestellt werden
Fehlertoleranz Loggen und monitoren Sie fehlgeschlagene Zustellungen
Secret rotieren Ändern Sie Ihr Webhook-Secret regelmäßig
IP-Whitelist Beschränken Sie den Zugriff auf Ihre Webhook-URL auf die Panel-IP