From 4e24e96dabc342b614cf8515fd205f394499be6c Mon Sep 17 00:00:00 2001 From: TheDanniCraft Date: Sun, 19 May 2024 21:14:13 +0200 Subject: [PATCH 1/9] [discord] thread/forum channel support (#4099) --- server/notification-providers/discord.js | 23 +++++++++--- src/components/notifications/Discord.vue | 46 ++++++++++++++++++++++++ src/lang/en.json | 9 +++++ 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/server/notification-providers/discord.js b/server/notification-providers/discord.js index f24d47252..129e334b0 100644 --- a/server/notification-providers/discord.js +++ b/server/notification-providers/discord.js @@ -13,6 +13,10 @@ class Discord extends NotificationProvider { try { const discordDisplayName = notification.discordUsername || "Uptime Kuma"; + const webhookUrl = new URL(notification.discordWebhookUrl); + if (notification.discordChannelType === "postToThread") { + webhookUrl.searchParams.append("thread_id", notification.threadId); + } // If heartbeatJSON is null, assume we're testing. if (heartbeatJSON == null) { @@ -20,7 +24,12 @@ class Discord extends NotificationProvider { username: discordDisplayName, content: msg, }; - await axios.post(notification.discordWebhookUrl, discordtestdata); + + if (notification.discordChannelType === "createNewForumPost") { + discordtestdata.thread_name = notification.postName; + } + + await axios.post(webhookUrl.toString(), discordtestdata); return okMsg; } @@ -72,12 +81,14 @@ class Discord extends NotificationProvider { ], }], }; - + if (notification.discordChannelType === "createNewForumPost") { + discorddowndata.thread_name = notification.postName; + } if (notification.discordPrefixMessage) { discorddowndata.content = notification.discordPrefixMessage; } - await axios.post(notification.discordWebhookUrl, discorddowndata); + await axios.post(webhookUrl.toString(), discorddowndata); return okMsg; } else if (heartbeatJSON["status"] === UP) { @@ -108,11 +119,15 @@ class Discord extends NotificationProvider { }], }; + if (notification.discordChannelType === "createNewForumPost") { + discordupdata.thread_name = notification.postName; + } + if (notification.discordPrefixMessage) { discordupdata.content = notification.discordPrefixMessage; } - await axios.post(notification.discordWebhookUrl, discordupdata); + await axios.post(webhookUrl.toString(), discordupdata); return okMsg; } } catch (error) { diff --git a/src/components/notifications/Discord.vue b/src/components/notifications/Discord.vue index 99389d29e..5d8334f5f 100644 --- a/src/components/notifications/Discord.vue +++ b/src/components/notifications/Discord.vue @@ -16,4 +16,50 @@ + +
+ + +
+ +
+
+ + +
+ {{ $t("whatHappensAtForumPost", { option: $t("postToExistingThread") }) }} +
+
+
+
+
+ + + +
+
+ diff --git a/src/lang/en.json b/src/lang/en.json index d4a0997c2..2c6e7887a 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -527,6 +527,15 @@ "Bot Display Name": "Bot Display Name", "Prefix Custom Message": "Prefix Custom Message", "Hello @everyone is...": "Hello {'@'}everyone is…", + "Select message type": "Select message type", + "Send to channel": "Send to channel", + "Create new forum post": "Create new forum post", + "postToExistingThread": "Post to existing thread / forum post", + "forumPostName": "Forum post name", + "threadForumPostID": "Thread / Forum post ID", + "e.g. {discordThreadID}": "e.g. {discordThreadID}", + "whatHappensAtForumPost": "Create a new forum post. This does NOT post messages in existing post. To post in existing post use \"{option}\"", + "wayToGetDiscordThreadId": "Getting a thread / forum post id is similar to getting a channel id. Read more about how to get ids {0}", "wayToGetTeamsURL": "You can learn how to create a webhook URL {0}.", "wayToGetZohoCliqURL": "You can learn how to create a webhook URL {0}.", "needSignalAPI": "You need to have a signal client with REST API.", From e856cb6007dd1cd6e8e33bf8813fde232a7237cb Mon Sep 17 00:00:00 2001 From: Laurent Aupse Date: Sun, 19 May 2024 21:56:55 +0200 Subject: [PATCH 2/9] Make auto refresh interval customizable (#4260) Co-authored-by: Frank Elsinga --- .../2023-12-20-0000-alter-status-page.js | 12 ++++++++++ server/model/status_page.js | 2 ++ .../status-page-socket-handler.js | 2 ++ src/lang/en.json | 2 ++ src/pages/StatusPage.vue | 24 ++++++++++++------- 5 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 db/knex_migrations/2023-12-20-0000-alter-status-page.js diff --git a/db/knex_migrations/2023-12-20-0000-alter-status-page.js b/db/knex_migrations/2023-12-20-0000-alter-status-page.js new file mode 100644 index 000000000..61ef5d607 --- /dev/null +++ b/db/knex_migrations/2023-12-20-0000-alter-status-page.js @@ -0,0 +1,12 @@ +exports.up = function (knex) { + return knex.schema + .alterTable("status_page", function (table) { + table.integer("auto_refresh_interval").defaultTo(300).unsigned(); + }); +}; + +exports.down = function (knex) { + return knex.schema.alterTable("status_page", function (table) { + table.dropColumn("auto_refresh_interval"); + }); +}; diff --git a/server/model/status_page.js b/server/model/status_page.js index 235582981..528d1dd49 100644 --- a/server/model/status_page.js +++ b/server/model/status_page.js @@ -238,6 +238,7 @@ class StatusPage extends BeanModel { description: this.description, icon: this.getIcon(), theme: this.theme, + autoRefreshInterval: this.autoRefreshInterval, published: !!this.published, showTags: !!this.show_tags, domainNameList: this.getDomainNameList(), @@ -260,6 +261,7 @@ class StatusPage extends BeanModel { title: this.title, description: this.description, icon: this.getIcon(), + autoRefreshInterval: this.autoRefreshInterval, theme: this.theme, published: !!this.published, showTags: !!this.show_tags, diff --git a/server/socket-handlers/status-page-socket-handler.js b/server/socket-handlers/status-page-socket-handler.js index 53128914c..0804da15d 100644 --- a/server/socket-handlers/status-page-socket-handler.js +++ b/server/socket-handlers/status-page-socket-handler.js @@ -155,6 +155,7 @@ module.exports.statusPageSocketHandler = (socket) => { statusPage.title = config.title; statusPage.description = config.description; statusPage.icon = config.logo; + statusPage.autoRefreshInterval = config.autoRefreshInterval, statusPage.theme = config.theme; //statusPage.published = ; //statusPage.search_engine_index = ; @@ -280,6 +281,7 @@ module.exports.statusPageSocketHandler = (socket) => { statusPage.title = title; statusPage.theme = "auto"; statusPage.icon = ""; + statusPage.autoRefreshInterval = 300; await R.store(statusPage); callback({ diff --git a/src/lang/en.json b/src/lang/en.json index 2c6e7887a..2a3e6628c 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -361,6 +361,8 @@ "Proxy": "Proxy", "Date Created": "Date Created", "Footer Text": "Footer Text", + "Refresh Interval": "Refresh Interval", + "Refresh Interval Description": "The status page will do a full site refresh every {0} seconds", "Show Powered By": "Show Powered By", "Domain Names": "Domain Names", "signedInDisp": "Signed in as {0}", diff --git a/src/pages/StatusPage.vue b/src/pages/StatusPage.vue index af2f028d7..1f67c22e2 100644 --- a/src/pages/StatusPage.vue +++ b/src/pages/StatusPage.vue @@ -34,6 +34,14 @@ +
+ + +
+ {{ $t("Refresh Interval Description", [config.autoRefreshInterval]) }} +
+
+