|
|
@ -1,5 +1,5 @@ |
|
|
|
const { R } = require("redbean-node"); |
|
|
|
const { Liquid } = require( 'liquidjs'); |
|
|
|
const { Liquid } = require( "liquidjs"); |
|
|
|
const { UP } = require("../src/util"); |
|
|
|
const dayjs = require("dayjs"); |
|
|
|
|
|
|
@ -28,9 +28,8 @@ 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 MinimalDetailTemplate = "{{monitor.name}}: {{monitor.health}}"; |
|
|
|
const LowDetailTemplate = "[{{monitor.name}}] [{{monitor.health}}] {{heartbeat.msg}}"; |
|
|
|
const MediumDetailTemplate = `Monitor: {{monitor.name}}
|
|
|
|
Health: {{monitor.health}} |
|
|
|
Address: {{monitor.url}} |
|
|
@ -45,7 +44,7 @@ Address: {{monitor.url}} |
|
|
|
Your {{monitor.type}} monitor is unexpectedly down. |
|
|
|
{%- endif %} |
|
|
|
Time: {{heartbeat.time}} |
|
|
|
Uptime Message: {{heartbeat.msg}}` |
|
|
|
Uptime Message: {{heartbeat.msg}}`;
|
|
|
|
|
|
|
|
const FullDetailTemplate = `Monitor: {{monitor.name}}
|
|
|
|
Health: {{monitor.health}} |
|
|
@ -70,11 +69,11 @@ Tags |
|
|
|
{%- if tag.value and tag.value != "" -%} |
|
|
|
: {{tag.value}} |
|
|
|
{%- endif %} |
|
|
|
{% endfor -%}` |
|
|
|
{% endfor -%}`;
|
|
|
|
|
|
|
|
class Notification { |
|
|
|
|
|
|
|
static generateTestHeartbeat(){ |
|
|
|
static generateTestHeartbeat() { |
|
|
|
return { |
|
|
|
monitorID: 5, |
|
|
|
status: 1, |
|
|
@ -85,7 +84,8 @@ class Notification { |
|
|
|
duration: 8, |
|
|
|
}; |
|
|
|
} |
|
|
|
static generateTestMonitor(){ |
|
|
|
|
|
|
|
static generateTestMonitor() { |
|
|
|
return { |
|
|
|
id: 5, |
|
|
|
name: "Test Notification Monitor", |
|
|
@ -110,10 +110,17 @@ class Notification { |
|
|
|
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"}], |
|
|
|
notificationIDList: { "1": true, |
|
|
|
"5": true }, |
|
|
|
tags: [{ "id": 21, |
|
|
|
"monitor_id": 16, |
|
|
|
"tag_id": 2, |
|
|
|
"value": "", |
|
|
|
"name": "Internal", |
|
|
|
"color": "#059669" }], |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
providerList = {}; |
|
|
|
|
|
|
|
static init() { |
|
|
@ -158,7 +165,6 @@ class Notification { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* |
|
|
|
* @param notification : BeanModel |
|
|
@ -170,74 +176,76 @@ class Notification { |
|
|
|
*/ |
|
|
|
static async send(notification, msg, monitorJSON, heartbeatJSON) { |
|
|
|
if (this.providerList[notification.type]) { |
|
|
|
try { |
|
|
|
monitorJSON.health = ((heartbeatJSON.status == 1) !== monitorJSON.upsideDown) ? "✅ Healthy": "❌ Unhealthy" |
|
|
|
|
|
|
|
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, |
|
|
|
} |
|
|
|
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 |
|
|
|
} |
|
|
|
monitorJSON.health = ((heartbeatJSON.status == 1) !== monitorJSON.upsideDown) ? "✅ Healthy" : "❌ Unhealthy"; |
|
|
|
|
|
|
|
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, |
|
|
|
}; |
|
|
|
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); |
|
|
|
|
|
|
|
//Removed try-catch here. I am not sure what the default should be in the case of a broken template.
|
|
|
|
//switch to manually building the message?
|
|
|
|
//the problem is that it would still need to send a message after the template fails of if it failed to send completely..
|
|
|
|
//im not sure if that is the desired result on a template fail.
|
|
|
|
|
|
|
|
} else { |
|
|
|
throw new Error("Notification type is not supported"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static getTemplateFromNotification(notification){ |
|
|
|
static getTemplateFromNotification(notification) { |
|
|
|
|
|
|
|
let template = notification.template |
|
|
|
let detail = notification.detail |
|
|
|
console.log(`Detail: (${detail}) Template: (${template})`) |
|
|
|
let template = notification.template; |
|
|
|
let detail = notification.detail; |
|
|
|
console.log(`Detail: (${detail}) Template: (${template})`); |
|
|
|
switch (detail) { |
|
|
|
case "Minimal Detail": |
|
|
|
return MinimalDetailTemplate |
|
|
|
return MinimalDetailTemplate; |
|
|
|
case "Low Detail": |
|
|
|
return LowDetailTemplate |
|
|
|
return LowDetailTemplate; |
|
|
|
case "Medium Detail": |
|
|
|
return MediumDetailTemplate |
|
|
|
return MediumDetailTemplate; |
|
|
|
case "Full Detail": |
|
|
|
return FullDetailTemplate |
|
|
|
return FullDetailTemplate; |
|
|
|
case "Custom Template": |
|
|
|
if (template) { |
|
|
|
return template |
|
|
|
return template; |
|
|
|
} |
|
|
|
//returns low in the case of a template being empty string or undefined.
|
|
|
|
} |
|
|
|
return LowDetailTemplate |
|
|
|
return LowDetailTemplate; |
|
|
|
} |
|
|
|
|
|
|
|
static async save(notification, notificationID, userID) { |
|
|
|
let bean |
|
|
|
let bean; |
|
|
|
|
|
|
|
if (notificationID) { |
|
|
|
bean = await R.findOne("notification", " id = ? AND user_id = ? ", [ |
|
|
|
notificationID, |
|
|
|
userID, |
|
|
|
]) |
|
|
|
]); |
|
|
|
|
|
|
|
if (! bean) { |
|
|
|
throw new Error("notification not found") |
|
|
|
throw new Error("notification not found"); |
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
bean = R.dispense("notification") |
|
|
|
bean = R.dispense("notification"); |
|
|
|
} |
|
|
|
|
|
|
|
bean.name = notification.name; |
|
|
|
bean.user_id = userID; |
|
|
|
bean.config = JSON.stringify(notification); |
|
|
|
bean.is_default = notification.isDefault || false; |
|
|
|
await R.store(bean) |
|
|
|
await R.store(bean); |
|
|
|
|
|
|
|
if (notification.applyExisting) { |
|
|
|
await applyNotificationEveryMonitor(bean.id, userID); |
|
|
@ -250,13 +258,13 @@ class Notification { |
|
|
|
let bean = await R.findOne("notification", " id = ? AND user_id = ? ", [ |
|
|
|
notificationID, |
|
|
|
userID, |
|
|
|
]) |
|
|
|
]); |
|
|
|
|
|
|
|
if (! bean) { |
|
|
|
throw new Error("notification not found") |
|
|
|
throw new Error("notification not found"); |
|
|
|
} |
|
|
|
|
|
|
|
await R.trash(bean) |
|
|
|
await R.trash(bean); |
|
|
|
} |
|
|
|
|
|
|
|
static checkApprise() { |
|
|
@ -276,17 +284,17 @@ async function applyNotificationEveryMonitor(notificationID, userID) { |
|
|
|
let checkNotification = await R.findOne("monitor_notification", " monitor_id = ? AND notification_id = ? ", [ |
|
|
|
monitors[i].id, |
|
|
|
notificationID, |
|
|
|
]) |
|
|
|
]); |
|
|
|
|
|
|
|
if (! checkNotification) { |
|
|
|
let relation = R.dispense("monitor_notification"); |
|
|
|
relation.monitor_id = monitors[i].id; |
|
|
|
relation.notification_id = notificationID; |
|
|
|
await R.store(relation) |
|
|
|
await R.store(relation); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
module.exports = { |
|
|
|
Notification, |
|
|
|
} |
|
|
|
}; |
|
|
|