diff --git a/server/notification-providers/vkteams.js b/server/notification-providers/vkteams.js new file mode 100644 index 000000000..4db0fee18 --- /dev/null +++ b/server/notification-providers/vkteams.js @@ -0,0 +1,48 @@ +const NotificationProvider = require("./notification-provider"); +const axios = require("axios"); + +class VKTeams extends NotificationProvider { + name = "VKTeams"; + + /** + * @inheritdoc + */ + async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { + const okMsg = "Sent Successfully."; + const baseUrl = (notification.vkteamsBaseUrl || "https://myteam.mail.ru").replace(/\/$/, ""); + + try { + const rawParams = { + token: notification.vkteamsBotToken, + chatId: notification.vkteamsChatId, + text: msg, + }; + + if (notification.vkteamsUseTemplate && notification.vkteamsTemplate) { + rawParams.text = await this.renderTemplate( + notification.vkteamsTemplate, + msg, + monitorJSON, + heartbeatJSON + ); + + if (notification.vkteamsTemplateFormat && notification.vkteamsTemplateFormat !== "plain") { + rawParams.parseMode = notification.vkteamsTemplateFormat; + } + } + + const params = new URLSearchParams(rawParams).toString(); + const config = this.getAxiosConfigWithProxy({}); + const response = await axios.get(`${baseUrl}/bot/v1/messages/sendText?${params}`, config); + if (response.data?.ok === false) { + throw new Error(`VKTeams API returned error: ${response.data.description}`); + } + + return okMsg; + } catch (error) { + this.throwGeneralAxiosError(error); + } + } +} + +module.exports = VKTeams; diff --git a/server/notification.js b/server/notification.js index b1a42d003..c1b1f49b0 100644 --- a/server/notification.js +++ b/server/notification.js @@ -93,6 +93,7 @@ const Webpush = require("./notification-providers/Webpush"); const HaloPSA = require("./notification-providers/HaloPSA"); const Max = require("./notification-providers/max"); const VK = require("./notification-providers/vk"); +const VKTeams = require("./notification-providers/vkteams"); class Notification { providerList = {}; @@ -201,6 +202,7 @@ class Notification { new HaloPSA(), new Max(), new VK(), + new VKTeams(), ]; for (let item of list) { if (!item.name) { diff --git a/src/components/NotificationDialog.vue b/src/components/NotificationDialog.vue index 1db32b8da..1784e7b53 100644 --- a/src/components/NotificationDialog.vue +++ b/src/components/NotificationDialog.vue @@ -336,6 +336,7 @@ export default { YZJ: "YZJ (云之家自定义机器人)", SMSPlanet: "SMSPlanet.pl", VK: "VK", + VKTeams: "VKTeams", }; // Sort by notification name alphabetically diff --git a/src/components/notifications/VKTeams.vue b/src/components/notifications/VKTeams.vue new file mode 100644 index 000000000..1df6e5995 --- /dev/null +++ b/src/components/notifications/VKTeams.vue @@ -0,0 +1,95 @@ + + + diff --git a/src/components/notifications/index.js b/src/components/notifications/index.js index 07da96fde..9cc13ae39 100644 --- a/src/components/notifications/index.js +++ b/src/components/notifications/index.js @@ -90,6 +90,7 @@ import HaloPSA from "./HaloPSA.vue"; import Resend from "./Resend.vue"; import Max from "./Max.vue"; import VK from "./VK.vue"; +import VKTeams from "./VKTeams.vue"; /** * Manage all notification form. @@ -188,6 +189,7 @@ const NotificationFormList = { HaloPSA: HaloPSA, max: Max, VK: VK, + VKTeams: VKTeams, }; export default NotificationFormList; diff --git a/src/lang/en.json b/src/lang/en.json index 2cd29baaf..a1fb8347a 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -1532,5 +1532,11 @@ "teltonikaModem": "Modem Id", "teltonikaModemHelptext": "The id of the SMS modem, must be in the format {0}. Refer to https://developers.teltonika-networks.com/reference/ for guidance.", "teltonikaPhoneNumber": "Phone number", - "teltonikaPhoneNumberHelptext": "The number must be in the international format {0}, {1}. Only one number is allowed." + "teltonikaPhoneNumberHelptext": "The number must be in the international format {0}, {1}. Only one number is allowed.", + "VKTeams Bot Token Description": "You can find out how to get a bot token and other details at {0}.", + "VKTeams Base Url Description": "VKTeams base API URL, may differ in On-Premise solution. Default: https://myteam.mail.ru", + "VKTeams Chat Id Description": "For users, this is their email address. For groups and channels, get the ID from their settings and append {'@'}chat.agent", + "VKTeams Use Template": "Use custom message template", + "VKTeams Use Template Description": "If enabled, the message will be sent using a custom template.", + "VKTeams Template Format Description": "For message styling, VKTeams supports plain text, MarkdownV2, and HTML formatting." }