From bc90af1833bf2e09910b019fa0d925ddb5cc1456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Helfensd=C3=B6rfer?= Date: Sun, 15 Feb 2026 14:58:56 +0100 Subject: [PATCH] feat: add tags to teams notifications (#6939) Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Frank Elsinga --- server/model/rdap-dns.json | 3 +- server/notification-providers/teams.js | 155 ++++++++++++++++--------- src/components/notifications/Teams.vue | 11 ++ src/lang/en.json | 2 + 4 files changed, 111 insertions(+), 60 deletions(-) diff --git a/server/model/rdap-dns.json b/server/model/rdap-dns.json index 2587546b..8c6842fc 100644 --- a/server/model/rdap-dns.json +++ b/server/model/rdap-dns.json @@ -1,6 +1,6 @@ { "description": "RDAP bootstrap file for Domain Name System registrations", - "publication": "2026-02-12T00:00:02Z", + "publication": "2026-02-13T23:00:01Z", "services": [ [["kg"], ["http://rdap.cctld.kg/"]], [["mg"], ["http://rdap.nic.mg/"]], @@ -652,7 +652,6 @@ "weibo", "weir", "wine", - "wolterskluwer", "works", "world", "wtf", diff --git a/server/notification-providers/teams.js b/server/notification-providers/teams.js index 2f493b17..5fd93afe 100644 --- a/server/notification-providers/teams.js +++ b/server/notification-providers/teams.js @@ -37,16 +37,31 @@ class Teams extends NotificationProvider { return "emphasis"; }; + /** + * Format the tag for display. If the tag has a value, display as "name: value", otherwise just "name". + * @param {object} tag The tag object to format + * @returns {string} Formatted tag for display + */ + _tagDisplayText = (tag) => { + if (tag.value === "" || tag.value === undefined || tag.value === null) { + return tag.name; + } else { + return `${tag.name}: ${tag.value}`; + } + }; + /** * Generate payload for notification * @param {object} args Method arguments * @param {object} args.heartbeatJSON Heartbeat details - * @param {string} args.monitorName Name of the monitor affected - * @param {string} args.monitorUrl URL of the monitor affected + * @param {object} args.monitorJSON Monitor details * @param {string} args.dashboardUrl URL of the dashboard affected + * @param {boolean} args.enableTags Whether to include tags in the notification * @returns {object} Notification payload */ - _notificationPayloadFactory = ({ heartbeatJSON, monitorName, monitorUrl, dashboardUrl }) => { + _notificationPayloadFactory = ({ heartbeatJSON, monitorJSON, dashboardUrl, enableTags }) => { + const monitorUrl = this.extractAddress(monitorJSON); + const monitorName = monitorJSON?.name; const status = heartbeatJSON?.status; const facts = []; const actions = []; @@ -93,6 +108,82 @@ class Teams extends NotificationProvider { }); } + const payloadBody = [ + { + type: "Container", + verticalContentAlignment: "Center", + items: [ + { + type: "ColumnSet", + style: this._getStyle(status), + columns: [ + { + type: "Column", + width: "auto", + verticalContentAlignment: "Center", + items: [ + { + type: "Image", + width: "32px", + style: "Person", + url: "https://raw.githubusercontent.com/louislam/uptime-kuma/master/public/icon.png", + altText: "Uptime Kuma Logo", + }, + ], + }, + { + type: "Column", + width: "stretch", + items: [ + { + type: "TextBlock", + size: "Medium", + weight: "Bolder", + text: `**${this._statusMessageFactory(status, monitorName, false)}**`, + }, + { + type: "TextBlock", + size: "Small", + weight: "Default", + text: "Uptime Kuma Alert", + isSubtle: true, + spacing: "None", + }, + ], + }, + ], + }, + ], + }, + { + type: "FactSet", + separator: false, + facts: facts, + }, + ]; + + if (enableTags && monitorJSON?.tags?.length > 0) { + payloadBody.push({ + type: "Container", + layouts: [ + { + type: "Layout.Flow", + columnSpacing: "Small", + rowSpacing: "Small", + horizontalItemsAlignment: "Left", + }, + ], + items: monitorJSON.tags.map((tag) => { + return { + type: "Badge", + text: this._tagDisplayText(tag), + size: "Medium", + style: "Accent", + }; + }), + }); + } + const payload = { type: "message", // message with status prefix as notification text @@ -103,59 +194,7 @@ class Teams extends NotificationProvider { contentUrl: "", content: { type: "AdaptiveCard", - body: [ - { - type: "Container", - verticalContentAlignment: "Center", - items: [ - { - type: "ColumnSet", - style: this._getStyle(status), - columns: [ - { - type: "Column", - width: "auto", - verticalContentAlignment: "Center", - items: [ - { - type: "Image", - width: "32px", - style: "Person", - url: "https://raw.githubusercontent.com/louislam/uptime-kuma/master/public/icon.png", - altText: "Uptime Kuma Logo", - }, - ], - }, - { - type: "Column", - width: "stretch", - items: [ - { - type: "TextBlock", - size: "Medium", - weight: "Bolder", - text: `**${this._statusMessageFactory(status, monitorName, false)}**`, - }, - { - type: "TextBlock", - size: "Small", - weight: "Default", - text: "Uptime Kuma Alert", - isSubtle: true, - spacing: "None", - }, - ], - }, - ], - }, - ], - }, - { - type: "FactSet", - separator: false, - facts: facts, - }, - ], + body: payloadBody, $schema: "http://adaptivecards.io/schemas/adaptive-card.json", version: "1.5", }, @@ -220,9 +259,9 @@ class Teams extends NotificationProvider { const payload = this._notificationPayloadFactory({ heartbeatJSON: heartbeatJSON, - monitorName: monitorJSON.name, - monitorUrl: this.extractAddress(monitorJSON), + monitorJSON: monitorJSON, dashboardUrl: dashboardUrl, + enableTags: notification.teamsEnableTags ?? false, }); await this._sendNotification(notification.webhookUrl, payload); diff --git a/src/components/notifications/Teams.vue b/src/components/notifications/Teams.vue index a46e8b71..4820d83e 100644 --- a/src/components/notifications/Teams.vue +++ b/src/components/notifications/Teams.vue @@ -17,4 +17,15 @@ + +
+
+ + +
+ +
+ {{ $t("teamsEnableTagsDescription") }} +
+
diff --git a/src/lang/en.json b/src/lang/en.json index eee97046..af06934d 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -640,6 +640,8 @@ "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}.", + "teamsEnableTags": "Include tags", + "teamsEnableTagsDescription": "If enabled, the message will include the monitor tags.", "wayToGetZohoCliqURL": "You can learn how to create a webhook URL {0}.", "needSignalAPI": "You need to have a signal client with REST API.", "wayToCheckSignalURL": "You can check this URL to view how to set one up:",