FastComments.com

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

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

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

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

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


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

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

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


Δοκιμές Internal Link

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

Επαλήθευση Payloads

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

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

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

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

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

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

  • Συμβάν Δημιουργίας: Εκκινείται όταν δημιουργείται νέο σχόλιο. Προεπιλεγμένη μέθοδος: PUT
  • Συμβάν Ενημέρωσης: Εκκινείται όταν ένα σχόλιο επεξεργάζεται. Προεπιλεγμένη μέθοδος: PUT
  • Συμβάν Διαγραφής: Εκκινείται όταν ένα σχόλιο διαγράφεται. Προεπιλεγμένη μέθοδος: DELETE

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

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

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

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

The "Create" Event Structure

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

The "Update" Event Structure

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

The "Delete" Event Structure

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

Αλλαγή από 14 Νοεμβρίου 2023
Προηγουμένως, το σώμα του αιτήματος για το event "delete" περιείχε μόνο το id του σχολίου. Τώρα περιέχει ολόκληρο το σχόλιο τη στιγμή της διαγραφής.
Το Αντικείμενο WebhookComment
Copy CopyRun External Link
1
2interface WebhookComment {
3 /** Το id του σχολίου. **/
4 id: string
5 /** Το id ή το URL που προσδιορίζει το νήμα σχολίων. Κανονικοποιημένο. **/
6 urlId: string
7 /** Το URL που δείχνει πού γράφτηκε το σχόλιο. **/
8 url?: string
9 /** Το user id που άφησε το σχόλιο. Αν είναι SSO, έχει προθεματισμένο το tenant id. **/
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 /** Ο κωδικός locale (μορφή: en_us) του χρήστη όταν το σχόλιο γράφτηκε. **/
52 locale: string
53 /** Οι @mentions που γράφτηκαν στο σχόλιο και επεξεργάστηκαν επιτυχώς. **/
54 mentions?: CommentUserMention[]
55 /** Το domain από το οποίο προέρχεται το σχόλιο. **/
56 domain?: string
57 /** Η προαιρετική λίστα με moderation group ids που σχετίζονται με αυτό το σχόλιο. **/
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.

Το Αντικείμενο Mentions του Webhook
Copy CopyRun External Link
1
2interface CommentUserMention {
3 /** Το user id. Για χρήστες SSO, αυτό θα έχει προθεματισμένο το tenant id σας. **/
4 id: string
5 /** Το τελικό κείμενο του @mention tag, συμπεριλαμβανομένου του συμβόλου @. **/
6 tag: string
7 /** Το αρχικό κείμενο του @mention tag, συμπεριλαμβανομένου του συμβόλου @. **/
8 rawTag: string
9 /** Τι τύπος χρήστη επισημάνθηκε. user = λογαριασμός FastComments.com. sso = SSOUser. **/
10 type: 'user'|'sso'
11 /** Ακόμη και αν ο χρήστης έχει απενεργοποιήσει τις ειδοποιήσεις, αυτό θα παραμένει true. **/
12 sent: boolean
13}
14

Μέθοδοι HTTP

Μπορείτε να ρυθμίσετε τη μέθοδο HTTP για κάθε τύπο event webhook στο admin panel:

  • 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 Το 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 εύκολη στην κατανόηση και γρήγορη στη ρύθμιση.

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