Uygulamayı aç
Moonborn — Developers

Webhook'lar

HMAC-SHA256 imzalı olay gönderimleri; üstel geri çekilmeyle (exponential backoff) 5 yeniden deneme; panelden veya API'den yeniden gönderim. 16 olay tipi, gizli anahtar yenileme süresi (grace window).

Webhook'lar Moonborn'un çalışma zamanı olaylarını yığınına ittiği (push) yoldur — persona yaşam döngüsü, üretim hattı sonuçları, faturalama değişiklikleri, moderasyon işaretleri. Bugün 16 gerçek olay tipi gönderilir; her gönderim HMAC-SHA256 ile imzalıdır, beş yeniden denemesi vardır, başarısız gönderimler yeniden gönderilebilir.

Bu sayfayı bitirdiğinde

  • Bir webhook'a abone olmanın kod akışını bileceksin.
  • HMAC-SHA256 imzasını doğrulayabileceksin (zaman güvenli — timing safe).
  • 5 yeniden deneme zamanlamasını ve dead-letter (ölü mektup) davranışını anlayacaksın.
  • Başarısız gönderimleri yeniden gönderebileceksin (replay).
  • İmza gizli anahtarını yenileyebileceksin (rotate) (60 dakikalık geçiş süresi).
  • Webhook'un kenar tetiklemeli (edge-triggered) olduğunu ve akış (streaming) alternatifini ayırt edebileceksin.

Ön koşul: API anahtarı + uç nokta URL'i (HTTPS, açıkça erişilebilir).

Abone ol

const hook = await client.webhooks.create({
  url: 'https://your-app.com/webhooks/moonborn',
  events: ['persona.created', 'persona.audit_failed'],
  description: 'Production listener',
});
 
console.log(hook.signingSecret);
// ⚠ Bu gizli anahtar tam olarak BİR KEZ döner. Şimdi sakla; ikinci bir okuma yok.

events: ['*'] tüm tiplere abone olur; üretimde olay başına liste önerilir (işleyiciyi sıkı tutmak ve gereksiz trafiği önlemek için).

Tam olay kataloğu: Webhook olayları.

İmza doğrulama

Her gönderim X-Moonborn-Signature başlığını taşır:

X-Moonborn-Signature: t=1747497600,v1=2c4f8a...
  • t — Unix zaman damgası (saniye, imzalama anı)
  • v1HMAC-SHA256(secret, "{t}.{rawBody}"), onaltılık (hex) kodlanmış
import { createHmac, timingSafeEqual } from 'node:crypto';
 
function verify(rawBody: string, header: string, secret: string): boolean {
  const parts = Object.fromEntries(
    header.split(',').map((p) => p.split('=', 2) as [string, string]),
  );
  const t = Number(parts['t']);
  const v1 = parts['v1'];
 
  // Yeniden gönderim penceresi — 5 dakikadan eski gönderimleri reddet
  if (Math.abs(Date.now() / 1000 - t) > 300) return false;
 
  const signed = `${t}.${rawBody}`;
  const expected = createHmac('sha256', secret).update(signed).digest('hex');
 
  return v1.length === expected.length &&
    timingSafeEqual(Buffer.from(v1, 'hex'), Buffer.from(expected, 'hex'));
}

Yeniden deneme politikası

DenemeGecikme
1anında
21 dakika
35 dakika
430 dakika
52 saat

Beş başarısızlık sonrası gönderim dead-letter (ölü mektup) kuyruğuna iner. Uç nokta aktif kalır — sonraki olaylar hâlâ gönderim denemesi yapar. Uç noktayı tamamen devre dışı bırakmak istiyorsan DELETE /v1/webhooks/{id}.

Yeniden deneme zamanlaması geçersiz kılınabilir (api.webhooks.retry.* organizasyon yapılandırması; Enterprise planı).

Yeniden gönderim (replay)

Başarısız gönderimleri yeniden denemeye sokmak:

const failed = await client.webhooks.deliveries.list({
  webhookId: hook.id,
  status: 'failed',
  range: '7d',
});
 
for (const d of failed.data) {
  await client.webhooks.deliveries.replay({
    webhookId: hook.id,
    deliveryId: d.id,
  });
}

Yeniden gönderim orijinal yük (payload) + imza zaman damgasını korur. İşleyicin idempotent olmalı; tekrar tespit (dedupe) anahtarı olarak olay yükünün id alanını kullan:

if (await redis.set(`webhook:${event.id}`, '1', { NX: true, EX: 86400 })) {
  // Yeni olay — işle
  await handleEvent(event);
}
// Aksi halde daha önce işlenmiş, atla

Test gönderimi — uç nokta sağlığı

await client.webhooks.ping({ id: hook.id });

Sentetik bir webhook.endpoint.test_ping olayı tetiklenir. Gerçek bir olay beklemeden alıcıyı doğrulayabilirsin. Yanıt 200 ise uç nokta sağlıklıdır.

Gizli anahtar yenileme (secret rotation)

const result = await client.webhooks.rotateSecret({ id: hook.id });
console.log(result.newSecret);
// Eski gizli anahtar 60 dakika daha geçerli kalır

60 dakikalık geçiş penceresi süresince iki imza paralel gelir — biri eski gizli anahtarla, biri yeni. Alıcını iki adayı da doğrulayacak şekilde yaz:

const valid = candidates.some((v1) => timingSafeEqual(...));

Detay: Webhook imza doğrulama — gizli anahtar yenileme bölümü.

Geçiş penceresi geçersiz kılma: api.webhooks.secret_rotation_grace_minutes (varsayılan 60, en fazla 1440 / 24 saat).

Akış (streaming) alternatifi — ne zaman webhook değil

Webhook'lar kenar tetiklemelidir (edge-triggered): bir şey oldu, bir kez gönderim, sonu var. Şu durumlarda webhook değil akış kullan:

  • Üretim hattı ilerlemesiPOST /v1/personas?stream=true SSE. Adım adım ilerleme webhook'a sığmaz.
  • Token-token sohbet yanıtıPOST /v1/chat/sessions/{id}/messages?stream=true SSE.
  • Gerçek zamanlı drift paneli — webhook toplu (batch), panel için yoklama (polling) daha temiz.

Detay: Akış desenleri.

Plan gereksinimi

Team ve üzeri. Pro planında özel olay aboneliği yoktur; Free + Pro yoklama tabanlıdır.

Dürüst kapsam

İlgili

Webhook imza doğrulama

Üretim-hazır HMAC + yeniden gönderim penceresi + gizli anahtar yenileme deseni.

Open →
Voice drift'i ele al

Drift webhook'unu uçtan uca QA kuyruğuna bağlama.

Open →
Webhook olay kataloğu

16 olay tipi ve yük şemaları.

Open →
Akış desenleri

Webhook'un alternatifi — token-token akış için SSE.

Open →