From b22969a3e6c6fdf226325eca08347f369c0c4512 Mon Sep 17 00:00:00 2001
From: youpie <37704067+youpie@users.noreply.github.com>
Date: Thu, 1 May 2025 19:36:34 +0200
Subject: [PATCH 1/2] Allow HTML for custom email bodies (#5635)
---
server/notification-providers/smtp.js | 6 ++++--
src/components/notifications/SMTP.vue | 9 +++++++++
src/lang/en.json | 1 +
3 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/server/notification-providers/smtp.js b/server/notification-providers/smtp.js
index 980c7dfd3..d0ad5b728 100644
--- a/server/notification-providers/smtp.js
+++ b/server/notification-providers/smtp.js
@@ -42,6 +42,7 @@ class SMTP extends NotificationProvider {
// default values in case the user does not want to template
let subject = msg;
let body = msg;
+ let useHTMLBody = false;
if (heartbeatJSON) {
body = `${msg}\nTime (${heartbeatJSON["timezone"]}): ${heartbeatJSON["localDateTime"]}`;
}
@@ -50,11 +51,11 @@ class SMTP extends NotificationProvider {
// cannot end with whitespace as this often raises spam scores
const customSubject = notification.customSubject?.trim() || "";
const customBody = notification.customBody?.trim() || "";
-
if (customSubject !== "") {
subject = await this.renderTemplate(customSubject, msg, monitorJSON, heartbeatJSON);
}
if (customBody !== "") {
+ useHTMLBody = notification.htmlBody || false;
body = await this.renderTemplate(customBody, msg, monitorJSON, heartbeatJSON);
}
}
@@ -67,7 +68,8 @@ class SMTP extends NotificationProvider {
bcc: notification.smtpBCC,
to: notification.smtpTo,
subject: subject,
- text: body,
+ // If the email body is custom, and the user wants it, set the email body as HTML
+ [useHTMLBody ? "html" : "text"]: body
});
return okMsg;
diff --git a/src/components/notifications/SMTP.vue b/src/components/notifications/SMTP.vue
index 4e0fb4b57..8f0e1501d 100644
--- a/src/components/notifications/SMTP.vue
+++ b/src/components/notifications/SMTP.vue
@@ -79,6 +79,15 @@
{{ $t("leave blank for default body") }}
+
+
+
+
+
+
+
{{ $t("documentation") }}
diff --git a/src/lang/en.json b/src/lang/en.json
index b089478f8..63c28b56c 100644
--- a/src/lang/en.json
+++ b/src/lang/en.json
@@ -517,6 +517,7 @@
"Clone": "Clone",
"cloneOf": "Clone of {0}",
"smtp": "Email (SMTP)",
+ "Use HTML for custom E-mail body": "Use HTML for custom E-mail body",
"secureOptionNone": "None / STARTTLS (25, 587)",
"secureOptionTLS": "TLS (465)",
"Ignore TLS Error": "Ignore TLS Error",
From 6a5011ad34ee7c1507cada9b9fced59a4b7245b6 Mon Sep 17 00:00:00 2001
From: vapao
Date: Fri, 2 May 2025 14:58:16 +0800
Subject: [PATCH 2/2] Add SpugPush notification provider (#5813)
Co-authored-by: Frank Elsinga
---
server/notification-providers/spugpush.js | 37 +++++++++++++++++++++++
server/notification.js | 2 ++
src/components/NotificationDialog.vue | 1 +
src/components/notifications/SpugPush.vue | 19 ++++++++++++
src/components/notifications/index.js | 2 ++
src/lang/en.json | 1 +
6 files changed, 62 insertions(+)
create mode 100644 server/notification-providers/spugpush.js
create mode 100644 src/components/notifications/SpugPush.vue
diff --git a/server/notification-providers/spugpush.js b/server/notification-providers/spugpush.js
new file mode 100644
index 000000000..e84174f38
--- /dev/null
+++ b/server/notification-providers/spugpush.js
@@ -0,0 +1,37 @@
+const NotificationProvider = require("./notification-provider");
+const axios = require("axios");
+const { DOWN, UP } = require("../../src/util");
+
+class SpugPush extends NotificationProvider {
+
+ name = "SpugPush";
+
+ /**
+ * @inheritdoc
+ */
+ async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
+ let okMsg = "Sent Successfully.";
+ try {
+ let formData = {
+ msg
+ };
+ const apiUrl = `https://push.spug.cc/send/${notification.templateKey}`;
+ if (heartbeatJSON == null) {
+ formData.title = "Uptime Kuma Message";
+ } else if (heartbeatJSON["status"] === UP) {
+ formData.title = `UptimeKuma 「${monitorJSON["name"]}」 is Up`;
+ formData.msg = `[✅ Up] ${heartbeatJSON["msg"]}`;
+ } else if (heartbeatJSON["status"] === DOWN) {
+ formData.title = `UptimeKuma 「${monitorJSON["name"]}」 is Down`;
+ formData.msg = `[🔴 Down] ${heartbeatJSON["msg"]}`;
+ }
+
+ await axios.post(apiUrl, formData);
+ return okMsg;
+ } catch (error) {
+ this.throwGeneralAxiosError(error);
+ }
+ }
+}
+
+module.exports = SpugPush;
diff --git a/server/notification.js b/server/notification.js
index b3f745854..468d026c0 100644
--- a/server/notification.js
+++ b/server/notification.js
@@ -75,6 +75,7 @@ const Wpush = require("./notification-providers/wpush");
const SendGrid = require("./notification-providers/send-grid");
const YZJ = require("./notification-providers/yzj");
const SMSPlanet = require("./notification-providers/sms-planet");
+const SpugPush = require("./notification-providers/spugpush");
class Notification {
@@ -167,6 +168,7 @@ class Notification {
new SendGrid(),
new YZJ(),
new SMSPlanet(),
+ new SpugPush(),
];
for (let item of list) {
if (! item.name) {
diff --git a/src/components/NotificationDialog.vue b/src/components/NotificationDialog.vue
index 1b15616aa..2e66de8e9 100644
--- a/src/components/NotificationDialog.vue
+++ b/src/components/NotificationDialog.vue
@@ -185,6 +185,7 @@ export default {
"WeCom": "WeCom (企业微信群机器人)",
"ServerChan": "ServerChan (Server酱)",
"PushPlus": "PushPlus (推送加)",
+ "SpugPush": "SpugPush(Spug推送助手)",
"smsc": "SMSC",
"WPush": "WPush(wpush.cn)",
"YZJ": "YZJ (云之家自定义机器人)",
diff --git a/src/components/notifications/SpugPush.vue b/src/components/notifications/SpugPush.vue
new file mode 100644
index 000000000..37dffccf3
--- /dev/null
+++ b/src/components/notifications/SpugPush.vue
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ https://push.spug.cc
+
+
+
+
diff --git a/src/components/notifications/index.js b/src/components/notifications/index.js
index 70e7d336d..be7feb820 100644
--- a/src/components/notifications/index.js
+++ b/src/components/notifications/index.js
@@ -64,6 +64,7 @@ import WeCom from "./WeCom.vue";
import GoAlert from "./GoAlert.vue";
import ZohoCliq from "./ZohoCliq.vue";
import Splunk from "./Splunk.vue";
+import SpugPush from "./SpugPush.vue";
import SevenIO from "./SevenIO.vue";
import Whapi from "./Whapi.vue";
import WAHA from "./WAHA.vue";
@@ -140,6 +141,7 @@ const NotificationFormList = {
"threema": Threema,
"twilio": Twilio,
"Splunk": Splunk,
+ "SpugPush": SpugPush,
"webhook": Webhook,
"WeCom": WeCom,
"GoAlert": GoAlert,
diff --git a/src/lang/en.json b/src/lang/en.json
index 63c28b56c..37c023ee4 100644
--- a/src/lang/en.json
+++ b/src/lang/en.json
@@ -799,6 +799,7 @@
"PushDeer Server": "PushDeer Server",
"pushDeerServerDescription": "Leave blank to use the official server",
"PushDeer Key": "PushDeer Key",
+ "SpugPush Template Code": "Template Code",
"wayToGetClickSendSMSToken": "You can get API Username and API Key from {0} .",
"Custom Monitor Type": "Custom Monitor Type",
"Google Analytics ID": "Google Analytics ID",