Create a push notification for website
So, I got a task that required a notification, and after some discussion, it was decided to use push notifications because the need was simple. So, I explored how to make them. By the way, before you continue reading, I want to let you know that here I am using Node.js for the backend and have not tried with other languages.
Steps to Create Push Notifications
Preparation
To create push notifications simply, we only need a few functions, showNotification
and subscription
on the client side, and sendNotification
from the web-push library.
Displaying Notifications
As you can see, showNotification
and subscription
require a service worker to run their functions. So, you can only use these functions if you have installed a service worker on your website. To display notifications in the browser, you only need:
1serviceWorkerRegistration.showNotification(title, [options]);
However, that only applies to displaying the notification itself. If we want to request to show notifications from the server, what we need to do next step
Subscription
If you have installed a service worker on your website, you can try calling:
1const options = { applicationServerKey, userVisibleOnly: true }
To get the applicationServerKey
, you can use the web-push library. How to install it:
1web-push generate-vapid-keys
Then run command:
1web-push generate-vapid-keys
If successful, you will get a result like this:
1Public Key:
2xxxxxx...
3
4Private Key:
5xyxyxy...
6
7=======================================
Then put your public key for the applicationServerKey
above. After that, the result from the subscribe
call can be sent to the backend and saved. I save it in the users table, to make it easy. So, for example, if I need to send a notification to username ‘A’, I just select subscribe
from users
where username = 'A'
.
Push Notifications from the Server
Next, for the backend, let’s say I create sendNotif.js
:
1import webpush from "web-push"
2
3export const pushNotif = async (subs, title, msg) => {
4 const vapidKeys = {
5 publicKey: "xxxxxx...",
6 privateKey: "xyxyxy...",
7 }
8 try {
9 const subject = "< 'mailto' Address or URL >"
10 webpush.setVapidDetails(
11 subject,
12 vapidKeys.publicKey,
13 vapidKeys.privateKey
14 )
15 await webpush.sendNotification(
16 subs,
17 JSON.stringify({ title: title, msg: msg })
18 )
19 } catch (e) {
20 if (e.statusCode != 410) console.log(e)
21 }
22}
We get the public
and private keys
from the generated result above, and the subject
can be a URL or email.
To use it, you can run:
1import { pushNotif } from "../sendNotif";
2
3// Then query to get the subs and call the function
4pushNotif(subs, "This is the title", "This is the message content")
Listening for Incoming Pushes in the Service Worker
1self.addEventListener("push", function(event) {
2 if (event.data) {
3 const { title, msg } = event.data.json()
4 self.registration.showNotification(title, {
5 body: msg,
6 })
7 }
8})
And that’s it~