FastComments.com


Met FastComments is het mogelijk een API-eindpunt aan te roepen telkens wanneer een reactie aan ons systeem wordt toegevoegd, bijgewerkt of verwijderd.

Wij realiseren dit met asynchrone webhooks via HTTP/HTTPS.


Wat zijn Webhooks Internal Link

Een Webhook is een mechanisme, of een integratie, tussen twee systemen waar de "producent" (FastComments) een gebeurtenis die de "consument" (U) via een API-aanroep verwerkt.

Ondersteunde gebeurtenissen en bronnen Internal Link


FastComments ondersteunt webhooks alleen voor de Comment resource.

We ondersteunen webhooks voor comment-creatie, -verwijdering en bij comment-updates.

Elk van deze wordt in ons systeem als een apart evenement beschouwd en heeft daardoor verschillende semantiek en structuren voor de webhook events.


Testen Internal Link

In de Webhooks-admin staan Send Test Payload-knoppen voor elk gebeurtenistype (Create, Update, Delete). De Create- en Update-gebeurtenissen sturen een dummy WebhookComment-object, terwijl bij het testen van Delete een dummy request body met alleen een ID wordt verzonden.

Verifiëren van payloads

Controleer bij het testen van je webhook-integratie of de binnenkomende verzoeken de volgende headers bevatten:

  1. token - Your API Secret
  2. X-FastComments-Timestamp - Unix timestamp (seconds)
  3. X-FastComments-Signature - HMAC-SHA256 signature

Gebruik de HMAC-handtekeningverificatie om te zorgen dat payloads authentiek zijn.

Testtools

Je kunt tools zoals webhook.site of ngrok gebruiken om binnenkomende webhook-payloads tijdens de ontwikkeling te inspecteren.

Gebeurtenistypen

  • Create-gebeurtenis: Wordt geactiveerd wanneer een nieuwe reactie wordt aangemaakt. Standaardmethode: PUT
  • Update-gebeurtenis: Wordt geactiveerd wanneer een reactie wordt bewerkt. Standaardmethode: PUT
  • Delete-gebeurtenis: Wordt geactiveerd wanneer een reactie wordt verwijderd. Standaardmethode: DELETE

Elke gebeurtenis bevat de volledige reactiegegevens in de request body (zie Gegevensstructuren voor het payloadformaat).

Datastructuren Internal Link

De enige structuur die via webhooks wordt verzonden is het WebhookComment-object, hieronder in TypeScript uiteengezet.

De WebhookComment Object-structuur

Structuur van het "create"-event

De request body van het "create" event is een WebhookComment-object.

Structuur van het "update"-event

De request body van het "update" event is een WebhookComment-object.

Structuur van het "delete"-event

De request body van het "delete" event is een WebhookComment-object.

Change as of Nov 14th 2023
Previously the "delete" event request body only contained the comment id. It now contains the full comment at the time of deletion.
Het WebhookComment-object
Copy CopyRun External Link
1
2interface WebhookComment {
3 /** De id van de reactie. **/
4 id: string
5 /** De id of URL die de reactiedraad identificeert. Genormaliseerd. **/
6 urlId: string
7 /** De URL die verwijst naar waar de reactie is achtergelaten. **/
8 url?: string
9 /** De gebruiker-id die de reactie plaatste. Bij SSO voorafgegaan door de tenant-id. **/
10 userId?: string
11 /** Het e-mailadres van de gebruiker die de reactie achterliet. **/
12 commenterEmail?: string
13 /** De naam van de gebruiker die in de comment-widget wordt weergegeven. Bij SSO kan dit displayName zijn. **/
14 commenterName: string
15 /** Ruwe reactietekst. **/
16 comment: string
17 /** Reactietekst na parsing. **/
18 commentHTML: string
19 /** Externe id van de reactie. **/
20 externalId?: string
21 /** De id van de bovenliggende reactie. **/
22 parentId?: string | null
23 /** De UTC-datum waarop de reactie is geplaatst. **/
24 date: UTC_ISO_DateString
25 /** Gecombineerde karma (up - down) van stemmen. **/
26 votes: number
27 votesUp: number
28 votesDown: number
29 /** Waar als de gebruiker was ingelogd toen hij reageerde, of als de reactie geverifieerd is, of als de sessie van de gebruiker geverifieerd was toen de reactie werd geplaatst. **/
30 verified: boolean
31 /** Datum waarop de reactie is geverifieerd. **/
32 verifiedDate?: number
33 /** Of een moderator de reactie als beoordeeld heeft gemarkeerd. **/
34 reviewed: boolean
35 /** De locatie, of base64-encoding, van de avatar. Alleen base64 als dat de waarde was die bij SSO werd doorgegeven. **/
36 avatarSrc?: string
37 /** Is de reactie handmatig of automatisch als spam gemarkeerd? **/
38 isSpam: boolean
39 /** Is de reactie automatisch als spam gemarkeerd? **/
40 aiDeterminedSpam: boolean
41 /** Bevat de reactie afbeeldingen? **/
42 hasImages: boolean
43 /** Het paginanummer waarop de reactie staat voor de sorteer richting "Most Relevant". **/
44 pageNumber: number
45 /** Het paginanummer waarop de reactie staat voor de sorteer richting "Oldest First". **/
46 pageNumberOF: number
47 /** Het paginanummer waarop de reactie staat voor de sorteer richting "Newest First". **/
48 pageNumberNF: number
49 /** Is de reactie automatisch of handmatig goedgekeurd? **/
50 approved: boolean
51 /** De locale-code (format: en_us) van de gebruiker toen de reactie werd geschreven. **/
52 locale: string
53 /** De @mentions in de reactie die succesvol zijn geparseerd. **/
54 mentions?: CommentUserMention[]
55 /** Het domein waar de reactie vandaan komt. **/
56 domain?: string
57 /** De optionele lijst met moderatiegroep-ids die aan deze reactie zijn gekoppeld. **/
58 moderationGroupIds?: string[]|null
59}
60

Wanneer gebruikers in een reactie worden getagd, wordt de informatie opgeslagen in een lijst genaamd mentions. Elk object in die lijst heeft de volgende structuur.

Het Webhook Vermeldingen-object
Copy CopyRun External Link
1
2interface CommentUserMention {
3 /** De gebruiker-id. Voor SSO-gebruikers wordt deze voorafgegaan door uw tenant-id. **/
4 id: string
5 /** De uiteindelijke @mention-tagtekst, inclusief het @-symbool. **/
6 tag: string
7 /** De oorspronkelijke @mention-tagtekst, inclusief het @-symbool. **/
8 rawTag: string
9 /** Welk type gebruiker werd getagd. user = FastComments.com-account. sso = SSOUser. **/
10 type: 'user'|'sso'
11 /** Als de gebruiker zich afmeldt voor notificaties, blijft dit toch op true staan. **/
12 sent: boolean
13}
14

HTTP-methoden

U kunt de HTTP-methode voor elk type webhook-gebeurtenis configureren in het beheerderspaneel:

  • Create Event: POST of PUT (standaard: PUT)
  • Update Event: POST of PUT (standaard: PUT)
  • Delete Event: DELETE, POST of PUT (standaard: DELETE)

Omdat alle requests een ID bevatten, zijn Create- en Update-bewerkingen standaard idempotent (PUT). Het opnieuw versturen van dezelfde Create- of Update-request zou geen dubbele objecten aan uw zijde mogen aanmaken.

Request Headers

Elke webhook-request bevat de volgende headers:

Header Beschrijving
Content-Type application/json
token Uw API Secret
X-FastComments-Timestamp Unix-tijdstempel (seconden) waarop het verzoek werd ondertekend
X-FastComments-Signature HMAC-SHA256-handtekening (sha256=<hex>)

Zie Security & API Tokens voor informatie over het verifiëren van de HMAC-handtekening.

Beveiliging & API-tokens Internal Link

FastComments webhookverzoeken bevatten meerdere authenticatiemechanismen voor beveiliging.

Verzonden headers

Header Beschrijving
token Uw API Secret (voor achterwaartse compatibiliteit)
X-FastComments-Timestamp Unix-timestamp (seconden) wanneer het verzoek werd ondertekend
X-FastComments-Signature HMAC-SHA256-handtekening van de payload

HMAC-handtekeningverificatie (aanbevolen)

We raden sterk aan de HMAC-handtekening te verifiëren om ervoor te zorgen dat webhook-payloads authentiek zijn en niet zijn gewijzigd.

Handtekeningformaat: sha256=<hex-encoded-signature>

Hoe de handtekening wordt berekend:

  1. Samenvoegen: timestamp + "." + JSON_payload_body
  2. Bereken HMAC-SHA256 met uw API Secret als sleutel
  3. Hex-encodeer het resultaat

Voorbeeldverificatie (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;
    }

    // Controleer of de timestamp recent is (binnen 5 minuten)
    const now = Math.floor(Date.now() / 1000);
    if (Math.abs(now - parseInt(timestamp, 10)) > 300) {
        return false;  // Ter voorkoming van replay-aanvallen
    }

    // Verifieer handtekening
    const payload = JSON.stringify(req.body);
    const expectedSignature = crypto
        .createHmac('sha256', apiSecret)
        .update(`${timestamp}.${payload}`)
        .digest('hex');

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

Voorbeeldverificatie (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

    # Controleer of de timestamp recent is
    now = int(time.time())
    if abs(now - int(timestamp)) > 300:
        return False

    # Verifieer handtekening
    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}"

Voorbeeldverificatie (PHP)

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

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

    // Controleer of de timestamp recent is (binnen 5 minuten)
    $now = time();
    if (abs($now - intval($timestamp)) > 300) {
        return false;
    }

    // Verifieer handtekening
    $payload = json_encode($body, JSON_UNESCAPED_SLASHES);
    $message = $timestamp . '.' . $payload;
    $expectedSignature = 'sha256=' . hash_hmac('sha256', $message, $apiSecret);

    return hash_equals($expectedSignature, $signature);
}

Verouderde authenticatie

De token-header die uw API Secret bevat, wordt nog steeds verzonden voor achterwaartse compatibiliteit. We raden echter aan over te stappen op HMAC-verificatie voor verbeterde beveiliging, omdat dit beschermt tegen replay-aanvallen.


Tot slot

Hiermee is onze Webhooks-documentatie afgerond.

We hopen dat je de FastComments Webhook-integratie gemakkelijk te begrijpen vindt en snel kunt instellen.

Als je denkt dat er hiaten in onze documentatie zitten, laat het ons hieronder weten.