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-Event | push.send |
| Metot | POST |
| İçerik türü | application/json |
Yük
{
"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"
}
}| Alan | Tür | Açıklama |
|---|---|---|
user_ids | string[] | Bildirilecek Loyetta kullanıcı kimlikleri (ULID). Bunları kendi cihaz token'larınıza eşleyin. |
notification.title | string | null | Bildirim başlığı. |
notification.body | string | null | Bildirim gövde metni. |
notification.image | string | null | İsteğe bağlı görsel URL'si. Atlanabilir/null olabilir. |
data | object | İ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
- İmzayı doğrulayın (bkz. Genel Bakış). Başarısız olursa
401ile reddedin. - Hızlı onaylayın — hemen bir
2xxdöndürün, ardından push'u asenkron olarak (kuyruk/worker) iletin. İstek 15 saniye sonra zaman aşımına uğrar. - Yeniden denenen bir gönderimin iki kez gönderilmemesi için
X-Loyetta-Deliverybaşlığını kullanarak tekilleştirin. Bkz. Idempotency. - Her
user_idiçin cihaz token'larını çözümleyin ve push sağlayıcınız (FCM/APNs/vb.) üzerinden gönderin.
Örnek
// 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.