From 2371acc37173f43d20910c3a646c16845525b3c0 Mon Sep 17 00:00:00 2001 From: Ali Artukov <68611579+AliArtukov@users.noreply.github.com> Date: Tue, 2 Jun 2026 16:30:04 +0500 Subject: [PATCH 1/6] Add messageThreadId for Telegram notifications Add messageThreadId for sending alerts to specific topic of telegram group. --- .../boot/admin/server/notify/TelegramNotifier.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java b/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java index d5229868273..3e0bf53808a 100644 --- a/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java +++ b/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java @@ -47,6 +47,11 @@ public class TelegramNotifier extends AbstractContentNotifier { */ @Nullable private String chatId; + /** + * Unique identifier for the target chat or username of the target channel + */ + @Nullable private String messageThreadId; + /** * The token identifying und authorizing your Telegram bot (e.g. * `123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11`) @@ -83,6 +88,7 @@ protected String buildUrl() { private Map createMessage(InstanceEvent event, Instance instance) { Map parameters = new HashMap<>(); parameters.put("chat_id", this.chatId); + parameters.put("message_thread_id", this.messageThreadId); parameters.put("parse_mode", this.parseMode); parameters.put("disable_notification", this.disableNotify); parameters.put("text", createContent(event, instance)); @@ -114,6 +120,14 @@ public void setChatId(@Nullable String chatId) { this.chatId = chatId; } + @Nullable public String getMessageThreadId() { + return messageThreadId; + } + + public void setMessageThreadId(@Nullable String messageThreadId) { + this.messageThreadId = messageThreadId; + } + @Nullable public String getAuthToken() { return authToken; } From 9b2c3b29c3aac00e294dd9731da3fd0227b26cfc Mon Sep 17 00:00:00 2001 From: Ali Artukov <68611579+AliArtukov@users.noreply.github.com> Date: Tue, 2 Jun 2026 16:39:16 +0500 Subject: [PATCH 2/6] Refactor TelegramNotifier messageThreadId handling Updated messageThreadId to default to '0' and removed nullable annotations. --- .../boot/admin/server/notify/TelegramNotifier.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java b/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java index 3e0bf53808a..c0a4ed41880 100644 --- a/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java +++ b/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java @@ -48,9 +48,10 @@ public class TelegramNotifier extends AbstractContentNotifier { @Nullable private String chatId; /** - * Unique identifier for the target chat or username of the target channel + * Unique identifier for the target topic of the target super group + * 0 is an ID of general topic */ - @Nullable private String messageThreadId; + private String messageThreadId = "0"; /** * The token identifying und authorizing your Telegram bot (e.g. @@ -120,11 +121,11 @@ public void setChatId(@Nullable String chatId) { this.chatId = chatId; } - @Nullable public String getMessageThreadId() { + public String getMessageThreadId() { return messageThreadId; } - public void setMessageThreadId(@Nullable String messageThreadId) { + public void setMessageThreadId(String messageThreadId) { this.messageThreadId = messageThreadId; } From 6f5e48b182f7c89d3d5ed768297e4ed26d38b3eb Mon Sep 17 00:00:00 2001 From: Ali Artukov <68611579+AliArtukov@users.noreply.github.com> Date: Tue, 2 Jun 2026 21:59:35 +0500 Subject: [PATCH 3/6] Update buildUrl method to include message_thread_id --- .../boot/admin/server/notify/TelegramNotifier.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java b/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java index c0a4ed41880..e775a2f8d1f 100644 --- a/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java +++ b/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java @@ -81,10 +81,12 @@ protected Mono doNotify(InstanceEvent event, Instance instance) { .fromRunnable(() -> restTemplate.getForObject(buildUrl(), Void.class, createMessage(event, instance))); } - protected String buildUrl() { - return String.format("%s/bot%s/sendmessage?chat_id={chat_id}&text={text}&parse_mode={parse_mode}" - + "&disable_notification={disable_notification}", this.apiUrl, this.authToken); - } + protected String buildUrl() { + return String.format( + "%s/bot%s/sendmessage?chat_id={chat_id}&message_thread_id={message_thread_id}&text={text}&parse_mode={parse_mode}&disable_notification={disable_notification}", + this.apiUrl, this.authToken + ); + } private Map createMessage(InstanceEvent event, Instance instance) { Map parameters = new HashMap<>(); From 6d3b36778f1bc620bdc7f5d1fbcdb7b889c257c5 Mon Sep 17 00:00:00 2001 From: Ali Artukov <68611579+AliArtukov@users.noreply.github.com> Date: Tue, 2 Jun 2026 22:13:24 +0500 Subject: [PATCH 4/6] Change messageThreadId type from String to Integer --- .../boot/admin/server/notify/TelegramNotifier.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java b/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java index e775a2f8d1f..6b1b9963529 100644 --- a/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java +++ b/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java @@ -49,9 +49,8 @@ public class TelegramNotifier extends AbstractContentNotifier { /** * Unique identifier for the target topic of the target super group - * 0 is an ID of general topic */ - private String messageThreadId = "0"; + private Integer messageThreadId; /** * The token identifying und authorizing your Telegram bot (e.g. @@ -123,11 +122,11 @@ public void setChatId(@Nullable String chatId) { this.chatId = chatId; } - public String getMessageThreadId() { + public Integer getMessageThreadId() { return messageThreadId; } - public void setMessageThreadId(String messageThreadId) { + public void setMessageThreadId(Integer messageThreadId) { this.messageThreadId = messageThreadId; } From fde273b1e35200508fa085f8f88a6ddcad3e8386 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20Ko=CC=88ninger?= Date: Fri, 19 Jun 2026 08:45:58 +0200 Subject: [PATCH 5/6] feat(TelegramNotifier): include messageThreadId in URL when set --- .../admin/server/notify/TelegramNotifier.java | 27 +++++++++++++------ .../server/notify/TelegramNotifierTest.java | 18 +++++++++++++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java b/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java index 6b1b9963529..f41b9a34780 100644 --- a/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java +++ b/spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/TelegramNotifier.java @@ -21,6 +21,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; import reactor.core.publisher.Mono; import de.codecentric.boot.admin.server.domain.entities.Instance; @@ -50,7 +51,7 @@ public class TelegramNotifier extends AbstractContentNotifier { /** * Unique identifier for the target topic of the target super group */ - private Integer messageThreadId; + @Nullable private Integer messageThreadId; /** * The token identifying und authorizing your Telegram bot (e.g. @@ -80,17 +81,27 @@ protected Mono doNotify(InstanceEvent event, Instance instance) { .fromRunnable(() -> restTemplate.getForObject(buildUrl(), Void.class, createMessage(event, instance))); } - protected String buildUrl() { - return String.format( - "%s/bot%s/sendmessage?chat_id={chat_id}&message_thread_id={message_thread_id}&text={text}&parse_mode={parse_mode}&disable_notification={disable_notification}", - this.apiUrl, this.authToken - ); - } + protected String buildUrl() { + UriComponentsBuilder builder = UriComponentsBuilder + .fromUriString(this.apiUrl + "/bot" + this.authToken + "/sendmessage") + .queryParam("chat_id", "{chat_id}") + .queryParam("text", "{text}") + .queryParam("parse_mode", "{parse_mode}") + .queryParam("disable_notification", "{disable_notification}"); + + if (this.messageThreadId != null) { + builder.queryParam("message_thread_id", "{message_thread_id}"); + } + + return builder.build().toUriString(); + } private Map createMessage(InstanceEvent event, Instance instance) { Map parameters = new HashMap<>(); parameters.put("chat_id", this.chatId); - parameters.put("message_thread_id", this.messageThreadId); + if (this.messageThreadId != null) { + parameters.put("message_thread_id", this.messageThreadId); + } parameters.put("parse_mode", this.parseMode); parameters.put("disable_notification", this.disableNotify); parameters.put("text", createContent(event, instance)); diff --git a/spring-boot-admin-server/src/test/java/de/codecentric/boot/admin/server/notify/TelegramNotifierTest.java b/spring-boot-admin-server/src/test/java/de/codecentric/boot/admin/server/notify/TelegramNotifierTest.java index 5a63ace7817..ba04a1d78b2 100644 --- a/spring-boot-admin-server/src/test/java/de/codecentric/boot/admin/server/notify/TelegramNotifierTest.java +++ b/spring-boot-admin-server/src/test/java/de/codecentric/boot/admin/server/notify/TelegramNotifierTest.java @@ -109,6 +109,24 @@ void test_onApplicationEvent_trigger() { Void.class, getParameters("DOWN")); } + @Test + void test_includes_messageThreadId_in_url_when_set() { + notifier.setMessageThreadId(1337); + + StepVerifier + .create(notifier + .notify(new InstanceStatusChangedEvent(instance.getId(), instance.getVersion(), StatusInfo.ofDown()))) + .verifyComplete(); + + Map parameters = getParameters("DOWN"); + parameters.put("message_thread_id", 1337); + + verify(restTemplate).getForObject( + "https://telegram.com/bot--token-/sendmessage?chat_id={chat_id}&text={text}" + + "&parse_mode={parse_mode}&disable_notification={disable_notification}&message_thread_id={message_thread_id}", + Void.class, parameters); + } + private Map getParameters(String status) { Map parameters = new HashMap<>(); parameters.put("chat_id", "-room-"); From acab4941b74951738b621a8828c18cce86fde533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20Ko=CC=88ninger?= Date: Fri, 19 Jun 2026 12:28:21 +0200 Subject: [PATCH 6/6] test(TelegramNotifier): update test to verify message_thread_id in URL --- .../boot/admin/server/notify/TelegramNotifierTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spring-boot-admin-server/src/test/java/de/codecentric/boot/admin/server/notify/TelegramNotifierTest.java b/spring-boot-admin-server/src/test/java/de/codecentric/boot/admin/server/notify/TelegramNotifierTest.java index ba04a1d78b2..b06ba5d3fca 100644 --- a/spring-boot-admin-server/src/test/java/de/codecentric/boot/admin/server/notify/TelegramNotifierTest.java +++ b/spring-boot-admin-server/src/test/java/de/codecentric/boot/admin/server/notify/TelegramNotifierTest.java @@ -121,10 +121,9 @@ void test_includes_messageThreadId_in_url_when_set() { Map parameters = getParameters("DOWN"); parameters.put("message_thread_id", 1337); - verify(restTemplate).getForObject( - "https://telegram.com/bot--token-/sendmessage?chat_id={chat_id}&text={text}" + verify(restTemplate).getForObject("https://telegram.com/bot--token-/sendmessage?chat_id={chat_id}&text={text}" + "&parse_mode={parse_mode}&disable_notification={disable_notification}&message_thread_id={message_thread_id}", - Void.class, parameters); + Void.class, parameters); } private Map getParameters(String status) {