FastComments.com


ืขื FastComments ื ื™ืชืŸ ืœืงืจื•ื ืœื ืงื•ื“ืช ืงืฆื” ืฉืœ API ื‘ื›ืœ ืคืขื ืฉืชื’ื•ื‘ื” ืžืชื•ื•ืกืคืช, ืžืชืขื“ื›ื ืช ืื• ื ืžื—ืงืช ืžื”ืžืขืจื›ืช ืฉืœื ื•.

ืื ื• ืžืžืžืฉื™ื ื–ืืช ื‘ืืžืฆืขื•ืช webhooks ืืกื™ื ื›ืจื•ื ื™ื™ื ืขืœ ื’ื‘ื™ HTTP/HTTPS.


ืžื” ื”ื ื•ื•ื‘ึพื”ื•ืงื™ื Internal Link

Webhook ื”ื•ื ืžื ื’ื ื•ืŸ, ืื• ืื™ื ื˜ื’ืจืฆื™ื”, ื‘ื™ืŸ ืฉืชื™ ืžืขืจื›ื•ืช ืฉื‘ื” ื”"ืžืคื™ืง" (FastComments) ืฉื•ืœื— ืื™ืจื•ืข ืฉื”"ืฆืจื›ืŸ" (ืืชื”) ืฆื•ืจืš ื‘ืืžืฆืขื•ืช ืงืจื™ืืช API.

ืื™ืจื•ืขื™ื ื•ืžืฉืื‘ื™ื ื ืชืžื›ื™ื Internal Link

FastComments ืชื•ืžื›ืช ื‘-webhooks ืจืง ื‘ืžืฉืื‘ Comment.

ืื ื• ืชื•ืžื›ื™ื ื‘-webhooks ืขื‘ื•ืจ ื™ืฆื™ืจืช Comment, ื”ืกืจื” ื•ืขื“ ืขื“ื›ื•ืŸ.

ื›ืœ ืื—ื“ ืžื”ื ื ื—ืฉื‘ ืœืื™ืจื•ืข ื ืคืจื“ ื‘ืžืขืจื›ืช ืฉืœื ื• ื•ืœื›ืŸ ื™ืฉ ืœื• ืกืžื ื˜ื™ืงื” ืฉื•ื ื” ื•ืžื‘ื ื™ื ืฉื•ื ื™ื ืขื‘ื•ืจ ืื™ืจื•ืขื™ webhook.

ื‘ื“ื™ืงื•ืช Internal Link

ื‘ืžืžืฉืง ื”ื ื™ื”ื•ืœ ืฉืœ Webhooks ื™ืฉ ื›ืคืชื•ืจื™ Send Test Payload ืขื‘ื•ืจ ื›ืœ ืกื•ื’ ืื™ืจื•ืข (Create, Update, Delete). ืื™ืจื•ืขื™ Create ื•-Update ืฉื•ืœื—ื™ื ืื•ื‘ื™ื™ืงื˜ WebhookComment ืžื“ื•ืžื”, ื‘ืขื•ื“ ืฉื‘ื“ื™ืงืช Delete ืชืฉืœื— ื’ื•ืฃ ื‘ืงืฉื” ืžื“ื•ืžื” ืขื ืžื–ื”ื” ื‘ืœื‘ื“.

ืื™ืžื•ืช ื”ืžื˜ืขื ื™ื

ื‘ืขืช ื‘ื“ื™ืงืช ืื™ื ื˜ื’ืจืฆื™ื™ืช ื”-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" ื”ื›ื™ืœ ืจืง ืืช ืžื–ื”ื” ื”ื”ืขืจื”. ื›ืขืช ื”ื•ื ืžื›ื™ืœ ืืช ื”ื”ืขืจื” ื”ืžืœืื” ื‘ื–ืžืŸ ื”ืžื—ื™ืงื”.
ืื•ื‘ื™ื™ืงื˜ WebhookComment
Copy CopyRun External Link
1
2interface WebhookComment {
3 /** ื”ืžื–ื”ื” ืฉืœ ื”ื”ืขืจื”. **/
4 id: string
5 /** ื”ืžื–ื”ื” ืื• ื”-URL ืฉืžื–ื”ื” ืืช ืฉืจืฉื•ืจ ื”ื”ืขืจื•ืช. ืžื ื•ืจืžืœ. **/
6 urlId: string
7 /** ื”-URL ืฉืžืฆื‘ื™ืข ืขืœ ื”ืžืงื•ื ืฉื‘ื• ื”ื•ืฉืืจื” ื”ื”ืขืจื”. **/
8 url?: string
9 /** ื”ืžื–ื”ื” ืฉืœ ื”ืžืฉืชืžืฉ ืฉื”ืฉืื™ืจ ืืช ื”ื”ืขืจื”. ืื SSO, ืžืงื“ื™ื ืื•ืชื• ื‘-tenant id. **/
10 userId?: string
11 /** ื”ื“ื•ื"ืœ ืฉืœ ื”ืžืฉืชืžืฉ ืฉื”ืฉืื™ืจ ืืช ื”ื”ืขืจื”. **/
12 commenterEmail?: string
13 /** ื”ืฉื ืฉืœ ื”ืžืฉืชืžืฉ ืฉืžื•ืฆื’ ื‘ื•ื•ื™ื“ื’'ื˜ ื”ื”ืขืจื•ืช. ืขื SSO, ื™ื›ื•ืœ ืœื”ื™ื•ืช displayName. **/
14 commenterName: string
15 /** ื”ื˜ืงืกื˜ ื”ื’ื•ืœืžื™ ืฉืœ ื”ื”ืขืจื”. **/
16 comment: string
17 /** ื”ื˜ืงืกื˜ ืฉืœ ื”ื”ืขืจื” ืœืื—ืจ ื ื™ืชื•ื—. **/
18 commentHTML: string
19 /** ืžื–ื”ื” ื—ื™ืฆื•ื ื™ ืฉืœ ื”ื”ืขืจื”. **/
20 externalId?: string
21 /** ื”ืžื–ื”ื” ืฉืœ ื”ื”ืขืจื” ื”ืื‘. **/
22 parentId?: string | null
23 /** ื”ืชืืจื™ืš ื‘-UTC ื›ืืฉืจ ื”ื•ืฉืืจื” ื”ื”ืขืจื”. **/
24 date: UTC_ISO_DateString
25 /** ื”ืงืืจืžื” ื”ืžืฉื•ืœื‘ืช (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, ืฉืœ ื”ืื•ื•ื˜ืืจ. ื™ื”ื™ื” base64 ืจืง ืื ื–ื” ื”ืขืจืš ืฉื ืฉืœื— ืขื SSO. **/
36 avatarSrc?: string
37 /** ื”ืื ื”ื”ืขืจื” ืกื•ืžื ื” ื›ืกืคืื ื‘ืื•ืคืŸ ื™ื“ื ื™ ืื• ืื•ื˜ื•ืžื˜ื™? **/
38 isSpam: boolean
39 /** ื”ืื ื”ื”ืขืจื” ืกื•ืžื ื” ื›ืกืคืื ื‘ืื•ืคืŸ ืื•ื˜ื•ืžื˜ื™? **/
40 aiDeterminedSpam: boolean
41 /** ื”ืื ื™ืฉ ืชืžื•ื ื•ืช ื‘ื”ืขืจื”? **/
42 hasImages: boolean
43 /** ืžืกืคืจ ื”ืขืžื•ื“ ืฉื‘ื• ื ืžืฆืืช ื”ื”ืขืจื” ืขื‘ื•ืจ ื›ื™ื•ื•ืŸ ื”ืžื™ื•ืŸ "ื”ื›ื™ ืจืœื•ื•ื ื˜ื™". **/
44 pageNumber: number
45 /** ืžืกืคืจ ื”ืขืžื•ื“ ืฉื‘ื• ื ืžืฆืืช ื”ื”ืขืจื” ืขื‘ื•ืจ ื›ื™ื•ื•ืŸ ื”ืžื™ื•ืŸ "ื”ื™ืฉื ื™ื ื‘ื™ื•ืชืจ ืชื—ื™ืœื”". **/
46 pageNumberOF: number
47 /** ืžืกืคืจ ื”ืขืžื•ื“ ืฉื‘ื• ื ืžืฆืืช ื”ื”ืขืจื” ืขื‘ื•ืจ ื›ื™ื•ื•ืŸ ื”ืžื™ื•ืŸ "ื”ื—ื“ืฉื™ื ื‘ื™ื•ืชืจ ืชื—ื™ืœื”". **/
48 pageNumberNF: number
49 /** ื”ืื ื”ื”ืขืจื” ืื•ืฉืจื” ื‘ืื•ืคืŸ ืื•ื˜ื•ืžื˜ื™ ืื• ื™ื“ื ื™? **/
50 approved: boolean
51 /** ืงื•ื“ ื”ืฉืคื”/ืœื•ืงืœ (ืคื•ืจืžื˜: en_us) ืฉืœ ื”ืžืฉืชืžืฉ ื›ืืฉืจ ื ื›ืชื‘ื” ื”ื”ืขืจื”. **/
52 locale: string
53 /** ื”-@mentions ืฉื ื›ืชื‘ื• ื‘ื”ืขืจื” ื•ื ื•ืชื—ื• ื‘ื”ืฆืœื—ื”. **/
54 mentions?: CommentUserMention[]
55 /** ื”ื“ื•ืžื™ื™ืŸ ืฉืžืžื ื• ื”ื”ืขืจื”. **/
56 domain?: string
57 /** ืจืฉื™ืžื” ืื•ืคืฆื™ื•ื ืœื™ืช ืฉืœ ืžื–ื”ื™ ืงื‘ื•ืฆื•ืช ื”ืžื•ื“ืจืฆื™ื” ื”ืžืฉื•ื™ื›ื™ื ืœื”ืขืจื” ื–ื•. **/
58 moderationGroupIds?: string[]|null
59}
60

ื›ืืฉืจ ืžืฉืชืžืฉื™ื ืžืชื•ื™ื™ื’ื™ื ื‘ื”ืขืจื”, ื”ืžื™ื“ืข ืžืื•ื—ืกืŸ ื‘ืจืฉื™ืžื” ืฉื ืงืจืืช mentions. ื›ืœ ืื•ื‘ื™ื™ืงื˜ ื‘ืจืฉื™ืžื” ื–ื• ื™ืฉ ืืช ื”ืžื‘ื ื” ื”ื‘ื.

ืื•ื‘ื™ื™ืงื˜ ื”ื–ื›ืจืช ืžืฉืชืžืฉื™ื ืฉืœ Webhook
Copy CopyRun External Link
1
2interface CommentUserMention {
3 /** ืžื–ื”ื” ื”ืžืฉืชืžืฉ. ืขื‘ื•ืจ ืžืฉืชืžืฉื™ SSO, ื™ื”ื™ื” ืžืงื•ื“ื ื‘-tenant id ืฉืœื›ื. **/
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 Event: POST ืื• PUT (ื‘ืจื™ืจืช ืžื—ื“ืœ: PUT)
  • Update Event: POST ืื• PUT (ื‘ืจื™ืจืช ืžื—ื“ืœ: PUT)
  • Delete Event: DELETE, POST, ืื• PUT (ื‘ืจื™ืจืช ืžื—ื“ืœ: DELETE)

ืžื›ื™ื•ื•ืŸ ืฉื›ืœ ื”ื‘ืงืฉื•ืช ืžื›ื™ืœื•ืช ืžื–ื”ื”, ืคืขื•ืœื•ืช Create ื•-Update ื”ืŸ ืื™ื“ืžื•ืคื˜ื ื˜ื™ื•ืช ื›ื‘ืจื™ืจืช ืžื—ื“ืœ (PUT). ื—ื–ืจื” ืขืœ ืื•ืชื” ื‘ืงืฉืช Create ืื• Update ืœื ืืžื•ืจื” ืœื™ืฆื•ืจ ืขืฆืžื™ื ื›ืคื•ืœื™ื ืืฆืœื›ื.

ื›ื•ืชืจื•ืช ื‘ืงืฉื”

ื›ืœ ื‘ืงืฉืช webhook ื›ื•ืœืœืช ืืช ื”ื›ื•ืชืจื•ืช ื”ื‘ืื•ืช:

Header ืชื™ืื•ืจ
Content-Type application/json
token ืกื•ื“ ื”-API ืฉืœืš
X-FastComments-Timestamp ื—ื•ืชืžืช ื–ืžืŸ ืฉืœ Unix (ืฉื ื™ื•ืช) ื›ืืฉืจ ื”ื‘ืงืฉื” ื ื—ืชืžื”
X-FastComments-Signature ื—ืชื™ืžืช HMAC-SHA256 (sha256=<hex>)

ืจืื• ืื‘ื˜ื—ื” ื•ื˜ื•ืงื ื™ื ืฉืœ API ืœืžื™ื“ืข ืขืœ ืื™ืžื•ืช ื—ืชื™ืžืช HMAC.

ืื‘ื˜ื—ื” ื•ืืกื™ืžื•ื ื™ API Internal Link

FastComments webhook requests include multiple authentication mechanisms for security.

Headers Sent

Header Description
token Your API Secret (for backwards compatibility)
X-FastComments-Timestamp Unix timestamp (seconds) when the request was signed
X-FastComments-Signature HMAC-SHA256 signature of the payload

We strongly recommend verifying the HMAC signature to ensure webhook payloads are authentic and haven't been tampered with.

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);
}

Legacy Authentication

The token header containing your API Secret is still sent for backwards compatibility. However, we recommend migrating to HMAC verification for improved security as it protects against replay attacks.


ืœืกื™ื›ื•ื

ื–ื” ืžืกื™ื™ื ืืช ืชื™ืขื•ื“ ื”-Webhooks ืฉืœื ื•.

ืื ื• ืžืงื•ื•ื™ื ืฉืชืžืฆืื• ืืช ืื™ื ื˜ื’ืจืฆื™ื™ืช ื”-Webhook ืฉืœ FastComments ืงืœื” ืœื”ื‘ื ื” ื•ืžื”ื™ืจื” ืœื”ืงืžื”.

ืื ืืชื ืžืจื’ื™ืฉื™ื ืฉื–ื™ื”ื™ืชื ื—ื•ืกืจื™ื ื‘ืชื™ืขื•ื“ ืฉืœื ื•, ื”ื•ื“ื™ืขื• ืœื ื• ืœืžื˜ื”.