FastComments.com

Webhooks


FastComments ile sistemimizde bir yorum eklendiğinde, güncellendiğinde veya kaldırıldığında bir API endpoint'i çağırmak mümkündür.

Bunu HTTP/HTTPS üzerinden asenkron webhooks ile gerçekleştiriyoruz.


Webhooks Nedir Internal Link


Webhook, iki sistem arasında bir mekanizma veya entegrasyon olup "üretici" (FastComments) bir olay tetikler ve "tüketici" (Siz) bu olayı bir API çağrısı ile tüketir.


Desteklenen Olaylar ve Kaynaklar Internal Link


FastComments yalnızca Yorum kaynağı için webhook'ları destekler.

Yorum oluşturma, silme ve güncelleme için webhook'ları destekliyoruz.

Bunların her biri sistemimizde ayrı olaylar olarak kabul edilir ve bu nedenle webhook olayları için farklı anlamlar ve yapılar içerir.

Dashboard'dan veya API üzerinden (API aracılığıyla Webhook'ları Yönetmeye bakın) aynı olaya birden fazla uç nokta abone olabilir. Her webhook bağımsız olarak teslim edilir.


Test Internal Link

The new and edit webhook pages have a Send Test Payload button that sends a request to the URL currently in the form, whether or not it has been saved. The Create and Update events send a dummy WebhookComment object, while testing Delete will send a dummy request body with just an ID.

Payload'ları Doğrulama

When testing your webhook integration, verify the incoming requests include the following headers:

  1. X-FastComments-Timestamp - Unix timestamp (seconds)
  2. X-FastComments-Signature - HMAC-SHA256 signature

Webhooks created before the signature scheme was introduced also receive a token header containing your API Secret. New webhooks do not.

Use the HMAC signature verification to ensure payloads are authentic.

Test Araçları

You can use tools like webhook.site or ngrok to inspect incoming webhook payloads during development.

Olay Türleri

  • Create Event: Triggered when a new comment is created.
  • Update Event: Triggered when a comment is edited.
  • Delete Event: Triggered when a comment is deleted.

Each webhook is tied to one event and one HTTP method (POST, PUT or DELETE). Each event includes the full comment data in the request body (see Data Structures for the payload format).

Veri Yapıları Internal Link

Webhooks aracılığıyla gönderilen tek yapı, aşağıda TypeScript ile açıklanan WebhookComment nesnesidir.

WebhookComment Nesne Yapısı

"Create" Olayı Yapısı

"create" olayı isteği gövdesi bir WebhookComment nesnesidir.

"Update" Olayı Yapısı

"update" olayı isteği gövdesi bir WebhookComment nesnesidir.

"Delete" Olayı Yapısı

"delete" olayı isteği gövdesi bir WebhookComment nesnesidir.

Değişiklik 14 Kasım 2023 tarihinden itibaren
Daha önce "delete" olayı isteği gövdesi yalnızca yorum kimliğini içeriyordu. Şimdi silme anındaki tam yorumu içeriyor.

Gövde içinde her anahtar her zaman bulunur. Yorum bir alan için değere sahip olmadığında gövde null (veya booleans için false ve listeler için []) taşır, böylece teslimatın şekli bir yorumdan diğerine asla değişmez.

WebhookComment Nesnesi
Copy CopyRun External Link
1
2interface WebhookComment {
3 /** Yorumun kimliği. **/
4 id: string
5 /** Yorum dizisini tanımlayan kimlik veya URL. Normalleştirilmiş. **/
6 urlId: string
7 /** Yorumun bırakıldığı yeri gösteren URL. **/
8 url: string | null
9 /** Yorumu bırakan kullanıcının kimliği. SSO ise, tenant kimliğiyle ön eklenir. **/
10 userId: string | null
11 /** Yorumu bırakan kullanıcının e-posta adresi. **/
12 commenterEmail: string | null
13 /** Yorum widget'ında gösterilen kullanıcının adı. SSO ile, displayName olabilir. **/
14 commenterName: string
15 /** Ham yorumun metni. **/
16 comment: string
17 /** Ayrıştırma sonrası yorum metni. **/
18 commentHTML: string
19 /** Yorumun dış kimliği. **/
20 externalId: string | null
21 /** Üst yorumun kimliği. **/
22 parentId: string | null
23 /** Yorumun bırakıldığı UTC tarih. **/
24 date: UTC_ISO_DateString
25 /** Oyların birleşik karması (yukarı - aşağı). **/
26 votes: number
27 votesUp: number
28 votesDown: number
29 /** Kullanıcı yorum yaptığında oturum açmışsa, yorumu doğrulamışsa veya yorum bırakıldığında oturumu doğrulamışsa true. **/
30 verified: boolean
31 /** Yorumun doğrulandığı UTC tarih. **/
32 verifiedDate: UTC_ISO_DateString | null
33 /** Bir moderatör yorumun incelendiğini işaretlediyse. **/
34 reviewed: boolean
35 /** Avatarın konumu veya base64 kodlaması. SSO ile gönderilen değer base64 ise sadece base64 olur. **/
36 avatarSrc: string | null
37 /** Yorum manuel veya otomatik olarak spam olarak işaretlendi mi? **/
38 isSpam: boolean
39 /** Yorum otomatik olarak spam olarak işaretlendi mi? **/
40 aiDeterminedSpam: boolean
41 /** Yorumda resimler var mı? **/
42 hasImages: boolean
43 /** "Most Relevant" sıralama yönü için yorumun bulunduğu sayfa numarası. **/
44 pageNumber: number | null
45 /** "Oldest First" sıralama yönü için yorumun bulunduğu sayfa numarası. **/
46 pageNumberOF: number | null
47 /** "Newest First" sıralama yönü için yorumun bulunduğu sayfa numarası. **/
48 pageNumberNF: number | null
49 /** Yorum otomatik veya manuel olarak onaylandı mı? **/
50 approved: boolean
51 /** Yorum yazıldığında kullanıcının yerel kodu (format: en_us). **/
52 locale: string | null
53 /** Yorumda yazılan ve başarıyla ayrıştırılan @mentions. Hiçbiri yoksa boş. **/
54 mentions: CommentUserMention[]
55 /** Yorumun geldiği domain. **/
56 domain: string | null
57 /** Bu yorumla ilişkili moderasyon grup kimlikleri. Hiçbiri yoksa boş. **/
58 moderationGroupIds: string[]
59}
60

Kullanıcılar bir yorumda etiketlendiğinde, bilgi mentions adlı bir listede saklanır. Bu listedeki her nesnenin yapısı aşağıdaki gibidir.

Webhook Mentions Nesnesi
Copy CopyRun External Link
1
2interface CommentUserMention {
3 /** Kullanıcı kimliği. SSO kullanıcıları için tenant kimliği ön eklenir. **/
4 id: string
5 /** Son @mention etiket metni, @ sembolü dahil. **/
6 tag: string
7 /** Orijinal @mention etiket metni, @ sembolü dahil. **/
8 rawTag: string
9 /** Etiketlenen kullanıcının tipi. user = FastComments.com hesabı. sso = SSOUser. **/
10 type: 'user'|'sso'
11 /** Kullanıcı bildirimlerden çıkmayı seçse bile, bu değer true olarak ayarlanır. **/
12 sent: boolean
13}
14

HTTP Yöntemleri

Her webhook olay türü için HTTP yöntemini yönetim panelinde yapılandırabilirsiniz:

  • Create Olayı: POST veya PUT (varsayılan: PUT)
  • Update Olayı: POST veya PUT (varsayılan: PUT)
  • Delete Olayı: DELETE, POST veya PUT (varsayılan: DELETE)

Tüm istekler bir ID içerdiğinden, Create ve Update işlemleri varsayılan olarak (PUT) idempotenttir. Aynı Create veya Update isteğini tekrarlamak, tarafınızda yinelenen nesneler oluşturmaz.

İstek Başlıkları

Her webhook isteği aşağıdaki başlıkları içerir:

HeaderDescription
Content-Typeapplication/json
tokenAPI Gizliniz
X-FastComments-Timestampİsteğin imzalandığı Unix zaman damgası (saniye)
X-FastComments-SignatureHMAC-SHA256 imzası (sha256=<hex>)

HMAC imzasını doğrulama hakkında bilgi için Security & API Tokens sayfasına bakın.

Güvenlik ve API Token'ları Internal Link

FastComments webhook istekleri güvenlik için birden fazla kimlik doğrulama mekanizması içerir.

Gönderilen Başlıklar

HeaderAçıklama
tokenAPI Gizli Anahtarınız (geriye dönük uyumluluk için)
X-FastComments-Timestampİsteğin imzalandığı Unix zaman damgası (saniye)
X-FastComments-SignatureGönderinin HMAC-SHA256 imzası

HMAC İmza Doğrulaması (Önerilen)

Webhook gönderilerinin orijinal ve değiştirilmemiş olduğunu sağlamak için HMAC imzasını doğrulamanızı şiddetle tavsiye ederiz.

İmza Formatı: sha256=<hex-encoded-signature>

İmzanın nasıl hesaplandığı:

  1. Birleştir: timestamp + "." + JSON_payload_body
  2. Anahtar olarak API Gizli Anahtarınızı kullanarak HMAC-SHA256 hesaplayın
  3. Sonucu hexadecimal (hex) olarak kodlayın

Doğrulama Örneği (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;
    }

    // Zaman damgasının güncel olduğunu doğrula (5 dakika içinde)
    const now = Math.floor(Date.now() / 1000);
    if (Math.abs(now - parseInt(timestamp, 10)) > 300) {
        return false;  // Tekrar oynatma (replay) saldırılarını önlemek için
    }

    // İmzayı doğrula
    const payload = JSON.stringify(req.body);
    const expectedSignature = crypto
        .createHmac('sha256', apiSecret)
        .update(`${timestamp}.${payload}`)
        .digest('hex');

    return signature === `sha256=${expectedSignature}`;
}

Doğrulama Örneği (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

    # Zaman damgasının güncel olduğunu doğrula
    now = int(time.time())
    if abs(now - int(timestamp)) > 300:
        return False

    # İmzayı doğrula
    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}"

Doğrulama Örneği (PHP)

function verifyWebhookSignature($headers, $body, $apiSecret) {
    $timestamp = $headers['X-FastComments-Timestamp'] ?? null;
    $signature = $headers['X-FastComments-Signature'] ?? null;

    if (!$timestamp || !$signature) {
        return false;
    }

    // Zaman damgasının güncel olduğunu doğrula (5 dakika içinde)
    $now = time();
    if (abs($now - intval($timestamp)) > 300) {
        return false;
    }

    // İmzayı doğrula
    $payload = json_encode($body, JSON_UNESCAPED_SLASHES);
    $message = $timestamp . '.' . $payload;
    $expectedSignature = 'sha256=' . hash_hmac('sha256', $message, $apiSecret);

    return hash_equals($expectedSignature, $signature);
}

Eski Kimlik Doğrulama

token başlığı, API Gizli Anahtarınızı içeren, geriye dönük uyumluluk için hâlâ gönderilmektedir. Ancak, tekrar oynatma saldırılarına karşı koruma sağladığı için geliştirilmiş güvenlik için HMAC doğrulamasına geçmenizi öneririz.


API üzerinden Webhook'ları Yönetme Internal Link

Webhooks ayrıca REST API üzerinden yönetilebilir. Bu, Zapier gibi entegrasyonların kontrol paneline dokunmadan yorum olaylarına abone olmasını sağlar ve REST Hooks desenini izler: abone ol, olayları al, aboneliği iptal et.

API abonelikleri, kontrol panelinde yapılandırılmış webhooks'ların yanında bulunur. Bir yorum olayı, alanına uyan her webhook'a, webhook'un nasıl oluşturulduğuna bakılmaksızın, ayrı bir teslimat olarak gönderilir.

Kimlik Doğrulama

Her istek, x-api-key başlığında (veya API_KEY sorgu parametresinde) API Anahtarınızı ve tenantId sorgu parametresinde kiracı kimliğinizi gerektirir. Her ikisi de kontrol panelindeki API Gizli Sayfası'nda gösterilir.

Abone Ol

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"
}
AlanGerekliAçıklama
urlEvetMutlak bir http veya https URL'si.
eventEvetcomment-created, comment-updated or comment-deleted.
domainHayırHesap yapılandırmanızdaki bir alan adı. Varsayılan * olup, her alan adı için olayları alır.
methodHayırPOST (default), PUT or DELETE.

Yanıt, aboneliği içerir:

{
    "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"
    }
}

Aynı URL'yi aynı olay ve alan adına tekrar abone etmek, bir kopya oluşturmak yerine mevcut aboneliği döndürür, böylece bir istemci güvenle yeniden deneyebilir. Her kiracı en fazla 50 API aboneliğine sahip olabilir.

Liste

GET https://fastcomments.com/api/v1/webhooks?tenantId=YOUR_TENANT_ID

Kiracı için kontrol panelinde yönetilenler dahil olmak üzere tüm webhook'ları döndürür ("source": "dashboard"). event, domain veya source ile filtreleyin.

Aboneliği İptal Et

DELETE https://fastcomments.com/api/v1/webhooks/SUBSCRIPTION_ID?tenantId=YOUR_TENANT_ID

Bir aboneliği silmek, ona hâlâ kuyrukta bekleyen olayları da iptal eder. Bu şekilde yalnızca API üzerinden oluşturulan abonelikler silinebilir; kontrol paneli webhook'u veya hesabınızda bulunmayan bir kimlik, 404 yanıtını not-found koduyla verir. Kontrol paneli webhook'ları Webhooks sayfasında düzenlenir.

Yükler ve İmzalama

Teslimatlar, kontrol paneli webhook'larıyla aynı yükü kullanır (Data Structures bölümüne bakın) ve aynı HMAC şemasıyla imzalanır (Security & API Tokens bölümüne bakın). API abonelikleri asla eski token başlığını almaz, bu yüzden X-FastComments-Signature başlığını doğrulayın.

Örnek Yükler

GET https://fastcomments.com/api/v1/webhooks/sample-payloads?tenantId=YOUR_TENANT_ID&event=comment-created&limit=3

Hesabın en son yorumlarını, teslimatın taşıdığı tam biçimde döndürür, böylece bir entegrasyon ilk olay gelmeden gerçek örnek verileri gösterebilir. event isteğe bağlıdır ve sadece doğrulanır, çünkü her olay aynı yorum nesnesini taşır. limit varsayılan olarak 3'tür ve 1 ile 10 arasında kabul eder. 2 API kredisi maliyetlidir.

{
    "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 Yanıtı

Bir API aboneliğinin uç noktası HTTP 410 Gone yanıtı verirse, FastComments bunu bir abonelik iptali olarak değerlendirir: abonelik, kuyrukta bekleyen olaylarıyla birlikte silinir ve başka teslimat denenmez. Kontrol panelinde yapılandırılmış webhook'lar otomatik olarak silinmez; onlar için 410 sıradan bir hatadır. Diğer tüm hata durumları yeniden denenir ve sonunda webhook devre dışı bırakılır, How it Works & Handling Retries bölümünde açıklandığı gibi.

Kontrol Paneli

API abonelikleri, Webhooks listesinde API kaynağıyla görünür; burada bir yönetici onları düzenleyebilir, devre dışı bırakabilir, yeniden etkinleştirebilir veya silebilir.

Sonuç olarak

Bu, Webhooks belgelerimizin sonudur.

Umarız FastComments Webhook entegrasyonunu anlaşılması kolay ve kurulumu hızlı bulursunuz.

Belgelerimizde herhangi bir boşluk tespit ettiğinizi düşünüyorsanız, lütfen aşağıdan bize bildirin.