mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-04-20 07:36:05 -04:00
Merge e191d1329570dfc2600252e740212f0ffc3e3342 into 510056fbbcfd5fea271dd412e139520b4c62ec3b
This commit is contained in:
commit
507e2debf6
@ -0,0 +1,27 @@
|
||||
exports.up = function (knex) {
|
||||
return knex.schema
|
||||
.alterTable("monitor_notification", function (table) {
|
||||
table.text("trigger").notNullable().defaultTo("always");
|
||||
})
|
||||
.alterTable("notification", function (table) {
|
||||
table.text("default_trigger").notNullable().defaultTo("always");
|
||||
})
|
||||
.then(() => {
|
||||
knex("monitor_notification").whereNull("trigger").update({
|
||||
trigger: "always",
|
||||
});
|
||||
knex("notification").whereNull("default_trigger").update({
|
||||
default_trigger: "always",
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.down = function (knex) {
|
||||
return knex.schema
|
||||
.alterTable("monitor_notification", function (table) {
|
||||
table.dropColumn("trigger");
|
||||
})
|
||||
.alterTable("notification", function (table) {
|
||||
table.dropColumn("default_trigger");
|
||||
});
|
||||
};
|
@ -1340,7 +1340,14 @@ class Monitor extends BeanModel {
|
||||
heartbeatJSON["timezoneOffset"] = UptimeKumaServer.getInstance().getTimezoneOffset();
|
||||
heartbeatJSON["localDateTime"] = dayjs.utc(heartbeatJSON["time"]).tz(heartbeatJSON["timezone"]).format(SQL_DATETIME_FORMAT);
|
||||
|
||||
await Notification.send(JSON.parse(notification.config), msg, monitor.toJSON(preloadData, false), heartbeatJSON);
|
||||
if (
|
||||
notification.trigger === "always" ||
|
||||
notification.trigger === "up_down" ||
|
||||
((notification.trigger === "up" || notification.trigger === "up_certificate") && bean.status === UP) ||
|
||||
((notification.trigger === "down" || notification.trigger === "down_certificate") && bean.status === DOWN)
|
||||
) {
|
||||
await Notification.send(JSON.parse(notification.config), msg, monitor.toJSON(preloadData, false), heartbeatJSON);
|
||||
}
|
||||
} catch (e) {
|
||||
log.error("monitor", "Cannot send notification to " + notification.name);
|
||||
log.error("monitor", e);
|
||||
@ -1355,7 +1362,7 @@ class Monitor extends BeanModel {
|
||||
* @returns {Promise<LooseObject<any>[]>} List of notifications
|
||||
*/
|
||||
static async getNotificationList(monitor) {
|
||||
let notificationList = await R.getAll("SELECT notification.* FROM notification, monitor_notification WHERE monitor_id = ? AND monitor_notification.notification_id = notification.id ", [
|
||||
let notificationList = await R.getAll("SELECT notification.*, monitor_notification.trigger FROM notification, monitor_notification WHERE monitor_id = ? AND monitor_notification.notification_id = notification.id ", [
|
||||
monitor.id,
|
||||
]);
|
||||
return notificationList;
|
||||
@ -1432,6 +1439,9 @@ class Monitor extends BeanModel {
|
||||
log.debug("monitor", "Send certificate notification");
|
||||
|
||||
for (let notification of notificationList) {
|
||||
if (notification.trigger !== "always" && notification.trigger !== "certificate" && notification.trigger !== "up_certificate" && notification.trigger !== "down_certificate") {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
log.debug("monitor", "Sending to " + notification.name);
|
||||
await Notification.send(JSON.parse(notification.config), `[${this.name}][${this.url}] ${certType} certificate ${certCN} will expire in ${daysRemaining} days`);
|
||||
@ -1509,7 +1519,7 @@ class Monitor extends BeanModel {
|
||||
*/
|
||||
static async getMonitorNotification(monitorIDs) {
|
||||
return await R.getAll(`
|
||||
SELECT monitor_notification.monitor_id, monitor_notification.notification_id
|
||||
SELECT monitor_notification.monitor_id, monitor_notification.notification_id, monitor_notification.trigger
|
||||
FROM monitor_notification
|
||||
WHERE monitor_notification.monitor_id IN (${monitorIDs.map((_) => "?").join(",")})
|
||||
`, monitorIDs);
|
||||
@ -1558,7 +1568,10 @@ class Monitor extends BeanModel {
|
||||
if (!notificationsMap.has(row.monitor_id)) {
|
||||
notificationsMap.set(row.monitor_id, {});
|
||||
}
|
||||
notificationsMap.get(row.monitor_id)[row.notification_id] = true;
|
||||
notificationsMap.get(row.monitor_id)[row.notification_id] = {
|
||||
active: true,
|
||||
trigger: row.trigger,
|
||||
};
|
||||
});
|
||||
|
||||
tags.forEach(row => {
|
||||
|
@ -219,6 +219,7 @@ class Notification {
|
||||
bean.user_id = userID;
|
||||
bean.config = JSON.stringify(notification);
|
||||
bean.is_default = notification.isDefault || false;
|
||||
bean.default_trigger = notification.defaultTrigger;
|
||||
await R.store(bean);
|
||||
|
||||
if (notification.applyExisting) {
|
||||
@ -271,15 +272,20 @@ async function applyNotificationEveryMonitor(notificationID, userID) {
|
||||
]);
|
||||
|
||||
for (let i = 0; i < monitors.length; i++) {
|
||||
let checkNotification = await R.findOne("monitor_notification", " monitor_id = ? AND notification_id = ? ", [
|
||||
let checkNotification = await R.getRow(`
|
||||
SELECT n.default_trigger FROM notification AS n
|
||||
LEFT JOIN monitor_notification mn on n.id = mn.notification_id AND mn.monitor_id = ? AND mn.notification_id = ?
|
||||
WHERE mn.monitor_id IS NULL
|
||||
`, [
|
||||
monitors[i].id,
|
||||
notificationID,
|
||||
]);
|
||||
|
||||
if (! checkNotification) {
|
||||
if (checkNotification) {
|
||||
let relation = R.dispense("monitor_notification");
|
||||
relation.monitor_id = monitors[i].id;
|
||||
relation.notification_id = notificationID;
|
||||
relation.trigger = checkNotification.default_trigger;
|
||||
await R.store(relation);
|
||||
}
|
||||
}
|
||||
|
@ -1426,6 +1426,7 @@ let needSetup = false;
|
||||
ok: true,
|
||||
msg: "Saved.",
|
||||
msgi18n: true,
|
||||
defaultTrigger: notificationBean.default_trigger,
|
||||
id: notificationBean.id,
|
||||
});
|
||||
|
||||
@ -1636,10 +1637,11 @@ async function updateMonitorNotification(monitorID, notificationIDList) {
|
||||
]);
|
||||
|
||||
for (let notificationID in notificationIDList) {
|
||||
if (notificationIDList[notificationID]) {
|
||||
if (notificationIDList[notificationID].active) {
|
||||
let relation = R.dispense("monitor_notification");
|
||||
relation.monitor_id = monitorID;
|
||||
relation.notification_id = notificationID;
|
||||
relation.trigger = notificationIDList[notificationID].trigger;
|
||||
await R.store(relation);
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,35 @@
|
||||
|
||||
<br>
|
||||
|
||||
<select id="notificationTrigger" v-model="notification.defaultTrigger" class="form-select">
|
||||
<option value="always">
|
||||
{{ $t("notificationTriggerAlways") }}
|
||||
</option>
|
||||
<option value="up_down">
|
||||
{{ $t("notificationTriggerUpDown") }}
|
||||
</option>
|
||||
<option value="up">
|
||||
{{ $t("notificationTriggerUp") }}
|
||||
</option>
|
||||
<option value="down">
|
||||
{{ $t("notificationTriggerDown") }}
|
||||
</option>
|
||||
<option value="certificate">
|
||||
{{ $t("notificationTriggerCertificate") }}
|
||||
</option>
|
||||
<option value="up_certificate">
|
||||
{{ $t("notificationTriggerUpCertificate") }}
|
||||
</option>
|
||||
<option value="down_certificate">
|
||||
{{ $t("notificationTriggerDownCertificate") }}
|
||||
</option>
|
||||
</select>
|
||||
<div class="form-text">
|
||||
{{ $t("enableDefaultTriggerNotificationDescription") }}
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="form-check form-switch">
|
||||
<input v-model="notification.applyExisting" class="form-check-input" type="checkbox">
|
||||
<label class="form-check-label">{{ $t("Apply on all existing monitors") }}</label>
|
||||
@ -95,6 +124,7 @@ export default {
|
||||
/** @type { null | keyof NotificationFormList } */
|
||||
type: null,
|
||||
isDefault: false,
|
||||
defaultTrigger: "always",
|
||||
// Do not set default value here, please scroll to show()
|
||||
}
|
||||
};
|
||||
@ -270,6 +300,7 @@ export default {
|
||||
name: "",
|
||||
type: "telegram",
|
||||
isDefault: false,
|
||||
defaultTrigger: "always",
|
||||
};
|
||||
}
|
||||
|
||||
@ -291,7 +322,7 @@ export default {
|
||||
|
||||
// Emit added event, doesn't emit edit.
|
||||
if (! this.id) {
|
||||
this.$emit("added", res.id);
|
||||
this.$emit("added", res.id, res.defaultTrigger);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1067,5 +1067,14 @@
|
||||
"YZJ Robot Token": "YZJ Robot token",
|
||||
"Plain Text": "Plain Text",
|
||||
"Message Template": "Message Template",
|
||||
"Template Format": "Template Format"
|
||||
"Template Format": "Template Format",
|
||||
"notificationTriggerAlways": "Notify on up, down state or certificate expiry",
|
||||
"notificationTriggerUpDown": "Notify on up or down state",
|
||||
"notificationTriggerUp": "Notify on up state only",
|
||||
"notificationTriggerDown": "Notify on down state only",
|
||||
"notificationTriggerUpCertificate": "Notify on up state or certificate expiry",
|
||||
"notificationTriggerDownCertificate": "Notify on down state or certificate expiry",
|
||||
"notificationTriggerCertificate": "Notify on certificate expiry only",
|
||||
"notificationTriggerCertificateWarning": "Certificate expiry notifications are disabled for this monitor. You will not receive alerts when the certificate is about to expire.",
|
||||
"enableDefaultTriggerNotificationDescription": "This notification trigger will be the default for new monitors. You can still edit the notification trigger separately for each monitor."
|
||||
}
|
||||
|
@ -733,17 +733,49 @@
|
||||
{{ $t("Not available, please setup.") }}
|
||||
</p>
|
||||
|
||||
<div v-for="notification in $root.notificationList" :key="notification.id" class="form-check form-switch my-3">
|
||||
<input :id=" 'notification' + notification.id" v-model="monitor.notificationIDList[notification.id]" class="form-check-input" type="checkbox">
|
||||
<div v-if="Object.keys(monitor.notificationIDList).length > 0">
|
||||
<div v-for="notification in $root.notificationList" :key="notification.id" class="form-check form-switch my-3">
|
||||
<input :id=" 'notification' + notification.id" v-model="monitor.notificationIDList[notification.id].active" class="form-check-input" type="checkbox">
|
||||
|
||||
<label class="form-check-label" :for=" 'notification' + notification.id">
|
||||
{{ notification.name }}
|
||||
<a href="#" @click="$refs.notificationDialog.show(notification.id)">{{ $t("Edit") }}</a>
|
||||
</label>
|
||||
<label class="form-check-label" :for=" 'notification' + notification.id">
|
||||
{{ notification.name }}
|
||||
<a href="#" @click="$refs.notificationDialog.show(notification.id)">{{ $t("Edit") }}</a>
|
||||
</label>
|
||||
|
||||
<span v-if="notification.isDefault == true" class="badge bg-primary ms-2">{{ $t("Default") }}</span>
|
||||
<span v-if="notification.isDefault == true" class="badge bg-primary ms-2">{{ $t("Default") }}</span>
|
||||
<div v-if="monitor.notificationIDList[notification.id].active">
|
||||
<select id="notificationTrigger" v-model="monitor.notificationIDList[notification.id].trigger" class="form-select">
|
||||
<option value="always">
|
||||
{{ $t("notificationTriggerAlways") }}
|
||||
</option>
|
||||
<option value="up_down">
|
||||
{{ $t("notificationTriggerUpDown") }}
|
||||
</option>
|
||||
<option value="up">
|
||||
{{ $t("notificationTriggerUp") }}
|
||||
</option>
|
||||
<option value="down">
|
||||
{{ $t("notificationTriggerDown") }}
|
||||
</option>
|
||||
<option value="certificate">
|
||||
{{ $t("notificationTriggerCertificate") }}
|
||||
</option>
|
||||
<option value="up_certificate">
|
||||
{{ $t("notificationTriggerUpCertificate") }}
|
||||
</option>
|
||||
<option value="down_certificate">
|
||||
{{ $t("notificationTriggerDownCertificate") }}
|
||||
</option>
|
||||
</select>
|
||||
<div
|
||||
v-if="(monitor.notificationIDList[notification.id].trigger === 'certificate' || monitor.notificationIDList[notification.id].trigger === 'up_certificate' || monitor.notificationIDList[notification.id].trigger === 'down_certificate') && (!(monitor.type === 'http' || monitor.type === 'keyword' || monitor.type === 'json-query') || !monitor.expiryNotification)"
|
||||
class="alert alert-warning my-2" role="alert"
|
||||
>
|
||||
{{ $t("notificationTriggerCertificateWarning") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary me-2" type="button" @click="$refs.notificationDialog.show()">
|
||||
{{ $t("Setup Notification") }}
|
||||
</button>
|
||||
@ -1576,9 +1608,11 @@ message HealthCheckResponse {
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.$root.notificationList.length; i++) {
|
||||
if (this.$root.notificationList[i].isDefault === true) {
|
||||
this.monitor.notificationIDList[this.$root.notificationList[i].id] = true;
|
||||
}
|
||||
let notification = this.$root.notificationList[i];
|
||||
this.monitor.notificationIDList[notification.id] = {
|
||||
active: notification.isDefault === true,
|
||||
trigger: notification.defaultTrigger,
|
||||
};
|
||||
}
|
||||
} else if (this.isEdit || this.isClone) {
|
||||
this.$root.getSocket().emit("getMonitor", this.$route.params.id, (res) => {
|
||||
@ -1593,6 +1627,16 @@ message HealthCheckResponse {
|
||||
|
||||
this.monitor = res.monitor;
|
||||
|
||||
for (let i = 0; i < this.$root.notificationList.length; i++) {
|
||||
let notification = this.$root.notificationList[i];
|
||||
if (!this.monitor.notificationIDList[notification.id]) {
|
||||
this.monitor.notificationIDList[notification.id] = {
|
||||
active: notification.isDefault === true,
|
||||
trigger: notification.defaultTrigger,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isClone) {
|
||||
/*
|
||||
* Cloning a monitor will include properties that can not be posted to backend
|
||||
@ -1794,10 +1838,14 @@ message HealthCheckResponse {
|
||||
* Added a Notification Event
|
||||
* Enable it if the notification is added in EditMonitor.vue
|
||||
* @param {number} id ID of notification to add
|
||||
* @param {string} defaultTrigger default notification trigger (both, up, down, certificate, up_certificate, down_certificate)
|
||||
* @returns {void}
|
||||
*/
|
||||
addedNotification(id) {
|
||||
this.monitor.notificationIDList[id] = true;
|
||||
addedNotification(id, defaultTrigger) {
|
||||
this.monitor.notificationIDList[id] = {
|
||||
active: true,
|
||||
trigger: defaultTrigger,
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user