How to send notifications to the browser (wep push) using Node.js and Service Workers

in Steem Sri Lanka4 years ago


Today I will teach you how to create web notifications from our Node - Express.js server to an HTML web application, the notifications will be created from the API provided by the browser, we will use a module called web push ( web-push ) that will help us create them, additionally we will use what is called Service workers ( processes that are kept running from the browser)

NODE.js

We will start by creating a folder on our desktop web-notification-app-node / and activating the console of our favorite code editor, and we will install the following dependencies:

   npm  init --yes
 
 
And
   npm  i express morgan dotenv web-push
 
 

We will create a file called .env where we will place our public and private keys provided by the web-push module

.env

  PUBLIC_KEY = tu_public_key_here
 PRIVATE_KEY = you_private_key_here
 
 


Once our environment variables file is created, we proceed to generate these keys, for this we will write the following in the console

  npx web-push generate-vapid-keys
 
 

This will return something like



Those keys are the ones that we will place in the .env file

We will create a file called webpush.js with the following configuration

src / webpush.js

  const webpush = require ('web-push')
 webpush.setVapidDetails (
     `mailto: $ {process.env.EMAIL}`,
     process.env.PUBLIC_KEY,
     process.env.PRIVATE_KEY
   );
 module.exports = webpush
 
 


src / index.js

  require ('dotenv'). config ()
 const express = require ('express')
 const morgan = require ('morgan')
 const path = require ('path')
 const app = express ()
 // MIDDLEWARES
 app.use (morgan ('dev'))
 app.use (express.urlencoded ({extended: false}))
 app.use (express.json ())
 // ROUTES
 app.use (require ('./ routes /'))
 // STATICS FILES
 app.use (express.static (path.join (__ dirname, 'public')))
 app.listen (process.env.PORT || 3000, () => console.log ('Server on port', process.env.PORT || 3000))
 
 


We create a folder routes/ and inside an index.js file with our 2 routes

routes / index.js

  const {Router} = require ('express')
 const router = Router ()
 const webpush = require ('../ webpush')
 let pushSubscripton;
 router.post ('/ subscribeUser', async (req, res) => {
     pushSubscripton = req.body;
     res.status (200) .json ();
 })
 router.post ('/ new-msg', async (req, res) => {
     const {title, message} = req.body;
     const payload = JSON.stringify ({
         title,
         message
       });
       res.status (200) .json ();
       try {
         await webpush.sendNotification (pushSubscripton, payload);
       } catch (error) {
         console.log (error);
       }
 })
 module.exports = router
 
 


We will create a public / folder and inside a file index.html, main.js and serviceWorker.js

public / index.html

  <! DOCTYPE html>
 <html lang = "en">
 <head>
     <meta charset = "UTF-8">
     <meta http-equiv = "X-UA-Compatible" content = "IE = edge">
     <meta name = "viewport" content = "width = device-width, initial-scale = 1.0">
     <title> How to send notifications to the browser (wep push) using Node.js and Service Workers </title>
     <link href = "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel = "stylesheet"
         integrity = "sha384-BmbxuPwQa2lc / FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH / Ev + nYRRuWlolflfl" crossorigin = "anonymous">
 </head>
 <body>
     <div class = "container mt-5 mb-2">
         <h2> How to send notifications to the browser (wep push) using Node.js and Service Workers - <code> <a href="https://hive.blog/@jfdesousa7"> Jfdesousa7 </a> </code> </h2>
         <div class = "col-md-4 mt-5 mx-auto">
             <div class = "card">
                 <div class = "card-body">
                     <form id = "form">
                         <div class = "mb-4">
                             <input type = "text" id = "title" placeholder = "Enter the title of the message"
                                 class = "form-control" autofocus>
                         </div>
                         <div class = "mb-4">
                             <textarea class = "form-control" id = "message" rows = "2"
                                 placeholder = "Enter the message"> </textarea>
                         </div>
                         <div class = "mb-4>
                             <button type = "submit" class = "btn btn-primary"> Send notification </button>
                         </div>
                     </form>
                 </div>
             </div>
         </div>
     </div>
     <script src = "./ main.js"> </script>
 </body>
 </html>
 
 


public / main.js

  const PUBLIC_KEY = "BPU1qVu0bNbIFdC15E4EooVBhjuOV8w40rk5NO3xR-UtF_3I7l5h5EQxeT2yXvEBS4ArrUfE7-YfKEPoLAYVi9k";
 async function subscribeUser () {
   const register = await navigator.serviceWorker.register ("/ serviceWorker.js", {
     scope: "/",
   });
   const subscribe = await register.pushManager.subscribe ({
     userVisibleOnly: true,
     applicationServerKey: urlBase64ToUint8Array (PUBLIC_KEY),
   });
   await fetch ("/ subscribeUser", {
     method: "POST",
     body: JSON.stringify (subscribe),
     headers: {
       "Content-Type": "application / json",
     },
   });
   console.log ("Subscribed!");
 }
 function urlBase64ToUint8Array (base64String) {
     const padding = "=". repeat ((4 - (base64String.length% 4))% 4);
     const base64 = (base64String + padding) .replace (/ - / g, "+"). replace (/ _ / g, "/");
     const rawData = window.atob (base64);
     const outputArray = new Uint8Array (rawData.length);
     for (let i = 0; i <rawData.length; ++ i) {
       outputArray [i] = rawData.charCodeAt (i);
     }
     return outputArray;
   };
   const form = document.querySelector ('# form')
   const title = document.querySelector ('# title')
   const message = document.querySelector ('# message')
   form.addEventListener ('submit', async (e) => {
       e.preventDefault ()
      await fetch ('/ new-msg', {
           method: "POST",
           body: JSON.stringify ({
               title: title.value,
               message: message.value
           }),
           headers: {
               "Content-Type": "application / json"
           }
       })
       form.reset ()
   })
   subscribeUser ();
 
 


public / serviceWorker.js

  self.addEventListener ("push", (e) => {
   const data = e.data.json ();
   self.registration.showNotification (data.title, {
     body: data.message,
     icon: "./images/jfdesousa7.png",
   });
 });
 
 


Once we run our example with node src / index.js we must allow the browser to send notifications





And with those friends we reached the end of the tutorial, I hope you enjoyed it and until next time!


Visit my official website for budges and much more

TupaginaOnline.net

Sort:  

Your post has been upvoted by Steem Sri Lanka Community Curation Trail.

Steem Sri Lanka Discord Channel

✵✵✵✵✵✵✵✵✵✵✵✵✵✵✵✵✵✵✵✵✵✵✵✵✵✵✵✵✵

Join With
steem-sri.lanka
Curation Trail For Better Curation Rewards

Coin Marketplace

STEEM 0.17
TRX 0.24
JST 0.034
BTC 95696.21
ETH 2793.14
SBD 0.67