FastComments.com


Са FastComments-ом је могуће позвати API крајњу тачку кад год се коментар дода, ажурира или уклони из нашег система.

Ово постигавамо асинхроним вебхуковима преко HTTP/HTTPS.

Шта су вебхукови Internal Link

Вебхук је механизам, или интеграција, између два система где "произвођач" (FastComments) покреће догађај који "потрошач" (Ви) прима путем API позива.

Подржани догађаји и ресурси Internal Link

FastComments подржава вебхукове само за ресурс Comment.

Подржавамо вебхукове за креирање, уклањање и ажурирање коментара.

Сваки од њих се у нашем систему сматра посебним догађајем и као такав има различиту семантику и структуру за вебхук догађаје.

Тестирање Internal Link

U Webhooks administraciji postoje dugmad Send Test Payload za svaki tip događaja (Kreiranje, Ažuriranje, Brisanje). Događaji Kreiranja i Ažuriranja šalju lažni objekat WebhookComment, dok testiranje Brisanja šalje lažno tijelo zahtjeva sa samo jednim ID-jem.

Provjera payload-ova

Prilikom testiranja vaše webhook integracije, provjerite da dolazni zahtjevi sadrže sljedeća zaglavlja:

  1. token - Vaš API tajni ključ
  2. X-FastComments-Timestamp - Unix vremenska oznaka (sekunde)
  3. X-FastComments-Signature - HMAC-SHA256 potpis

Koristite verifikaciju HMAC potpisa da biste osigurali da su payload-ovi autentični.

Alati za testiranje

Možete koristiti alate kao što su webhook.site ili ngrok da pregledate dolazne webhook payload-ove tokom razvoja.

Tipovi događaja

  • Događaj kreiranja: Okida se kada se kreira novi komentar. Zadana metoda: PUT
  • Događaj ažuriranja: Okida se kada se komentar izmijeni. Zadana metoda: PUT
  • Događaj brisanja: Okida se kada se komentar obriše. Zadana metoda: DELETE

Svaki događaj uključuje kompletne podatke komentara u tijelu zahtjeva (pogledajte Strukture podataka za format payload-a).

Структуре података Internal Link

Jedina struktura koja se šalje putem webhook-ova je objekat WebhookComment, prikazan u TypeScript-u ispod.

Struktura objekta WebhookComment

Struktura događaja "Create"

Telo zahteva za događaj "create" je objekat WebhookComment.

Struktura događaja "Update"

Telo zahteva za događaj "update" je objekat WebhookComment.

Struktura događaja "Delete"

Telo zahteva za događaj "delete" je objekat WebhookComment.

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.
Objekat WebhookComment
Copy CopyRun External Link
1
2interface WebhookComment {
3 /** ID komentara. **/
4 id: string
5 /** ID ili URL koji identifikuje nit komentara. Normalizovano. **/
6 urlId: string
7 /** URL koji pokazuje gdje je komentar ostavljen. **/
8 url?: string
9 /** ID korisnika koji je ostavio komentar. Ako je SSO, prefiksovano tenant id-jem. **/
10 userId?: string
11 /** Email korisnika koji je ostavio komentar. **/
12 commenterEmail?: string
13 /** Ime korisnika koje se prikazuje u widgetu komentara. Kod SSO, može biti displayName. **/
14 commenterName: string
15 /** Originalan tekst komentara. **/
16 comment: string
17 /** Tekst komentara nakon parsiranja. **/
18 commentHTML: string
19 /** Eksterni ID komentara. **/
20 externalId?: string
21 /** ID roditeljskog komentara. **/
22 parentId?: string | null
23 /** UTC datum kada je komentar ostavljen. **/
24 date: UTC_ISO_DateString
25 /** Kombinovana karma (za - protiv) glasova. **/
26 votes: number
27 votesUp: number
28 votesDown: number
29 /** Tačno ako je korisnik bio prijavljen kada je komentarisao, ili je verifikovao komentar, ili je verifikovao svoju sesiju kada je komentar ostavljen. **/
30 verified: boolean
31 /** Datum kada je komentar verifikovan. **/
32 verifiedDate?: number
33 /** Ako je moderator označio komentar kao pregledan. **/
34 reviewed: boolean
35 /** Lokacija, ili base64 enkodiranje avatara. Biće base64 samo ako je ta vrijednost poslana sa SSO. **/
36 avatarSrc?: string
37 /** Da li je komentar ručno ili automatski označen kao spam? **/
38 isSpam: boolean
39 /** Da li je komentar automatski označen kao spam? **/
40 aiDeterminedSpam: boolean
41 /** Da li postoje slike u komentaru? **/
42 hasImages: boolean
43 /** Broj stranice na kojoj se komentar nalazi za smer sortiranja "Most Relevant". **/
44 pageNumber: number
45 /** Broj stranice na kojoj se komentar nalazi za smer sortiranja "Oldest First". **/
46 pageNumberOF: number
47 /** Broj stranice na kojoj se komentar nalazi za smer sortiranja "Newest First". **/
48 pageNumberNF: number
49 /** Da li je komentar odobren automatski ili ručno? **/
50 approved: boolean
51 /** Kod lokala (format: en_us) korisnika kada je komentar napisan. **/
52 locale: string
53 /** @pominjanja napisana u komentaru koja su uspješno parsirana. **/
54 mentions?: CommentUserMention[]
55 /** Domen odakle je komentar. **/
56 domain?: string
57 /** Opcionalna lista ID-jeva grupa za moderaciju povezanih sa ovim komentarom. **/
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.

Objekat pomena u webhook-u
Copy CopyRun External Link
1
2interface CommentUserMention {
3 /** ID korisnika. Za SSO korisnike, biće prefiksovano vašim tenant id-jem. **/
4 id: string
5 /** Krajnji tekst @mention taga, uključujući simbol @. **/
6 tag: string
7 /** Originalni tekst @mention taga, uključujući simbol @. **/
8 rawTag: string
9 /** Koji tip korisnika je tagovan. user = FastComments.com nalog. sso = SSOUser. **/
10 type: 'user'|'sso'
11 /** Ako se korisnik odjavi od obavještenja, ovo će i dalje biti postavljeno na true. **/
12 sent: boolean
13}
14

HTTP Methods

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

  • Create Event: POST or PUT (default: PUT)
  • Update Event: POST or PUT (default: PUT)
  • Delete Event: DELETE, POST, or PUT (default: 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.

Request Headers

Each webhook request includes the following headers:

Header Description
Content-Type application/json
token Vaš API tajni ključ
X-FastComments-Timestamp Unix timestamp (sekunde) kada je zahtev potpisan
X-FastComments-Signature HMAC-SHA256 potpis (sha256=<hex>)

See Sigurnost i API tokeni for information on verifying the HMAC signature.


Безбедност и API токени Internal Link

FastComments webhook захтеви укључују више механизама аутентификације ради безбедности.

Заглавља која се шаљу

Header Description
token Ваш API Secret (ради назадне компатибилности)
X-FastComments-Timestamp Unix временска ознака (у секундама) када је захтев потписан
X-FastComments-Signature HMAC-SHA256 потпис података (payload)

Верификација HMAC потписа (препоручено)

Снажно препоручујемо верификацију HMAC потписа како бисте осигурали да су payload-ови вебхука аутентични и да нису биле измене.

Формат потписа: sha256=<hex-encoded-signature>

Како се потпис израчунава:

  1. Concatenate: timestamp + "." + JSON_payload_body
  2. Compute HMAC-SHA256 using your API Secret as the key
  3. Hex-encode the result

Пример верификације (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;
    }

    // Потврдите да је временска ознака новија (у року од 5 минута)
    const now = Math.floor(Date.now() / 1000);
    if (Math.abs(now - parseInt(timestamp, 10)) > 300) {
        return false;  // Заштита од replay напада
    }

    // Потврдите потпис
    const payload = JSON.stringify(req.body);
    const expectedSignature = crypto
        .createHmac('sha256', apiSecret)
        .update(`${timestamp}.${payload}`)
        .digest('hex');

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

Пример верификације (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

    # Потврдите да је временска ознака новија
    now = int(time.time())
    if abs(now - int(timestamp)) > 300:
        return False

    # Потврдите потпис
    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}"

Пример верификације (PHP)

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

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

    // Потврдите да је временска ознака новија (у року од 5 минута)
    $now = time();
    if (abs($now - intval($timestamp)) > 300) {
        return false;
    }

    // Потврдите потпис
    $payload = json_encode($body, JSON_UNESCAPED_SLASHES);
    $message = $timestamp . '.' . $payload;
    $expectedSignature = 'sha256=' . hash_hmac('sha256', $message, $apiSecret);

    return hash_equals($expectedSignature, $signature);
}

Наслеђе аутентификације

Хедер token који садржи ваш API Secret и даље се шаље ради назадне компатибилности. Међутим, препоручујемо миграцију на HMAC верификацију за побољшану безбедност јер штити од replay напада.

У закључку

Ово завршава нашу документацију за Webhooks.

Надамо се да ћете сматрати да је FastComments Webhook интеграција лака за разумјевање и брза за подешавање.

Ако сматрате да сте идентификовали било какве празнине у нашој документацији, обавијестите нас испод.