FastComments.com


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.


Webhook'lar 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 Comment kaynağı için webhookları destekler.

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

Her biri sistemimizde ayrı olaylar olarak kabul edilir ve bu nedenle webhook olayları için farklı semantiklere ve yapılara sahiptir.

Test Etme Internal Link

Webhooks yönetim panelinde her bir etkinlik türü (Create, Update, Delete) için Send Test Payload düğmeleri bulunur. Create ve Update etkinlikleri sahte bir WebhookComment object gönderirken, Delete testi yalnızca bir ID içeren sahte bir istek gövdesi gönderecektir.

Verifying Payloads

Webhook entegrasyonunuzu test ederken, gelen isteklerin aşağıdaki başlıkları içerdiğini doğrulayın:

  1. token - API Gizli Anahtarınız
  2. X-FastComments-Timestamp - Unix zaman damgası (saniye)
  3. X-FastComments-Signature - HMAC-SHA256 imzası

Gelen payload'ların gerçekliğini sağlamak için HMAC imza doğrulamasını kullanın.

Testing Tools

Geliştirme sırasında gelen webhook payload'larını incelemek için webhook.site veya ngrok gibi araçları kullanabilirsiniz.

Event Types

  • Create Event: Yeni bir yorum oluşturulduğunda tetiklenir. Varsayılan yöntem: PUT
  • Update Event: Bir yorum düzenlendiğinde tetiklenir. Varsayılan yöntem: PUT
  • Delete Event: Bir yorum silindiğinde tetiklenir. Varsayılan yöntem: DELETE

Her etkinlik, istek gövdesinde tam yorum verilerini içerir (yük formatı için bkz. Veri Yapıları).

Veri Yapıları Internal Link

Webhook'lar aracılığıyla gönderilen tek yapı aşağıda TypeScript ile özetlenen WebhookComment nesnesidir.

WebhookComment Nesnesi 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.

14 Kasım 2023 itibarıyla değişiklik
Daha önce "delete" olay isteği gövdesi yalnızca yorum id'sini içeriyordu. Artık silme anındaki tam yorumu içerir.
WebhookComment Nesnesi
Copy CopyRun External Link
1
2interface WebhookComment {
3 /** Yorumun id'si. **/
4 id: string
5 /** Yorum dizisini tanımlayan id veya URL. Normalleştirilmiş. **/
6 urlId: string
7 /** Yorumun bırakıldığı yeri gösteren URL. **/
8 url?: string
9 /** Yorumu bırakan kullanıcı id'si. SSO ise, tenant id ile öneklenmiş. **/
10 userId?: string
11 /** Yorumu bırakan kullanıcının e-postası. **/
12 commenterEmail?: string
13 /** Yorum widget'ında görünen kullanıcı adı. SSO ile displayName olabilir. **/
14 commenterName: string
15 /** Ham yorum metni. **/
16 comment: string
17 /** Ayrıştırıldıktan sonraki yorum metni. **/
18 commentHTML: string
19 /** Yorumun harici id'si. **/
20 externalId?: string
21 /** Üst yorumun id'si. **/
22 parentId?: string | null
23 /** Yorumun bırakıldığı UTC tarih. **/
24 date: UTC_ISO_DateString
25 /** Oyların (yukarı - aşağı) toplamı. **/
26 votes: number
27 votesUp: number
28 votesDown: number
29 /** Kullanıcı yorum yaparken giriş yapmışsa, yorumu doğrulanmışsa veya yorum bırakılırken oturum doğrulaması yapılmışsa true. **/
30 verified: boolean
31 /** Yorumun doğrulandığı tarih. **/
32 verifiedDate?: number
33 /** Bir moderatör yorum'u incelendi olarak işaretlediyse. **/
34 reviewed: boolean
35 /** Avatarın konumu veya base64 kodlaması. Yalnızca SSO ile base64 olarak gönderildiyse base64 olur. **/
36 avatarSrc?: string
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 görseller var mı? **/
42 hasImages: boolean
43 /** "Most Relevant" sıralama yönü için yorumun bulunduğu sayfa numarası. **/
44 pageNumber: number
45 /** "Oldest First" sıralama yönü için yorumun bulunduğu sayfa numarası. **/
46 pageNumberOF: number
47 /** "Newest First" sıralama yönü için yorumun bulunduğu sayfa numarası. **/
48 pageNumberNF: number
49 /** Yorum otomatik veya manuel olarak onaylandı mı? **/
50 approved: boolean
51 /** Yorum yazılırken kullanıcının yerel ayar kodu (format: en_us). **/
52 locale: string
53 /** Yoruma yazılan ve başarıyla ayrıştırılan @mention'lar. **/
54 mentions?: CommentUserMention[]
55 /** Yorumun geldiği alan adı. **/
56 domain?: string
57 /** Bu yorumla ilişkili isteğe bağlı moderasyon grup id'lerinin listesi. **/
58 moderationGroupIds?: string[]|null
59}
60

Kullanıcılar bir yorumda etiketlendiğinde, bilgiler mentions adlı bir listede saklanır. O listedeki her nesne aşağıdaki yapıya sahiptir.

Webhook Mentions Nesnesi
Copy CopyRun External Link
1
2interface CommentUserMention {
3 /** Kullanıcı id'si. SSO kullanıcıları için, tenant id öneklenmiş olacaktır. **/
4 id: string
5 /** @ sembolü dahil son @mention etiket metni. **/
6 tag: string
7 /** @ sembolü dahil orijinal @mention etiket metni. **/
8 rawTag: string
9 /** Hangi tip kullanıcının etiketlendiği. user = FastComments.com hesabı. sso = SSOUser. **/
10 type: 'user'|'sso'
11 /** Kullanıcı bildirimleri kapatmış olsa bile, bu yine de true olarak ayarlanır. **/
12 sent: boolean
13}
14

HTTP Yöntemleri

Yönetici panelinde her webhook olay türü için HTTP yöntemini yapılandırabilirsiniz:

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

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

İstek Başlıkları

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

Başlık Açıklama
Content-Type application/json
token API Gizli Anahtarınız
X-FastComments-Timestamp İsteğin imzalandığı Unix zaman damgası (saniye)
X-FastComments-Signature HMAC-SHA256 imzası (sha256=<hex>)

HMAC imzasını doğrulama hakkında bilgi için Güvenlik ve API Anahtarları sayfasına bakın.


Güvenlik ve API Jetonları Internal Link

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

Gönderilen Başlıklar

Header Açıklama
token API Gizli Anahtarınız (geriye dönük uyumluluk için)
X-FastComments-Timestamp İsteğin imzalandığı Unix zaman damgası (saniye)
X-FastComments-Signature Gö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.


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.