diff --git a/package-lock.json b/package-lock.json index b50218a..d0ca70a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6041,9 +6041,9 @@ "dev": true }, "liquidjs": { - "version": "9.28.0", - "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-9.28.0.tgz", - "integrity": "sha512-BsLhHbv+dHH8hzac1/4tx2f4yPujD87wPOz9gnosPMoDgR0HiRrZXqPUVpfXJgZbWaqEJX1lawnS0GDyG/1r6Q==" + "version": "9.28.1", + "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-9.28.1.tgz", + "integrity": "sha512-3nt07YdKCt/4u3D/B5ngBWvyCxENGH2+vcrlBzBdaUBlyX2htzj9MjWKqeXdJJfz7xtbcwbaWEuP84/SZvDSog==" }, "locate-path": { "version": "5.0.0", diff --git a/package.json b/package.json index 5f85145..394687d 100644 --- a/package.json +++ b/package.json @@ -62,8 +62,8 @@ "axios": "~0.21.4", "bcryptjs": "~2.4.3", "bootstrap": "~5.1.1", - "chardet": "^1.3.0", "bree": "~6.3.1", + "chardet": "^1.3.0", "chart.js": "~3.5.1", "chartjs-adapter-dayjs": "~1.0.0", "command-exists": "~1.2.9", @@ -75,7 +75,7 @@ "http-graceful-shutdown": "~3.1.4", "iconv-lite": "^0.6.3", "jsonwebtoken": "~8.5.1", - "liquidjs": "^9.28.0", + "liquidjs": "^9.28.1", "nodemailer": "~6.6.5", "notp": "~2.0.3", "password-hash": "~1.2.2", diff --git a/server/notification.js b/server/notification.js index 089ddb4..26abd01 100644 --- a/server/notification.js +++ b/server/notification.js @@ -27,8 +27,92 @@ const Feishu = require("./notification-providers/feishu"); const AliyunSms = require("./notification-providers/aliyun-sms"); const DingDing = require("./notification-providers/dingding"); + +const MinimalDetailTemplate = "{{monitor.name}}: {{monitor.health}}" +const LowDetailTemplate = "[{{monitor.name}}] [{{monitor.health}}] {{heartbeat.msg}}" +const MediumDetailTemplate = `Monitor: {{monitor.name}} +Health: {{monitor.health}} +Address: {{monitor.url}} + +{% if heartbeat.status == 1 and monitor.upsideDown -%} + Your Upside down {{monitor.type}} monitor is unexpectedly connected +{%- elsif heartbeat.status == 1 and monitor.upsideDown==false -%} + Your {{monitor.type}} monitor is up +{%- elsif heartbeat.status == 0 and monitor.upsideDown -%} + Your Upside down {{monitor.type}} monitor is no longer connected +{%- elsif heartbeat.status == 0 and monitor.upsideDown == false -%} + Your {{monitor.type}} monitor is unexpectedly down. +{%- endif %} +Time: {{heartbeat.time}} +Uptime Message: {{heartbeat.msg}}` + +const FullDetailTemplate = `Monitor: {{monitor.name}} +Health: {{monitor.health}} +Address: {{monitor.url}} + +{% if heartbeat.status == 1 and monitor.upsideDown -%} + Your Upside down {{monitor.type}} monitor is unexpectedly connected +{%- elsif heartbeat.status == 1 and monitor.upsideDown==false -%} + Your {{monitor.type}} monitor is up +{%- elsif heartbeat.status == 0 and monitor.upsideDown -%} + Your Upside down {{monitor.type}} monitor is no longer connected +{%- elsif heartbeat.status == 0 and monitor.upsideDown == false -%} + Your {{monitor.type}} monitor is unexpectedly down. +{%- endif %} +Time: {{heartbeat.time}} +Uptime Message: {{heartbeat.msg}} + +Tags +---------------------------------------- +{% for tag in monitor.tags -%} + {{ tag.name }} + {%- if tag.value and tag.value != "" -%} + : {{tag.value}} + {%- endif %} +{% endfor -%}` + class Notification { + static generateTestHeartbeat(){ + return { + monitorID: 5, + status: 1, + time: (new Date()).toLocaleString(), + msg: "TEST NOTIFICATION MESSAGE", + ping: 278, + important: true, + duration: 8, + }; + } + static generateTestMonitor(){ + return { + id: 5, + name: "Test Notification Monitor", + url: "https://www.example.com", + method: "Get", + body: "OK", + headers: null, + hostname: "www.example.com", + port: 443, + maxretries: 2, + weight: 2000, + active: 1, + type: "HTTP", + interval: 60, + retryInterval: this.retryInterval, + keyword: null, + ignoreTls: false, + upsideDown: false, + maxredirects: 10, + accepted_statuscodes: ["200-299"], + dns_resolve_type: "A", + dns_resolve_server: "1.1.1.1", + dns_last_result: null, + pushToken: null, + notificationIDList:{"1":true,"5":true}, + tags: [{"id":21,"monitor_id":16,"tag_id":2,"value":"","name":"Internal","color":"#059669"}], + }; + } providerList = {}; static init() { @@ -73,6 +157,7 @@ class Notification { } } + /** * * @param notification : BeanModel @@ -82,34 +167,22 @@ class Notification { * @returns {Promise} Successful msg * Throw Error with fail msg */ - static async send( - notification, - msg, - monitorJSON = { - id: "this.id", - name: "this.name", - url: "this.url", - hostname: "this.hostname", - }, - heartbeatJSON = { - status: UP, - message: "new message", - ping: "1ms", - duration:"5 seconds", - monitor:"asd", - - }) { + static async send(notification, msg, monitorJSON, heartbeatJSON) { if (this.providerList[notification.type]) { - //TODO need to check for errors. try { + monitorJSON.health = ((heartbeatJSON.status == 1) !== monitorJSON.upsideDown) ? "✅ Healthy": "❌ Unhealthy" - let newmsg = await engine.parseandrender("{{msg}} {{monitor | json}} {{heartbeat | json}} {{notification | json}}", { - notification: notification, - msg: msg, + let parseData = { + // I actually dont think that it is necessary to put the notification in the data sent to the template. + // notification: notification, monitor: monitorJSON, heartbeat: heartbeatJSON, - }) - return this.providerList[notification.type].send(notification, newmsg, monitorJSON, heartbeatJSON); + } + let template = this.getTemplateFromNotification(notification) + console.log(`Template: (${template})`) + let message = await engine.parseAndRender(template, parseData) + + return this.providerList[notification.type].send(notification, message, monitorJSON, heartbeatJSON); } catch (e) { throw e } @@ -119,6 +192,29 @@ class Notification { } } + static getTemplateFromNotification(notification){ + + let template = notification.template + let detail = notification.detail + console.log(`Detail: (${detail}) Template: (${template})`) + switch (detail) { + case "Minimal Detail": + return MinimalDetailTemplate + case "Low Detail": + return LowDetailTemplate + case "Medium Detail": + return MediumDetailTemplate + case "Full Detail": + return FullDetailTemplate + case "Custom Template": + if (template) { + return template + } + //returns low in the case of a template being empty string or undefined. + } + return LowDetailTemplate + } + static async save(notification, notificationID, userID) { let bean diff --git a/server/server.js b/server/server.js index 1846fe6..9ab511c 100644 --- a/server/server.js +++ b/server/server.js @@ -970,7 +970,8 @@ exports.entryPage = "dashboard"; try { checkLogin(socket); - let msg = await Notification.send(notification, notification.name + " Testing"); + let notificationText = `[Monitor Name] [Up/Down] Status Message (${notification.name} Testing)`; + let msg = await Notification.send(notification, notificationText, Notification.generateTestMonitor(),Notification.generateTestHeartbeat()); callback({ ok: true, diff --git a/src/components/NotificationDialog.vue b/src/components/NotificationDialog.vue index 659f572..8cc4f98 100644 --- a/src/components/NotificationDialog.vue +++ b/src/components/NotificationDialog.vue @@ -22,6 +22,19 @@ +
+ + +
+ + +
+ + +
+ @@ -72,7 +85,9 @@ import { Modal } from "bootstrap"; import { ucfirst } from "../util.ts"; import Confirm from "./Confirm.vue"; -import NotificationFormList from "./notifications"; +import {NotificationFormList, NotificationDetailList} from "./notifications"; +// import from "./notifications"; + export default { components: { @@ -92,7 +107,9 @@ export default { type: null, isDefault: false, // Do not set default value here, please scroll to show() - } + }, + detailLevels: NotificationDetailList, + }; }, @@ -118,6 +135,9 @@ export default { this.notification.name = this.getUniqueDefaultName(to); } }, + "notification.detail"(to,from){ + this.notification.detail = to + } }, mounted() { this.modal = new Modal(this.$refs.modal); @@ -149,6 +169,9 @@ export default { // Set Default value here this.notification.type = this.notificationTypes[0]; + this.notification.detail = this.detailLevels[0]; + this.notification.template = "[{{monitor.name}}] [{{monitor.health}}] {{monitor.msg}}" + } this.modal.show(); diff --git a/src/components/notifications/index.js b/src/components/notifications/index.js index 96ee282..0eaf4f4 100644 --- a/src/components/notifications/index.js +++ b/src/components/notifications/index.js @@ -26,7 +26,7 @@ import DingDing from "./DingDing.vue"; * * @type { Record } */ -const NotificationFormList = { +export const NotificationFormList = { "telegram": Telegram, "webhook": Webhook, "smtp": STMP, @@ -51,4 +51,11 @@ const NotificationFormList = { "DingDing": DingDing } -export default NotificationFormList +export const NotificationDetailList = [ + "Minimal Detail", + "Low Detail", + "Medium Detail", + "Full Detail", + "Custom Template", +] + diff --git a/src/languages/en.js b/src/languages/en.js index d3a69c1..8faefc7 100644 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -306,4 +306,16 @@ export default { "One record": "One record", "Showing {from} to {to} of {count} records": "Showing {from} to {to} of {count} records", steamApiKeyDescription: "For monitoring a Steam Game Server you need a Steam Web-API key. You can register your API key here: ", + "Message Template":"Message Template", + "Default Template":"[{{monitor.name}}] [{{monitor.health}}] {{monitor.msg}}", + HealthyStatus:"✅ Healthy", + UnhealthyStatus:"❌ Unhealthy", + //template levels + "Notification Message Detail":"Notification Message Detail", + + "Minimal Detail":"Minimal Detail", + "Low Detail":"Low Detail", + "Medium Detail":"Medium Detail", + "Full Detail":"Full Detail", + "Custom Template":"Custom Template", };