Menambahkan notifikasi push ke aplikasi web

Pesan push memberikan cara yang sederhana dan efektif untuk berinteraksi kembali dengan pengguna Anda. Dalam codelab ini, Anda akan mempelajari cara menambahkan notifikasi push ke aplikasi web.

Yang akan Anda pelajari

  • Cara berlangganan dan berhenti berlangganan pengguna untuk pesan push
  • Cara menangani pesan push masuk
  • Cara menampilkan notifikasi
  • Cara merespons klik notifikasi

Yang Anda butuhkan

  • Chrome 52 atau yang lebih baru
  • Server Web untuk Chrome, atau server web pilihan Anda sendiri
  • Editor teks
  • Pengetahuan dasar tentang HTML, CSS, JavaScript, dan Chrome DevTools
  • Kode contoh (Lihat bagian Mulai penyiapan.)

Download kode contoh

Anda memiliki dua opsi untuk mendapatkan kode contoh codelab ini:

  • Buat clone repositori Git:
git clone https://github.com/GoogleChrome/push-notifications.git
  • Download file ZIP:

Download kode sumber

Jika Anda mendownload sumber sebagai file ZIP, mengekstraknya akan memberi Anda folder root push-notifications-master.

Menginstal dan memverifikasi server web

Meskipun Anda bebas menggunakan server web sendiri, codelab ini dirancang agar berfungsi dengan baik dengan aplikasi Web Server for Chrome. Jika belum menginstal aplikasi tersebut, Anda bisa mendapatkannya dari Chrome Web Store:

Menginstal Server Web untuk Chrome

Setelah menginstal aplikasi Web Server untuk Chrome, klik pintasan Aplikasi di kolom bookmark:

Di jendela Aplikasi, klik ikon Server Web:

Anda akan melihat dialog ini berikutnya, yang memungkinkan Anda mengonfigurasi server web lokal:

Klik tombol Pilih folder, lalu pilih folder app di folder push-notifications yang Anda download. Tindakan ini memungkinkan Anda menyalurkan pekerjaan yang sedang berlangsung melalui URL yang ditampilkan di bagian URL Server Web dalam dialog.

Di bagian Opsi, centang kotak di samping Tampilkan index.html secara otomatis, seperti yang ditunjukkan di bawah:

Kemudian, hentikan dan mulai ulang server dengan menggeser tombol Web Server: STARTED ke kiri, lalu kembali ke kanan.

Klik URL Server Web untuk membuka situs Anda di browser web. Anda akan melihat halaman yang terlihat seperti ini — meskipun versi Anda mungkin menampilkan 127.0.0.1:8887 sebagai alamat:

00-push-codelab.png

Selalu update pekerja layanan

Selama pengembangan, sebaiknya pastikan pekerja layanan Anda selalu diupdate dan memiliki perubahan terbaru.

Untuk menyiapkannya di Chrome:

  1. Buka tab Push Codelab.
  2. Buka DevTools: Ctrl-Shift-I di Windows dan Linux, Cmd-Option-I di macOS.
  3. Pilih panel Application, klik tab Service Workers, lalu centang kotak Update on Reload. Jika kotak centang ini diaktifkan, pekerja layanan akan diperbarui secara paksa setiap kali halaman dimuat ulang.

Kode yang telah selesai

Di direktori app, perhatikan bahwa Anda memiliki file kosong bernama sw.js. File ini akan menjadi pekerja layanan Anda. Untuk saat ini, kolom tersebut dapat dibiarkan kosong. Anda akan menambahkan kode ke dalamnya nanti.

Pertama, Anda perlu mendaftarkan file ini sebagai pekerja layanan Anda.

Halaman app/index.html Anda dimuat scripts/main.js. Anda mendaftarkan pekerja layanan di file JavaScript ini.

Tambahkan kode berikut ke scripts/main.js:

if ('serviceWorker' in navigator && 'PushManager' in window) {
  console.log('Service Worker and Push are supported');

  navigator.serviceWorker.register('sw.js')
  .then(function(swReg) {
    console.log('Service Worker is registered', swReg);

    swRegistration = swReg;
  })
  .catch(function(error) {
    console.error('Service Worker Error', error);
  });
} else {
  console.warn('Push messaging is not supported');
  pushButton.textContent = 'Push Not Supported';
}

Kode ini memeriksa apakah pekerja layanan dan pesan push didukung oleh browser Anda. Jika didukung, kode akan mendaftarkan file sw.js Anda.

Coba

Periksa perubahan Anda dengan memuat ulang tab Push Codelab di browser.

Periksa konsol di Chrome DevTools untuk menemukan Service Worker is registered message, seperti berikut:

Mendapatkan kunci server aplikasi

Untuk menggunakan codelab ini, Anda perlu membuat kunci server aplikasi. Anda dapat melakukannya di situs pendamping: web-push-codelab.glitch.me

Di sini Anda dapat membuat pasangan kunci publik dan pribadi.

push-codelab-04-companion.png

Salin kunci publik Anda ke scripts/main.js dengan mengganti nilai <Your Public Key>:

const applicationServerPublicKey = '<Your Public Key>';

Penting: Anda tidak boleh memasukkan kunci pribadi di aplikasi web Anda.

Kode yang telah selesai

Saat ini, tombol Aktifkan aplikasi web dinonaktifkan dan tidak dapat diklik. Hal ini karena praktik yang baik adalah menonaktifkan tombol push secara default dan mengaktifkannya setelah Anda mengetahui bahwa pesan push didukung oleh browser dan Anda dapat memeriksa apakah pengguna saat ini berlangganan pesan atau tidak.

Anda harus membuat dua fungsi di scripts/main.js:

  • initializeUI, untuk memeriksa apakah pengguna saat ini berlangganan
  • updateBtn, untuk mengaktifkan tombol dan mengubah teks bergantung pada apakah pengguna berlangganan atau tidak

Tambahkan fungsi initializeUI ke main.js seperti ini:

function initializeUI() {
  // Set the initial subscription value
  swRegistration.pushManager.getSubscription()
  .then(function(subscription) {
    isSubscribed = !(subscription === null);

    if (isSubscribed) {
      console.log('User IS subscribed.');
    } else {
      console.log('User is NOT subscribed.');
    }

    updateBtn();
  });
}

Metode baru Anda menggunakan swRegistration dari langkah sebelumnya, mendapatkan properti pushManager darinya, dan memanggil getSubscription() di sana.

pushManager. getSubscription() menampilkan promise yang diselesaikan dengan langganan saat ini jika ada. Jika tidak, null akan ditampilkan. Dengan demikian, Anda dapat memeriksa apakah pengguna sudah berlangganan, menetapkan nilai isSubscribed, lalu memanggil updateBtn() untuk memperbarui tombol.

Tambahkan fungsi updateBtn() ke main.js:

function updateBtn() {
  if (isSubscribed) {
    pushButton.textContent = 'Disable Push Messaging';
  } else {
    pushButton.textContent = 'Enable Push Messaging';
  }

  pushButton.disabled = false;
}

Fungsi ini mengaktifkan tombol dan mengubah teks tombol, bergantung pada apakah pengguna berlangganan atau tidak.

Hal terakhir yang harus dilakukan adalah memanggil initializeUI() saat pekerja layanan Anda terdaftar di main.js:

navigator.serviceWorker.register('sw.js')
.then(function(swReg) {
  console.log('Service Worker is registered', swReg);

  swRegistration = swReg;
  initializeUI();
})

Coba

Muat ulang tab Push Codelab. Anda akan melihat bahwa tombol Enable Push Messaging kini diaktifkan (Anda dapat mengkliknya) dan Anda akan melihat User is NOT subscribed di konsol.

Saat Anda melanjutkan codelab ini, Anda akan melihat teks tombol berubah setiap kali Anda berlangganan atau berhenti berlangganan.

Kode yang telah selesai

Saat ini, tombol Aktifkan Pesan Push Anda tidak berfungsi. Ayo perbaiki.

Dalam fungsi initializeUI(), tambahkan pemroses klik untuk tombol Anda:

function initializeUI() {
  pushButton.addEventListener('click', function() {
    pushButton.disabled = true;
    if (isSubscribed) {
      // TODO: Unsubscribe user
    } else {
      subscribeUser();
    }
  });

  // Set the initial subscription value
  swRegistration.pushManager.getSubscription()
  .then(function(subscription) {
    isSubscribed = !(subscription === null);

    updateSubscriptionOnServer(subscription);

    if (isSubscribed) {
      console.log('User IS subscribed.');
    } else {
      console.log('User is NOT subscribed.');
    }

    updateBtn();
  });
}

Saat pengguna mengklik tombol, Anda menonaktifkan tombol tersebut hanya untuk memastikan pengguna tidak dapat mengkliknya untuk kedua kalinya, karena berlangganan pesan push dapat memerlukan waktu beberapa saat.

Kemudian, Anda memanggil subscribeUser() jika pengguna saat ini tidak berlangganan. Untuk melakukannya, Anda harus menempelkan kode berikut ke scripts/main.js:

function subscribeUser() {
  const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
  swRegistration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: applicationServerKey
  })
  .then(function(subscription) {
    console.log('User is subscribed.');

    updateSubscriptionOnServer(subscription);

    isSubscribed = true;

    updateBtn();
  })
  .catch(function(error) {
    console.error('Failed to subscribe the user: ', error);
    updateBtn();
  });
}

Mari kita bahas apa yang dilakukan kode ini dan cara kode ini mendaftarkan pengguna untuk menerima pesan push.

Pertama, Anda mengambil kunci publik server aplikasi, yang dienkode dengan Base64 yang aman untuk URL, dan mengonversinya menjadi UInt8Array, karena ini adalah input yang diharapkan dari panggilan subscribe(). Fungsi urlB64ToUint8Array() berada di bagian atas scripts/main.js.

Setelah mengonversi nilai, Anda memanggil metode subscribe() di pushManager pekerja layanan, dengan meneruskan kunci publik server aplikasi dan nilai userVisibleOnly: true.

const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
swRegistration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: applicationServerKey
})

Parameter userVisibleOnly adalah jaminan bahwa Anda akan menampilkan notifikasi setiap kali pesan push dikirim. Saat ini, nilai ini wajib diisi dan harus benar (true).

Memanggil subscribe() akan menampilkan promise yang akan diselesaikan setelah langkah-langkah berikut:

  1. Pengguna telah memberikan izin untuk menampilkan notifikasi.
  2. Browser telah mengirim permintaan jaringan ke layanan push untuk mendapatkan data yang diperlukan guna membuat PushSubscription.

Promise subscribe() akan diselesaikan dengan PushSubscription jika langkah-langkah ini berhasil. Jika pengguna tidak memberikan izin atau jika ada masalah saat mendaftarkan pengguna, promise akan ditolak dengan error. Hal ini memberi Anda rantai promise berikut dalam codelab:

swRegistration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: applicationServerKey
})
.then(function(subscription) {
  console.log('User is subscribed.');

  updateSubscriptionOnServer(subscription);

  isSubscribed = true;

  updateBtn();

})
.catch(function(err) {
  console.log('Failed to subscribe the user: ', err);
  updateBtn();
});

Dengan ini, Anda akan mendapatkan langganan dan memperlakukan pengguna sebagai pelanggan atau menangkap error dan mencatatnya ke konsol. Dalam kedua skenario, Anda memanggil updateBtn() untuk memastikan bahwa tombol diaktifkan kembali dan memiliki teks yang sesuai.

Dalam aplikasi sebenarnya, fungsi updateSubscriptionOnServer() adalah tempat Anda mengirim data langganan ke backend, tetapi untuk codelab, Anda cukup menampilkan langganan di UI. Tambahkan fungsi berikut ke scripts/main.js:

function updateSubscriptionOnServer(subscription) {
  // TODO: Send subscription to application server

  const subscriptionJson = document.querySelector('.js-subscription-json');
  const subscriptionDetails =
    document.querySelector('.js-subscription-details');

  if (subscription) {
    subscriptionJson.textContent = JSON.stringify(subscription);
    subscriptionDetails.classList.remove('is-invisible');
  } else {
    subscriptionDetails.classList.add('is-invisible');
  }
}

Coba

Buka tab Push Codelab, muat ulang halaman, lalu klik tombol. Anda akan melihat perintah izin seperti ini:

Jika Anda memberikan izin, Anda akan melihat User is subscribed dicatat ke konsol. Teks tombol akan berubah menjadi Nonaktifkan Pesan Push dan Anda akan dapat melihat langganan sebagai data JSON di bagian bawah halaman.

Kode yang telah selesai

Satu hal yang belum Anda tangani adalah apa yang terjadi jika pengguna memblokir permintaan izin. Hal ini memerlukan pertimbangan unik karena jika pengguna memblokir izin, aplikasi web Anda tidak akan dapat menampilkan kembali dialog izin dan tidak akan dapat mendaftarkan pengguna. Anda setidaknya harus menonaktifkan tombol push agar pengguna tahu bahwa tombol tersebut tidak dapat digunakan.

Tempat yang tepat untuk menangani skenario ini adalah di fungsi updateBtn(). Anda hanya perlu memeriksa nilai Notification.permission, seperti berikut:

function updateBtn() {
  if (Notification.permission === 'denied') {
    pushButton.textContent = 'Push Messaging Blocked';
    pushButton.disabled = true;
    updateSubscriptionOnServer(null);
    return;
  }

  if (isSubscribed) {
    pushButton.textContent = 'Disable Push Messaging';
  } else {
    pushButton.textContent = 'Enable Push Messaging';
  }

  pushButton.disabled = false;
}

Anda tahu bahwa jika izinnya denied, pengguna tidak dapat berlangganan dan tidak ada lagi yang dapat Anda lakukan, jadi menonaktifkan tombol secara permanen adalah pendekatan terbaik.

Coba

Karena Anda telah memberikan izin untuk aplikasi web dari langkah sebelumnya, Anda harus mengklik i dalam lingkaran di kolom URL dan mengubah izin Notifikasi menjadi Gunakan default global (Tanya).

Setelah Anda mengubah setelan ini, muat ulang halaman, lalu klik tombol Aktifkan Pesan Push dan pilih Blokir di dialog izin. Tombol akan dinonaktifkan dan menampilkan teks Pesan Push Diblokir.

Dengan perubahan ini, Anda kini dapat mendaftarkan pengguna, setelah menangani kemungkinan skenario izin.

Kode yang telah selesai

Sebelum mempelajari cara mengirim pesan push dari backend, Anda perlu mempertimbangkan apa yang sebenarnya akan terjadi saat pengguna yang berlangganan menerima pesan push.

Saat Anda memicu pesan push, browser akan menerima pesan push, mengetahui service worker yang dituju pesan push tersebut, mengaktifkan service worker tersebut, dan mengirimkan peristiwa push. Anda perlu memantau peristiwa ini dan menampilkan notifikasi sebagai hasilnya.

Tambahkan kode berikut ke file sw.js Anda:

self.addEventListener('push', function(event) {
  console.log('[Service Worker] Push Received.');
  console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);

  const title = 'Push Codelab';
  const options = {
    body: 'Yay it works.',
    icon: 'images/icon.png',
    badge: 'images/badge.png'
  };

  event.waitUntil(self.registration.showNotification(title, options));
});

Mari kita pelajari kode ini. Anda memproses peristiwa push di pekerja layanan dengan menambahkan pemroses peristiwa:

self.addEventListener('push', ... );

(Kecuali jika Anda pernah menggunakan Web Workers sebelumnya, self mungkin baru bagi Anda. Dalam file pekerja layanan, self merujuk pada pekerja layanan itu sendiri.)

Saat pesan push diterima, pemroses peristiwa akan dipanggil, dan Anda membuat notifikasi dengan memanggil showNotification() pada properti registration pekerja layanan. showNotification() memerlukan title; Anda juga dapat memberikan objek options untuk menyetel pesan isi, ikon, dan badge. (Badge hanya digunakan di Android pada saat penulisan.)

const title = 'Push Codelab';
const options = {
  body: 'Yay it works.',
  icon: 'images/icon.png',
  badge: 'images/badge.png'
};
self.registration.showNotification(title, options);

Hal terakhir yang perlu dibahas dalam penanganan peristiwa push adalah event.waitUntil(). Metode ini menggunakan promise untuk memungkinkan browser menjaga agar service worker Anda tetap aktif dan berjalan hingga promise yang diteruskan diselesaikan.

Agar kode di atas lebih mudah dipahami, Anda dapat menuliskannya kembali seperti ini:

const notificationPromise = self.registration.showNotification(title, options);
event.waitUntil(notificationPromise);

Setelah Anda mempelajari peristiwa push, mari kita uji peristiwa push.

Coba

Dengan penanganan peristiwa push di pekerja layanan, Anda dapat memicu peristiwa push palsu untuk menguji apa yang terjadi saat pesan diterima.

Di aplikasi web Anda, berlanggananlah pesan push dan pastikan Anda melihat User IS subscribed di konsol. Di panel Application di DevTools, di tab Service Workers, klik tombol Push:

Setelah mengklik Push, Anda akan melihat notifikasi seperti ini:

Catatan: Jika langkah ini tidak berhasil, coba batalkan pendaftaran pekerja layanan Anda dengan link Unregister di panel Aplikasi DevTools, tunggu hingga pekerja layanan dihentikan, lalu muat ulang halaman.

Kode yang telah selesai

Jika Anda mengklik salah satu notifikasi ini, Anda akan melihat bahwa tidak ada yang terjadi. Anda dapat menangani klik notifikasi dengan memproses peristiwa notificationclick di pekerja layanan.

Mulai dengan menambahkan pemroses notificationclick di sw.js:

self.addEventListener('notificationclick', function(event) {
  console.log('[Service Worker] Notification click received.');

  event.notification.close();

  event.waitUntil(
    clients.openWindow('https://developers.google.com/web')
  );
});

Saat pengguna mengklik notifikasi, pemroses peristiwa notificationclick akan dipanggil.

Kode pertama-tama menutup notifikasi yang diklik:

event.notification.close();

Kemudian, jendela atau tab baru akan dibuka, memuat URL https://developers.google.com/web. Anda dapat mengubahnya.

event.waitUntil(
    clients.openWindow('https://developers.google.com/web/')
  );

event.waitUntil() memastikan bahwa browser tidak menghentikan service worker sebelum jendela atau tab baru ditampilkan.

Coba

Coba picu pesan push di DevTools lagi, lalu klik notifikasi. Anda sekarang akan melihat notifikasi ditutup dan tab baru terbuka.

Anda telah melihat bahwa aplikasi web Anda dapat menampilkan notifikasi menggunakan DevTools dan melihat cara menutup notifikasi dengan mengklik. Langkah selanjutnya adalah mengirim pesan push yang sebenarnya.

Biasanya, hal ini memerlukan pengiriman langganan dari halaman web ke backend. Kemudian, backend akan memicu pesan push dengan melakukan panggilan API ke endpoint dalam langganan.

Hal ini berada di luar cakupan codelab ini, tetapi Anda dapat menggunakan situs pendamping (web-push-codelab.glitch.me) untuk memicu pesan push yang sebenarnya. Tempelkan langganan di bagian bawah halaman Anda:

Kemudian, tempelkan kode ini ke situs pendamping di area teks Subscription to Send To:

Di bagian Teks yang Akan Dikirim, tambahkan string yang ingin Anda kirim dengan pesan push.

Klik tombol Kirim pesan push.

Kemudian, Anda akan menerima pesan push. Teks yang Anda gunakan akan dicatat ke konsol.

Hal ini akan memberi Anda kesempatan untuk menguji pengiriman dan penerimaan data, serta memanipulasi notifikasi sebagai hasilnya.

Aplikasi pendamping hanyalah server node yang menggunakan library web-push untuk mengirim pesan. Sebaiknya tinjau org web-push-libs di GitHub untuk melihat library apa saja yang tersedia untuk mengirim pesan push bagi Anda. Hal ini menangani banyak detail untuk memicu pesan push.

Anda dapat melihat semua kode untuk situs pendamping di sini.

Kode yang telah selesai

Satu hal yang kurang adalah kemampuan untuk membatalkan langganan pengguna dari push. Untuk melakukannya, Anda harus memanggil unsubscribe() pada PushSubscription.

Kembali di file scripts/main.js, ubah pemroses klik pushButton di initializeUI() menjadi berikut:

pushButton.addEventListener('click', function() {
  pushButton.disabled = true;
  if (isSubscribed) {
    unsubscribeUser();
  } else {
    subscribeUser();
  }
});

Perhatikan bahwa Anda sekarang akan memanggil fungsi baru unsubscribeUser(). Dalam fungsi ini, Anda mendapatkan langganan saat ini dan memanggil unsubscribe() di dalamnya. Tambahkan kode berikut ke scripts/main.js:

function unsubscribeUser() {
  swRegistration.pushManager.getSubscription()
  .then(function(subscription) {
    if (subscription) {
      return subscription.unsubscribe();
    }
  })
  .catch(function(error) {
    console.log('Error unsubscribing', error);
  })
  .then(function() {
    updateSubscriptionOnServer(null);

    console.log('User is unsubscribed.');
    isSubscribed = false;

    updateBtn();
  });
}

Mari kita pelajari fungsi ini.

Pertama, Anda mendapatkan langganan saat ini dengan memanggil getSubscription():

swRegistration.pushManager.getSubscription()

Tindakan ini menampilkan promise yang diselesaikan dengan PushSubscription jika ada; jika tidak, promise akan menampilkan null. Jika ada langganan, Anda memanggil unsubscribe() di dalamnya, yang membuat PushSubscription tidak valid.

swRegistration.pushManager.getSubscription()
.then(function(subscription) {
  if (subscription) {
    // TODO: Tell application server to delete subscription
    return subscription.unsubscribe();
  }
})
.catch(function(error) {
  console.log('Error unsubscribing', error);
})

Memanggil unsubscribe() akan menampilkan promise, karena proses ini dapat memerlukan waktu beberapa saat hingga selesai. Anda menampilkan promise tersebut sehingga then() berikutnya dalam rantai menunggu hingga unsubscribe() selesai. Anda juga menambahkan pengendali catch jika panggilan unsubscribe() menghasilkan error. Setelah itu, Anda dapat memperbarui UI.

.then(function() {
  updateSubscriptionOnServer(null);

  console.log('User is unsubscribed.');
  isSubscribed = false;

  updateBtn();
})

Coba

Anda akan dapat menekan Aktifkan Pesan Push atau Nonaktifkan Pesan Push di aplikasi web, dan log akan menampilkan pengguna yang berlangganan dan berhenti berlangganan.

Selamat, Anda telah menyelesaikan codelab ini.

Codelab ini telah menunjukkan cara memulai dan menjalankan penambahan notifikasi push ke aplikasi web Anda. Jika Anda ingin mempelajari lebih lanjut kemampuan notifikasi web, lihat dokumen ini.

Jika ingin men-deploy notifikasi push di situs, Anda mungkin tertarik untuk menambahkan dukungan bagi browser lama atau browser yang tidak mematuhi standar yang menggunakan GCM. Pelajari lebih lanjut di sini.

Bacaan lebih lanjut

Postingan blog yang relevan