API: Webhook Entegrasyonu
YSN webhook'ları, platformda olay olduğunda (ör. sosyal medyaya post geldi, prompt tamamlandı, abonelik yenilendi) sizin dış sisteminize HTTP POST göndererek haberdar etmesi anlamına gelir. Bu doküman webhook kaydı, imza doğrulama, n8n ile entegrasyon ve cURL/JS örneklerini içerir.
Kayıt
Panelde Ayarlar > Webhook > "Yeni webhook" tıklayın. Form:
- **URL** — dinleyecek endpoint'iniz (HTTPS şart).
- **Olaylar** — abone olunacak event tipleri (checkbox).
- **Secret** — HMAC imza için 32+ karakter rastgele dize (otomatik üretilir, isterseniz değiştirin).
- **Aktif** — on/off.
Kaydettikten sonra YSN "ping" eventi gönderir; 2xx dönmezse webhook disabled olur.
Olay Tipleri
| Olay | Ne zaman |
|---|---|
| `prompt.executed` | Prompt çalıştırma tamamlandı |
| `prompt.failed` | Prompt hata aldı |
| `chatbot.message` | Chatbot widget'ına yeni mesaj |
| `chatbot.lead` | Chatbot lead yakaladı |
| `social.post.published` | Sosyal medya post yayınlandı |
| `social.comment.received` | Yeni yorum geldi |
| `social.dm.received` | Yeni DM geldi |
| `credits.low` | Kontör %10'un altına düştü |
| `subscription.renewed` | Abonelik yenilendi |
| `subscription.cancelled` | Abonelik iptal edildi |
İstek Yapısı
POST /your/endpoint HTTP/1.1
Host: example.com
Content-Type: application/json
X-YSN-Event: social.comment.received
X-YSN-Signature: sha256=7b3a2f...
X-YSN-Delivery: evt_01HX9...
X-YSN-Timestamp: 1714050000
{
"event": "social.comment.received",
"created_at": "2026-04-20T12:30:00Z",
"data": {
"platform": "instagram",
"account_id": "acc_123",
"post_id": "17xxx",
"comment_id": "18yyy",
"author": "ziyaretci_99",
"text": "fiyat bilgisi rica ederim"
}
}İmza Doğrulama
Gelen her istek HMAC-SHA256 ile imzalanır:
X-YSN-Signature: sha256=<hex>Hesaplama:
hmac_sha256(secret, timestamp + "." + raw_body_bytes)Node.js doğrulama
import crypto from "crypto";
import express from "express";
const app = express();
app.use(express.raw({ type: "application/json" }));
app.post("/ysn-webhook", (req, res) => {
const sig = req.get("X-YSN-Signature");
const ts = req.get("X-YSN-Timestamp");
const expected = "sha256=" + crypto
.createHmac("sha256", process.env.YSN_SECRET)
.update(ts + "." + req.body)
.digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
return res.status(401).send("invalid signature");
}
const event = JSON.parse(req.body);
console.log("YSN event", event.event, event.data);
res.sendStatus(200);
});Python doğrulama
import hmac, hashlib
from fastapi import FastAPI, Request, HTTPException
app = FastAPI()
SECRET = b"your_secret"
@app.post("/ysn-webhook")
async def ysn_webhook(req: Request):
body = await req.body()
ts = req.headers.get("X-YSN-Timestamp", "")
sig = req.headers.get("X-YSN-Signature", "")
expected = "sha256=" + hmac.new(SECRET, (ts + ".").encode() + body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(sig, expected):
raise HTTPException(401, "invalid signature")
return {"ok": True}Curl test
curl -i -X POST https://example.com/ysn-webhook \
-H "Content-Type: application/json" \
-H "X-YSN-Event: ping" \
-H "X-YSN-Signature: sha256=..." \
-H "X-YSN-Timestamp: 1714050000" \
-d '{"event":"ping","data":{}}'Yeniden Deneme Politikası
5xx veya timeout alırsak exponential backoff ile 6 kez deneriz: 30sn, 2dk, 10dk, 1sa, 6sa, 24sa. 6. denemeden sonra webhook "devre dışı" bayrağı alır. Panelde "Tekrar dene" butonu ile manuel yeniden başlatabilirsiniz.
İdempotency
Aynı X-YSN-Delivery ID'si tekrar gelirse (retry nedeniyle) tekrar işlemeyin. Bu ID'yi veritabanında unique index olarak tutun.
n8n Pattern
n8n'de "Webhook" node'u oluşturun, URL'yi panele YSN webhook URL'si olarak yapıştırın. n8n "HMAC verify" node'u yoktur; onun yerine "Function" node'una şu kodu yazın:
const sig = $input.first().headers["x-ysn-signature"];
const ts = $input.first().headers["x-ysn-timestamp"];
const body = JSON.stringify($json);
const crypto = require("crypto");
const expected = "sha256=" + crypto
.createHmac("sha256", $env.YSN_SECRET)
.update(ts + "." + body)
.digest("hex");
if (sig !== expected) throw new Error("bad sig");
return $input.all();Sonraki node olarak Switch (event tipi), ardından Google Sheets, Slack, Telegram gibi istediğiniz hedefleri bağlayın.
Sık Yapılan Hatalar
- Body'yi JSON olarak parse edip tekrar stringify edip imza hesaplamak — `raw_body` kullanın.
- Timestamp'ı doğrulamamak — 5 dakikadan eski isteği reddedin.
- 200 yerine 201/202 dönmek — tercih edilir ama YSN 2xx'in hepsini başarı sayar.
- Uzun işlem yapıp 30sn'yi aşmak — YSN 10sn sonra timeout sayar; async queue'ya atıp hemen 200 dönün.