Push mesajları göndermek için önce kullanıcıdan izin almanız, ardından kullanıcının cihazını bir push hizmetine abone etmeniz gerekir. Bu işlem, JavaScript API'yi kullanarak bir PushSubscription nesnesi almayı ve ardından bu nesneyi sunucunuza göndermeyi içerir.
JavaScript API, bu süreci basit bir şekilde yönetir. Bu kılavuzda; özellik algılama, izin isteme ve abonelik sürecini yönetme dahil olmak üzere tüm akış açıklanmaktadır.
Özellik algılama
Öncelikle tarayıcının push mesajlaşmayı destekleyip desteklemediğini kontrol edin. Anlık bildirim desteğini iki şekilde kontrol edebilirsiniz:
navigatornesnesindeserviceWorkerolup olmadığını kontrol edin.windownesnesindePushManagerolup olmadığını kontrol edin.
if (!('serviceWorker' in navigator)) {
// Service Worker isn't supported on this browser, disable or hide UI.
return;
}
if (!('PushManager' in window)) {
// Push isn't supported on this browser, disable or hide UI.
return;
}
Hem hizmet çalışanı hem de push mesajlaşma için tarayıcı desteği artarken her iki özelliği de her zaman tespit edin ve uygulamanızı aşamalı olarak geliştirin.
Hizmet çalışanını kaydetme
Özellik algılamadan sonra, hizmet çalışanlarının ve push mesajlaşmanın desteklendiğini bilirsiniz. Ardından hizmet çalışanınızı kaydedin.
Bir hizmet çalışanını kaydettiğinizde tarayıcıya hizmet çalışanı dosyanızın konumunu bildirirsiniz. Dosya bir JavaScript dosyasıdır ancak tarayıcı, push mesajlaşma dahil olmak üzere hizmet çalışanı API'lerine erişim izni verir. Tarayıcı, dosyayı özellikle bir hizmet çalışanı ortamında çalıştırır.
Hizmet çalışanı kaydetmek için navigator.serviceWorker.register() yöntemini çağırın ve dosyanızın yolunu iletin. Örneğin:
function registerServiceWorker() {
return navigator.serviceWorker
.register('/service-worker.js')
.then(function (registration) {
console.log('Service worker successfully registered.');
return registration;
})
.catch(function (err) {
console.error('Unable to register service worker.', err);
});
}
Bu işlev, tarayıcıya hizmet çalışanı dosyanızın konumunu bildirir. Burada, hizmet çalışanı dosyası /service-worker.js konumundadır. register() yöntemini çağırdıktan sonra tarayıcı şu adımları uygular:
Hizmet çalışanı dosyasını indirin.
JavaScript'i çalıştırın.
Dosya hatasız bir şekilde doğru çalışırsa
register()tarafından döndürülen promise çözümlenir. Hata oluşursa promise reddedilir.
Not: register() reddederse Chrome Geliştirici Araçları'nda JavaScript'inizde yazım hatası veya başka hata olup olmadığını kontrol edin.
register() çözümlendiğinde ServiceWorkerRegistration döndürür. PushManager API'ye erişmek için bu kaydı kullanırsınız.
PushManager API tarayıcı uyumluluğu
İzin isteniyor
Hizmet çalışanınızı kaydedip izin aldıktan sonra kullanıcıdan push mesajları gönderme izni alın.
İzin almak için kullanılan API basittir. Ancak API, yakın zamanda geri çağırma yerine Promise döndürecek şekilde değiştirildi. Tarayıcının hangi API sürümünü uyguladığını belirleyemediğiniz için her iki sürümü de uygulamanız ve işlemeniz gerekir.
function askPermission() {
return new Promise(function (resolve, reject) {
const permissionResult = Notification.requestPermission(function (result) {
resolve(result);
});
if (permissionResult) {
permissionResult.then(resolve, reject);
}
}).then(function (permissionResult) {
if (permissionResult !== 'granted') {
throw new Error("We weren't granted permission.");
}
});
}
Yukarıdaki kodda, Notification.requestPermission() çağrısı kullanıcıya bir istem gösterir:

Kullanıcı İzin ver veya Engelle'yi seçerek ya da kapatarak izin istemiyle etkileşimde bulunduktan sonra sonucu dize olarak alırsınız: 'granted', 'default' veya 'denied'.
Örnek kodda, izin verilirse askPermission() tarafından döndürülen promise çözümlenir. Aksi takdirde hata verir ve promise reddedilir.
Kullanıcının Engelle düğmesini tıkladığı uç durumu ele alın. Bu durumda web uygulamanız kullanıcıdan tekrar izin isteyemez. Kullanıcının, bir ayarlar panelinde uygulamanızın izin durumunu değiştirerek uygulamanızın engellemesini manuel olarak kaldırması gerekir. Kullanıcı Engelle'yi tıkladığında bu kararı geri almak kolay olmadığından ne zaman ve nasıl izin isteyeceğinizi dikkatlice düşünün.
Çoğu kullanıcı, uygulamanın neden izin istediğini anlarsa izin verir.
Bu belgenin ilerleyen kısımlarında, bazı popüler sitelerin nasıl izin istediği ele alınmaktadır.
PushManager ile kullanıcıya abone olma
Hizmet çalışanınızı kaydedip izin aldıktan sonra registration.pushManager.subscribe() yöntemini çağırarak bir kullanıcıyı abone yapabilirsiniz.
function subscribeUserToPush() {
return navigator.serviceWorker
.register('/service-worker.js')
.then(function (registration) {
const subscribeOptions = {
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(
'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U',
),
};
return registration.pushManager.subscribe(subscribeOptions);
})
.then(function (pushSubscription) {
console.log(
'Received PushSubscription: ',
JSON.stringify(pushSubscription),
);
return pushSubscription;
});
}
subscribe() yöntemini çağırdığınızda, zorunlu ve isteğe bağlı parametrelerden oluşan bir options nesnesi iletirsiniz.
Bu bölümde, iletebileceğiniz seçenekler açıklanmaktadır.
userVisibleOnly seçenekleri
Push mesajlaşma tarayıcılara ilk eklendiğinde geliştiriciler, bildirim göstermeden push mesaj gönderme konusunda kararsızdı. Kullanıcı arka planda bir etkinlik gerçekleştiğini bilmediği için bu genellikle sessiz push olarak adlandırılır.
Geliştiricilerin, kullanıcının bilgisi olmadan kullanıcının konumunu sürekli olarak takip edebileceğinden endişe ediliyordu.
Bu senaryoyu önlemek ve spesifikasyon yazarlarının bu özelliği en iyi şekilde nasıl destekleyeceklerini düşünmelerine olanak tanımak için userVisibleOnly seçeneği eklendi. true değerinin iletilmesi, web uygulamasının her push mesajı aldığında bildirim göstereceğine (yani sessiz push olmayacağına) dair tarayıcıyla yapılan sembolik bir anlaşmadır.
true değerini iletmeniz gerekir. userVisibleOnly anahtarını eklemez veya false değerini iletmezseniz aşağıdaki hatayı alırsınız:
Chrome currently only supports the Push API for subscriptions that will result
in user-visible messages. You can indicate this by calling
`pushManager.subscribe({userVisibleOnly: true})` instead. See
[https://goo.gl/yqv4Q4](https://goo.gl/yqv4Q4) for more details.
Chrome, Push API'yi yalnızca kullanıcı tarafından görülebilen mesajlarla sonuçlanan abonelikler için destekler. Bunu belirtmek için pushManager.subscribe({userVisibleOnly: true}) numaralı telefonu arayın. Daha fazla bilgi için https://goo.gl/yqv4Q4 adresini ziyaret edin.
Chrome'da genel sessiz push bildirimleri uygulanmayacak. Bunun yerine, spesifikasyon yazarları, web uygulamalarının web uygulaması kullanımına dayalı olarak belirli sayıda sessiz push mesajı göndermesine olanak tanıyan bir bütçe API'sini araştırıyor.
applicationServerKey seçeneği
Bu dokümanda daha önce uygulama sunucusu anahtarlarından bahsediliyordu. Push hizmeti, bir kullanıcıya abone olan uygulamayı tanımlamak ve aynı uygulamanın kullanıcıya mesaj göndermesini sağlamak için uygulama sunucusu anahtarlarını kullanır.
Uygulama sunucusu anahtarları, uygulamanıza özel bir ortak ve özel anahtar çiftidir. Özel anahtarı uygulamanızda gizli tutun ve ortak anahtarı dilediğiniz gibi paylaşın.
subscribe() çağrısına iletilen applicationServerKey seçeneği, uygulamanızın ortak anahtarıdır. Tarayıcı, kullanıcıya abone olurken bu anahtarı bir push hizmetine iletir. Bu sayede push hizmeti, uygulamanızın ortak anahtarını kullanıcının PushSubscription anahtarına bağlayabilir.
Aşağıdaki şemada bu adımlar gösterilmektedir.
- Web uygulamanızı bir tarayıcıda yükleyin ve herkese açık uygulama sunucusu anahtarınızı ileterek
subscribe()yöntemini çağırın. - Ardından tarayıcı, bir push hizmetine ağ isteği gönderir. Bu hizmet bir uç nokta oluşturur, bu uç noktayı uygulamanızın ortak anahtarıyla ilişkilendirir ve uç noktayı tarayıcıya döndürür.
- Tarayıcı, bu uç noktayı
subscribe()vaadinin döndürdüğüPushSubscriptionöğesine ekler.
Push mesajı gönderirken uygulama sunucunuzun özel anahtarıyla imzalanmış bilgileri içeren bir Yetkilendirme başlığı oluşturun. Push hizmeti, push mesajı gönderme isteği aldığında, isteği alan uç noktaya bağlı ortak anahtarı arayarak bu imzalı Authorization başlığını doğrular. İmza geçerliyse push hizmeti, isteğin eşleşen özel anahtara sahip uygulama sunucusundan geldiğini anlar. Bu, başkalarının uygulamanızın kullanıcılarına mesaj göndermesini engelleyen bir güvenlik önlemidir.
Teknik olarak applicationServerKey isteğe bağlıdır. Ancak Chrome'daki en basit uygulama için bu gereklidir ve diğer tarayıcılar da gelecekte bunu gerektirebilir. Firefox'ta isteğe bağlıdır.
VAPID spesifikasyonu, uygulama sunucusu anahtarını tanımlar. Uygulama sunucusu anahtarları veya VAPID anahtarlarıyla ilgili referanslar gördüğünüzde bunların aynı olduğunu unutmayın.
Uygulama sunucusu anahtarları oluşturma
Aşağıdaki gibi anahtar oluşturmak için web-push komut satırını kullanarak herkese açık ve özel bir uygulama sunucusu anahtarı grubu oluşturabilirsiniz:
$ npm install -g web-push
$ web-push generate-vapid-keys
Bu anahtarları uygulamanız için yalnızca bir kez oluşturun ve özel anahtarı gizli tuttuğunuzdan emin olun.
İzinler ve subscribe()
subscribe() çağrısının bir yan etkisi vardır. Web uygulamanızın subscribe() yöntemini çağırdığınızda bildirim gösterme izni yoksa tarayıcı sizin adınıza izin ister. Kullanıcı arayüzünüz bu akışla çalışıyorsa bu yöntem kullanışlıdır. Ancak daha fazla kontrol istiyorsanız (çoğu geliştirici ister) bu belgede daha önce bahsedilen Notification.requestPermission() API'yi kullanın.
PushSubscription'a genel bakış
subscribe() işlevini çağırır, seçenekleri iletir ve PushSubscription olarak çözümlenen bir promise alırsınız. Örneğin:
function subscribeUserToPush() {
return navigator.serviceWorker
.register('/service-worker.js')
.then(function (registration) {
const subscribeOptions = {
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(
'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U',
),
};
return registration.pushManager.subscribe(subscribeOptions);
})
.then(function (pushSubscription) {
console.log(
'Received PushSubscription: ',
JSON.stringify(pushSubscription),
);
return pushSubscription;
});
}
PushSubscription nesnesi, ilgili kullanıcıya push mesajları göndermek için gereken tüm bilgileri içerir. İçerikleri JSON.stringify() kullanarak yazdırırsanız aşağıdakileri görürsünüz:
{
"endpoint": "https://some.pushservice.com/something-unique",
"keys": {
"p256dh":
"BIPUL12DLfytvTajnryr2PRdAgXS3HGKiLqndGcJGabyhHheJYlNGCeXl1dn18gSJ1WAkAPIxr4gK0_dQds4yiI=",
"auth":"FPssNDTKnInHVndSTdbKFw=="
}
}
endpoint, push hizmetinin URL'sidir. Push mesajını tetiklemek için bu URL'ye bir POST isteği gönderin.
keys nesnesi, push mesajıyla gönderilen mesaj verilerini şifrelemek için kullanılan değerleri içerir. (Bu dokümanda, ileti şifreleme konusuna daha sonra değinilecektir.)
Sunucunuza abonelik gönderme
Push aboneliğiniz olduktan sonra bunu sunucunuza gönderin. Nasıl göndereceğinizi siz belirlersiniz ancak abonelik nesnesinden gerekli tüm verileri ayıklamak için JSON.stringify() kullanmanızı öneririz. Alternatif olarak, aynı sonucu manuel olarak da oluşturabilirsiniz. Örneğin:
const subscriptionObject = {
endpoint: pushSubscription.endpoint,
keys: {
p256dh: pushSubscription.getKeys('p256dh'),
auth: pushSubscription.getKeys('auth'),
},
};
// The above is the same output as:
const subscriptionObjectToo = JSON.stringify(pushSubscription);
Aboneliği web sayfasından göndermek için aşağıdakileri kullanın:
function sendSubscriptionToBackEnd(subscription) {
return fetch('/api/save-subscription/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(subscription),
})
.then(function (response) {
if (!response.ok) {
throw new Error('Bad status code from server.');
}
return response.json();
})
.then(function (responseData) {
if (!(responseData.data && responseData.data.success)) {
throw new Error('Bad response from server.');
}
});
}
Node.js sunucusu bu isteği alır ve verileri daha sonra kullanmak üzere bir veritabanına kaydeder.
app.post('/api/save-subscription/', function (req, res) {
if (!isValidSaveRequest(req, res)) {
return;
}
return saveSubscriptionToDatabase(req.body)
.then(function (subscriptionId) {
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({data: {success: true}}));
})
.catch(function (err) {
res.status(500);
res.setHeader('Content-Type', 'application/json');
res.send(
JSON.stringify({
error: {
id: 'unable-to-save-subscription',
message:
'The subscription was received but we were unable to save it to our database.',
},
}),
);
});
});
Sunucunuzdaki PushSubscription bilgileriyle kullanıcınıza istediğiniz zaman mesaj gönderebilirsiniz.
Süresinin dolmasını önlemek için düzenli olarak yeniden abone olun.
Push bildirimlerine abone olduğunuzda genellikle null değerinde bir PushSubscription.expirationTime alırsınız. Teorik olarak bu, aboneliğin süresinin hiçbir zaman dolmayacağı anlamına gelir. (Buna karşılık, DOMHighResTimeStamp tam geçerlilik bitiş zamanını gösterir.) Ancak uygulamada, tarayıcılar genellikle aboneliklerin süresinin dolmasına izin verir. Örneğin, uzun süre push bildirimi alınmazsa veya tarayıcı, kullanıcının push bildirimi izni olan bir uygulama kullanmadığını algılarsa bu durum ortaya çıkabilir. Bunu önlemenin bir yolu, aşağıdaki snippet'te gösterildiği gibi, alınan her bildirimde kullanıcıyı yeniden abone etmektir. Bu durumda, tarayıcının aboneliği otomatik olarak sonlandırmasını önlemek için yeterli sıklıkta bildirim göndermeniz gerekir. Yalnızca abonelik süresinin dolmasını önlemek için kullanıcıya istemeden spam göndermek yerine, meşru bildirim ihtiyaçlarının avantajlarını ve dezavantajlarını dikkatlice değerlendirmeniz gerekir. Sonuç olarak, tarayıcının kullanıcıyı uzun süre önce unutulmuş bildirim aboneliklerinden koruma çabalarını engellemeye çalışmamalısınız.
/* In the Service Worker. */
self.addEventListener('push', function(event) {
console.log('Received a push message', event);
// Display notification or handle data
// Example: show a notification
const title = 'New Notification';
const body = 'You have new updates!';
const icon = '/images/icon.png';
const tag = 'simple-push-demo-notification-tag';
event.waitUntil(
self.registration.showNotification(title, {
body: body,
icon: icon,
tag: tag
})
);
// Attempt to resubscribe after receiving a notification
event.waitUntil(resubscribeToPush());
});
function resubscribeToPush() {
return self.registration.pushManager.getSubscription()
.then(function(subscription) {
if (subscription) {
return subscription.unsubscribe();
}
})
.then(function() {
return self.registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array('YOUR_PUBLIC_VAPID_KEY_HERE')
});
})
.then(function(subscription) {
console.log('Resubscribed to push notifications:', subscription);
// Optionally, send new subscription details to your server
})
.catch(function(error) {
console.error('Failed to resubscribe:', error);
});
}
Sık sorulan sorular
Sık sorulan bazı soruları aşağıda bulabilirsiniz:
Tarayıcının kullandığı push hizmetini değiştirebilir misiniz?
Hayır, push hizmetini tarayıcı seçer. Bu belgede subscribe() çağrısıyla ilgili olarak açıklandığı gibi, tarayıcı PushSubscription'i oluşturan ayrıntıları almak için push hizmetine ağ istekleri gönderir.
Farklı push hizmetleri farklı API'ler mi kullanıyor?
Tüm push hizmetleri aynı API'yi bekler.
Web Push Protokolü olarak adlandırılan bu ortak API, uygulamanızın push mesajını tetiklemek için yaptığı ağ isteğini açıklar.
Bir kullanıcıyı masaüstünde abone yaparsanız telefonunda da abone olur mu?
Hayır. Kullanıcı, mesaj almak istediği her tarayıcıda push mesajlaşma için kaydolmalıdır. Bu durumda kullanıcının her cihazda izin vermesi de gerekir.
Sonraki adımlar
- Web push bildirimlerine genel bakış
- Push mesajlaşmanın işleyiş şekli
- Kullanıcıları abone yapma
- İzin kullanıcı deneyimi
- Web push kitaplıklarıyla mesaj gönderme
- Web Push Protokolü
- Push etkinliklerini işleme
- Bildirim gösterme
- Bildirim davranışı
- Sık kullanılan bildirim kalıpları
- Push bildirimleriyle ilgili sık sorulan sorular
- Sık karşılaşılan sorunlar ve hataları bildirme