Files
uptime-kuma/server/notification-providers/telegram.js
Frank Elsinga 0f61d7ee1b chore: enable formatting over the entire codebase in CI (#6655)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-01-09 02:10:36 +01:00

113 lines
3.9 KiB
JavaScript

const NotificationProvider = require("./notification-provider");
const axios = require("axios");
class Telegram extends NotificationProvider {
name = "telegram";
/**
* Escapes special characters for Telegram MarkdownV2 format
* @param {string} text Text to escape
* @returns {string} Escaped text
*/
escapeMarkdownV2(text) {
if (!text) {
return text;
}
// Characters that need to be escaped in MarkdownV2
// https://core.telegram.org/bots/api#markdownv2-style
return String(text).replace(/[_*[\]()~>#+\-=|{}.!\\]/g, "\\$&");
}
/**
* Recursively escapes string properties of an object for Telegram MarkdownV2
* @param {object|string} obj Object or string to escape
* @returns {object|string} Escaped object or string
*/
escapeObjectRecursive(obj) {
if (typeof obj === "string") {
return this.escapeMarkdownV2(obj);
}
if (typeof obj === "object" && obj !== null) {
// Check if array
if (Array.isArray(obj)) {
return obj.map((item) => this.escapeObjectRecursive(item));
}
const newObj = {};
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
newObj[key] = this.escapeObjectRecursive(obj[key]);
}
}
return newObj;
}
return obj;
}
/**
* @inheritdoc
*/
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
const okMsg = "Sent Successfully.";
const url = notification.telegramServerUrl ?? "https://api.telegram.org";
try {
let params = {
chat_id: notification.telegramChatID,
text: msg,
disable_notification: notification.telegramSendSilently ?? false,
protect_content: notification.telegramProtectContent ?? false,
link_preview_options: { is_disabled: true },
};
if (notification.telegramMessageThreadID) {
params.message_thread_id = notification.telegramMessageThreadID;
}
if (notification.telegramUseTemplate) {
let monitorJSONCopy = monitorJSON;
let heartbeatJSONCopy = heartbeatJSON;
if (notification.telegramTemplateParseMode === "MarkdownV2") {
msg = this.escapeMarkdownV2(msg);
if (monitorJSONCopy) {
monitorJSONCopy = this.escapeObjectRecursive(monitorJSONCopy);
} else {
// for testing monitorJSON is null, provide escaped defaults
monitorJSONCopy = {
name: this.escapeMarkdownV2("Monitor Name not available"),
hostname: this.escapeMarkdownV2("testing.hostname"),
url: this.escapeMarkdownV2("testing.hostname"),
};
}
if (heartbeatJSONCopy) {
heartbeatJSONCopy = this.escapeObjectRecursive(heartbeatJSONCopy);
}
}
params.text = await this.renderTemplate(
notification.telegramTemplate,
msg,
monitorJSONCopy,
heartbeatJSONCopy
);
if (notification.telegramTemplateParseMode !== "plain") {
params.parse_mode = notification.telegramTemplateParseMode;
}
}
let config = this.getAxiosConfigWithProxy();
await axios.post(`${url}/bot${notification.telegramBotToken}/sendMessage`, params, config);
return okMsg;
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
}
module.exports = Telegram;