Webhook

Ein Webhook liefert ein GAMEMONITORING-Ereignis direkt nach einer Aktion auf der Plattform an Ihr System. Es ist ein normaler POST-Request mit JSON-Body, damit Ihre Website, Ihr Panel oder Ihr Spielservice automatisch reagieren kann.

Für Stimm-Belohnungen richten Sie zuerst den Webhook ein und nutzen danach den eigenen Ablauf: Belohnungen für Stimmen.

Verbindung

Diese Einrichtung verknüpft ein GAMEMONITORING-Projekt mit Ihrem Handler und stellt den Signatur-Token zur Prüfung eingehender Anfragen bereit.

  1. Öffnen Sie Meine Projekte, erstellen Sie ein Projekt oder wählen Sie ein bestehendes aus, und gehen Sie danach zu den Webhook-Einstellungen.
  2. Erstellen Sie einen öffentlichen HTTPS-Endpunkt, der POST mit Content-Type: application/json annimmt und nicht weiterleitet.
  3. Tragen Sie in den Webhook-Einstellungen die vollständige Handler-URL ein, zum Beispiel https://panel.example.com/gamemonitoring-webhook, und speichern Sie sie.
  4. Kopieren Sie den Signatur-Token aus demselben Block und tragen Sie ihn in Ihr Handler-Skript ein.
  5. Prüfen Sie im Handler signature, verarbeiten Sie das benötigte event_type und geben Sie eine erfolgreiche 2xx-Antwort erst zurück, nachdem das Ereignis verarbeitet wurde.

Senden Sie nach der Einrichtung einen Test-Webhook aus der Oberfläche und prüfen Sie den Zustellstatus. Für die Beispiel-URL muss Ihr Server POST auf /gamemonitoring-webhook annehmen.

Wenn der Test fehlschlägt, beginnen Sie mit der Handler-Antwort: 401 bedeutet ein Signaturproblem, 403 oder eine HTML-Challenge deutet meist auf WAF oder Bot-Protection hin, ein Timeout bedeutet, dass die URL aus dem Internet nicht erreichbar ist oder zu langsam antwortet.

Anforderungen an den Handler

  • Die URL muss aus dem Internet erreichbar sein. Lokale Adressen, private Netzwerke und URLs mit Login oder Passwort sind nicht geeignet.
  • HTTPS wird für Produktion empfohlen. HTTP wird unterstützt, schützt Daten bei der Übertragung aber schwächer.
  • Der Handler muss POST und einen JSON-Body ohne Weiterleitungen annehmen.
  • Geben Sie 2xx erst zurück, nachdem Ihr System das Ereignis verarbeitet hat. In der Regel reicht 204.
  • Wenn das Ereignis nicht sicher verarbeitet werden kann, geben Sie einen Fehlerstatus zurück. 3xx, 4xx, 5xx, Timeout oder Verbindungsfehler gelten als fehlgeschlagene Zustellung.
  • Wenn Sie Firewall, Bot-Schutz oder Allowlist verwenden, fügen Sie die IP-Adressen von GAMEMONITORING als Ausnahme hinzu.
  • Geben Sie im Antwortkörper keine Tokens, Stack Traces, SQL-Fehler oder andere internen Details zurück. Die Handler-Antwort wird in der Oberfläche angezeigt, daher muss der Fehlertext sicher und verständlich sein.

Ereignisdaten

Jeder Webhook wird als JSON-Body mit Kernfeldern zugestellt:

  • event_type — welches Ereignis verarbeitet werden muss.
  • event_id — eindeutige Ereignis-ID. Verwenden Sie sie zusammen mit event_type für Idempotenz und Schutz vor wiederholter Zustellung.
  • is_test — kennzeichnet eine Testzustellung aus der Oberfläche.
  • signature — Signatur des Ereignis-Bodys.
Beispiel eines Webhook-Ereignisses
{
  "event_id": "9824cabb-2203-437e-9b6c-aba43dde3e4b",
  "event_type": "example.event",
  "is_test": false,
  "signature": "0ac4c97a5d934599dbd78985c4bcbb6926e77b4809d2be56333b1b25f638f064"
}

So lesen Sie das Beispiel: event_type zeigt, welches Ereignis verarbeitet werden muss, event_id wird vor Zustandsänderungen gespeichert, is_test: true bedeutet nur eine Zustellprüfung, und signature ist nur für die Echtheitsprüfung gedacht.

Die Verarbeitung hängt von event_type ab. Für server.vote nutzen Sie den eigenen Ablauf: Belohnungen für Stimmen.

Wenn is_test true ist, prüfen Sie die Signatur und geben 2xx zurück, ändern aber keinen Kontostand und geben keine Gegenstände aus.

Beispiel für die Handler-Antwort

Wählen Sie für jedes eingehende Ereignis ein klares Ergebnis:

  • 204 No Content — die Signatur ist korrekt und das Ereignis wurde verarbeitet. Nutzen Sie dieselbe Antwort für Testzustellungen und bereits verarbeitete Duplikate.
  • 400 Bad Request — Pflichtfelder fehlen. Das deutet auf einen Handler-Fehler oder unerwarteten Body hin; Business-Logik darf nicht laufen.
  • 401 Unauthorized — die Signatur ist falsch. Führen Sie keine API-Requests aus, ändern Sie keine Datenbankdaten und geben Sie keine Belohnungen aus.
  • 500 Internal Server Error — Ihre Datenbank, Queue oder interne Systeme sind vorübergehend nicht verfügbar. Die Zustellung bleibt fehlgeschlagen und kann nach der Korrektur erneut gesendet werden.

Beispiel: Wenn der Handler das Ereignis empfangen, die Signatur geprüft, event_type + event_id gespeichert und das Ereignis verarbeitet hat, kann er sofort 204 zurückgeben. Ist die Datenbank nicht verfügbar, geben Sie 500 zurück, damit die Zustellung nicht zu früh als erfolgreich gilt.

Signaturprüfung

Die Signatur befindet sich im Feld signature. Prüfen Sie sie vor jeder Geschäftslogik, vor API-Anfragen und vor Datenbankänderungen.

Nehmen Sie zur Prüfung alle Felder des Ereignisses außer signature, sortieren Sie die Schlüssel alphabetisch und bauen Sie eine Zeichenkette key=value, verbunden mit &. Boolesche Werte werden als true oder false geschrieben.

Signatur-String
event_id=9824cabb-2203-437e-9b6c-aba43dde3e4b&event_type=example.event&is_test=false

Für das Beispiel oben wird der Signatur-String nur aus event_id, event_type und is_test gebaut. Danach berechnen Sie HMAC-SHA256 mit dem Token aus den Webhook-Einstellungen und vergleichen ihn mit signature aus dem Request.

Vorberechnete Signaturen in den Beispielen nutzen den Demo-Token paste-webhook-token-here. In Ihrem Handler verwenden Sie den Token aus den Webhook-Einstellungen.

Im Handler:

  • bauen Sie die Signatur-Zeichenkette aus sortierten Schlüsseln;
  • berechnen Sie HMAC-SHA256 mit dem Signatur-Token;
  • vergleichen Sie das Ergebnis mit signature über eine Funktion mit konstanter Vergleichszeit: hash_equals in PHP, timingSafeEqual in Node.js oder compare_digest in Python;
  • geben Sie 401 zurück, wenn die Signatur ungültig ist.

Minimaler Handler

Dieses Beispiel akzeptiert jeden Webhook: Es liest JSON, prüft signature, verarbeitet Testzustellungen, validiert Kernfelder und gibt 204 zurück. Ereignisspezifische Logik fügen Sie nach der Signaturprüfung hinzu.

php
<?php
// Replace this token with the signing token from your GAMEMONITORING webhook settings.
$secret = 'paste-webhook-token-here';

// Read and decode the JSON body sent by GAMEMONITORING.
$event = json_decode(file_get_contents('php://input'), true) ?: [];

// Test deliveries are signed too. Normalize the boolean value to the lowercase
// string used by GAMEMONITORING when the signature is calculated.
$isTest = ($event['is_test'] ?? false) === true;
$signingData = array_replace($event, ['is_test' => $isTest ? 'true' : 'false']);

// Build the exact signing string: all body fields except signature,
// sorted by key and joined as key=value pairs with &.
$fields = array_values(array_filter(array_keys($event), fn($field) => $field !== 'signature'));
sort($fields, SORT_STRING);

// Calculate HMAC-SHA256 with the webhook token from your settings.
$signing = implode('&', array_map(fn($field) => $field . '=' . (string) ($signingData[$field] ?? ''), $fields));
$expected = hash_hmac('sha256', $signing, $secret);
$actual = (string) ($event['signature'] ?? '');

// Reject the request before doing any work when the signature is invalid.
if (!hash_equals($expected, $actual)) {
    http_response_code(401);
    exit;
}

// Test deliveries must not change balance, inventory, roles, or production data.
if ($isTest) {
    http_response_code(204);
    exit;
}

// Real deliveries must include an event type and a stable event id.
$eventType = (string) ($event['event_type'] ?? '');
$eventId = (string) ($event['event_id'] ?? '');

if ($eventType === '' || $eventId === '') {
    http_response_code(400);
    exit;
}

// At this point the webhook is trusted. Add event-specific logic here.
error_log('Accepted webhook event ' . $eventType . ' #' . $eventId);

// 204 tells GAMEMONITORING that the delivery was accepted successfully.
http_response_code(204);

Wiederholte Zustellung und Deduplikation

Webhook-Zustellung arbeitet nach dem At-least-once-Modell: dasselbe Ereignis kann mehr als einmal ankommen. Jede Aktion, die den Zustand Ihres Systems ändert, muss anhand von event_type + event_id idempotent sein.

Speichern Sie das Paar event_type und event_id in einer Tabelle mit eindeutigem Schlüssel. Wenn der Datensatz bereits existiert, wurde das Ereignis schon verarbeitet: geben Sie 204 zurück und ändern Sie den Zustand nicht erneut.

Tabelle verarbeiteter Webhook-Ereignisse
CREATE TABLE gamemonitoring_webhooks (
  event_type varchar(64) NOT NULL,
  event_id varchar(100) NOT NULL,
  created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (event_type, event_id)
);

Wenn ein Webhook Ihre Datenbank ändert, speichern Sie das Ereignis und führen Sie die Aktion in einer Transaktion aus. Wenn der Handler eine Belohnung ausgibt, müssen das Einfügen von event_type + event_id und das Belohnungsupdate gemeinsam erfolgreich sein. Wenn das Einfügen keine neue Zeile erzeugt, wurde das Ereignis bereits verarbeitet.

Verwenden Sie Nickname, Benutzer-ID oder Server-ID nicht als Deduplikationsschlüssel: ein Benutzer kann verschiedene Ereignisse auslösen oder eine erlaubte Aktion später wiederholen. Der Schlüssel muss event_type + event_id sein.

Beispiel: Der Handler hat die Belohnung ausgegeben, aber die Verbindung brach ab, bevor GAMEMONITORING 204 erhielt. Später wird die Zustellung wiederholt. Ihr Handler muss die bereits gespeicherten event_type + event_id finden, keine zweite Belohnung ausgeben und 204 zurückgeben.

Wenn der Handler das Ereignis vorübergehend nicht verarbeiten kann, geben Sie eine fehlgeschlagene Antwort zurück. Nach Behebung der Ursache kann die Zustellung aus der Oberfläche wiederholt werden, wenn dies für das Ereignis verfügbar ist.

Tests und erneutes Senden

Eine Testzustellung (is_test: true) prüft Handler-URL, Signatur und HTTP-Antwort. Der Handler sollte denselben Verarbeitungspfad durchlaufen: JSON lesen, signature prüfen, is_test erkennen und eine erfolgreiche 2xx-Antwort zurückgeben.

Ein Testereignis darf keinen Kontostand, kein Inventar, keine Rollen, keine Abonnements und keine anderen produktiven Daten ändern. Ein technisches Log und die Antwort 204 reichen für den Test aus.

Wenn die Zustellung fehlschlägt, zeigt die Oberfläche Status, HTTP-Code und Handler-Antwort an. Nach Behebung der Ursache kann eine fehlgeschlagene Zustellung erneut gesendet werden, wenn dies für das Ereignis verfügbar ist.