FastComments.com

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

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

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

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

Υποστηριζόμενα συμβάντα και πόροι Internal Link


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

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

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


Δοκιμές Internal Link


Στο Webhooks admin υπάρχουν τα κουμπιά Send Test Payload για κάθε τύπο συμβάντος (Create, Update, Delete). Τα Create και Update συμβάντα στέλνουν ένα δοκιμαστικό αντικείμενο WebhookComment, ενώ το δοκιμαστικό για το Delete θα στείλει ένα δοκιμαστικό σώμα αιτήματος με μόνο ένα ID.

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

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

  1. token - Το μυστικό API σας
  2. X-FastComments-Timestamp - Unix χρονοσφραγίδα (δευτερόλεπτα)
  3. X-FastComments-Signature - Υπογραφή HMAC-SHA256

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

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

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

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

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

Κάθε συμβάν περιλαμβάνει τα πλήρη δεδομένα του σχολίου στο σώμα του αιτήματος (δείτε τις Δομές Δεδομένων για τη μορφή του φορτίου).


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

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

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

Η Δομή του συμβάντος "Create"

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

Η Δομή του συμβάντος "Update"

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

Η Δομή του συμβάντος "Delete"

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

Αλλαγή από 14 Νοεμβρίου 2023
Πριν, το σώμα του αιτήματος για το συμβάν "delete" περιείχε μόνο το id του σχολίου. Τώρα περιέχει ολόκληρο το σχόλιο κατά τη στιγμή της διαγραφής.
Το αντικείμενο WebhookComment
Copy CopyRun External Link
1
2interface WebhookComment {
3 /** Το id του σχολίου. **/
4 id: string
5 /** Το id ή το URL που προσδιορίζει το thread των σχολίων. Κανονικοποιημένο. **/
6 urlId: string
7 /** Το URL που δείχνει το σημείο όπου καταχώρηθηκε το σχόλιο. **/
8 url?: string
9 /** Το id του χρήστη που άφησε το σχόλιο. Αν είναι SSO, έχει προθεματισμένο το id του tenant. **/
10 userId?: string
11 /** Το email του χρήστη που άφησε το σχόλιο. **/
12 commenterEmail?: string
13 /** Το όνομα του χρήστη που εμφανίζεται στο widget σχολίων. Με SSO, μπορεί να είναι displayName. **/
14 commenterName: string
15 /** Ακατέργαστο κείμενο σχολίου. **/
16 comment: string
17 /** Κείμενο σχολίου μετά την ανάλυση/επεξεργασία. **/
18 commentHTML: string
19 /** Εξωτερικό id του σχολίου. **/
20 externalId?: string
21 /** Το id του γονικού σχολίου. **/
22 parentId?: string | null
23 /** Η ημερομηνία σε UTC όταν καταχωρήθηκε το σχόλιο. **/
24 date: UTC_ISO_DateString
25 /** Συνδυασμένο karma (up - down) των ψήφων. **/
26 votes: number
27 votesUp: number
28 votesDown: number
29 /** True αν ο χρήστης ήταν συνδεδεμένος όταν σχολίασε, ή επαλήθευσε το σχόλιο, ή αν επαλήθευσε τη συνεδρία του όταν καταχωρήθηκε το σχόλιο. **/
30 verified: boolean
31 /** Ημερομηνία κατά την οποία επαληθεύτηκε το σχόλιο. **/
32 verifiedDate?: number
33 /** Αν ένας moderator σήμανε το σχόλιο ως αναθεωρημένο. **/
34 reviewed: boolean
35 /** Η τοποθεσία, ή η base64 κωδικοποίηση, του avatar. Θα είναι base64 μόνο αν αυτή ήταν η τιμή που δόθηκε με SSO. **/
36 avatarSrc?: string
37 /** Το σχόλιο χαρακτηρίστηκε χειροκίνητα ή αυτόματα ως spam; **/
38 isSpam: boolean
39 /** Το σχόλιο χαρακτηρίστηκε αυτόματα ως spam; **/
40 aiDeterminedSpam: boolean
41 /** Υπάρχουν εικόνες στο σχόλιο; **/
42 hasImages: boolean
43 /** Ο αριθμός σελίδας στον οποίο βρίσκεται το σχόλιο για την ταξινόμηση "Most Relevant". **/
44 pageNumber: number
45 /** Ο αριθμός σελίδας για την ταξινόμηση "Oldest First". **/
46 pageNumberOF: number
47 /** Ο αριθμός σελίδας για την ταξινόμηση "Newest First". **/
48 pageNumberNF: number
49 /** Το σχόλιο εγκρίθηκε αυτόματα ή χειροκίνητα; **/
50 approved: boolean
51 /** Ο κωδικός τοπικής ρύθμισης (μορφή: en_us) του χρήστη όταν γράφτηκε το σχόλιο. **/
52 locale: string
53 /** Οι @mentions που γράφτηκαν στο σχόλιο και αναλύθηκαν επιτυχώς. **/
54 mentions?: CommentUserMention[]
55 /** Το domain από το οποίο προέρχεται το σχόλιο. **/
56 domain?: string
57 /** Η προαιρετική λίστα με τα ids των ομάδων moderation που σχετίζονται με αυτό το σχόλιο. **/
58 moderationGroupIds?: string[]|null
59}
60

Όταν οι χρήστες ετικετοποιούνται σε ένα σχόλιο, οι πληροφορίες αποθηκεύονται σε μια λίστα που ονομάζεται mentions. Κάθε αντικείμενο σε αυτή τη λίστα έχει την ακόλουθη δομή.

Το αντικείμενο Mentions του Webhook
Copy CopyRun External Link
1
2interface CommentUserMention {
3 /** Το id του χρήστη. Για χρήστες SSO, θα έχει προθεματισμένο το tenant id σας. **/
4 id: string
5 /** Το τελικό κείμενο του @mention tag, συμπεριλαμβανομένου του συμβόλου @. **/
6 tag: string
7 /** Το αρχικό κείμενο του @mention tag, συμπεριλαμβανομένου του συμβόλου @. **/
8 rawTag: string
9 /** Τι τύπος χρήστη ετικετοποιήθηκε. user = FastComments.com account. sso = SSOUser. **/
10 type: 'user'|'sso'
11 /** Αν ο χρήστης επιλέξει να μην λαμβάνει ειδοποιήσεις, αυτό θα παραμείνει ρυθμισμένο σε 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, οι λειτουργίες Create και Update είναι από προεπιλογή ιδιοδυναμικές (idempotent) (PUT). Η επανάληψη του ίδιου αιτήματος Create ή Update δεν θα πρέπει να δημιουργήσει διπλότυπα αντικείμενα στην πλευρά σας.

Επικεφαλίδες Αιτήματος

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

Επικεφαλίδα Περιγραφή
Content-Type application/json
token Your API Secret
X-FastComments-Timestamp Unix timestamp (δευτερόλεπτα) όταν υπογράφτηκε το αίτημα
X-FastComments-Signature HMAC-SHA256 υπογραφή (sha256=<hex>)

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

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


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

Αποστελλόμενες κεφαλίδες

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

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

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

Μορφή Υπογραφής: sha256=<hex-encoded-signature>

Πώς υπολογίζεται η υπογραφή:

  1. Συνένωση: timestamp + "." + JSON_payload_body
  2. Υπολογισμός HMAC-SHA256 χρησιμοποιώντας το API Secret σας ως κλειδί
  3. Κωδικοποιήστε το αποτέλεσμα σε hex

Παράδειγμα Επαλήθευσης (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;
    }

    // Verify timestamp is recent (within 5 minutes)
    const now = Math.floor(Date.now() / 1000);
    if (Math.abs(now - parseInt(timestamp, 10)) > 300) {
        return false;  // Replay attack prevention
    }

    // Verify signature
    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

    # Verify timestamp is recent
    now = int(time.time())
    if abs(now - int(timestamp)) > 300:
        return False

    # Verify signature
    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;
    }

    // Verify timestamp is recent (within 5 minutes)
    $now = time();
    if (abs($now - intval($timestamp)) > 300) {
        return false;
    }

    // Verify signature
    $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 μας.

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

Αν θεωρείτε ότι εντοπίσατε κενά στην τεκμηρίωσή μας, ενημερώστε μας παρακάτω.