Untuk mengirim pesan push, Anda harus mendapatkan izin dari pengguna terlebih dahulu, lalu mendaftarkan perangkatnya ke layanan push. Hal ini melibatkan penggunaan JavaScript API untuk mendapatkan objek PushSubscription, yang kemudian Anda kirim ke server.
JavaScript API mengelola proses ini secara langsung. Panduan ini menjelaskan seluruh alur, termasuk deteksi fitur, meminta izin, dan mengelola proses langganan.
Deteksi fitur
Pertama, periksa apakah browser mendukung pesan push. Anda dapat memeriksa dukungan push dengan dua pemeriksaan:
- Periksa
serviceWorkerpada objeknavigator. - Periksa
PushManagerpada objekwindow.
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;
}
Meskipun dukungan browser untuk pekerja layanan dan pesan push meningkat, selalu deteksi kedua fitur tersebut dan tingkatkan aplikasi Anda secara progresif.
Mendaftarkan pekerja layanan
Setelah deteksi fitur, Anda mengetahui bahwa pekerja layanan dan pesan push didukung. Selanjutnya, daftarkan pekerja layanan Anda.
Saat mendaftarkan pekerja layanan, Anda memberi tahu browser lokasi file pekerja layanan Anda. File tersebut adalah file JavaScript, tetapi browser memberikan akses ke API pekerja layanan, termasuk pesan push. Secara khusus, browser menjalankan file di lingkungan pekerja layanan.
Untuk mendaftarkan service worker, panggil navigator.serviceWorker.register() dan teruskan jalur ke file Anda. Contoh:
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);
});
}
Fungsi ini memberi tahu browser lokasi file pekerja layanan Anda. Di sini, file pekerja layanan berada di /service-worker.js. Setelah Anda memanggil register(), browser akan melakukan langkah-langkah berikut:
Download file pekerja layanan.
Jalankan JavaScript.
Jika file berjalan dengan benar tanpa error, promise yang ditampilkan oleh
register()akan diselesaikan. Jika terjadi error, promise akan ditolak.
Catatan: Jika register() ditolak, periksa apakah ada salah ketik atau error di JavaScript Anda di Chrome DevTools.
Saat register() diselesaikan, register() akan menampilkan ServiceWorkerRegistration. Anda menggunakan pendaftaran ini untuk mengakses PushManager API.
Kompatibilitas browser PushManager API
Meminta izin
Setelah mendaftarkan pekerja layanan dan mendapatkan izin, dapatkan izin dari pengguna untuk mengirim pesan push.
API untuk mendapatkan izin sangat sederhana. Namun, API baru-baru ini berubah dari mengambil callback menjadi menampilkan Promise. Karena Anda tidak dapat menentukan versi API mana yang diterapkan browser, Anda harus menerapkan dan menangani kedua versi.
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.");
}
});
}
Dalam kode sebelumnya, panggilan ke Notification.requestPermission() menampilkan perintah kepada pengguna:

Setelah pengguna berinteraksi dengan dialog izin dengan memilih Izinkan, Blokir, atau menutupnya, Anda akan menerima hasilnya sebagai string: 'granted', 'default', atau 'denied'.
Dalam kode contoh, promise yang ditampilkan oleh askPermission() akan diselesaikan jika izin diberikan; jika tidak, promise akan menampilkan error dan ditolak.
Tangani kasus ekstrem saat pengguna mengklik tombol Blokir. Jika hal ini terjadi, aplikasi web Anda tidak dapat meminta izin lagi kepada pengguna. Pengguna harus membatalkan pemblokiran aplikasi Anda secara manual dengan mengubah status izinnya di panel setelan. Pertimbangkan dengan cermat kapan dan bagaimana cara meminta izin, karena jika pengguna mengklik Blokir, keputusan tersebut tidak dapat dibatalkan dengan mudah.
Sebagian besar pengguna memberikan izin jika mereka memahami alasan aplikasi memintanya.
Dokumen ini membahas cara beberapa situs populer meminta izin di bagian selanjutnya dalam dokumen ini.
Membuat pengguna berlangganan dengan PushManager
Setelah mendaftarkan pekerja layanan dan mendapatkan izin, Anda dapat mengikutsertakan pengguna dengan memanggil registration.pushManager.subscribe().
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;
});
}
Saat memanggil metode subscribe(), Anda meneruskan objek options yang terdiri dari parameter wajib dan opsional.
Bagian ini menjelaskan opsi yang dapat Anda teruskan.
Opsi userVisibleOnly
Saat pesan push pertama kali ditambahkan ke browser, developer tidak yakin tentang pengiriman pesan push tanpa menampilkan notifikasi. Hal ini biasanya disebut sebagai push senyap karena pengguna tidak mengetahui bahwa peristiwa terjadi di latar belakang.
Kekhawatirannya adalah developer dapat melacak lokasi pengguna secara terus-menerus tanpa sepengetahuan pengguna.
Untuk menghindari skenario ini dan memungkinkan penulis spesifikasi mempertimbangkan cara terbaik untuk mendukung fitur ini, opsi userVisibleOnly ditambahkan. Meneruskan nilai true adalah perjanjian simbolis dengan browser bahwa aplikasi web menampilkan notifikasi setiap kali menerima pesan push (yaitu, tidak ada push senyap).
Anda harus meneruskan nilai true. Jika Anda tidak menyertakan kunci userVisibleOnly atau meneruskan false, Anda akan menerima error berikut:
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 mendukung Push API hanya untuk langganan yang menghasilkan pesan yang terlihat pengguna. Tunjukkan hal ini dengan memanggil pushManager.subscribe({userVisibleOnly: true}). Untuk mengetahui informasi selengkapnya, lihat https://goo.gl/yqv4Q4.
Tampaknya push senyap menyeluruh tidak akan diterapkan di Chrome. Sebagai gantinya, penulis spesifikasi sedang mempelajari API anggaran yang memungkinkan aplikasi web mengirim sejumlah pesan push senyap berdasarkan penggunaan aplikasi web.
Opsi applicationServerKey
Dokumen ini sebelumnya menyebutkan kunci server aplikasi. Layanan push menggunakan kunci server aplikasi untuk mengidentifikasi aplikasi yang mendaftarkan pengguna dan untuk memastikan bahwa aplikasi yang sama mengirimkan pesan kepada pengguna tersebut.
Kunci server aplikasi adalah pasangan kunci publik dan pribadi yang unik untuk aplikasi Anda. Rahasiakan kunci pribadi aplikasi Anda, dan bagikan kunci publik secara bebas.
Opsi applicationServerKey yang diteruskan ke panggilan subscribe() adalah kunci publik aplikasi Anda. Browser meneruskan kunci ini ke layanan push saat mendaftarkan pengguna, yang memungkinkan layanan push mengikat kunci publik aplikasi Anda ke PushSubscription pengguna.
Diagram berikut menggambarkan langkah-langkah ini.
- Muat aplikasi web Anda di browser dan panggil
subscribe(), dengan meneruskan kunci server aplikasi publik Anda. - Kemudian, browser membuat permintaan jaringan ke layanan push, yang menghasilkan endpoint, mengaitkan endpoint ini dengan kunci publik aplikasi Anda, dan menampilkan endpoint ke browser.
- Browser menambahkan endpoint ini ke
PushSubscription, yang ditampilkan oleh promisesubscribe().
Saat Anda mengirim pesan push, buat header Authorization yang berisi informasi yang ditandatangani dengan kunci pribadi server aplikasi Anda. Saat menerima permintaan untuk mengirim pesan push, layanan push akan memvalidasi header Authorization bertanda tangan ini dengan mencari kunci publik yang ditautkan ke endpoint yang menerima permintaan. Jika tanda tangan valid, layanan push akan mengetahui bahwa permintaan berasal dari server aplikasi dengan kunci pribadi yang cocok. Ini adalah langkah keamanan yang mencegah orang lain mengirim pesan kepada pengguna aplikasi Anda.
Secara teknis, applicationServerKey bersifat opsional. Namun, penerapan paling sederhana di Chrome memerlukannya, dan browser lain mungkin memerlukannya pada masa mendatang. Kolom ini bersifat opsional di Firefox.
Spesifikasi VAPID menentukan kunci server aplikasi. Saat Anda melihat referensi ke kunci server aplikasi atau kunci VAPID, ingatlah bahwa keduanya sama.
Membuat kunci server aplikasi
Anda dapat membuat kumpulan kunci server aplikasi publik dan pribadi dengan membuka web-push-codelab.glitch.me atau dengan menggunakan command line web-push untuk membuat kunci sebagai berikut:
$ npm install -g web-push
$ web-push generate-vapid-keys
Buat kunci ini hanya sekali untuk aplikasi Anda, dan pastikan Anda menjaga kerahasiaan kunci pribadi.
Izin dan subscribe()
Memanggil subscribe() memiliki satu efek samping. Jika aplikasi web Anda tidak memiliki izin untuk menampilkan notifikasi saat Anda memanggil subscribe(), browser akan meminta izin untuk Anda. Hal ini berguna jika UI Anda berfungsi dengan alur ini, tetapi jika Anda menginginkan lebih banyak kontrol (yang diinginkan sebagian besar developer), gunakan Notification.requestPermission() API yang dibahas dalam dokumen ini sebelumnya.
Ringkasan PushSubscription
Anda memanggil subscribe(), meneruskan opsi, dan menerima promise yang diselesaikan ke PushSubscription. Contoh:
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;
});
}
Objek PushSubscription berisi semua informasi yang diperlukan untuk mengirim pesan push kepada pengguna tersebut. Jika Anda mencetak konten menggunakan JSON.stringify(), Anda akan melihat hal berikut:
{
"endpoint": "https://some.pushservice.com/something-unique",
"keys": {
"p256dh":
"BIPUL12DLfytvTajnryr2PRdAgXS3HGKiLqndGcJGabyhHheJYlNGCeXl1dn18gSJ1WAkAPIxr4gK0_dQds4yiI=",
"auth":"FPssNDTKnInHVndSTdbKFw=="
}
}
endpoint adalah URL layanan push. Untuk memicu pesan push, buat permintaan POST ke URL ini.
Objek keys berisi nilai yang digunakan untuk mengenkripsi data pesan yang dikirim dengan pesan push. (Dokumen ini akan membahas enkripsi pesan nanti.)
Mengirim langganan ke server Anda
Setelah memiliki langganan push, kirimkan ke server Anda. Anda menentukan cara mengirimkannya, tetapi sebaiknya gunakan JSON.stringify() untuk mengekstrak semua data yang diperlukan dari objek langganan. Atau, Anda dapat merakit hasil yang sama secara manual, misalnya:
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);
Untuk mengirim langganan dari halaman web, gunakan perintah berikut:
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.');
}
});
}
Server Node.js menerima permintaan ini dan menyimpan data ke database untuk digunakan nanti.
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.',
},
}),
);
});
});
Dengan detail PushSubscription di server, Anda dapat mengirim pesan kepada pengguna kapan saja.
Berlangganan lagi secara rutin untuk mencegah masa berlaku habis
Saat berlangganan notifikasi push, Anda sering menerima PushSubscription.expirationTime null. Secara teori, ini berarti langganan tidak pernah berakhir. (Sebaliknya, DOMHighResTimeStamp menunjukkan waktu habis masa berlaku yang tepat.) Namun, dalam praktiknya, browser biasanya membiarkan langganan berakhir. Misalnya, hal ini dapat terjadi jika tidak ada notifikasi push yang diterima dalam waktu yang lama, atau jika browser mendeteksi bahwa pengguna tidak menggunakan aplikasi yang memiliki izin notifikasi push. Salah satu pola untuk mencegah hal ini adalah dengan mendaftarkan ulang pengguna saat setiap notifikasi diterima, seperti yang ditunjukkan oleh cuplikan berikut. Hal ini mengharuskan Anda mengirim notifikasi cukup sering untuk mencegah browser menghentikan langganan secara otomatis. Anda harus mempertimbangkan dengan cermat keuntungan dan kerugian dari kebutuhan notifikasi yang sah dibandingkan dengan mengirim spam kepada pengguna secara tidak sukarela hanya untuk mencegah langganan berakhir. Pada akhirnya, Anda tidak boleh mencoba mengakali upaya browser untuk melindungi pengguna dari langganan notifikasi yang sudah lama tidak digunakan.
/* 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);
});
}
Pertanyaan umum (FAQ)
Berikut beberapa pertanyaan umum:
Dapatkah Anda mengubah layanan push yang digunakan browser?
Tidak, browser memilih layanan push. Seperti yang dibahas dalam dokumen ini dengan panggilan subscribe(), browser membuat permintaan jaringan ke layanan push untuk mengambil detail yang membentuk PushSubscription.
Apakah layanan push yang berbeda menggunakan API yang berbeda?
Semua layanan push mengharapkan API yang sama.
API umum ini, yang disebut Web Push Protocol, menjelaskan permintaan jaringan yang dibuat aplikasi Anda untuk memicu pesan push.
Jika Anda menyubscribe pengguna di desktop, apakah pengguna tersebut juga disubscribe di ponselnya?
Tidak. Pengguna harus mendaftar untuk pesan push di setiap browser tempat mereka ingin menerima pesan. Pengguna juga harus memberikan izin di setiap perangkat.
Langkah berikutnya
- Ringkasan Notifikasi Push Web
- Cara kerja pesan push
- Menyertakan pengguna dalam langganan
- Pengalaman pengguna izin
- Mengirim pesan dengan library push web
- Protokol Push Web
- Menangani peristiwa push
- Menampilkan notifikasi
- Perilaku notifikasi
- Pola notifikasi umum
- Pertanyaan umum (FAQ) tentang notifikasi push
- Masalah umum dan pelaporan bug