FastComments.com

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

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

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

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

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


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

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

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


Δοκιμές Internal Link

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

Επαλήθευση Payloads

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

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

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

Εργαλεία δοκιμών

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

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

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

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


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

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

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

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

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

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

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

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

Το σώμα του αιτήματος για το συμβάν "delete" είναι ένα αντικείμενο 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.
Το αντικείμενο 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 /** Το 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 /** Εάν ένας συντονιστής σήμανε το σχόλιο ως ελεγμένο. **/
34 reviewed: boolean
35 /** Η τοποθεσία, ή η κωδικοποίηση base64, του avatar. Θα είναι base64 μόνο αν αυτή ήταν η τιμή που δόθηκε με SSO. **/
36 avatarSrc?: string
37 /** Το σχόλιο επισημάνθηκε ως ανεπιθύμητο χειροκίνητα ή αυτόματα; **/
38 isSpam: boolean
39 /** Το σχόλιο επισημάνθηκε αυτόματα ως ανεπιθύμητο; **/
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. Κάθε αντικείμενο σε αυτή τη λίστα έχει την ακόλουθη δομή.

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

Μέθοδοι HTTP

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

  • Συμβάν Create: POST ή PUT (προεπιλογή: PUT)
  • Συμβάν Update: POST ή PUT (προεπιλογή: PUT)
  • Συμβάν Delete: DELETE, POST, ή PUT (προεπιλογή: DELETE)

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

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

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

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

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


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


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

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

Κεφαλίδα Περιγραφή
token Το API Secret σας (για συμβατότητα προς τα πίσω)
X-FastComments-Timestamp Unix timestamp (δευτερόλεπτα) όταν υπογράφηκε το αίτημα
X-FastComments-Signature HMAC-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.

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

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