From 84c0bc8ed81cadd053ac6da4604cd817de3ce064 Mon Sep 17 00:00:00 2001 From: 3wc <3wc.git@doesthisthing.work> Date: Wed, 2 Jun 2021 15:17:00 +0200 Subject: [PATCH] Web push notifications Re: #931 --- config.sample.json | 5 ++-- src/libs/sw-toolbox.js | 59 +++++++++++++++++++++++++++++++++++++++++- src/service-worker.js | 20 ++++++++++++++ 3 files changed, 81 insertions(+), 3 deletions(-) diff --git a/config.sample.json b/config.sample.json index 7d9c843..01ad9e0 100644 --- a/config.sample.json +++ b/config.sample.json @@ -2,7 +2,8 @@ "client": { "name": "Sample of a functional Orbit", "logo": "https://cdn.startinblox.com/logos/webp/startinblox.webp", - "server": "http://localhost:8000" + "server": "http://localhost:8000", + "vapid_key": "BFZaZjfjx9RlH6v8AEmhMeJobFYm3gOJK4DvroHLE3Wc3sd66SEgGc6rp6hLvesFpfELjHI7MjOCnbth-sBnwf4" }, "components": [{ "type": "registering", @@ -104,4 +105,4 @@ "route": false } ] -} \ No newline at end of file +} diff --git a/src/libs/sw-toolbox.js b/src/libs/sw-toolbox.js index b32edac..86cc6b6 100644 --- a/src/libs/sw-toolbox.js +++ b/src/libs/sw-toolbox.js @@ -39,6 +39,63 @@ import(`https://storage.googleapis.com/workbox-cdn/releases/6.1.5/workbox-window wb.addEventListener('externalwaiting', showSkipWaitingPrompt); wb.register().then((r) => registration = r); + + function urlB64ToUint8Array(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); + const outputData = outputArray.map((output, index) => rawData.charCodeAt(index)); + + return outputData; + } + + const subscribe = async (reg) => { + const subscription = await reg.pushManager.getSubscription(); + if (subscription) { + sendSubData(subscription); + return; + } + + const options = { + userVisibleOnly: true, + // if key exists, create applicationServerKey property + ...(orbit.client.vapid_key && {applicationServerKey: urlB64ToUint8Array(orbit.client.vapid_key)}) + }; + + const sub = await reg.pushManager.subscribe(options); + sendSubData(sub) + }; + const sendSubData = async (subscription) => { + const browser = navigator.userAgent.match(/(firefox|msie|chrome|safari|trident)/ig)[0].toLowerCase(); + const data = { + status_type: 'subscribe', + subscription: subscription.toJSON(), + browser: browser, + }; + + const res = await fetch(orbit.client.server + "/webpush/save_information", { + method: 'POST', + body: JSON.stringify(data), + headers: { + 'content-type': 'application/json' + }, + credentials: "include" + }); + + handleResponse(res); + }; + + const handleResponse = (res) => { + console.log(res.status); + }; + + navigator.serviceWorker.getRegistration().then(function(reg) { + subscribe(reg); + }); }); } -}); \ No newline at end of file +}); diff --git a/src/service-worker.js b/src/service-worker.js index e3a88db..8d2773b 100644 --- a/src/service-worker.js +++ b/src/service-worker.js @@ -2,6 +2,26 @@ importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.1.5/workbox workbox.precaching.precacheAndRoute([]); +addEventListener('push', function (event) { + // Retrieve the textual payload from event.data (a PushMessageData object). + // Other formats are supported (ArrayBuffer, Blob, JSON), check out the documentation + // on https://developer.mozilla.org/en-US/docs/Web/API/PushMessageData. + const eventInfo = event.data.text(); + const data = JSON.parse(eventInfo); + const head = data.head || 'New Notification πŸ•ΊπŸ•Ί'; + const body = data.body || 'This is default content. Your notification didn\'t have one πŸ™„πŸ™„'; + + console.log('hello from sw.js: push'); + + // Keep the service worker alive until the notification is created. + event.waitUntil( + self.registration.showNotification(head, { + body: body, + icon: 'https://i.imgur.com/MZM3K5w.png' + }) + ); +}); + addEventListener('message', (event) => { if (event.data && event.data.type === 'SKIP_WAITING') { skipWaiting();