Hızlı başlangıç
Bu sayfanın sonunda API, worker, MongoDB ve Redis çalışıyor olacak; iki API anahtarı olan bir uygulamanız ve kuyruğa girip teslim edilmiş bir bildiriminiz olacak.
Gerekenler: Docker (Compose v2 ile) ve tek seferlik kurulum komutları için Bun ≥ 1.2.
1 Klonla ve yapılandır
git clone https://github.com/Aproder/opennotification.git
cd opennotification
cp .env.example .env
2 Sırları üret
bun run generate:keys >> .env
bun run generate:admin-password >> .env # panel parolasını sorar
.env'e yedi değer eklenir:
| Değişken | Nedir |
|---|---|
ENCRYPTION_KEY | 32 baytlık AES-256-GCM anahtarı. Yüklediğiniz her kimlik bilgisi (.p8, service account JSON, VAPID private key) veritabanına değmeden önce bununla mühürlenir. |
HMAC_SECRET | Her push'a gömülü izleme kimliğini imzalar; izleme ucunun kimlik doğrulamasız kalabilmesini sağlayan şey budur. |
VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY | Web push için P-256 anahtar çifti. Web uygulaması ekleyene kadar isteğe bağlı. |
ADMIN_API_TOKEN | Panel ile API'nin /v1/admin uçları arasındaki paylaşılan sır. |
SESSION_SECRET | Panelin oturum çerezini imzalar. |
ADMIN_PASSWORD_HASH | Panelin bootstrap parolasının argon2id hash'i (base64). |
.env'i açıp bu değişkenlerin boş satırlarını silin; yalnızca üretilenler kalsın. Herhangi biri boşken Compose başlamayı reddeder.
ENCRYPTION_KEY'i yedekleyinKaybederseniz saklanan her kimlik bilgisi okunamaz olur ve hepsini yeniden girersiniz. Şimdi bir parola yöneticisine koyun.
3 Stack'i başlat
docker compose up -d
Altı konteyner kalkar: api, worker, dashboard, docs, mongo, redis. Index'ler ve time-series events koleksiyonu ilk açılışta oluşturulur.
curl localhost:3000/health
# {"status":"ok","db":"ready","uptimeSeconds":3}
Etkileşimli OpenAPI tarayıcısı http://localhost:3000/docs adresinde.
Compose'u tamamen atlayın — Docker'sız çalıştırma.
4 İlk uygulamanı oluştur
Uygulama bir kiracıdır: bir takım push kimlik bilgisi, bir kitle, kendi API anahtarları. Komut satırından oluşturun:
docker compose exec api bun packages/api/scripts/create-app.ts \
--name "My App" --slug my-app
İki anahtar yazdırır, bir kez:
secret key (server, Authorization: Bearer) sk_live_64b7…
public key (SDKs, x-app-key) pk_live_64b7…
- sk_live_… sunucu anahtarı backend'inize aittir. Bildirim gönderebilir, kullanıcıları yönetebilir, rapor okuyabilir.
- pk_live_… public anahtar uygulama paketinin ya da web sayfasının içinde yaşar. Yalnızca cihaz kaydedebilir ve o cihazın kendi kullanıcısını günceller.
Uygulamayı panelden de oluşturabilirsiniz; aynı iki anahtarı tek seferlik bir diyalogda gösterir.

5 Cihaz kaydet ve gönder
Henüz SDK yokken SDK'ymış gibi davranın:
curl -X POST localhost:3000/v1/subscriptions \
-H "x-app-key: pk_live_…" \
-H "content-type: application/json" \
-d '{
"platform": "ios",
"token": "<64 hex APNs cihaz token'ı>",
"externalId": "user_123",
"tags": { "plan": "premium" },
"language": "tr",
"timezone": "Europe/Istanbul"
}'
# {"id":"66f1…","platform":"ios","userId":"66f1…"}
Backend'inizden o kullanıcıya gönderin:
curl -X POST localhost:3000/v1/notifications \
-H "Authorization: Bearer sk_live_…" \
-H "content-type: application/json" \
-d '{
"target": { "externalIds": ["user_123"] },
"content": {
"en": { "title": "Welcome aboard", "body": "Your account is ready." },
"tr": { "title": "Hoş geldin", "body": "Hesabın hazır." },
"_default": "en"
},
"data": { "screen": "home" }
}'
# HTTP 202 {"id":"66f1…","status":"sending"}
API bir kampanya kimliğiyle 202 döner; teslimatı worker yapar. İzleyin:
docker compose logs -f worker
curl -H "Authorization: Bearer sk_live_…" localhost:3000/v1/campaigns/<id>/stats
Gerçek kimlik bilgilerini yükleyene kadar gönderim worker günlüğünde net bir hatayla başarısız olur — bu beklenen durum. Sırada onlar var.
Sırada ne var
| Hedef | Sayfa |
|---|---|
| APNs anahtarı, FCM service account, VAPID çifti yükle | Platform kurulumu ya da Kimlik bilgileri sayfası |
| Yönetim panelini aç | Panel kurulumu |
| SDK'yı uygulamaya koy | SDK'lar |
| Kullanıcı / abonelik / kampanya farkını anla | Kavramlar |
| TLS ile bir alan adının arkasına kur | Dokploy / Traefik |