-
Notifications
You must be signed in to change notification settings - Fork 1
/
http.mjs
102 lines (80 loc) · 2.59 KB
/
http.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import path from 'node:path';
import fs from 'node:fs';
import { fileURLToPath } from 'url';
import express from 'express';
import webpush from 'web-push';
const HTTP_PORT = 8000;
const vapidKeys = {
subject : "mailto:[email protected]",
publicKey: 'BEIExHp6gQ6RBs-2bWFpFRxZkmdp4m29l9BtjjSWPOAddYxCM3k1YLokAtnxVarRuMquQiGslzicGaWBL20kyaM',
privateKey: 'umejD7kPNtnM82Pk3xB5GH2vQhwUy7t4inHH1mc0mh8'
};
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const app = express();
webpush.setVapidDetails(
vapidKeys.subject,
vapidKeys.publicKey,
vapidKeys.privateKey
);
app.use(express.static(path.resolve(__dirname, './public')));
app.set('view engine', 'ejs');
app.set('views', path.resolve(__dirname, './views/'));
const logger = {
info: console.log,
error: console.error
};
const browsersByIdFilepath = path.resolve(__dirname, 'browsers-by-id');
let browsersById = {};
try {
const contents = await fs.promises.readFile(browsersByIdFilepath);
browsersById = JSON.parse(contents);
} catch (ex) {
// ignore
}
async function writeBrowsersById() {
await fs
.promises
.writeFile(browsersByIdFilepath, JSON.stringify(browsersById));
}
function buildHandler(fn) {
return async (req, res) => {
try {
await fn(req, res);
} catch (ex) {
logger.error(ex);
res.status(500).json({ error: ex.message });
}
};
}
app.get('/', buildHandler((req, res) => {
res.render('index', {
vapidPublicKey: vapidKeys.publicKey,
browsers: Object.values(browsersById)
});
}));
app.post('/subscribe', express.json(), buildHandler(async (req, res) => {
const { browserId, pushSubscription } = req.body;
browsersById[browserId] = { id: browserId, pushSubscription };
await writeBrowsersById();
res.status(200).json({ ok: true });
}));
app.post('/notify-all', express.json(), buildHandler(async (req, res) => {
const { message } = req.body;
const str = JSON.stringify({ title: 'Hello World!', body: message });
for (const { id, pushSubscription } of Object.values(browsersById)) {
logger.info(`Sending notification for ${id}`);
try {
await webpush.sendNotification(pushSubscription, str);
} catch (ex) {
logger.error(ex);
// if error, removes from browsersById
delete browsersById[id];
}
}
await writeBrowsersById();
res.status(200).json({ ok: true });
}));
app.listen(HTTP_PORT, () => {
logger.info(`http server opened on ${HTTP_PORT}`);
});