FastComments.com

Webhooki


Z FastComments je mogoče poklicati API endpoint vsakič, ko je komentar dodan, posodobljen ali odstranjen iz našega sistema.

To dosežemo z asinhronimi webhooks prek HTTP/HTTPS.


Kaj so webhooki Internal Link

Webhook je mehanizem, ali integracija, med dvema sistemoma, kjer "producent" (FastComments) sproži dogodek ki ga "potrošnik" (Vi) prejme prek API klica.

Podprti dogodki in viri Internal Link

FastComments podpira webhooks samo za vir Comment.

Podpiramo webhooks za ustvarjanje komentarjev, odstranjevanje in posodobitev.

Vsak od teh se v našem sistemu šteje kot ločen dogodek in zato ima različne semantike in strukture za webhook dogodke.

Poljubno število končnih točk se lahko naroči na isti dogodek, iz nadzorne plošče ali prek API-ja (glejte Managing Webhooks via the API). Vsak webhook se dostavi neodvisno.

Testiranje Internal Link

The new and edit webhook pages have a Send Test Payload button that sends a request to the URL currently in the form, whether or not it has been saved. The Create and Update events send a dummy WebhookComment object, while testing Delete will send a dummy request body with just an ID.

Verifying Payloads

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

  1. X-FastComments-Timestamp - Unix timestamp (seconds)
  2. X-FastComments-Signature - HMAC-SHA256 signature

Webhooks created before the signature scheme was introduced also receive a token header containing your API Secret. New webhooks do not.

Use the HMAC signature verification to ensure payloads are authentic.

Testing Tools

You can use tools like webhook.site or ngrok to inspect incoming webhook payloads during development.

Event Types

  • Create Event: Triggered when a new comment is created.
  • Update Event: Triggered when a comment is edited.
  • Delete Event: Triggered when a comment is deleted.

Each webhook is tied to one event and one HTTP method (POST, PUT or DELETE). Each event includes the full comment data in the request body (see Data Structures for the payload format).

Podatkovne strukture Internal Link

The only structure sent via webhooks is the WebhookComment object, outlined in TypeScript below.

Struktura objekta WebhookComment

Struktura dogodka "Create"

The "create" event request body is a WebhookComment object.

Struktura dogodka "Update"

The "update" event request body is a WebhookComment object.

Struktura dogodka "Delete"

The "delete" event request body is a WebhookComment object.

Sprememba od 14. novembra 2023
Prej je telo zahteve za dogodek "delete" vsebovalo le ID komentarja. Zdaj vsebuje celoten komentar v času brisanja.

Every key is always present in the body. When the comment has no value for a field the body carries null (or false for booleans and [] for lists), so the shape of a delivery never varies from one comment to the next.

Objekt WebhookComment
Copy CopyRun External Link
1
2interface WebhookComment {
3 /** ID komentarja. **/
4 id: string
5 /** ID ali URL, ki identificira nit komentarjev. Normalizirano. **/
6 urlId: string
7 /** URL, ki kaže na mesto, kjer je bil komentar objavljen. **/
8 url: string | null
9 /** ID uporabnika, ki je napisal komentar. Če je SSO, je predponjen z ID najemnika. **/
10 userId: string | null
11 /** E‑mail uporabnika, ki je napisal komentar. **/
12 commenterEmail: string | null
13 /** Ime uporabnika, ki se prikaže v pripomočku za komentarje. Pri SSO je lahko displayName. **/
14 commenterName: string
15 /** Surovo besedilo komentarja. **/
16 comment: string
17 /** Besedilo komentarja po razčlenitvi. **/
18 commentHTML: string
19 /** Zunanji ID komentarja. **/
20 externalId: string | null
21 /** ID nadrejenega komentarja. **/
22 parentId: string | null
23 /** Datum v UTC, ko je bil komentar objavljen. **/
24 date: UTC_ISO_DateString
25 /** Skupna karma (glasovi + - -). **/
26 votes: number
27 votesUp: number
28 votesDown: number
29 /** Resnično, če je bil uporabnik prijavljen, ko je komentiral, ali je potrdil komentar, ali je potrdil sejo, ko je bil komentar objavljen. **/
30 verified: boolean
31 /** Datum v UTC, ko je bil komentar potrjen. **/
32 verifiedDate: UTC_ISO_DateString | null
33 /** Če je moderator označil komentar kot pregledan. **/
34 reviewed: boolean
35 /** Lokacija ali base64 kodiranje avatarja. Base64 bo le, če je bila to vrednost posredovana z SSO. **/
36 avatarSrc: string | null
37 /** Ali je bil komentar ročno ali samodejno označen kot neželen? **/
38 isSpam: boolean
39 /** Ali je bil komentar samodejno označen kot neželen? **/
40 aiDeterminedSpam: boolean
41 /** Ali komentar vsebuje slike? **/
42 hasImages: boolean
43 /** Številka strani, na kateri je komentar pri razvrščanju po "Najbolj relevantnih". **/
44 pageNumber: number | null
45 /** Številka strani, na kateri je komentar pri razvrščanju po "Najstarejših najprej". **/
46 pageNumberOF: number | null
47 /** Številka strani, na kateri je komentar pri razvrščanju po "Najnovejših najprej". **/
48 pageNumberNF: number | null
49 /** Ali je bil komentar odobren samodejno ali ročno? **/
50 approved: boolean
51 /** Koda jezika (format: en_us) uporabnika, ko je bil komentar napisan. **/
52 locale: string | null
53 /** Oznake @, zapisane v komentarju, ki so bile uspešno razčlenjene. Prazno, ko jih ni. **/
54 mentions: CommentUserMention[]
55 /** Domena, iz katere je komentar. **/
56 domain: string | null
57 /** ID-ji moderacijskih skupin, povezani s tem komentarjem. Prazno, ko jih ni. **/
58 moderationGroupIds: string[]
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.

Objekt Webhook Mentions
Copy CopyRun External Link
1
2interface CommentUserMention {
3 /** ID uporabnika. Za SSO uporabnike bo predponjen z ID najemnika. **/
4 id: string
5 /** Končni besedilni niz @omenjanja, vključno s simbolom @. **/
6 tag: string
7 /** Izvirni besedilni niz @omenjanja, vključno s simbolom @. **/
8 rawTag: string
9 /** Kakšna vrsta uporabnika je bila označena. user = račun FastComments.com. sso = SSOUser. **/
10 type: 'user'|'sso'
11 /** Če se uporabnik odkloni od obvestil, bo to še vedno nastavljeno na true. **/
12 sent: boolean
13}
14

HTTP metode

You can configure the HTTP method for each webhook event type in the admin panel:

  • Create Event: POST or PUT (default: PUT) -> Create Event: POST ali PUT (privzeto: PUT)
  • Update Event: POST or PUT (default: PUT) -> Update Event: POST ali PUT (privzeto: PUT)
  • Delete Event: DELETE, POST, or PUT (default: DELETE) -> Delete Event: DELETE, POST ali PUT (privzeto: DELETE)

Since all requests contain an ID, Create and Update operations are idempotent by default (PUT). Repeating the same Create or Update request should not create duplicate objects on your side.

Glave zahteve

Each webhook request includes the following headers:

HeaderDescription
Content-Typeapplication/json
tokenVaše API skrivnost
X-FastComments-TimestampUnix časovni žig (sekunde), ko je bila zahteva podpisana
X-FastComments-SignatureHMAC-SHA256 podpis (sha256=<hex>)

See Varnost in API žetoni for information on verifying the HMAC signature.

Varnost in API žetoni Internal Link

FastComments webhook zahtevki vsebujejo več mehanizmov za overjanje za zagotavljanje varnosti.

Poslane glave

GlavaOpis
tokenVaš API skrivni ključ (za združljivost z starejšimi različicami)
X-FastComments-TimestampUnix časovni žig (v sekundah), ko je bil zahtevek podpisan
X-FastComments-SignatureHMAC-SHA256 podpis vsebine

Preverjanje HMAC podpisa (priporočeno)

Močno priporočamo preverjanje HMAC podpisa, da zagotovite, da so podatki webhooka avtentični in da z njimi ni bilo manipulirano.

Oblika podpisa: sha256=<hex-encoded-signature>

Kako se izračuna podpis:

  1. Združi: timestamp + "." + JSON_payload_body
  2. Izračunajte HMAC-SHA256 z vašim API skrivnim ključem kot ključem
  3. Hex-kodirajte rezultat

Primer preverjanja (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;
    }

    // Preveri, ali je časovni žig svež (v 5 minutah)
    const now = Math.floor(Date.now() / 1000);
    if (Math.abs(now - parseInt(timestamp, 10)) > 300) {
        return false;  // Preprečevanje ponovitvenega napada
    }

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

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

Primer preverjanja (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

    # Preveri, ali je časovni žig svež
    now = int(time.time())
    if abs(now - int(timestamp)) > 300:
        return False

    # Preveri podpis
    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}"

Primer preverjanja (PHP)

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

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

    // Preveri, ali je časovni žig svež (v 5 minutah)
    $now = time();
    if (abs($now - intval($timestamp)) > 300) {
        return false;
    }

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

    return hash_equals($expectedSignature, $signature);
}

Zastarelo overjanje

Glava token, ki vsebuje vaš API skrivni ključ, se še vedno pošilja zaradi združljivosti z starejšimi različicami. Vendar priporočamo prehod na preverjanje preko HMAC zaradi boljše varnosti, saj ščiti pred ponovitvenimi napadi.


Upravljanje webhookov prek API-ja Internal Link

Webhooks can also be managed through the REST API. This is how integrations such as Zapier subscribe to comment events without touching the dashboard, and it follows the REST Hooks pattern: subscribe, receive events, unsubscribe.

API subscriptions live alongside the webhooks configured in the dashboard. A comment event is delivered to every webhook that matches its domain, each as its own delivery, whichever way the webhook was created.

Avtentikacija

Every request needs your API Key in the x-api-key header (or the API_KEY query parameter) and your tenant ID in the tenantId query parameter. Both are shown on the API Secret page in the dashboard.

Naročanje

POST https://fastcomments.com/api/v1/webhooks?tenantId=YOUR_TENANT_ID
x-api-key: YOUR_API_KEY
Content-Type: application/json

{
    "url": "https://hooks.zapier.com/hooks/catch/123/abc",
    "event": "comment-created"
}
PoljeObveznoOpis
urlDaAn absolute http or https URL.
eventDacomment-created, comment-updated or comment-deleted.
domainNeA domain from your account configuration. Defaults to *, which receives events for every domain.
methodNePOST (default), PUT or DELETE.

The response contains the subscription:

{
    "status": "success",
    "webhook": {
        "id": "66f1c4c1e7a2b3d4f5a6b7c8",
        "url": "https://hooks.zapier.com/hooks/catch/123/abc",
        "event": "comment-created",
        "domain": "*",
        "method": "POST",
        "source": "api",
        "enabled": true,
        "createdAt": "2026-09-08T12:00:00.000Z"
    }
}

Subscribing the same URL to the same event and domain again returns the existing subscription rather than creating a duplicate, so a client can safely retry. Each tenant can have up to 50 API subscriptions.

Seznam

GET https://fastcomments.com/api/v1/webhooks?tenantId=YOUR_TENANT_ID

Returns every webhook for the tenant, including those managed in the dashboard ("source": "dashboard"). Filter with event, domain or source.

Odjava

DELETE https://fastcomments.com/api/v1/webhooks/SUBSCRIPTION_ID?tenantId=YOUR_TENANT_ID

Deleting a subscription also discards any events still queued for it. Only subscriptions created through the API can be deleted this way; a dashboard webhook, or an id that does not exist on your account, answers 404 with code not-found. Dashboard webhooks are edited on the Webhooks page.

Telesa zahtevkov in podpisovanje

Deliveries use the same payload as dashboard webhooks (see Data Structures) and are signed with the same HMAC scheme (see Security & API Tokens). API subscriptions never receive the legacy token header, so verify the X-FastComments-Signature header instead.

Vzorčna telesa

GET https://fastcomments.com/api/v1/webhooks/sample-payloads?tenantId=YOUR_TENANT_ID&event=comment-created&limit=3

Returns the account's most recent comments in exactly the shape a delivery carries, so an integration can show real sample data before the first event arrives. event is optional and only validated, since every event delivers the same comment object. limit defaults to 3 and accepts 1 to 10. Costs 2 API credits.

{
    "status": "success",
    "payloads": [
        {
            "id": "66f1c4c1e7a2b3d4f5a6b7c8",
            "urlId": "https://example.com/blog/hello-world",
            "commenterName": "Jane Reader",
            "comment": "Great article!",
            "date": "2026-09-08T12:00:00.000Z",
            "approved": true
        }
    ]
}

Odgovor z 410 Gone

If an API subscription's endpoint responds with HTTP 410 Gone, FastComments treats that as an unsubscribe: the subscription is deleted along with its queued events, and no further deliveries are attempted. Webhooks configured in the dashboard are never deleted automatically; for them a 410 is an ordinary failure. Any other failure status is retried and eventually disables the webhook, as described in How it Works & Handling Retries.

Nadzorna plošča

API subscriptions appear in the Webhooks list with the source API, where an administrator can edit, disable, re-enable or delete them.

Za zaključek

To zaključuje našo dokumentacijo o Webhookih.

Upamo, da boste integracijo FastComments Webhookov našli enostavno za razumevanje in hitro za nastavitev.

Če menite, da ste odkrili kakšne vrzeli v naši dokumentaciji, nam sporočite spodaj.