Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
How to create Web Chrome Notifications ?
I have been searching for how to create a web push chrome notification using payload and after a decent R&D, i would like to share my code with you all.
Client Side Code:
main.js
function base64UrlToUint8Array(base64UrlData) {
const padding = '='.repeat((4 - base64UrlData.length % 4) % 4);
const base64 = (base64UrlData + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = atob(base64);
const buffer = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
buffer[i] = rawData.charCodeAt(i);
}
return buffer;
}
(function() {
if (!('serviceWorker' in navigator)) {
return;
}
return navigator.serviceWorker.register('sw.js')
.then(function(registration) {
console.log('service worker registered');
return navigator.serviceWorker.ready;
})
.then(function(reg) {
var channel = new MessageChannel();
channel.port1.onmessage = function(e) {
window.document.title = e.data;
}
reg.active.postMessage('setup', [channel.port2]);
var subscribeOptions = { userVisibleOnly: true };
// Figure out the vapid key
var searchParam = window.location.search;
vapidRegex = searchParam.match(/vapid=(.[^&]*)/);
if (vapidRegex) {
// Convert the base 64 encoded string
subscribeOptions.applicationServerKey = base64UrlToUint8Array(vapidRegex[1]);
}
console.log(subscribeOptions);
return reg.pushManager.subscribe(subscribeOptions);
})
.then(function(subscription) {
console.log(JSON.stringify(subscription));
window.subscribeSuccess = true;
window.testSubscription = JSON.stringify(subscription);
})
.catch(function(err) {
window.subscribeSuccess = false;
window.subscribeError = err;
});
})();
sw.js
'use strict';
let port;
let pushMessage;
console.log('Started', self);
self.addEventListener('install', function (event) {
self.skipWaiting();
console.log('Installed', event);
});
self.addEventListener('activate', function (event) {
console.log('Activated', event);
});
self.addEventListener('push', function (event) {
if (event.data) {
console.log(event.data);
}
var payload = event.data ? event.data.text() : 'no payload';
event.waitUntil(
self.registration.showNotification('Web Push Notification ', {
body: payload,
icon: 'images/abc.png',
}));
});
self.addEventListener('notificationclick', function(event) {
console.log('Notification click: tag', event.notification.tag);
event.notification.close();
var url = 'http://www.google.com/';
event.waitUntil(
clients.matchAll({
type: 'window'
})
.then(function(windowClients) {
console.log('WindowClients', windowClients);
for (var i = 0; i < windowClients.length; i++) {
var client = windowClients[i];
console.log('WindowClient', client);
if (client.url === url && 'focus' in client) {
return client.focus();
}
}
if (clients.openWindow) {
return clients.openWindow(url);
}
})
);
});
.................................................................................
SERVER SIDE CODE:
routers/notifications.js
var express = require('express');
var router = express.Router();
var webPush = require('web-push');
var gcmUrl = "https://android.googleapis.com/gcm/send/";
//this key is coming from gcm project
var GCM_API_KEY = "AIzaSyAI2OM3My5E8uulEGtQn31zfydBlCjhezZZWlpE";
router.get('/', function (req, res, next) {
res.send('Hello');
})
webPush.setGCMAPIKey(GCM_API_KEY);
router.post('/', function (req, res, next) {
var payload = req.body;
console.log(payload);
gcmUrl = "https://android.googleapis.com/gcm/send/"+req.body.registrationId;
console.log('sending request to GCM');
webPush.sendNotification(gcmUrl, {
RegistrationID: req.body.registrationId,
TTL: req.body.ttl,
payload: req.body.payload,
userPublicKey: req.body.key,
userAuth: req.body.authSecret,
})
.then(function (gcmResponse) {
console.log('gcm: ', gcmResponse);
res.sendStatus(201);
}).catch(function (gcmError) {
console.error("error frm gcm");
console.log(gcmError);
});
});
module.exports = router;
.................................................................................
Sending Request:
I used postman to send notification.
{
"ttl" : "5",
"payload" :"Your Request #123 is accepted" ,
"key" : "BBqMWJxSWFFcnvpowevnskdhdX0im4nADVSj9F_53xhxahcz-dnnR8wZv44o=",
"authSecret" : "elOOVcwciiaaavkYiDA==",
"registrationId": "doPVnhn3Ymc:APA91bFx_2tyfKs2xbpaocnakdrzdjS0ED9okiNEz-jECb3lC43kTqfltBZ54prNgtH3P_mBaDs5JOEQihhZld-E-vggxaUVUhyphe-oSoCE"
}
Check this guide, is not hard at all
https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API
Here's the guide with examples for Google Chrome: https://developers.google.com/web/updates/2015/03/push-notifications-on-the-open-web
Related
I am trying to create a middleware that receive a form-data and return the fieldname, contentType and the value. So when I send the firts post the data view in the terminal but if I send the same request again doesn't show me the data in the terminal.
And if a toggle the image, the data come show in the terminal
This is my code:
server:
const express = require("express");
const Upes = require("../upes");
const app = express();
const start = new Upes();
app.post("/", start.setup.bind(start), (req, res) => {
res.send("all right");
});
app.listen(3000, () => {
console.log("The server is active");
});
the index of my middleware:
const getData = require("./utils/getData");
const parseContentType = require("./utils/parseContentType");
class Upes {
setup(req, res, next) {
const contentType = parseContentType(req.headers["content-type"]);
if (!contentType) {
throw new Error("Malformed content-type");
}
const SUBTYPES = ["form-data", "x-www-form-urlencoded"];
if (!SUBTYPES.includes(contentType.subtype)) {
throw new Error(
"The subtypes does not match the following subtypes: " + SUBTYPES
);
}
getData(req, contentType.params.boundary, (data) => {
console.log(data);
});
next();
}
}
module.exports = Upes;
The function that receive the data and processes it:
function getData(req, boundary, callback) {
let chunk = "";
let data = [];
req.on("data", (buffer) => {
chunk += buffer.toString();
});
req.on("end", () => {
// Split the chunk in blocks
const blocks = getBlock(chunk, boundary);
blocks.forEach((block) => {
let [params, value] = block.split("\r\n\r\n");
params = params.split(";");
let fieldname = params[1].split("=")[1].replaceAll('"', "");
let contentType = () => {
const condition = params.length === 3;
if (condition) {
let type = params[2].split(":")[1].replace(" ", "");
return type;
}
return "text-plain";
};
const payload = {
fieldname: fieldname,
contentType: contentType(),
value: "", // value.replace("\r\n", "")
};
data.push(payload);
});
callback(data);
});
}
function getBlock(body, boundary) {
boundary = boundary.replaceAll("-", "");
return body.replaceAll("-", "").split(`${boundary}`).slice(1, -1);
}
module.exports = getData;
Send the same request 20 times
I don't know what happend, please can someone help me?
As the question says, I'm having an issue with our bulk mailing server.
So for abit of background, This emailing application of ours runs on a CRON job, sending out mails every hour.
Every 12 hours, We send out our biggest bulks, there are around 8 different groups and each group can have anywhere between 2000 - 4000 mails in each group that needs to be sent.
This application is built in Nodejs and uses Nodemailer to handle the sending of the mails.
What I've noticed for awhile now is that every so often the server would essentially "freeze" up and the memory usage of the app would slowly climb.
Windows Event log showed this error after the last bulk emailing was meant to run, "A request to allocate an ephemeral port number from the global TCP port space has failed due to all such ports being in use."
I've gone through the documentation on the Nodemailer website and applied the following changes
Using a pooled SMTP - This is still currently in the application
Set maxMessages to infinity - I've removed this as it didn't seem to help
Set maxConnections to 20 - Also removed because it made no difference
Using a dedicated queue manager - This was my final attempt, I went with RabbitMQ and have applied their Publish/Subscribe model.
RabbitMQ has improved the performance alot but it still hasn't resolved the issue.
Publish Function
const PublishMails = (mailObj) => {
return new Promise((resolve, reject) => {
var publishMailResult = {};
if (mailObj.length > 0) {
var connection = global.RabbitMQConnection;
connection.createChannel((err, channel) => {
if (err) {
publishMailResult.Result = false;
publishMailResult.Message = err.stack;
resolve(publishMailResult);
//return process.exit(1);
}
channel.assertQueue(config.RabbitMQ.Queue_EmailQueue, {
durable: true
}, err => {
if (err) {
publishMailResult.Result = false;
publishMailResult.Message = err.stack;
resolve(publishMailResult);
//return process.exit(1);
}
var mailData = {}
for (var x = 0; x < mailObj.length; x++) {
mailData.from = 'XXX#XXX.com';
mailData.to = mailObj[x].Email;
mailData.firstName = mailObj[x].FirstName;
mailData.login = mailObj[x].Login;
mailData.email = mailObj[x].Email;
mailData.mailID = mailObj[x].MailID;
mailData.sendID = mailObj[x].SendID;
mailData.subject = "Email Message";
mailData.template = 'EmailTempLate';
channel.sendToQueue(config.RabbitMQ.Queue_EmailQueue,
Buffer.from(JSON.stringify(mailData)), {
persistent: true,
contentType: 'application/json'
});
if (x === mailObj.length - 1) {
channel.close();
publishMailResult.Result = true;
publishMailResult.Message = "All mails successfully published.";
resolve(publishMailResult);
}
}
});
})
} else {
publishMailResult.Result = false;
publishMailResult.Message = "No mails were received - Mails Not Published.";
resolve(publishMailResult);
}
});
}
Subscribe function
const SubscribeMails = (mailObj) => {
return new Promise((resolve, reject) => {
if (mailObj.PublishMailResult.Result == true) {
var options = {
viewEngine: {
extname: '.html',
layoutsDir: 'views/email/',
defaultLayout: 'Email_Template'
},
viewPath: 'views/email',
extName: '.html'
};
var transporter = nodemailer.createTransport(smtpTransport({
host: 'XXX.XXX.XXX.XX',
port: 25,
pool: true
}));
transporter.use('stream', require('nodemailer-dkim').signer({
domainName: 'XXX.com',
keySelector: 'main',
privateKey: 'XXXX'
}));
transporter.use('compile', hbs(options));
var connection = global.RabbitMQConnection;
connection.createChannel((err, channel) => {
if (err) {
console.error(err.stack);
return process.exit(1);
}
channel.assertQueue(config.RabbitMQ.Queue_EmailQueue, {
durable: true
}, err => {
if (err) {
console.error(err.stack);
return process.exit(1);
}
channel.prefetch(1);
channel.consume(config.RabbitMQ.Queue_EmailQueue, data => {
if (data === null) {
return;
}
let mail = JSON.parse(data.content.toString());
transporter.sendMail({
from: mail.from,
to: mail.to,
subject: mail.subject,
template: mail.template,
context: {
FirstName: mail.firstName,
Email: mail.email,
MailID: mail.mailID,
SendID: mail.sendID,
}
}, (err, info) => {
if (err) {
console.error(err.stack);
return channel.nack(data);
}
channel.ack(data);
channel.checkQueue(config.RabbitMQ.Queue_EmailQueue, function (checkErr, queueData) {
if (queueData != null) {
if (queueData.messageCount == 0) {
channel.close();
transporter.close(); // Added in to test if this free's up TCP ports - Didn't help
}
}
});
});
});
resolve(true);
});
});
}
});
}
It really feels like I'm meant to be somehow closing these TCP connections manually but I haven't seen anything written about this in the documentation or haven't seen it mentioned on any example code I've seen.
I'm adding in the Cron job that starts this process to perhaps help debug this issue.
var cronPCSec = '0';
var cronPCMin = '58';
var cronPCHour = '*';
var cronPCDay = '*';
var cronPCMonth = '*';
var cronPCDayOfWeek = '0-6';
var cronPCfulltimes = "" + cronPCSec + " " + cronPCMin + " " + cronPCHour + " " + cronPCDay + " " + cronPCMonth + " " + cronPCDayOfWeek + "";
var MailerCronJob = new CronJob({
cronTime: cronPCfulltimes,
onTick: function () {
let objCronJob = {};
modelPC.GetMails().then(function (mail) {
return mail;
}).then(PublishMails).then(function (PublishResult) {
objCronJob.PublishMailResult = PublishResult;
return objCronJob;
}).then(SubscribeMails).then(function (result) {
console.log("Completed Successfully");
}).catch(err => {
console.log("Failed");
console.log(err)
});
},
start: false
});
MailerCronJob.start();
Thanks
First of all, I apologize for my poor English.
When you press the Write button on the main page, you want to go to the writeBoard page.
Go to writeBoard.ejs only if you are logged in and validate jwt in auth_login.js.
However, res.render does not work after jwt authentication.
What's the problem?
main.js
app.get('/writeBoard', authMWRouter, (req, res) => {
res.render('./basicBoard/writeBoard');
})
auth_login(authMWRouter)
const jwt = require('jsonwebtoken');
const { Account } = require('../models');
module.exports = (req, res, next) => {
console.log(3)
const { authorization } = req.headers;
const [tokenType, tokenValue] = authorization.split(' ');
if (tokenType != 'Bearer') {
res.status(400).send({
result: "fail",
modal_title: "로그인 필요",
modal_body: "로그인을 해주세요."
});
return;
}
try {
const { nickname } = jwt.verify(tokenValue, 'DongGyunKey');
Account.findByPk(nickname).then((account) => {
res.locals.account = account;
next();
});
console.log(1)
} catch (err) {
res.status(400).send({
result: "fail",
modal_title: "로그인 필요",
modal_body: "로그인을 해주세요."
});
return;
}
}
basicBoard.ejs (my main page)
function move_writeBoard() {
const write_ajax = new XMLHttpRequest();
var myModal = new bootstrap.Modal(document.getElementById("noticeModal"), {});
write_ajax.onload = () => {
if (write_ajax.status == 400 || write_ajax.status == 401) {
responseTxt = JSON.parse(write_ajax.responseText);
const modalTitle = document.querySelector('#msgTitle');
var mtTxt = document.createTextNode(responseTxt['modal_title']);
modalTitle.appendChild(mtTxt);
const modalBody = document.querySelector('#msgbody');
var mbTxt = document.createTextNode(responseTxt['modal_body']);
modalBody.appendChild(mbTxt);
document.getElementById('exitButton').setAttribute('onclick', 'window.location.href="/login"');
document.getElementById('correctButton').setAttribute('onclick', 'window.location.href="/login"');
myModal.show();
}
}
write_ajax.onerror = () => {
console.error(write_ajax.responseText);
}
write_ajax.open('GET', '/writeBoard');
write_ajax.setRequestHeader('authorization', 'Bearer ' + localStorage.getItem("token"));
write_ajax.setRequestHeader('Content-Type', 'application/json');
write_ajax.send();
}
I am making an experimental web proxy in Node.js. A lot of websites work like normal even Discord.com. The problem is on this website.
For some odd reason, it's showing a lot of weird symbols instead of the website. But if I go on any image on that site the images work fine. I would love the help. I would also prefer to use regular HTTPS / HTTP modules.
By the way, the commented out parts are for a WebSocket proxy so discard that.
const express = require('express'),
app = express(),
WebSocket = require('ws'),
fs = require('fs'),
https = require('https'),
http = require('http');
btoa = (str) => {
str = new Buffer.from(str).toString('base64');
return str;
};
atob = (str) => {
str = new Buffer.from(str, 'base64').toString('utf-8');
return str;
};
const server_options = {
key: fs.readFileSync('./ssl/default.key'),
cert: fs.readFileSync('./ssl/default.crt')
}
const server = https.createServer(server_options, app);
//server.on('upgrade', function upgrade(req, socket, head) {
// const wss = new WebSocket.Server({
// server: server
// });
// wss.on('connection', function connection(ws) {
// console.log(req.url.slice(1))
// const client = new WebSocket(req.url.slice(1));
//ws.on('message', function incoming(message) {
// client.send(message)
// });
// client.on('message', function incoming(data) {
// ws.send(data)
// })
// ws.on('error', function incoming(data) {
// client.send(data)
// });
// client.on('error', function incoming(data) {
// ws.send(data)
//});
// });
//});
app.use('/', async(req, res, next) => {
var proxy = {};
proxy.url = `https://www.startpage.com${req.url}`;
proxy.url = {
href: proxy.url,
hostname : proxy.url.split('/').splice(2).splice(0, 1).join('/'),
origin : proxy.url.split('/').splice(0, 3).join('/'),
encoded_origin : btoa(proxy.url.split('/').splice(0, 3).join('/')),
path : '/' + proxy.url.split('/').splice(3).join('/'),
protocol : proxy.url.split('\:').splice(0, 1).join(''),
}
proxy.requestHeaders = req.headers;
proxy.requestHeaders.host = proxy.url.hostname;
delete proxy.requestHeaders['accept-encoding']
proxy.requestHeaders['referer'] = proxy.url.href;
proxy.requestHeaders['origin'] = proxy.url.origin;
proxy.options = {
method: req.method,
headers: proxy.requestHeaders,
rejectUnauthorized: false
}
if (proxy.url.protocol == 'https') { proxy.protocol = https; }
else {proxy.protocol = http};
proxy.sendRequest = proxy.protocol.request(proxy.url.href, proxy.options, server_res => {
var body = [], redirect = false, redirect_value = '';
server_res.on('data', (chunk) => {
body.push(Buffer.from(chunk, 'binary'))
});
var ct = 'text/plain';
Object.entries(server_res.headers).forEach(([header_name, header_value]) => {
if (header_name.startsWith('content-encoding') || header_name.startsWith('x-') || header_name.startsWith('cf-') || header_name.startsWith('strict-transport-security') || header_name.startsWith('content-security-policy')) {
delete server_res.headers[header_name];
}
if (header_name.startsWith('location') || header_name.startsWith('Location')) {
redirect = true; redirect_value = header_value;
delete server_res.headers[header_name];
}
if (header_name == 'content-type') ct = header_value;
});
if (ct == null || typeof ct == 'undefined') ct = 'text/html';
if (redirect == true) { return res.redirect(307, '/' + redirect_value); };
server_res.on('end', () => {
body = Buffer.concat(body)
res.contentType(ct)
res.set(server_res.headers);
res.status(server_res.statusCode)
res.send(body)
});
});
proxy.sendRequest.on('error', err => {
res.send(err.toString())
});
if (req.method == 'POST') {
req.raw_body = '';
req.str_body = '';
req.on('data', chunk => {
req.raw_body += chunk.toString(); // convert Buffer to string
});
req.on('end', () => {
req.str_body = req.raw_body;
proxy.sendRequest.write(req.str_body);
proxy.sendRequest.end();
});
} else proxy.sendRequest.end();
});
server.listen('9000')
I am working on solutions using which i can send desktop push notification to subscribed clients.
I have created basic solution in where whenever user click on button i ask user for whether they want to allow notifications for my app or not!
I am getting an error of "Registration failed - permission denied" whenever i click on button for first time.
So that i am not able to get required endpoints to save at backend
Here is my code
index.html
<html>
<head>
<title>PUSH NOT</title>
<script src="index.js"></script>
</head>
<body>
<button onclick="main()">Ask Permission</button>
</body>
</html>
index.js
const check = () => {
if (!("serviceWorker" in navigator)) {
throw new Error("No Service Worker support!");
} else {
console.log("service worker supported")
}
if (!("PushManager" in window)) {
throw new Error("No Push API Support!");
} else {
console.log("PushManager worker supported")
}
};
const registerServiceWorker = async () => {
const swRegistration = await navigator.serviceWorker.register("/service.js?"+Math.random());
return swRegistration;
};
const requestNotificationPermission = async () => {
const permission = await window.Notification.requestPermission();
// value of permission can be 'granted', 'default', 'denied'
// granted: user has accepted the request
// default: user has dismissed the notification permission popup by clicking on x
// denied: user has denied the request.
if (permission !== "granted") {
throw new Error("Permission not granted for Notification");
}
};
const main = async () => {
check();
const swRegistration = await registerServiceWorker();
const permission = await requestNotificationPermission();
};
// main(); we will not call main in the beginning.
service.js
// urlB64ToUint8Array is a magic function that will encode the base64 public key
// to Array buffer which is needed by the subscription option
const urlB64ToUint8Array = base64String => {
const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, "+")
.replace(/_/g, "/");
const rawData = atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
};
const saveSubscription = async subscription => {
console.log("Save Sub")
const SERVER_URL = "http://localhost:4000/save-subscription";
const response = await fetch(SERVER_URL, {
method: "post",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(subscription)
});
return response.json();
};
self.addEventListener("activate", async () => {
try {
const applicationServerKey = urlB64ToUint8Array(
"BFPtpIVOcn2y25il322-bHQIqXXm-OACBtFLdo0EnzGfs-jIGXgAzjY6vNapPb4MM1Z1WuTBUo0wcIpQznLhVGM"
);
const options = { applicationServerKey, userVisibleOnly: true };
const subscription = await self.registration.pushManager.subscribe(options);
console.log(JSON.stringify(subscription))
const response = await saveSubscription(subscription);
} catch (err) {
console.log(err.code)
console.log(err.message)
console.log(err.name)
console.log('Error', err)
}
});
self.addEventListener("push", function(event) {
if (event.data) {
console.log("Push event!! ", event.data.text());
} else {
console.log("Push event but no data");
}
});
Also i have created a bit of backend as well
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const webpush = require('web-push')
const app = express();
app.use(cors());
app.use(bodyParser.json());
const port = 4000;
app.get("/", (req, res) => res.send("Hello World!"));
const dummyDb = { subscription: null }; //dummy in memory store
const saveToDatabase = async subscription => {
// Since this is a demo app, I am going to save this in a dummy in memory store. Do not do this in your apps.
// Here you should be writing your db logic to save it.
dummyDb.subscription = subscription;
};
// The new /save-subscription endpoint
app.post("/save-subscription", async (req, res) => {
const subscription = req.body;
await saveToDatabase(subscription); //Method to save the subscription to Database
res.json({ message: "success" });
});
const vapidKeys = {
publicKey:
'BFPtpIVOcn2y25il322-bHQIqXXm-OACBtFLdo0EnzGfs-jIGXgAzjY6vNapPb4MM1Z1WuTBUo0wcIpQznLhVGM',
privateKey: 'mHSKS-uwqAiaiOgt4NMbzYUb7bseXydmKObi4v4bN6U',
}
webpush.setVapidDetails(
'mailto:janakprajapati90#email.com',
vapidKeys.publicKey,
vapidKeys.privateKey
)
const sendNotification = (subscription, dataToSend='') => {
webpush.sendNotification(subscription, dataToSend)
}
app.get('/send-notification', (req, res) => {
const subscription = {endpoint:"https://fcm.googleapis.com/fcm/send/dLjyDYvI8yo:APA91bErM4sn_wRIW6xCievhRZeJcIxTiH4r_oa58JG9PHUaHwX7hQlhMqp32xEKUrMFJpBTi14DeOlECrTsYduvHTTnb8lHVUv3DkS1FOT41hMK6zwMvlRvgWU_QDDS_GBYIMRbzjhg",expirationTime:null,keys:{"p256dh":"BE6kUQ4WTx6v8H-wtChgKAxh3hTiZhpfi4DqACBgNRoJHt44XymOWFkQTvRPnS_S9kmcOoDSgOVD4Wo8qDQzsS0",auth:"CfO4rOsisyA6axdxeFgI_g"}} //get subscription from your databse here.
const message = 'Hello World'
sendNotification(subscription, message)
res.json({ message: 'message sent' })
})
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
Please help me
Try the following code:
index.js
const check = () => {
if (!("serviceWorker" in navigator)) {
throw new Error("No Service Worker support!");
} else {
console.log("service worker supported")
}
if (!("PushManager" in window)) {
throw new Error("No Push API Support!");
} else {
console.log("PushManager worker supported")
}
};
const saveSubscription = async subscription => {
console.log("Save Sub")
const SERVER_URL = "http://localhost:4000/save-subscription";
const response = await fetch(SERVER_URL, {
method: "post",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(subscription)
});
return response.json();
};
const urlB64ToUint8Array = base64String => {
const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, "+")
.replace(/_/g, "/");
const rawData = atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
};
const registerServiceWorker = async () => {
return navigator.serviceWorker.register("service.js?"+Math.random()).then((swRegistration) => {
console.log(swRegistration);
return swRegistration;
});
};
const requestNotificationPermission = async (swRegistration) => {
return window.Notification.requestPermission().then(() => {
const applicationServerKey = urlB64ToUint8Array(
"BFPtpIVOcn2y25il322-bHQIqXXm-OACBtFLdo0EnzGfs-jIGXgAzjY6vNapPb4MM1Z1WuTBUo0wcIpQznLhVGM"
);
const options = { applicationServerKey, userVisibleOnly: true };
return swRegistration.pushManager.subscribe(options).then((pushSubscription) => {
console.log(pushSubscription);
return pushSubscription;
});
});
};
const main = async () => {
check();
const swRegistration = await registerServiceWorker();
const subscription = await requestNotificationPermission(swRegistration);
// saveSubscription(subscription);
};
service.js
self.addEventListener("push", function(event) {
if (event.data) {
console.log("Push event!! ", event.data.text());
} else {
console.log("Push event but no data");
}
});
I can think of three reasons that the permission is denied
1) your site is not on https (including localhost that is not on https), the default behaviour from chrome as far as i know is to block notifications on http sites. If that's the case, click on the info icon near the url, then click on site settings, then change notifications to ask
2) if you are on Safari, then safari is using the deprecated interface of the Request permission, that is to say the value is not returned through the promise but through a callback so instead of
Notification.requestPermission().then(res => console.log(res))
it is
Notification.requestPermission(res => console.log(res))
3) Your browser settings are blocking the notifications request globally, to ensure that this is not your problem run the following code in the console (on a secured https site)
Notification.requestPermission().then(res => console.log(res))
if you receive the alert box then the problem is something else, if you don't then make sure that the browser is not blocking notifications requests