Skip to Content
API ReferansıWebhooklar

Webhooklar

Sosyal Köprü, belirli olaylar gerçekleştiğinde kaydettiğiniz URL’e HTTP POST isteği gönderir. Her workspace’te en fazla 10 webhook endpoint’i tanımlanabilir.

Desteklenen Olaylar

OlayAçıklama
post.publishingGönderi yayınlanmaya başladı (BullMQ worker aldı)
post.publishedGönderi başarıyla yayınlandı
post.failedGönderi yayınlama başarısız oldu
post.scheduledGönderi planlandı
post.cancelledGönderi iptal edildi
post.updatedGönderi güncellendi
webhook.testTest ping gönderildi

Webhook Oluştur

POST/v1/webhooks

Yeni bir webhook endpoint’i kaydeder. Oluşturma yanıtında dönen secret yalnızca bir kez gösterilir.

İstek Gövdesi

AlanTipZorunluAçıklama
urlstringEvetHTTPS webhook URL’i
eventsstring[]EvetDinlenecek olaylar (en az 1)
descriptionstringHayırWebhook açıklaması (maks. 255 karakter)

SSRF Koruması: Yerel IP adresleri (127.0.0.1, 192.168.x.x, 10.x.x.x vb.) reddedilir. URL mutlaka kamuya açık, HTTPS ile erişilebilir bir endpoint olmalıdır.

Kod Örnekleri

webhook-olustur.js
const response = await fetch('https://api.sosyalkopru.com/v1/webhooks', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.SOSYALKOPRU_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ url: 'https://sizin-siteniz.com/webhooks/sosyalkopru', events: ['post.published', 'post.failed'], description: 'Üretim ortamı bildirimleri', }), }) const { data } = await response.json() console.log('Webhook ID:', data.id) // ⚠️ Secret yalnızca bir kez gösterilir! console.log('Secret:', data.secret) // Bunu güvenli bir yerde saklayın (örn. ortam değişkeni) process.env.SOSYALKOPRU_WEBHOOK_SECRET = data.secret

Başarılı Yanıt (201 Created)

{ "success": true, "data": { "id": "wh_01HZGK9P3QABC", "url": "https://sizin-siteniz.com/webhooks/sosyalkopru", "events": ["post.published", "post.failed"], "isActive": true, "secret": "whsec_aBcDeFgH1234...", "createdAt": "2025-06-10T12:00:00.000Z" }, "meta": { "requestId": "req_01XYZ", "timestamp": "...", "version": "1" } }

secret alanı yalnızca oluşturma yanıtında döner. Mutlaka güvenli bir şekilde saklayın. Kaybetmeniz durumunda webhook’u silip yeniden oluşturmanız gerekir.


Webhookları Listele

GET/v1/webhooks

Tüm webhook endpoint’lerini son teslimat durumuyla birlikte döner.

webhook-listele.js
const response = await fetch('https://api.sosyalkopru.com/v1/webhooks', { headers: { 'Authorization': `Bearer ${process.env.SOSYALKOPRU_API_KEY}` }, }) const { data } = await response.json() data.forEach(wh => { const durum = wh.isActive ? 'aktif' : 'pasif' console.log(`${wh.id} [${durum}]: ${wh.url}`) console.log(` Olaylar: ${wh.events.join(', ')}`) console.log(` Teslimat: ${wh.deliveryCount} toplam`) if (wh.lastDelivery) { console.log(` Son teslimat: ${wh.lastDelivery.status} @ ${wh.lastDelivery.timestamp}`) } })

Başarılı Yanıt

{ "success": true, "data": [ { "id": "wh_01HZGK9P3QABC", "url": "https://sizin-siteniz.com/webhooks/sosyalkopru", "events": ["post.published", "post.failed"], "isActive": true, "deliveryCount": 47, "lastDelivery": { "status": "success", "timestamp": "2025-06-10T11:55:00.000Z" }, "createdAt": "2025-06-01T10:00:00.000Z", "updatedAt": "2025-06-10T11:55:00.000Z" } ], "meta": { "requestId": "req_01XYZ", "timestamp": "...", "version": "1" } }

Webhook Detayı

GET/v1/webhooks/{id}

Tek bir webhook’u teslimat istatistikleriyle döner.

webhook-detay.js
const response = await fetch( `https://api.sosyalkopru.com/v1/webhooks/${webhookId}`, { headers: { 'Authorization': `Bearer ${process.env.SOSYALKOPRU_API_KEY}` } } ) const { data } = await response.json() const successRate = data.stats.total > 0 ? ((data.stats.success / data.stats.total) * 100).toFixed(1) : 0 console.log(`Başarı oranı: %${successRate} (${data.stats.success}/${data.stats.total})`)

Başarılı Yanıt

{ "success": true, "data": { "id": "wh_01HZGK9P3QABC", "url": "https://sizin-siteniz.com/webhooks/sosyalkopru", "events": ["post.published", "post.failed"], "isActive": true, "stats": { "total": 47, "success": 45, "failed": 2 }, "createdAt": "2025-06-01T10:00:00.000Z", "updatedAt": "2025-06-10T11:55:00.000Z" }, "meta": { "requestId": "req_01XYZ", "timestamp": "...", "version": "1" } }

Webhook Güncelle

PATCH/v1/webhooks/{id}

Webhook URL’ini, event listesini veya aktif durumunu günceller.

İstek Gövdesi

AlanTipAçıklama
urlstringYeni webhook URL’i
eventsstring[]Yeni event listesi (en az 1)
isActivebooleanfalse ile webhook’u geçici olarak devre dışı bırakın
webhook-guncelle.js
// Webhook'u devre dışı bırak const response = await fetch( `https://api.sosyalkopru.com/v1/webhooks/${webhookId}`, { method: 'PATCH', headers: { 'Authorization': `Bearer ${process.env.SOSYALKOPRU_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ isActive: false }), } ) const { data } = await response.json() console.log('Aktif mi:', data.isActive) // false

Webhook Sil

DELETE/v1/webhooks/{id}
webhook-sil.js
await fetch(`https://api.sosyalkopru.com/v1/webhooks/${webhookId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${process.env.SOSYALKOPRU_API_KEY}` }, })

Test Ping Gönder

POST/v1/webhooks/{id}/test

webhook.test olayını URL’inize gönderir. Yanıt süresi (durationMs) dahil teslimat detaylarını döner.

Kod Örnekleri

webhook-test.js
const response = await fetch( `https://api.sosyalkopru.com/v1/webhooks/${webhookId}/test`, { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.SOSYALKOPRU_API_KEY}` }, } ) const { data } = await response.json() console.log('Başarılı :', data.success) console.log('HTTP Kodu :', data.statusCode) console.log('Yanıt süresi:', data.durationMs, 'ms') if (!data.success) { console.error('Hata:', data.responseBody) }

Başarılı Yanıt

{ "success": true, "data": { "deliveryId": "del_01HZGK9P3QABC", "success": true, "statusCode": 200, "responseBody": "{\"received\": true}", "durationMs": 142 }, "meta": { "requestId": "req_01XYZ", "timestamp": "...", "version": "1" } }

İmza Doğrulama

Gelen webhook isteklerinin gerçekten Sosyal Köprü’den geldiğini doğrulamak için HMAC-SHA256 imzasını kontrol edin.

İstek Başlıkları

BaşlıkAçıklama
X-SosyalKopru-Signaturesha256= önekli HMAC-SHA256 imzası
X-SosyalKopru-EventOlay adı (post.published vb.)
X-SosyalKopru-DeliveryTeslimat ID’si

Doğrulama Örnekleri

webhook-dogrula.js
import crypto from 'crypto' export function webhookDogrula(rawBody, signature) { const secret = process.env.SOSYALKOPRU_WEBHOOK_SECRET const beklenen = 'sha256=' + crypto .createHmac('sha256', secret) .update(rawBody) // ham string ya da Buffer — asla parse edilmiş obje değil! .digest('hex') return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(beklenen) ) } // Express ile kullanım (ham body gereklidir) app.post('/webhooks/sosyalkopru', express.raw({ type: '*/*' }), (req, res) => { const signature = req.headers['x-sosyalkopru-signature'] ?? '' if (!webhookDogrula(req.body, signature)) { return res.status(401).json({ error: 'İmza geçersiz' }) } const olay = JSON.parse(req.body.toString()) console.log('Olay:', olay.event, '| Post:', olay.data?.postId) res.json({ received: true }) })

Webhook Payload Formatı

{ "event": "post.published", "timestamp": "2025-06-10T12:00:00.000Z", "data": { "postId": "post_01HZGK9P3QABC", "status": "PUBLISHED", "platforms": [ { "platform": "instagram", "status": "PUBLISHED", "platformPostUrl": "https://instagram.com/p/ABC123" } ] } }

Webhook endpoint’iniz 15 saniye içinde 2xx yanıt dönmelidir. Aksi hâlde teslimat başarısız sayılır. İstek alındığında hemen 200 OK dönün, işlemi arka planda gerçekleştirin.

HMAC imzasını hesaplarken ham HTTP body’sini (bytes) kullanın. JSON parse edilmiş nesneyi JSON.stringify ile tekrar stringe çevirmek anahtar sırasını değiştirebilir ve imza doğrulamasını bozabilir.

Last updated on