parent
892bd42dae
commit
23c4916c74
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,47 @@
|
||||
const NotificationProvider = require("./notification-provider");
|
||||
const { UP } = require("../../src/util");
|
||||
const webpush = require("web-push");
|
||||
const { setting } = require("../util-server");
|
||||
|
||||
class Webpush extends NotificationProvider {
|
||||
name = "Webpush";
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
|
||||
const okMsg = "Sent Successfully.";
|
||||
|
||||
try {
|
||||
const publicVapidKey = await setting("webpushPublicVapidKey");
|
||||
const privateVapidKey = await setting("webpushPrivateVapidKey");
|
||||
|
||||
webpush.setVapidDetails("https://github.com/louislam/uptime-kuma", publicVapidKey, privateVapidKey);
|
||||
|
||||
if (heartbeatJSON === null && monitorJSON === null) {
|
||||
// Test message
|
||||
const data = JSON.stringify({
|
||||
title: "TEST",
|
||||
body: `Test Alert - ${msg}`
|
||||
});
|
||||
|
||||
await webpush.sendNotification(notification.subscription, data);
|
||||
|
||||
return okMsg;
|
||||
}
|
||||
|
||||
const data = JSON.stringify({
|
||||
title: heartbeatJSON["status"] === UP ? "Monitor Up" : "Monitor DOWN",
|
||||
body: heartbeatJSON["status"] === UP ? `❌ ${heartbeatJSON["name"]} is DOWN` : `✅ ${heartbeatJSON["name"]} is UP`
|
||||
});
|
||||
|
||||
await webpush.sendNotification(notification.subscription, data);
|
||||
|
||||
return okMsg;
|
||||
} catch (error) {
|
||||
this.throwGeneralAxiosError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Webpush;
|
||||
@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<button
|
||||
class="mb-3"
|
||||
type="button" :class="[
|
||||
'btn',
|
||||
browserSupportsServiceWorkers ? 'btn-primary' : 'btn-danger'
|
||||
]"
|
||||
:disabled="!btnEnabled"
|
||||
@click="registerWebpush"
|
||||
>
|
||||
<div v-if="processing" class="spinner-border spinner-border-sm me-1"></div>
|
||||
<span v-else-if="$parent.notification.subscription" class="me-1">✓</span>
|
||||
{{ btnText }}
|
||||
</button>
|
||||
|
||||
<div class="form-text">
|
||||
{{ $t("Webpush Helptext") }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
btnEnabled: false,
|
||||
btnText: "",
|
||||
processing: false,
|
||||
browserSupportsServiceWorkers: false,
|
||||
publicVapidKey: null,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
if (this.$parent.notification.subscription) {
|
||||
this.btnEnabled = false;
|
||||
this.browserSupportsServiceWorkers = true;
|
||||
this.btnText = this.$t("Notifications Enabled");
|
||||
} else {
|
||||
if (("serviceWorker" in navigator)) {
|
||||
this.btnText = this.$t("Allow Notifications");
|
||||
this.browserSupportsServiceWorkers = true;
|
||||
this.btnEnabled = true;
|
||||
} else {
|
||||
this.btnText = this.$t("Browser not supported");
|
||||
this.browserSupportsServiceWorkers = false;
|
||||
this.btnEnabled = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async registerWebpush() {
|
||||
this.processing = true;
|
||||
|
||||
try {
|
||||
const publicKey = await new Promise((resolve, reject) => {
|
||||
this.$root.getSocket().emit("getWebpushVapidPublicKey", (resp) => {
|
||||
if (!resp.ok) {
|
||||
reject(new Error(resp.msg));
|
||||
}
|
||||
console.log(resp.msg);
|
||||
resolve(resp.msg);
|
||||
});
|
||||
});
|
||||
|
||||
const permission = await Notification.requestPermission();
|
||||
if (permission !== "granted") {
|
||||
this.$root.toastRes({
|
||||
ok: false,
|
||||
msg: this.$t("Unable to get permission to notify"),
|
||||
});
|
||||
this.processing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const registration = await navigator.serviceWorker.ready;
|
||||
|
||||
const subscription = await registration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: publicKey,
|
||||
});
|
||||
|
||||
this.$parent.notification.subscription = subscription;
|
||||
this.btnEnabled = false;
|
||||
this.browserSupportsServiceWorkers = true;
|
||||
this.btnText = this.$t("Notifications Enabled");
|
||||
} catch (error) {
|
||||
console.error("Subscription failed:", error);
|
||||
this.$root.toastRes({
|
||||
ok: false,
|
||||
msg: error
|
||||
});
|
||||
} finally {
|
||||
this.processing = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@ -0,0 +1,23 @@
|
||||
// Needed per Vite PWA docs
|
||||
import { precacheAndRoute } from 'workbox-precaching'
|
||||
declare let self: ServiceWorkerGlobalScope
|
||||
precacheAndRoute(self.__WB_MANIFEST)
|
||||
|
||||
// Receive push notifications
|
||||
self.addEventListener('push', function (event) {
|
||||
if (self.Notification?.permission !== 'granted') {
|
||||
console.error("Notifications aren't supported or permission not granted!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.data) {
|
||||
let message = event.data.json();
|
||||
try {
|
||||
self.registration.showNotification(message.title, {
|
||||
body: message.body,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to show notification:', error);
|
||||
}
|
||||
}
|
||||
});
|
||||
Loading…
Reference in new issue