Loyetta

Push Gönderimi

Push gönderimi uç noktanıza yönlendirildiğinde, bir veya daha fazla kullanıcıya bildirim iletilmesi gerektiğinde Loyetta bir push.send webhook'u gönderir. Loyetta cihaz token'larınızı saklamaz — user_ids'i kendi cihaz token'larınıza eşler ve push'u kendi altyapınız üzerinden iletirsiniz.

Herhangi bir push.send isteğine göre işlem yapmadan önce imzasını doğrulayın. Doğrulama akışı, başlıklar, yeniden denemeler ve idempotency kuralları tüm kanallarda ortaktır — bkz. Webhook'lar: Genel Bakış → Doğrulama.


Olay

X-Loyetta-Eventpush.send
MetotPOST
İçerik türüapplication/json

Yük

json
{
  "user_ids": [
    "01JRXYZ1234ABCDEF56789GH",
    "01JRXYZ9876ZYXWVU54321PQ"
  ],
  "notification": {
    "title": "Tekrar hoş geldiniz!",
    "body": "Bugün 50 puan kazandınız.",
    "image": "https://cdn.example.com/banner.png"
  },
  "data": {
    "deep_link": "app://campaigns/42"
  }
}
AlanTürAçıklama
user_idsstring[]Bildirilecek Loyetta kullanıcı kimlikleri (ULID). Bunları kendi cihaz token'larınıza eşleyin.
notification.titlestring | nullBildirim başlığı.
notification.bodystring | nullBildirim gövde metni.
notification.imagestring | nullİsteğe bağlı görsel URL'si. Atlanabilir/null olabilir.
dataobjectİsteğe bağlı anahtar-değer yükü (örn. derin bağlantılar). Boş olabilir.

Loyetta user_ids'inin push token'larına / cihazlara eşlenmesi sizin sorumluluğunuzdadır — Loyetta cihaz token'larınızı saklamaz.


Webhook'u işleme

  1. İmzayı doğrulayın (bkz. Genel Bakış). Başarısız olursa 401 ile reddedin.
  2. Hızlı onaylayın — hemen bir 2xx döndürün, ardından push'u asenkron olarak (kuyruk/worker) iletin. İstek 15 saniye sonra zaman aşımına uğrar.
  3. Yeniden denenen bir gönderimin iki kez gönderilmemesi için X-Loyetta-Delivery başlığını kullanarak tekilleştirin. Bkz. Idempotency.
  4. Her user_id için cihaz token'larını çözümleyin ve push sağlayıcınız (FCM/APNs/vb.) üzerinden gönderin.

Örnek

js
// Doğrulanmış webhook işleyicinizin içinde (verify() için bkz. Genel Bakış):
app.post('/webhooks/loyetta', express.raw({ type: 'application/json' }), async (req, res) => {
  const rawBody = req.body.toString('utf8');
  if (!verify(rawBody, req.get('X-Loyetta-Signature') || '', SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  if (req.get('X-Loyetta-Event') !== 'push.send') {
    return res.status(200).send('ignored');
  }

  // Önce onaylayın, ardından asenkron işleyin.
  res.status(200).send('ok');

  const deliveryId = req.get('X-Loyetta-Delivery');
  if (await alreadyProcessed(deliveryId)) return; // idempotency

  const { user_ids, notification, data } = JSON.parse(rawBody);
  const tokens = await resolveDeviceTokens(user_ids); // kendi eşlemeniz
  if (tokens.length) {
    await sendPushViaYourProvider(tokens, notification, data);
  }
  await markProcessed(deliveryId);
});

notification.body, notification.image ve data alanlarının tümü isteğe bağlıdır — sağlayıcı yükünüzü oluştururken eksik alanlara karşı korunun.