@@ -4,6 +4,47 @@ const axios = require("axios");
44class Telegram extends NotificationProvider {
55 name = "telegram" ;
66
7+ /**
8+ * Escapes special characters for Telegram MarkdownV2 format
9+ * @param {string } text Text to escape
10+ * @returns {string } Escaped text
11+ */
12+ escapeMarkdownV2 ( text ) {
13+ if ( ! text ) {
14+ return text ;
15+ }
16+
17+ // Characters that need to be escaped in MarkdownV2
18+ // https://core.telegram.org/bots/api#markdownv2-style
19+ return String ( text ) . replace ( / [ _ * [ \] ( ) ~ > # + \- = | { } . ! \\ ] / g, "\\$&" ) ;
20+ }
21+
22+ /**
23+ * Recursively escapes string properties of an object for Telegram MarkdownV2
24+ * @param {object|string } obj Object or string to escape
25+ * @returns {object|string } Escaped object or string
26+ */
27+ escapeObjectRecursive ( obj ) {
28+ if ( typeof obj === "string" ) {
29+ return this . escapeMarkdownV2 ( obj ) ;
30+ }
31+ if ( typeof obj === "object" && obj !== null ) {
32+ // Check if array
33+ if ( Array . isArray ( obj ) ) {
34+ return obj . map ( item => this . escapeObjectRecursive ( item ) ) ;
35+ }
36+
37+ const newObj = { } ;
38+ for ( const key in obj ) {
39+ if ( Object . prototype . hasOwnProperty . call ( obj , key ) ) {
40+ newObj [ key ] = this . escapeObjectRecursive ( obj [ key ] ) ;
41+ }
42+ }
43+ return newObj ;
44+ }
45+ return obj ;
46+ }
47+
748 /**
849 * @inheritdoc
950 */
@@ -24,7 +65,29 @@ class Telegram extends NotificationProvider {
2465 }
2566
2667 if ( notification . telegramUseTemplate ) {
27- params . text = await this . renderTemplate ( notification . telegramTemplate , msg , monitorJSON , heartbeatJSON ) ;
68+ let monitorJSONCopy = monitorJSON ;
69+ let heartbeatJSONCopy = heartbeatJSON ;
70+
71+ if ( notification . telegramTemplateParseMode === "MarkdownV2" ) {
72+ msg = this . escapeMarkdownV2 ( msg ) ;
73+
74+ if ( monitorJSONCopy ) {
75+ monitorJSONCopy = this . escapeObjectRecursive ( monitorJSONCopy ) ;
76+ } else {
77+ // for testing monitorJSON is null, provide escaped defaults
78+ monitorJSONCopy = {
79+ name : this . escapeMarkdownV2 ( "Monitor Name not available" ) ,
80+ hostname : this . escapeMarkdownV2 ( "testing.hostname" ) ,
81+ url : this . escapeMarkdownV2 ( "testing.hostname" ) ,
82+ } ;
83+ }
84+
85+ if ( heartbeatJSONCopy ) {
86+ heartbeatJSONCopy = this . escapeObjectRecursive ( heartbeatJSONCopy ) ;
87+ }
88+ }
89+
90+ params . text = await this . renderTemplate ( notification . telegramTemplate , msg , monitorJSONCopy , heartbeatJSONCopy ) ;
2891
2992 if ( notification . telegramTemplateParseMode !== "plain" ) {
3093 params . parse_mode = notification . telegramTemplateParseMode ;
0 commit comments