diff --git a/server/notification-providers/teams.js b/server/notification-providers/teams.js
new file mode 100644
index 000000000..72409ffc8
--- /dev/null
+++ b/server/notification-providers/teams.js
@@ -0,0 +1,124 @@
+const NotificationProvider = require("./notification-provider");
+const axios = require("axios");
+const { DOWN, UP } = require("../../src/util");
+
+class Teams extends NotificationProvider {
+ name = "teams";
+
+ _statusMessageFactory = (status, monitorName) => {
+ if (status === DOWN) {
+ return `🔴 Application [${monitorName}] went down`;
+ } else if (status === UP) {
+ return `✅ Application [${monitorName}] is back online`;
+ }
+ return "Notification";
+ };
+
+ _getThemeColor = (status) => {
+ if (status === DOWN) {
+ return "ff0000";
+ }
+ if (status === UP) {
+ return "00e804";
+ }
+ return "008cff";
+ };
+
+ _notificationPayloadFactory = ({
+ status,
+ monitorMessage,
+ monitorName,
+ monitorUrl,
+ }) => {
+ const notificationMessage = this._statusMessageFactory(
+ status,
+ monitorName
+ );
+
+ const facts = [];
+
+ if (monitorName) {
+ facts.push({
+ name: "Monitor",
+ value: monitorName,
+ });
+ }
+
+ if (monitorUrl) {
+ facts.push({
+ name: "URL",
+ value: monitorUrl,
+ });
+ }
+
+ return {
+ "@context": "https://schema.org/extensions",
+ "@type": "MessageCard",
+ themeColor: this._getThemeColor(status),
+ summary: notificationMessage,
+ sections: [
+ {
+ activityImage:
+ "https://raw.githubusercontent.com/louislam/uptime-kuma/master/public/icon.png",
+ activityTitle: "**Uptime Kuma**",
+ },
+ {
+ activityTitle: notificationMessage,
+ },
+ {
+ activityTitle: "**Description**",
+ text: monitorMessage,
+ facts,
+ },
+ ],
+ };
+ };
+
+ _sendNotification = async (webhookUrl, payload) => {
+ await axios.post(webhookUrl, payload);
+ };
+
+ _handleGeneralNotification = (webhookUrl, msg) => {
+ const payload = this._notificationPayloadFactory({
+ monitorMessage: msg
+ });
+
+ return this._sendNotification(webhookUrl, payload);
+ };
+
+ async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
+ let okMsg = "Sent Successfully. ";
+
+ try {
+ if (heartbeatJSON == null) {
+ await this._handleGeneralNotification(notification.webhookUrl, msg);
+ return okMsg;
+ }
+
+ let url;
+
+ if (monitorJSON["type"] === "port") {
+ url = monitorJSON["hostname"];
+ if (monitorJSON["port"]) {
+ url += ":" + monitorJSON["port"];
+ }
+ } else {
+ url = monitorJSON["url"];
+ }
+
+ const payload = this._notificationPayloadFactory({
+ monitorMessage: heartbeatJSON.msg,
+ monitorName: monitorJSON.name,
+ monitorUrl: url,
+ status: heartbeatJSON.status,
+ });
+
+ await this._sendNotification(notification.webhookUrl, payload);
+ return okMsg;
+ } catch (error) {
+ this.throwGeneralAxiosError(error);
+ }
+ }
+}
+
+module.exports = Teams;
diff --git a/server/notification.js b/server/notification.js
index 83dabc537..134472410 100644
--- a/server/notification.js
+++ b/server/notification.js
@@ -13,6 +13,7 @@ const RocketChat = require("./notification-providers/rocket-chat");
const Signal = require("./notification-providers/signal");
const Slack = require("./notification-providers/slack");
const SMTP = require("./notification-providers/smtp");
+const Teams = require("./notification-providers/teams");
const Telegram = require("./notification-providers/telegram");
const Webhook = require("./notification-providers/webhook");
@@ -28,6 +29,7 @@ class Notification {
const list = [
new Apprise(),
new Discord(),
+ new Teams(),
new Gotify(),
new Line(),
new LunaSea(),
diff --git a/src/components/NotificationDialog.vue b/src/components/NotificationDialog.vue
index 0db46a782..220ff8d71 100644
--- a/src/components/NotificationDialog.vue
+++ b/src/components/NotificationDialog.vue
@@ -17,6 +17,7 @@
+
@@ -400,6 +401,8 @@
+