FastComments.com

Webhooks

Uz FastComments moguće je pozvati API endpoint kad god se komentar doda, ažurira ili ukloni iz našeg sustava.

Ovo ostvarujemo pomoću asinkronih webhookova preko HTTP/HTTPS.

Što su Webhookovi Internal Link

Webhook je mehanizam, ili integracija, između dvaju sustava gdje "proizvođač" (FastComments) pokreće događaj koji "potrošač" (Vi) konzumira putem API poziva.

Podržani događaji i resursi Internal Link

FastComments podržava webhookove samo za resurs Comment.

Podržavamo webhookove za stvaranje komentara, uklanjanje i ažuriranje.

Svaki od ovih smatra se zasebnim događajem u našem sustavu i stoga ima različitu semantiku i strukture za webhook događaje.

Bilo koji broj krajnjih točaka može se pretplatiti na isti događaj, putem nadzorne ploče ili kroz API (pogledajte Upravljanje webhookovima putem API-ja). Svaki webhook se isporučuje neovisno.

Testiranje Internal Link

Stranice za stvaranje i uređivanje webhooks imaju gumb Send Test Payload koji šalje zahtjev na URL trenutno unesen u obrascu, bez obzira je li spremljen ili ne. Događaji Create i Update šalju lažni WebhookComment objekt, dok testiranje Delete šalje lažno tijelo zahtjeva samo s ID-om.

Provjera Payloada

Prilikom testiranja vaše webhook integracije, provjerite uključuju li dolazni zahtjevi sljedeća zaglavlja:

  1. X-FastComments-Timestamp - Unix vremenski pečat (sekunde)
  2. X-FastComments-Signature - HMAC-SHA256 potpis

Webhooks stvoreni prije uvođenja sheme potpisa također primaju zaglavlje token koje sadrži vaš API Secret. Novi webhooks to ne primaju.

Koristite HMAC provjeru potpisa kako biste osigurali da su payloadi autentični.

Alati za testiranje

Možete koristiti alate poput webhook.site ili ngrok za pregled dolaznih webhook payloada tijekom razvoja.

Vrste događaja

  • Create Event: Pokreće se kada se stvori novi komentar.
  • Update Event: Pokreće se kada se komentar uredi.
  • Delete Event: Pokreće se kada se komentar izbriše.

Svaki webhook vezan je uz jedan događaj i jednu HTTP metodu (POST, PUT ili DELETE). Svaki događaj uključuje potpune podatke o komentaru u tijelu zahtjeva (vidite Data Structures za format payloada).

Strukture podataka Internal Link

Jedina struktura koja se šalje putem webhooksa je objekt WebhookComment, prikazan u TypeScriptu u nastavku.

Struktura objekta WebhookComment

Struktura događaja "Create"

Tijelo zahtjeva događaja "create" je objekt WebhookComment.

Struktura događaja "Update"

Tijelo zahtjeva događaja "update" je objekt WebhookComment.

Struktura događaja "Delete"

Tijelo zahtjeva događaja "delete" je objekt WebhookComment.

Promjena od 14. studenog 2023.
Prethodno je tijelo zahtjeva događaja "delete" sadržavalo samo id komentara. Sada sadrži cijeli komentar u trenutku brisanja.

Svaki ključ je uvijek prisutan u tijelu. Kada komentar nema vrijednost za neko polje, tijelo nosi null (ili false za boolean vrijednosti i [] za liste), tako da oblik isporuke nikada ne varira od komentara do komentara.

Objekt WebhookComment
Copy CopyRun External Link
1
2interface WebhookComment {
3 /** The id of the comment. **/
4 id: string
5 /** The id or URL that identifies the comment thread. Normalized. **/
6 urlId: string
7 /** The URL that points to where the comment was left. **/
8 url: string | null
9 /** The user id that left the comment. If SSO, prefixed with tenant id. **/
10 userId: string | null
11 /** The email of the user left the comment. **/
12 commenterEmail: string | null
13 /** The name of the user that shows in the comment widget. With SSO, can be displayName. **/
14 commenterName: string
15 /** Raw comment text. **/
16 comment: string
17 /** Comment text after parsing. **/
18 commentHTML: string
19 /** Comment external id. **/
20 externalId: string | null
21 /** The id of the parent comment. **/
22 parentId: string | null
23 /** The UTC date when the comment was left. **/
24 date: UTC_ISO_DateString
25 /** Combined karma (up - down) of votes. **/
26 votes: number
27 votesUp: number
28 votesDown: number
29 /** True if the user was logged in when they commented, or their verified the comment, or if they verified their session when the comment was left. **/
30 verified: boolean
31 /** The UTC date when the comment was verified. **/
32 verifiedDate: UTC_ISO_DateString | null
33 /** If a moderator marked the comment reviewed. **/
34 reviewed: boolean
35 /** The location, or base64 encoding, of the avatar. Will only be base64 if that was the value passed with SSO. **/
36 avatarSrc: string | null
37 /** Was the comment manually or automatically marked as spam? **/
38 isSpam: boolean
39 /** Was the comment automatically marked as spam? **/
40 aiDeterminedSpam: boolean
41 /** Are there images in the comment? **/
42 hasImages: boolean
43 /** The page number the comment is on for the "Most Relevant" sort direction. **/
44 pageNumber: number | null
45 /** The page number the comment is on for the "Oldest First" sort direction. **/
46 pageNumberOF: number | null
47 /** The page number the comment is on for the "Newest First" sort direction. **/
48 pageNumberNF: number | null
49 /** Was the comment approved automatically or manually? **/
50 approved: boolean
51 /** The locale code (format: en_us) of the user when the comment was written. **/
52 locale: string | null
53 /** The @mentions written in the comment that were successfully parsed. Empty when there are none. **/
54 mentions: CommentUserMention[]
55 /** The domain the comment is from. **/
56 domain: string | null
57 /** The moderation group ids associated with this comment. Empty when there are none. **/
58 moderationGroupIds: string[]
59 /** The badges shown next to the commenter's name on this comment, as of when the event was created. Empty when there are none. **/
60 badges: CommentUserBadgeInfo[]
61}
62

Kada su korisnici označeni u komentaru, informacije se pohranjuju u listu pod nazivom mentions. Svaki objekt u toj listi ima sljedeću strukturu.

Objekt Webhook Mentions
Copy CopyRun External Link
1
2interface CommentUserMention {
3 /** The user id. For SSO users, this will have your tenant id prefixed. **/
4 id: string
5 /** The final @mention tag text, including the @ symbol. **/
6 tag: string
7 /** The original @mention tag text, including the @ symbol. **/
8 rawTag: string
9 /** What type of user was tagged. user = FastComments.com account. sso = SSOUser. **/
10 type: 'user'|'sso'
11 /** If the user opts out of notifications, this will still be set to true. **/
12 sent: boolean
13}
14

Svaki unos u listi badges ima sljedeću strukturu. Pogledajte vodič za Badges za vrste bedževa.

Objekt Webhook Badge
Copy CopyRun External Link
1
2interface CommentUserBadgeInfo {
3 /** The id of the badge awarded to this user. **/
4 id: string
5 /** The badge type. **/
6 type: number
7 /** The badge description, shown when hovering over the badge. **/
8 description: string
9 /** The text shown on the badge. **/
10 displayLabel?: string | null
11 /** The image shown for the badge, if it uses one. **/
12 displaySrc?: string | null
13 backgroundColor?: string | null
14 borderColor?: string | null
15 textColor?: string | null
16 /** An extra CSS class applied to the badge. **/
17 cssClass?: string | null
18}
19

HTTP metode

Možete konfigurirati HTTP metodu za svaku vrstu webhook događaja u admin panelu:

  • Create Event: POST ili PUT (zadano: PUT)
  • Update Event: POST ili PUT (zadano: PUT)
  • Delete Event: DELETE, POST ili PUT (zadano: DELETE)

Budući da svi zahtjevi sadrže ID, operacije Create i Update su idempotentne po zadanim postavkama (PUT). Ponavljanje istog Create ili Update zahtjeva ne bi trebalo stvoriti duplicirane objekte na vašoj strani.

Zaglavlja zahtjeva

Svaki webhook zahtjev uključuje sljedeća zaglavlja:

ZaglavljeOpis
Content-Typeapplication/json
tokenVaš API Secret
X-FastComments-TimestampUnix vremenski pečat (sekunde) kada je zahtjev potpisan
X-FastComments-SignatureHMAC-SHA256 potpis (sha256=<hex>)

Pogledajte Sigurnost i API tokeni za informacije o provjeri HMAC potpisa.

Sigurnost i API tokeni Internal Link

FastComments webhook zahtjevi uključuju više mehanizama provjere autentičnosti radi sigurnosti.

Zaglavlja koja se šalju

ZaglavljeOpis
tokenVaš API Secret (za kompatibilnost unatrag)
X-FastComments-TimestampUnix vremenska oznaka (sekunde) kada je zahtjev potpisan
X-FastComments-SignatureHMAC-SHA256 potpis payloada

Verifikacija HMAC potpisa (preporučeno)

Toplo preporučujemo provjeru HMAC potpisa kako biste osigurali da su webhook podaci autentični i da nisu izmijenjeni.

Format potpisa: sha256=<hex-encoded-signature>

Kako se potpis izračunava:

  1. Spojite: timestamp + "." + JSON_payload_body
  2. Izračunajte HMAC-SHA256 koristeći svoj API Secret kao ključ
  3. Hex-kodirajte rezultat

Primjer verifikacije (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;
    }

    // Provjerite je li vremenska oznaka svježa (u roku od 5 minuta)
    const now = Math.floor(Date.now() / 1000);
    if (Math.abs(now - parseInt(timestamp, 10)) > 300) {
        return false;  // Sprječavanje replay napada
    }

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

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

Primjer verifikacije (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

    # Provjerite je li vremenska oznaka svježa
    now = int(time.time())
    if abs(now - int(timestamp)) > 300:
        return False

    # Provjerite potpis
    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}"

Primjer verifikacije (PHP)

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

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

    // Provjerite je li vremenska oznaka svježa (u roku od 5 minuta)
    $now = time();
    if (abs($now - intval($timestamp)) > 300) {
        return false;
    }

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

    return hash_equals($expectedSignature, $signature);
}

Naslijeđena autentikacija

token zaglavlje koje sadrži vaš API Secret i dalje se šalje radi kompatibilnosti unatrag. Međutim, preporučujemo prelazak na HMAC provjeru radi poboljšane sigurnosti jer štiti od replay napada.

Upravljanje webhookovima putem API-ja Internal Link

Webhooks također mogu biti upravljani putem REST API‑ja. Tako integracije poput Zapiera pretplaćuju se na događaje komentara bez dodirivanja nadzorne ploče, a slijede uzorak REST Hooks: pretplata, primanje događaja, odjava.

API pretplate koegzistiraju uz webhooks konfigurirane u nadzornoj ploči. Događaj komentara isporučuje se svakom webhooku koji odgovara njegovoj domeni, svaki kao zasebna isporuka, bez obzira kako je webhook kreiran.

Autentifikacija

Svaki zahtjev treba vaš API ključ u zaglavlju x-api-key (ili u parametru upita API_KEY) i vaš ID najamnika u parametru upita tenantId. Oba su prikazana na stranici API tajne u nadzornoj ploči.

Pretplata

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"
}
PoljeObaveznoOpis
urlDaApsolutni http ili https URL.
eventDacomment-created, comment-updated ili comment-deleted.
domainNeDomena iz konfiguracije vašeg računa. Zadano je *, što prima događaje za svaku domenu.
methodNePOST (zadano), PUT ili DELETE.

Odgovor sadrži pretplatu:

{
    "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"
    }
}

Ponovna pretplata na isti URL za isti događaj i domenu vraća postojeću pretplatu umjesto stvaranja duplikata, pa klijent može sigurno ponoviti pokušaj. Svaki najamnik može imati najviše 50 API pretplata.

Popis

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

Vraća svaki webhook za najamnika, uključujući one upravljane u nadzornoj ploči ("source": "dashboard"). Filtrirajte pomoću event, domain ili source.

Odjava

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

Brisanje pretplate također odbacuje sve događaje koji su još u redu za nju. Samo pretplate kreirane preko API‑ja mogu se izbrisati na ovaj način; webhook iz nadzorne ploče ili ID koji ne postoji u vašem računu odgovara s 404 i kodom not-found. Webhookovi iz nadzorne ploče uređuju se na stranici Webhooks.

Učitci i potpisivanje

Isporuke koriste isti učitak kao webhookovi iz nadzorne ploče (pogledajte Strukture podataka) i potpisane su istim HMAC shemom (pogledajte Sigurnost i API tokeni). API pretplate nikada ne primaju zastarjelo zaglavlje token, pa provjerite zaglavlje X-FastComments-Signature umjesto toga.

Primjeri učitaka

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

Vraća najnovije komentare računa u točnom obliku koji isporuka nosi, tako da integracija može prikazati stvarne primjere podataka prije nego prvi događaj stigne. event je opcionalan i samo se provjerava, budući da svaki događaj isporučuje isti objekt komentara. limit je zadano 3 i prihvaća vrijednosti od 1 do 10. Troši 2 API kredita.

{
    "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 s 410 Gone

Ako krajnja točka API pretplate odgovori s HTTP 410 Gone, FastComments to tretira kao odjavu: pretplata se briše zajedno s događajima u redu, a daljnje isporuke se ne pokušavaju. Webhookovi konfigurirani u nadzornoj ploči nikada se ne brišu automatski; za njih je 410 obična greška. Svaki drugi status greške se ponavlja i na kraju onemogućuje webhook, kako je opisano u Kako funkcionira i rukovanje ponovnim pokušajima.

Nadzorna ploča

API pretplate pojavljuju se u popisu Webhooks s izvorom API, gdje administrator može uređivati, onemogućiti, ponovo omogućiti ili izbrisati ih.

Zaključno

Ovim završava naša dokumentacija za Webhooks.

Nadamo se da integraciju FastComments Webhooka smatrate jednostavnom za razumijevanje i brzom za postavljanje.

Ako smatrate da ste u našoj dokumentaciji uočili neke nedostatke, javite nam u nastavku.