FastComments.com


Mit FastComments ist es möglich, einen API-Endpunkt aufzurufen, wann immer ein Kommentar in unserem System hinzugefügt, aktualisiert oder entfernt wird.

Wir realisieren dies mit asynchronen Webhooks über HTTP/HTTPS.


Was sind Webhooks Internal Link

Ein Webhook ist ein Mechanismus oder eine Integration zwischen zwei Systemen, bei dem der "Produzent" (FastComments) ein Ereignis auslöst das der "Konsument" (Sie) per API-Aufruf verarbeitet.

Unterstützte Ereignisse und Ressourcen Internal Link


FastComments unterstützt Webhooks nur für die Kommentar-Ressource.

Wir unterstützen Webhooks für die Erstellung, Entfernung und Aktualisierung von Kommentaren.

Jedes davon wird in unserem System als separates Ereignis betrachtet und hat daher unterschiedliche Semantik und Strukturen für die Webhook-Ereignisse.


Testen Internal Link

Im Webhooks-Admin gibt es Send Test Payload-Schaltflächen für jeden Ereignistyp (Create, Update, Delete). Die Create- und Update-Ereignisse senden ein Dummy WebhookComment-Objekt, während beim Testen von Delete ein Dummy-Anfragekörper mit nur einer ID gesendet wird.

Überprüfung der Payloads

When testing your webhook integration, verify the incoming requests include the following headers:

  1. token - Ihr API-Secret
  2. X-FastComments-Timestamp - Unix-Zeitstempel (Sekunden)
  3. X-FastComments-Signature - HMAC-SHA256-Signatur

Verwenden Sie die HMAC-Signaturprüfung, um sicherzustellen, dass die Payloads authentisch sind.

Test-Tools

Sie können Werkzeuge wie webhook.site oder ngrok verwenden, um eingehende Webhook-Payloads während der Entwicklung zu untersuchen.

Ereignistypen

  • Create Event: Wird ausgelöst, wenn ein neuer Kommentar erstellt wird. Standardmethode: PUT
  • Update Event: Wird ausgelöst, wenn ein Kommentar bearbeitet wird. Standardmethode: PUT
  • Delete Event: Wird ausgelöst, wenn ein Kommentar gelöscht wird. Standardmethode: DELETE

Jedes Ereignis enthält die vollständigen Kommentardaten im Anfragekörper (siehe Datenstrukturen für das Payload-Format).

Datenstrukturen Internal Link

Die einzige Struktur, die über Webhooks gesendet wird, ist das WebhookComment-Objekt, unten in TypeScript dargestellt.

Die Struktur des WebhookComment-Objekts

Die "Create"-Event-Struktur

Der Request-Body des "create"-Events ist ein WebhookComment-Objekt.

Die "Update"-Event-Struktur

Der Request-Body des "update"-Events ist ein WebhookComment-Objekt.

Die "Delete"-Event-Struktur

Der Request-Body des "delete"-Events ist ein WebhookComment-Objekt.

Änderung ab 14. Nov 2023
Zuvor enthielt der Request-Body des "delete"-Events nur die Kommentar-ID. Er enthält jetzt den vollständigen Kommentar zum Zeitpunkt der Löschung.
Das WebhookComment-Objekt
Copy CopyRun External Link
1
2interface WebhookComment {
3 /** Die id des Kommentars. **/
4 id: string
5 /** Die id oder URL, die den Kommentar-Thread identifiziert. Normalisiert. **/
6 urlId: string
7 /** Die URL, die auf den Ort zeigt, an dem der Kommentar hinterlassen wurde. **/
8 url?: string
9 /** Die Benutzer-id, die den Kommentar hinterlassen hat. Bei SSO mit Tenant-id vorangestellt. **/
10 userId?: string
11 /** Die E-Mail des Benutzers, der den Kommentar hinterlassen hat. **/
12 commenterEmail?: string
13 /** Der Name des Benutzers, der im Kommentar-Widget angezeigt wird. Bei SSO kann dies displayName sein. **/
14 commenterName: string
15 /** Rohkommentartext. **/
16 comment: string
17 /** Kommentartext nach dem Parsen. **/
18 commentHTML: string
19 /** Externe Kommentar-id. **/
20 externalId?: string
21 /** Die id des übergeordneten Kommentars. **/
22 parentId?: string | null
23 /** Das UTC-Datum, an dem der Kommentar hinterlassen wurde. **/
24 date: UTC_ISO_DateString
25 /** Kombiniertes Karma (up - down) der Stimmen. **/
26 votes: number
27 votesUp: number
28 votesDown: number
29 /** Wahr, wenn der Benutzer beim Kommentieren eingeloggt war, oder seinen Kommentar verifiziert hat, oder wenn er seine Sitzung beim Hinterlassen des Kommentars verifiziert hatte. **/
30 verified: boolean
31 /** Datum, wann der Kommentar verifiziert wurde. **/
32 verifiedDate?: number
33 /** Ob ein Moderator den Kommentar als überprüft markiert hat. **/
34 reviewed: boolean
35 /** Der Speicherort oder die Base64-Codierung des Avatars. Wird nur Base64 sein, wenn dieser Wert mit SSO übergeben wurde. **/
36 avatarSrc?: string
37 /** Wurde der Kommentar manuell oder automatisch als Spam markiert? **/
38 isSpam: boolean
39 /** Wurde der Kommentar automatisch als Spam markiert? **/
40 aiDeterminedSpam: boolean
41 /** Enthält der Kommentar Bilder? **/
42 hasImages: boolean
43 /** Die Seitenzahl, auf der sich der Kommentar bei der Sortierung "Most Relevant" befindet. **/
44 pageNumber: number
45 /** Die Seitenzahl, auf der sich der Kommentar bei der Sortierung "Oldest First" befindet. **/
46 pageNumberOF: number
47 /** Die Seitenzahl, auf der sich der Kommentar bei der Sortierung "Newest First" befindet. **/
48 pageNumberNF: number
49 /** Wurde der Kommentar automatisch oder manuell genehmigt? **/
50 approved: boolean
51 /** Der Locale-Code (Format: en_us) des Benutzers beim Schreiben des Kommentars. **/
52 locale: string
53 /** Die im Kommentar geschriebenen @mentions, die erfolgreich geparst wurden. **/
54 mentions?: CommentUserMention[]
55 /** Die Domain, von der der Kommentar stammt. **/
56 domain?: string
57 /** Die optionale Liste von Moderationsgruppen-ids, die mit diesem Kommentar verknüpft sind. **/
58 moderationGroupIds?: string[]|null
59}
60

When users are tagged in a comment, the information is stored in a list called mentions. Each object in that list has the following structure.

Das Webhook-Mentions-Objekt
Copy CopyRun External Link
1
2interface CommentUserMention {
3 /** Die Benutzer-id. Für SSO-Benutzer wird Ihre Tenant-id vorangestellt. **/
4 id: string
5 /** Der endgültige @mention-Tag-Text, einschließlich des @-Symbols. **/
6 tag: string
7 /** Der ursprüngliche @mention-Tag-Text, einschließlich des @-Symbols. **/
8 rawTag: string
9 /** Welcher Benutzertyp markiert wurde. user = FastComments.com account. sso = SSOUser. **/
10 type: 'user'|'sso'
11 /** Wenn der Benutzer Benachrichtigungen abwählt, bleibt dieses Feld trotzdem auf true gesetzt. **/
12 sent: boolean
13}
14

HTTP-Methoden

Sie können die HTTP-Methode für jeden Webhook-Ereignistyp im Admin-Panel konfigurieren:

  • Create Event: POST oder PUT (Standard: PUT)
  • Update Event: POST oder PUT (Standard: PUT)
  • Delete Event: DELETE, POST oder PUT (Standard: DELETE)

Da alle Anfragen eine ID enthalten, sind Create- und Update-Operationen standardmäßig idempotent (PUT). Die wiederholte Zusendung derselben Create- oder Update-Anfrage sollte auf Ihrer Seite keine doppelten Objekte erzeugen.

Request-Header

Jede Webhook-Anfrage enthält folgende Header:

Header Description
Content-Type application/json
token Ihr API-Secret
X-FastComments-Timestamp Unix-Zeitstempel (Sekunden), zu dem die Anfrage signiert wurde
X-FastComments-Signature HMAC-SHA256-Signatur (sha256=<hex>)

Siehe Sicherheit & API-Token für Informationen zur Überprüfung der HMAC-Signatur.


Sicherheit & API-Token Internal Link

FastComments Webhook-Anfragen enthalten mehrere Authentifizierungsmechanismen zur Sicherheit.

Gesendete Header

Header Beschreibung
token Ihr API Secret (zur Abwärtskompatibilität)
X-FastComments-Timestamp Unix-Zeitstempel (Sekunden), zu dem die Anfrage signiert wurde
X-FastComments-Signature HMAC-SHA256-Signatur der Payload

HMAC-Signaturüberprüfung (empfohlen)

Wir empfehlen dringend, die HMAC-Signatur zu überprüfen, um sicherzustellen, dass Webhook-Payloads authentisch sind und nicht manipuliert wurden.

Signaturformat: sha256=<hex-encoded-signature>

Wie die Signatur berechnet wird:

  1. Verketten: timestamp + "." + JSON_payload_body
  2. Berechne HMAC-SHA256 mit Ihrem API Secret als Schlüssel
  3. Das Ergebnis hexadezimal kodieren

Beispielüberprüfung (Node.js)

const crypto = require('crypto');

function verifyWebhookSignature(req, apiSecret) {
    const timestamp = req.headers['x-fastcomments-timestamp'];
    const signature = req.headers['x-fastcomments-signature'];

    if (!timestamp || !signature) {
        return false;
    }

    // Überprüfe, ob der Zeitstempel aktuell ist (innerhalb von 5 Minuten)
    const now = Math.floor(Date.now() / 1000);
    if (Math.abs(now - parseInt(timestamp, 10)) > 300) {
        return false;  // Schutz vor Replay-Angriffen
    }

    // Überprüfe Signatur
    const payload = JSON.stringify(req.body);
    const expectedSignature = crypto
        .createHmac('sha256', apiSecret)
        .update(`${timestamp}.${payload}`)
        .digest('hex');

    return signature === `sha256=${expectedSignature}`;
}

Beispielüberprüfung (Python)

import hmac
import hashlib
import time
import json

def verify_webhook_signature(headers, body, api_secret):
    timestamp = headers.get('X-FastComments-Timestamp')
    signature = headers.get('X-FastComments-Signature')

    if not timestamp or not signature:
        return False

    # Überprüfe, ob der Zeitstempel aktuell ist
    now = int(time.time())
    if abs(now - int(timestamp)) > 300:
        return False

    # Überprüfe Signatur
    payload = json.dumps(body, separators=(',', ':'))
    message = f"{timestamp}.{payload}"
    expected = hmac.new(
        api_secret.encode(),
        message.encode(),
        hashlib.sha256
    ).hexdigest()

    return signature == f"sha256={expected}"

Beispielüberprüfung (PHP)

function verifyWebhookSignature($headers, $body, $apiSecret) {
    $timestamp = $headers['X-FastComments-Timestamp'] ?? null;
    $signature = $headers['X-FastComments-Signature'] ?? null;

    if (!$timestamp || !$signature) {
        return false;
    }

    // Überprüfe, ob der Zeitstempel aktuell ist (innerhalb von 5 Minuten)
    $now = time();
    if (abs($now - intval($timestamp)) > 300) {
        return false;
    }

    // Überprüfe Signatur
    $payload = json_encode($body, JSON_UNESCAPED_SLASHES);
    $message = $timestamp . '.' . $payload;
    $expectedSignature = 'sha256=' . hash_hmac('sha256', $message, $apiSecret);

    return hash_equals($expectedSignature, $signature);
}

Legacy-Authentifizierung

Der token-Header, der Ihr API Secret enthält, wird weiterhin zur Abwärtskompatibilität gesendet. Wir empfehlen jedoch, auf die HMAC-Überprüfung umzusteigen, um die Sicherheit zu verbessern, da diese vor Replay-Angriffen schützt.


Zum Abschluss

Dies schließt unsere Webhooks-Dokumentation ab.

Wir hoffen, dass Sie die FastComments-Webhook-Integration leicht verständlich finden und schnell einrichten können.

Wenn Sie der Meinung sind, dass unsere Dokumentation Lücken aufweist, teilen Sie uns dies unten mit.