Tutorial

Browser Push Notification — Dari Nol Sampai Ngangkring di Semua Browser

Browser Push Notification — Dari Nol Sampai Ngangkring di Semua Browser

Pernah merasa kesal setiap kali harus ngecek manual apakah artikel barumu sudah terbit? Atau pengin ngasih tahu subscriber bahwa ada konten baru tanpa mereka harus buka website dulu? Nah, itu masalah yang pengin aku selesaikan dengan plugin ini.

Browser push notification adalah teknologi yang memungkinkan website ngirim notifikasi langsung ke browser pengguna — mirip kayak notifikasi dari aplikasi HP, tetapi cukup lewat browser. Di desktop, notifikasi muncul di pojok kanan bawah. Di iOS, muncul seperti notifikasi aplikasi biasa. Dan yang keren: pengguna tidak perlu membuka websitenya terlebih dahulu.

Konsep Dasar Web Push

Sebelum bahas pluginnya, aku mau cerita sedikit gimana Web Push API bekerja. Ada tiga aktor di sini:

  1. Application Server — server kita (PHP, Node.js, atau lainnya) yang mengirim notifikasi
  2. Push Service — infrastruktur dari Google (FCM), Apple (APNs), Microsoft (WNS), atau Mozilla yang menjadi perantara
  3. Browser/Device — tempat notifikasi muncul

Alurnya begini: server kita mengenkripsi payload notifikasi, mengirimnya ke Push Service, Push Service meneruskannya ke browser, browser mendekripsi menggunakan kunci yang disimpan saat subscribe, lalu menampilkan notifikasi lewat Service Worker.

Yang membuat susah: enkripsi ini harus sesuai standar RFC 8291 — menggunakan ECDH key agreement, HKDF key derivation, dan AES-128-GCM. Jika enkripsinya salah satu byte saja, browser tidak bisa mendekripsi dan notifikasi tidak muncul. Aku alami sendiri ini saat mengembangkan plugin.

Kenapa PHP Native Saja Tidak Cukup?

Di percobaan pertama, aku implementasi enkripsi memakai PHP murni — openssl_pkey_derive(), hash_hmac() untuk HKDF, openssl_encrypt() untuk AES-GCM. Semua tes lokal lolos: enkripsi dan dekripsi cocok. Tapi saat dikirim ke browser asli, notifikasi tidak muncul. Nol besar. Gagal total.

Masalahnya? Aku lupa memberikan AAD (Additional Authenticated Data) ke fungsi AES-GCM. AAD itu header dari payload terenkripsi itu sendiri — salt, record size, dan key identifier. Tanpa AAD yang sesuai, browser tidak bisa memvalidasi authentication tag, jadinya event.data di Service Worker nilainya null, dan notifikasi batal tampil.

Pelajaran: Web Push encryption itu rumit. Satu byte salah di AAD, semua browser tidak bisa mendekripsi. Akhirnya aku menggunakan library Node.js web-push yang sudah diuji jutaan developer, dan fallback ke PHP jika Node.js tidak tersedia.

Arsitektur Plugin Browser Push

Plugin ini tidak hanya enkripsi saja. Ada beberapa komponen yang saling terkait:

1. Service Worker

File sw.js yang di-deploy di root website. Tugasnya: menangkap event push dari browser, mem-parse payload JSON, lalu menampilkan notifikasi menggunakan API showNotification(). Juga menangani event klik notifikasi — misalnya membuka artikel yang dimaksud.

2. Sidebar Widget

Tombol Subscribe/Unsubscribe yang muncul di sidebar blog. Saat diklik, widget meminta izin notifikasi ke pengguna, lalu subscribe ke Push Service melalui pushManager.subscribe(). Kunci publik (VAPID key) di-embed langsung di widget JavaScript agar tidak perlu fetch tambahan.

Push Subscribe Widget di Sidebar

3. Admin Dashboard

Di dashboard CMS, terdapat halaman Push Notification yang menampilkan statistik: jumlah subscriber aktif, riwayat notifikasi, dan tombol Send Test untuk mengirim notifikasi manual. Juga ada halaman Settings untuk konfigurasi VAPID keys.

4. Dual Path Encryption

Fitur yang paling aku banggakan: plugin otomatis mendeteksi apakah Node.js tersedia atau tidak. Jika ada, menggunakan library web-push (yang sudah teruji). Jika tidak ada (misalnya shared hosting seperti Hostinger), otomatis fallback ke PHP curl + enkripsi custom. Keduanya menghasilkan encrypted payload yang valid — diuji ke semua 5 push service (Apple APNs, Google FCM, Microsoft WNS, Mozilla Autopush, dan Samsung).

Perjalanan Debugging yang Melelahkan

Ini bagian yang paling aku ingat. Saat pertama kali tes, aku mengirim notifikasi ke HP iPhone — server balik "sent: 5, failed: 0". Tetapi notifikasi tidak muncul. Kupikir masalah di browser atau OS. Ternyata…

  • Pertama: VAPID key kurang prefix 0x04 (uncompressed EC point). Perbaikan: generate ulang kunci.
  • Kedua: openssl_pkey_get_private() membutuhkan format PEM, bukan raw d value. Perbaikan: simpan private key sebagai PEM di database.
  • Ketiga: AAD kosong. Perbaikan: tambah AAD sesuai RFC 8188.
  • Keempat: Apple APNs membutuhkan header Content-Encoding: aes128gcm. Perbaikan: tambah header.
  • Kelima: library web-push v3.6.7 memiliki regresi koneksi ke Apple APNs (ETIMEDOUT). Perbaikan: pin ke v3.4.5 + set --dns-result-order=ipv4first.

Bayangkan, lima bug berbeda yang membuat notifikasi tidak muncul. Dan masing-masing membutuhkan waktu berjam-jam untuk debug. Tetapi saat akhirnya melihat notifikasi "Node.js Test" muncul di iPhone, rasanya… puas sekali.

Instalasi dan Konfigurasi

Plugin ini tersedia di Jyavani Plugin Store dan GitHub. Cara installnya:

# 1. Download atau clone dari GitHub
git clone https://github.com/adammuizweb/browser-push.git
cp -r browser-push /var/www/anda/plugins/browser-push

# 2. Install Node.js dependencies (opsional)
cd plugins/browser-push && npm install

# 3. Generate VAPID keys
php plugins/browser-push/generate-vapid.php

# 4. Tambahkan VAPID keys ke database
#    push_vapid_public_key, push_vapid_private_key, push_vapid_subject

# 5. Aktifkan plugin dari Admin → Plugin Manager

Jika tidak punya Node.js di server, tidak masalah. Plugin tetap berjalan menggunakan PHP fallback — semua fitur sama, hanya encryption path-nya yang berbeda.

Kesimpulan

Membangun plugin browser push notification ini menjadi salah satu pengalaman coding paling intens yang pernah aku alami. Bukan karena rumit secara logika, tetapi karena standar Web Push encryption sangat ketat — satu byte salah, semua browser menolak.

Sekarang plugin ini sudah teruji di lima push service berbeda, mendukung dual path (Node.js + PHP), dan yang paling penting: benar-benar bekerja. Kamu bisa melihat sendiri cara kerjanya dengan subscribe melalui widget di sidebar artikel ini — klik Subscribe, izinkan notifikasi, dan kamu akan mendapatkan notifikasi setiap kali ada artikel baru.

Source code plugin ini open source di GitHub, silakan di-fork, di-custom, atau dilaporkan issue-nya. Jika ada pertanyaan, tulis di komentar ya.