Salah satu poin masalah ketika bekerja dengan {i>web push<i} adalah bahwa memicu pesan {i>push<i} sangat "fiddly". Untuk memicu pesan push, aplikasi perlu membuat permintaan POST ke push layanan setelah push web . Untuk menggunakan push di semua browser, Anda harus menggunakan VAPID (alias kunci server aplikasi) yang pada dasarnya memerlukan penyetelan header dengan nilai yang membuktikan aplikasi Anda bisa mengirimkan pesan kepada pengguna. Untuk mengirim data dengan pesan {i>push<i}, data harus terenkripsi dan header tertentu perlu ditambahkan agar {i>browser<i} dapat membongkar enkripsi pesan dengan benar.
Masalah utama yang memicu {i>push<i} adalah jika Anda menghadapi masalah, sulit untuk didiagnosis menyelesaikan masalah. Hal ini meningkat seiring waktu dan dukungan browser yang lebih luas, tetapi hal ini tidak mudah. Sebagai alasan ini, saya sangat menyarankan untuk menggunakan perpustakaan untuk menangani enkripsi, pemformatan, memicu pesan push Anda.
Jika Anda benar-benar ingin belajar tentang apa yang dilakukan {i>library<i}, kami akan membahasnya di bagian berikutnya. Untuk saat ini, kita akan melihat cara mengelola langganan dan menggunakan library web push yang ada untuk membuat permintaan push.
Di bagian ini, kita akan menggunakan node web-push library. Bahasa lain akan memiliki perbedaan, tetapi mereka tidak akan terlalu berbeda. Kita sedang melihat Node karena itu adalah JavaScript dan seharusnya paling mudah diakses oleh pembaca.
Kita akan melakukan langkah-langkah berikut:
- Kirim langganan ke backend dan simpan langganan tersebut.
- Mengambil langganan yang tersimpan dan memicu pesan push.
Menyimpan langganan
Menyimpan dan membuat kueri PushSubscription
dari database akan bervariasi bergantung pada
pilihan bahasa sisi server dan {i>database<i},
tetapi mungkin berguna untuk melihat
contoh bagaimana
hal itu bisa dilakukan.
Di halaman web demo, PushSubscription
dikirim ke backend kami dengan membuat permintaan POST sederhana:
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 Express dalam demo kami memiliki pemroses permintaan yang cocok untuk
Endpoint /api/save-subscription/
:
app.post('/api/save-subscription/', function (req, res) {
Dalam rute ini, kami memvalidasi langganan hanya untuk memastikan permintaan tidak dipenuhi dan tidak sampah:
const isValidSaveRequest = (req, res) => {
// Check the request body has at least an endpoint.
if (!req.body || !req.body.endpoint) {
// Not a valid subscription.
res.status(400);
res.setHeader('Content-Type', 'application/json');
res.send(
JSON.stringify({
error: {
id: 'no-endpoint',
message: 'Subscription must have an endpoint.',
},
}),
);
return false;
}
return true;
};
Jika langganan valid, kita harus menyimpannya dan mengembalikan langganan yang sesuai Respons JSON:
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.',
},
}),
);
});
Demo ini menggunakan nedb untuk menyimpan langganan, yaitu {i>database<i} berbasis file sederhana, tetapi Anda dapat menggunakan {i>database<i} pilihan Anda. Kita hanya menggunakan ini sebagai tidak perlu pengaturan apa pun. Untuk produksi, Anda ingin menggunakan sesuatu yang lebih dapat diandalkan. (Saya cenderung tetap menggunakan MySQL lama yang bagus.)
function saveSubscriptionToDatabase(subscription) {
return new Promise(function (resolve, reject) {
db.insert(subscription, function (err, newDoc) {
if (err) {
reject(err);
return;
}
resolve(newDoc._id);
});
});
}
Mengirim pesan push
Dalam hal mengirim pesan push, pada akhirnya kita memerlukan beberapa peristiwa untuk memicu proses
mengirim pesan ke pengguna. Pendekatan umumnya adalah membuat halaman admin yang memungkinkan Anda
mengonfigurasi dan memicu pesan push. Tetapi Anda dapat membuat program untuk
dijalankan secara lokal atau
pendekatan lain yang memungkinkan pengaksesan daftar PushSubscription
dan menjalankan kode untuk
memicu pesan push.
Demo kami memiliki "seperti admin" yang memungkinkan Anda memicu push. Karena ini hanya demo, ini adalah publik.
Saya akan menjelaskan setiap langkah agar demo berfungsi. Ini akan bayi langkah-langkah sehingga semua orang dapat mengikuti, termasuk siapa saja yang baru menggunakan Node.
Saat membahas cara membuat pengguna berlangganan, kita telah membahas cara menambahkan applicationServerKey
ke
subscribe()
opsi. Ada di backend di mana kita
akan memerlukan kunci pribadi ini.
Dalam demo, nilai-nilai ini ditambahkan ke aplikasi Node seperti itu (kode yang membosankan, tapi hanya ingin Anda tahu bahwa tidak ada sihir):
const vapidKeys = {
publicKey:
'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U',
privateKey: 'UUxI4O8-FbRouAevSmBQ6o18hgE4nSG3qwvJTfKc-ls',
};
Selanjutnya, kita perlu menginstal modul web-push
untuk server Node:
npm install web-push --save
Kemudian, dalam skrip Node kita memerlukan modul web-push
seperti ini:
const webpush = require('web-push');
Sekarang kita dapat mulai menggunakan modul web-push
. Pertama-tama, kita perlu memberi tahu modul web-push
tentang
kunci server aplikasi kita. (Ingat, kunci ini juga dikenal sebagai
kunci VAPID karena itu adalah namanya
spesifikasi.)
const vapidKeys = {
publicKey:
'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U',
privateKey: 'UUxI4O8-FbRouAevSmBQ6o18hgE4nSG3qwvJTfKc-ls',
};
webpush.setVapidDetails(
'mailto:web-push-book@gauntface.com',
vapidKeys.publicKey,
vapidKeys.privateKey,
);
Perhatikan bahwa kami juga menyertakan "mailto:" {i>string<i}. String ini harus berupa URL atau mailto alamat email Anda. Potongan informasi ini sebenarnya akan dikirim ke layanan {i>web push<i} sebagai bagian dari permintaan untuk memicu push. Alasan ini dilakukan adalah agar jika layanan {i>web push <i}perlu untuk menghubungi pengirim, mereka memiliki beberapa informasi yang akan memungkinkan mereka.
Dengan demikian, modul web-push
siap digunakan, langkah berikutnya adalah memicu pesan push.
Demo ini menggunakan panel admin fiktif untuk memicu pesan push.
Mengklik "Picu Pesan Push" akan membuat permintaan POST ke /api/trigger-push-msg/
,
yang merupakan sinyal bagi backend untuk
mengirim pesan {i>push<i}, jadi kita membuat rute di
ekspres untuk endpoint ini:
app.post('/api/trigger-push-msg/', function (req, res) {
Ketika permintaan ini diterima, kita mengambil langganan dari {i>database<i} dan untuk setiap instance, kita memicu pesan push.
return getSubscriptionsFromDatabase().then(function (subscriptions) {
let promiseChain = Promise.resolve();
for (let i = 0; i < subscriptions.length; i++) {
const subscription = subscriptions[i];
promiseChain = promiseChain.then(() => {
return triggerPushMsg(subscription, dataToSend);
});
}
return promiseChain;
});
Fungsi triggerPushMsg()
kemudian dapat menggunakan library web-push untuk mengirim pesan ke
langganan yang disediakan.
const triggerPushMsg = function (subscription, dataToSend) {
return webpush.sendNotification(subscription, dataToSend).catch((err) => {
if (err.statusCode === 404 || err.statusCode === 410) {
console.log('Subscription has expired or is no longer valid: ', err);
return deleteSubscriptionFromDatabase(subscription._id);
} else {
throw err;
}
});
};
Panggilan ke webpush.sendNotification()
akan menampilkan promise. Jika
pesan berhasil dikirim, promise akan diselesaikan dan ada
tidak ada yang perlu kita lakukan. Jika promise ditolak, Anda perlu memeriksa
error karena akan memberi tahu Anda apakah PushSubscription
masih
valid atau tidak.
Untuk menentukan jenis error dari layanan push, sebaiknya lihat kode status. {i>Error<i} pesan bervariasi antara layanan push dan beberapa layanan lebih membantu dibandingkan yang lain.
Dalam contoh ini, pemeriksaan memeriksa kode status 404
dan 410
, yang merupakan kode status HTTP untuk
'Tidak Ditemukan' dan 'Hilang'. Jika kami menerima salah satu dari langganan ini, berarti langganan telah berakhir
atau tidak lagi valid. Dalam skenario ini, kita perlu menghapus langganan dari database.
Dalam kasus error lain, kita hanya perlu throw err
, yang akan membuat promise ditampilkan oleh
triggerPushMsg()
menolak.
Kita akan membahas beberapa kode status lainnya di bagian berikutnya saat melihat push web protokol secara lebih rinci.
Setelah melakukan loop langganan, kita perlu menampilkan respons JSON.
.then(() => {
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-send-messages',
message: `We were unable to send messages to all subscriptions : ` +
`'${err.message}'`
}
}));
});
Kita telah membahas langkah-langkah penerapan utama:
- Buat API untuk mengirim langganan dari halaman web ke backend kami sehingga bisa menyimpannya ke dalam {i>database<i}.
- Buat API untuk memicu pengiriman pesan push (dalam hal ini, API yang dipanggil dari panel admin yang meniru).
- Mengambil semua langganan dari backend dan mengirim pesan ke setiap langganan dengan salah satu web-push library.
Terlepas dari backend Anda (Node, PHP, Python, ...), langkah-langkah untuk mengimplementasikan push akan berjalan dengan baik sama.
Selanjutnya, apa sebenarnya yang dilakukan library web-push ini untuk kita?
Langkah berikutnya
- Ringkasan Notifikasi Push Web
- Cara Kerja Push
- Berlangganan Pengguna
- UX Izin
- Mengirim Pesan dengan Library Web Push
- Protokol Push Web
- Menangani Peristiwa Push
- Menampilkan Notifikasi
- Perilaku Notifikasi
- Pola Notifikasi Umum
- FAQ Notifikasi Push
- Masalah Umum dan Melaporkan Bug