FastComments.com

Уебкуки


С FastComments е възможно да се извика API endpoint всеки път, когато коментар бъде добавен, актуализиран или премахнат от нашата система.

Постигаме това с помощта на асинхронни webhooks по HTTP/HTTPS.

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


Уебхук е механизъм, или интеграция, между две системи, при която "произвеждащият" (FastComments) изпраща събитие което "потребителят" (Вие) обработва чрез API повикване.


Поддържани събития и ресурси Internal Link


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

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

Всяко от тях се счита за отделно събитие в нашата система и като такова има различна семантика и структури за уебкук събитията.

Произволен брой крайни точки могат да се абонират за едно и също събитие, от таблото или чрез API (вижте Управление на уебкуки чрез API). Всяка уебкука се доставя независимо.


Тестване 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.

Проверка на полезните данни

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

  1. X-FastComments-Timestamp - Unix времева отметка (секунди)
  2. X-FastComments-Signature - HMAC-SHA256 подпис

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.

Инструменти за тестване

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

Видове събития

  • Create Event: Задейства се, когато се създаде нов коментар.
  • Update Event: Задейства се, когато коментарът се редактира.
  • Delete Event: Задейства се, когато коментарът се изтрие.

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).

Структури от данни Internal Link

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

Структура на обекта WebhookComment

Структура на събитието "Create"

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

Структура на събитието "Update"

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

Структура на събитието "Delete"

The "delete" event request body is a 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.

Промяна от 14 ноември 2023 г.
Преди тялото на заявката за събитие "delete" съдържаше само идентификатора на коментара. Сега съдържа целия коментар към момента на изтриване.

Всеки ключ винаги присъства в тялото. Когато коментарът няма стойност за дадено поле, тялото съдържа null
(или false за булеви стойности и [] за списъци), така че формата на доставката никога не се променя от един коментар към друг.

Обектът 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}
60

Когато потребители са споменати в коментар, информацията се съхранява в списък, наречен mentions. Всеки обект в този списък
има следната структура.

Обектът 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

HTTP методи

Можете да конфигурирате HTTP метода за всеки тип уебкук събитие в администраторския панел:

  • Create Event: POST или PUT (по подразбиране: PUT)
  • Update Event: POST или PUT (по подразбиране: PUT)
  • Delete Event: DELETE, POST или PUT (по подразбиране: DELETE)

Тъй като всички заявки съдържат ID, операциите Create и Update са идемпотентни по подразбиране (PUT). Повтарянето на една и съща заявка за Create или Update не трябва да създава дублирани обекти от ваша страна.

Заглавки на заявката

Всяка уебкук заявка включва следните заглавки:

HeaderDescription
Content-Typeapplication/json
tokenВашият API Secret
X-FastComments-TimestampUnix времева отметка (секунди), когато заявката е подписана
X-FastComments-SignatureHMAC-SHA256 подпис (sha256=<hex>)

Вижте Security & API Tokens за информация относно проверката на HMAC подписа.

Сигурност и API токени Internal Link

FastComments webhook requests include multiple authentication mechanisms for security.

Изпращани заглавки

HeaderDescription
tokenВашият API Secret (за обратна съвместимост)
X-FastComments-TimestampUnix времеви печат (в секунди), когато заявката е била подписана
X-FastComments-SignatureHMAC-SHA256 подпис на полезното съдържание

Силно препоръчваме да проверявате HMAC подписа, за да се уверите, че payload-ите на webhook-ите са автентични и не са били подправяни.

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

How the signature is computed:

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

Example Verification (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}`;
}

Example Verification (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}"

Example Verification (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 атаки.

Управление на уебкуки чрез API 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.

Удостоверяване

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.

Абониране

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"
}
ПолеЗадължителноОписание
urlДаАбсолютен http или https URL.
eventДаcomment-created, comment-updated or comment-deleted.
domainНеДомейн от конфигурацията на вашия акаунт. По подразбиране е *, което получава събития за всеки домейн.
methodНеPOST (по подразбиране), 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"
    }
}

Абонирането на същия URL за същото събитие и домейн отново връ връща съществуващия абонамент, вместо да създава дубликат, така че клиентът може безопасно да опита отново. Всеки наемател може да има до 50 API абонамента.

Списък

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.

Отписване

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.

Полезни данни и подписване

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.

Примерни полезни данни

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
        }
    ]
}

Отговор с 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.

Табло

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

В заключение

Това завършва нашата документация за Webhooks.

Надяваме се, че интеграцията на FastComments Webhook е лесна за разбиране и бърза за настройване.

Ако смятате, че сте открили пропуски в нашата документация, уведомете ни по-долу.