FastComments.com

Webhooks

Με το FastComments είναι δυνατό να κληθεί ένα API endpoint κάθε φορά που ένα σχόλιο προστίθεται, ενημερώνεται ή αφαιρείται από το σύστημά μας.

Αυτό το επιτυγχάνουμε με ασύγχρονα webhooks μέσω HTTP/HTTPS.

Τι είναι τα Webhooks Internal Link

Ένα Webhook είναι ένας μηχανισμός, ή μια ενσωμάτωση, μεταξύ δύο συστημάτων όπου ο "παραγωγός" (FastComments) πυροδοτεί ένα συμβάν που ο "καταναλωτής" (Εσείς) καταναλώνει μέσω κλήσης API.

Υποστηριζόμενα Γεγονότα & Πόροι Internal Link


Το FastComments υποστηρίζει webhooks μόνο για τον πόρο Comment.

Υποστηρίζουμε webhooks για τη δημιουργία, την αφαίρεση και την ενημέρωση σχολίων.

Κάθε ένα από αυτά θεωρείται ξεχωριστό γεγονός στο σύστημά μας και ως εκ τούτου έχει διαφορετική σημασιολογία και δομή για τα γεγονότα webhook.

Οποιοσδήποτε αριθμός τελικών σημείων μπορεί να εγγραφεί στο ίδιο γεγονός, είτε από τον πίνακα ελέγχου είτε μέσω του API (δείτε τη Διαχείριση Webhooks μέσω του API). Κάθε webhook παραδίδεται ανεξάρτητα.


Δοκιμή Internal Link

Οι νέες και οι σελίδες επεξεργασίας webhook διαθέτουν ένα κουμπί Send Test Payload που στέλνει ένα αίτημα στη διεύθυνση URL που βρίσκεται αυτή τη στιγμή στη φόρμα, ανεξάρτητα από το αν έχει αποθηκευτεί. Τα γεγονότα Create και Update στέλνουν ένα ψεύτικο αντικείμενο WebhookComment, ενώ η δοκιμή Delete θα στείλει ένα ψεύτικο σώμα αιτήματος με μόνο ένα ID.

Επαλήθευση Φορτίων

Κατά τη δοκιμή της ενσωμάτωσης webhook, επαληθεύστε ότι τα εισερχόμενα αιτήματα περιλαμβάνουν τις ακόλουθες κεφαλίδες:

  1. X-FastComments-Timestamp - Χρονική σήμανση Unix (δευτερόλεπτα)
  2. X-FastComments-Signature - Υπογραφή HMAC-SHA256

Τα webhooks που δημιουργήθηκαν πριν εισαχθεί το σχήμα υπογραφής λαμβάνουν επίσης μια κεφαλίδα token που περιέχει το API Secret σας. Τα νέα webhooks δεν το κάνουν.

Χρησιμοποιήστε την επαλήθευση υπογραφής HMAC για να διασφαλίσετε ότι τα φορτία είναι αυθεντικά.

Εργαλεία Δοκιμής

Μπορείτε να χρησιμοποιήσετε εργαλεία όπως το webhook.site ή το ngrok για να ελέγξετε τα εισερχόμενα φορτία webhook κατά την ανάπτυξη.

Τύποι Συμβάντων

  • Create Event: Ενεργοποιείται όταν δημιουργείται ένα νέο σχόλιο.
  • Update Event: Ενεργοποιείται όταν ένα σχόλιο επεξεργάζεται.
  • Delete Event: Ενεργοποιείται όταν ένα σχόλιο διαγράφεται.

Κάθε webhook συνδέεται με ένα γεγονός και μία μέθοδο HTTP (POST, PUT ή DELETE). Κάθε γεγονός περιλαμβάνει τα πλήρη δεδομένα του σχολίου στο σώμα του αιτήματος (δείτε το Data Structures για τη μορφή του φορτίου).


Δομές Δεδομένων Internal Link

Η μόνη δομή που αποστέλλεται μέσω webhooks είναι το αντικείμενο WebhookComment, περιγραφόμενο σε TypeScript παρακάτω.

Η Δομή του Αντικειμένου WebhookComment

Η Δομή του Γεγονότος "Create"

Το σώμα του αιτήματος του γεγονότος "create" είναι ένα αντικείμενο WebhookComment.

Η Δομή του Γεγονότος "Update"

Το σώμα του αιτήματος του γεγονότος "update" είναι ένα αντικείμενο WebhookComment.

Η Δομή του Γεγονότος "Delete"

Το σώμα του αιτήματος του γεγονότος "delete" είναι ένα αντικείμενο WebhookComment.

Αλλαγή από 14 Νοεμβρίου 2023
Πριν, το σώμα του αιτήματος του γεγονότος "delete" περιείχε μόνο το id του σχολίου. Τώρα περιέχει ολόκληρο το σχόλιο τη στιγμή της διαγραφής.

Κάθε κλειδί είναι πάντα παρόν στο σώμα. Όταν το σχόλιο δεν έχει τιμή για ένα πεδίο, το σώμα μεταφέρει nullfalse για boolean και [] για λίστες), έτσι η δομή μιας παράδοσης δεν διαφέρει ποτέ από ένα σχόλιο στο άλλο.

Το Αντικείμενο 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
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 για κάθε τύπο γεγονότος webhook στον πίνακα διαχείρισης:

  • Create Event: POST ή PUT (προεπιλογή: PUT)
  • Update Event: POST ή PUT (προεπιλογή: PUT)
  • Delete Event: DELETE, POST ή PUT (προεπιλογή: DELETE)

Δεδομένου ότι όλα τα αιτήματα περιέχουν ένα ID, οι λειτουργίες Δημιουργίας και Ενημέρωσης είναι ιδεομερείς από προεπιλογή (PUT). Η επανάληψη του ίδιου αιτήματος Δημιουργίας ή Ενημέρωσης δεν πρέπει να δημιουργεί διπλότυπα αντικείμενα από την πλευρά σας.

Κεφαλίδες Αιτήματος

Κάθε αίτημα webhook περιλαμβάνει τις ακόλουθες κεφαλίδες:

HeaderDescription
Content-Typeapplication/json
tokenΤο Μυστικό API σας
X-FastComments-TimestampΧρονική σήμανση Unix (δευτερόλεπτα) όταν υπογράφηκε το αίτημα
X-FastComments-SignatureΥπογραφή HMAC‑SHA256 (sha256=<hex>)

Δείτε το Ασφάλεια & Διακριτικά API για πληροφορίες σχετικά με την επαλήθευση της υπογραφής HMAC.

Ασφάλεια & Διακριτικά API Internal Link


Τα αιτήματα webhook του FastComments περιλαμβάνουν πολλούς μηχανισμούς πιστοποίησης για λόγους ασφάλειας.

Κεφαλίδες που αποστέλλονται

ΚεφαλίδαΠεριγραφή
tokenΤο API Secret σας (για συμβατότητα προς τα πίσω)
X-FastComments-TimestampUnix timestamp (δευτερόλεπτα) όταν υπογράφηκε το αίτημα
X-FastComments-SignatureHMAC-SHA256 υπογραφή του payload

Επαλήθευση Υπογραφής HMAC (Συνιστάται)

Συνιστούμε θερμά την επαλήθευση της υπογραφής HMAC για να διασφαλίσετε ότι τα payloads των webhook είναι αυθεντικά και δεν έχουν παραποιηθεί.

Signature Format: 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;
    }

    // Επαλήθευση ότι το timestamp είναι πρόσφατο (εντός 5 λεπτών)
    const now = Math.floor(Date.now() / 1000);
    if (Math.abs(now - parseInt(timestamp, 10)) > 300) {
        return false;  // Πρόληψη επίθεσης επανάληψης
    }

    // Επαλήθευση υπογραφής
    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

    # Επαλήθευση ότι το timestamp είναι πρόσφατο
    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;
    }

    // Επαλήθευση ότι το timestamp είναι πρόσφατο (εντός 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 για βελτιωμένη ασφάλεια καθώς προστατεύει από επιθέσεις επανάληψης.


Διαχείριση Webhooks μέσω του 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ΝαιΈνα απόλυτο URL http ή https.
eventΝαιcomment-created, comment-updated ή comment-deleted.
domainΌχιΈνα domain από τη ρύθμιση λογαριασμού σας. Προεπιλογή είναι *, που λαμβάνει συμβάντα για κάθε domain.
methodΌχιPOST (προεπιλογή), PUT ή 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.

Λίστα

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.

Ελπίζουμε να βρείτε την ενσωμάτωση Webhook του FastComments εύκολη στην κατανόηση και γρήγορη στη ρύθμιση.

Εάν πιστεύετε ότι έχετε εντοπίσει κενά στην τεκμηρίωσή μας, ενημερώστε μας παρακάτω.