API

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

OlayNe 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.