Skip to content

Commit

Permalink
Add Telegram notifier
Browse files Browse the repository at this point in the history
  • Loading branch information
wonwoo authored and joshiste committed Jan 1, 2018
1 parent f1a73bc commit 37ec7d2
Show file tree
Hide file tree
Showing 5 changed files with 290 additions and 18 deletions.
49 changes: 41 additions & 8 deletions spring-boot-admin-docs/src/main/asciidoc/server-notifications.adoc
Expand Up @@ -129,10 +129,10 @@ spring.boot.admin.notify.mail.to=admin@example.com
|===

[[pagerduty-notifications]]
==== Pagerduty notifications ====
To enable pagerduty notifications you just have to add a generic service to your pagerduty-account and set `spring.boot.admin.notify.pagerduty.service-key` to the service-key you received.
==== PagerDuty notifications ====
To enable https://www.pagerduty.com/[PagerDuty] notifications you just have to add a generic service to your PagerDuty-account and set `spring.boot.admin.notify.pagerduty.service-key` to the service-key you received.

.Pagerduty notifications configuration options
.PagerDuty notifications configuration options
|===
| Property name |Description |Default value

Expand All @@ -145,7 +145,7 @@ To enable pagerduty notifications you just have to add a generic service to your
| `"UNKNOWN:UP"`

| spring.boot.admin.notify.pagerduty.service-key
| Service-key to use for Pagerduty
| Service-key to use for PagerDuty
|

| spring.boot.admin.notify.pagerduty.url
Expand All @@ -168,7 +168,7 @@ To enable pagerduty notifications you just have to add a generic service to your

[[opsgenie-notifications]]
==== OpsGenie notifications ====
To enable OpsGenie notifications you just have to add a new JSON Rest API integration to your OpsGenie account and set `spring.boot.admin.notify.opsgenie.api-key` to the apiKey you received.
To enable https://www.opsgenie.com/[OpsGenie] notifications you just have to add a new JSON Rest API integration to your OpsGenie account and set `spring.boot.admin.notify.opsgenie.api-key` to the apiKey you received.

.OpsGenie notifications configuration options
|===
Expand Down Expand Up @@ -221,7 +221,7 @@ To enable OpsGenie notifications you just have to add a new JSON Rest API integr

[hipchat-notifications]
==== Hipchat notifications ====
To enable Hipchat notifications you need to create an API token from you Hipchat account and set the appropriate configuration properties.
To enable https://www.hipchat.com/[Hipchat] notifications you need to create an API token from you Hipchat account and set the appropriate configuration properties.

.Hipchat notifications configuration options
|===
Expand Down Expand Up @@ -259,7 +259,7 @@ To enable Hipchat notifications you need to create an API token from you Hipchat

[slack-notifications]
==== Slack notifications ====
To enable Slack notifications you need to add a incoming Webhook under custom integrations on your Slack
To enable https://slack.com/[Slack] notifications you need to add a incoming Webhook under custom integrations on your Slack
account and configure it appropriately.

.Slack notifications configuration options
Expand Down Expand Up @@ -298,7 +298,7 @@ account and configure it appropriately.

[letschat-notifications]
==== Let's Chat notifications ====
To enable Let's Chat notifications you need to add the host url and add the API token and username from Let's Chat
To enable https://sdelements.github.io/lets-chat/[Let's Chat] notifications you need to add the host url and add the API token and username from Let's Chat

.Let's Chat notifications configuration options
|===
Expand Down Expand Up @@ -353,4 +353,37 @@ To enable Microsoft Teams notifications you need to setup a connector webhook ur
| spring.boot.admin.notify.ms-teams.*
| There are several options to customize the message title and color
|
|===

[telegram-notifications]
==== Telegram notifications ====
To enable https://telegram.org/[Telegram] notifications you need to create and authorize a telegram bot and set the appropriate configuration properties for auth-token and chat-id.

.Microsoft Teams notifications configuration options
|===
| Property name |Description |Default value

| spring.boot.admin.notify.telegram.enabled
| Enable Microsoft Teams notifications
| `true`

| spring.boot.admin.notify.telegram.auth-token
| The token identifiying und authorizing your Telegram bot (e.g. `123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11`).
|

| spring.boot.admin.notify.telegram.chat-id
| Unique identifier for the target chat or username of the target channel
|

| spring.boot.admin.notify.telegram.disable-notify
| If true users will receive a notification with no sound.
| `false`

| spring.boot.admin.notify.telegram.parse_mode
| The parsing mode for the sent message. Currently ``HTML'` and `'Markdown'` are supported.
| `'HTML'`

| spring.boot.admin.notify.telegram.message
| Text to send. SpEL-expressions are supported.
| `+++"<strong>#{application.name}</strong>/#{application.id} is <strong>#{to.status}</strong>"+++`
|===
Expand Up @@ -43,6 +43,7 @@
import de.codecentric.boot.admin.notify.OpsGenieNotifier;
import de.codecentric.boot.admin.notify.PagerdutyNotifier;
import de.codecentric.boot.admin.notify.SlackNotifier;
import de.codecentric.boot.admin.notify.TelegramNotifier;
import de.codecentric.boot.admin.notify.filter.FilteringNotifier;
import de.codecentric.boot.admin.notify.filter.web.NotificationFilterController;
import de.codecentric.boot.admin.web.PrefixHandlerMapping;
Expand Down Expand Up @@ -102,7 +103,8 @@ public NotificationFilterController notificationFilterController() {

@Bean
public PrefixHandlerMapping prefixHandlerMappingNotificationFilterController() {
PrefixHandlerMapping prefixHandlerMapping = new PrefixHandlerMapping(notificationFilterController());
PrefixHandlerMapping prefixHandlerMapping = new PrefixHandlerMapping(
notificationFilterController());
prefixHandlerMapping.setPrefix(adminServerProperties.getContextPath());
return prefixHandlerMapping;
}
Expand All @@ -112,7 +114,7 @@ public PrefixHandlerMapping prefixHandlerMappingNotificationFilterController() {
@ConditionalOnBean(MailSender.class)
@AutoConfigureAfter({ MailSenderAutoConfiguration.class })
@AutoConfigureBefore({ NotifierListenerConfiguration.class,
CompositeNotifierConfiguration.class })
CompositeNotifierConfiguration.class })
public static class MailNotifierConfiguration {
@Autowired
private MailSender mailSender;
Expand All @@ -128,7 +130,7 @@ public MailNotifier mailNotifier() {
@Configuration
@ConditionalOnProperty(prefix = "spring.boot.admin.notify.pagerduty", name = "service-key")
@AutoConfigureBefore({ NotifierListenerConfiguration.class,
CompositeNotifierConfiguration.class })
CompositeNotifierConfiguration.class })
public static class PagerdutyNotifierConfiguration {
@Bean
@ConditionalOnMissingBean
Expand All @@ -138,7 +140,6 @@ public PagerdutyNotifier pagerdutyNotifier() {
}
}


@Configuration
@ConditionalOnProperty(prefix = "spring.boot.admin.notify.opsgenie", name = "api-key")
@AutoConfigureBefore({ NotifierListenerConfiguration.class,
Expand All @@ -152,12 +153,10 @@ public OpsGenieNotifier opsgenieNotifier() {
}
}



@Configuration
@ConditionalOnProperty(prefix = "spring.boot.admin.notify.hipchat", name = "url")
@AutoConfigureBefore({ NotifierListenerConfiguration.class,
CompositeNotifierConfiguration.class })
CompositeNotifierConfiguration.class })
public static class HipchatNotifierConfiguration {
@Bean
@ConditionalOnMissingBean
Expand All @@ -170,7 +169,7 @@ public HipchatNotifier hipchatNotifier() {
@Configuration
@ConditionalOnProperty(prefix = "spring.boot.admin.notify.slack", name = "webhook-url")
@AutoConfigureBefore({ NotifierListenerConfiguration.class,
CompositeNotifierConfiguration.class })
CompositeNotifierConfiguration.class })
public static class SlackNotifierConfiguration {
@Bean
@ConditionalOnMissingBean
Expand All @@ -196,11 +195,26 @@ public LetsChatNotifier letsChatNotifier() {
@Configuration
@ConditionalOnProperty(prefix = "spring.boot.admin.notify.ms-teams", name = "webhook-url")
@AutoConfigureBefore({ NotifierListenerConfiguration.class,
CompositeNotifierConfiguration.class})
CompositeNotifierConfiguration.class })
public static class MicrosoftTeamsNotifierConfiguration {
@Bean
@ConditionalOnMissingBean
@ConfigurationProperties("spring.boot.admin.notify.ms-teams")
public MicrosoftTeamsNotifier microsoftTeamsNotifier() { return new MicrosoftTeamsNotifier(); }
public MicrosoftTeamsNotifier microsoftTeamsNotifier() {
return new MicrosoftTeamsNotifier();
}
}

@Configuration
@ConditionalOnProperty(prefix = "spring.boot.admin.notify.telegram", name = "auth-token")
@AutoConfigureBefore({ NotifierListenerConfiguration.class,
CompositeNotifierConfiguration.class })
public static class TelegramNotifierConfiguration {
@Bean
@ConditionalOnMissingBean
@ConfigurationProperties("spring.boot.admin.notify.telegram")
public TelegramNotifier telegramNotifier() {
return new TelegramNotifier();
}
}
}
@@ -0,0 +1,145 @@
/*
* Copyright 2014-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.codecentric.boot.admin.notify;

import java.util.HashMap;
import java.util.Map;

import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.expression.Expression;
import org.springframework.expression.ParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.web.client.RestTemplate;

import de.codecentric.boot.admin.event.ClientApplicationEvent;

/**
* Notifier submitting events to Telegram.
*/
public class TelegramNotifier extends AbstractStatusChangeNotifier {
private static final String DEFAULT_MESSAGE = "<strong>#{application.name}</strong>/#{application.id} is <strong>#{to.status}</strong>";
private final SpelExpressionParser parser = new SpelExpressionParser();
private RestTemplate restTemplate = new RestTemplate();

/**
* base url for telegram (i.e. https://api.telegram.org)
*/
private String apiUrl = "https://api.telegram.org";

/**
* Unique identifier for the target chat or username of the target channel
*/
private String chatId;

/**
* The token identifiying und authorizing your Telegram bot (e.g. `123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11`)
*/
private String authToken;

/**
* Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
* inline URLs in your bot's message.
*/
private String parse_mode = "HTML";

/**
* If true users will receive a notification with no sound.
*/
private boolean disableNotify = false;

private Expression message;

public TelegramNotifier() {
this.message = parser.parseExpression(DEFAULT_MESSAGE, ParserContext.TEMPLATE_EXPRESSION);
}

@Override
protected void doNotify(ClientApplicationEvent event) {
restTemplate.getForObject(buildUrl(), Void.class, createMessage(event));
}

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);
}

private Map<String, Object> createMessage(ClientApplicationEvent event) {
Map<String, Object> parameters = new HashMap<>();
parameters.put("chat_id", this.chatId);
parameters.put("parse_mode", this.parse_mode);
parameters.put("disable_notification", this.disableNotify);
parameters.put("text", getText(event));
return parameters;
}

protected String getText(ClientApplicationEvent event) {
return message.getValue(event, String.class);
}

public void setRestTemplate(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}

public void setRestTemplate(RestTemplateBuilder builder) {
this.restTemplate = builder.build();
}

public String getApiUrl() {
return apiUrl;
}

public void setApiUrl(String apiUrl) {
this.apiUrl = apiUrl;
}

public String getChatId() {
return chatId;
}

public void setChatId(String chatId) {
this.chatId = chatId;
}

public String getAuthToken() {
return authToken;
}

public void setAuthToken(String authToken) {
this.authToken = authToken;
}

public boolean isDisableNotify() {
return disableNotify;
}

public void setDisableNotify(boolean disableNotify) {
this.disableNotify = disableNotify;
}

public String getParse_mode() {
return parse_mode;
}

public void setParse_mode(String parse_mode) {
this.parse_mode = parse_mode;
}

public void setMessage(String message) {
this.message = parser.parseExpression(message, ParserContext.TEMPLATE_EXPRESSION);
}
}
Expand Up @@ -46,6 +46,7 @@
import de.codecentric.boot.admin.notify.OpsGenieNotifier;
import de.codecentric.boot.admin.notify.PagerdutyNotifier;
import de.codecentric.boot.admin.notify.SlackNotifier;
import de.codecentric.boot.admin.notify.TelegramNotifier;

public class NotifierConfigurationTest {
private static final ClientApplicationEvent APP_DOWN = new ClientApplicationStatusChangedEvent(
Expand Down Expand Up @@ -113,6 +114,12 @@ public void test_ms_teams() {
assertThat(context.getBean(MicrosoftTeamsNotifier.class), is(instanceOf(MicrosoftTeamsNotifier.class)));
}

@Test
public void test_telegram() {
load(null, "spring.boot.admin.notify.telegram.auth-token:123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11");
assertThat(context.getBean(Notifier.class), is(instanceOf(TelegramNotifier.class)));
}

@Test
public void test_multipleNotifiers() {
load(TestMultipleNotifierConfig.class);
Expand Down

0 comments on commit 37ec7d2

Please sign in to comment.