1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package de.codecentric.boot.admin.notify;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
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;
import de.codecentric.boot.admin.event.ClientApplicationStatusChangedEvent;
/**
* Notifier submitting events to Slack.
*
* @author Artur Dobosiewicz
*/
public class SlackNotifier extends AbstractStatusChangeNotifier {
private static final String DEFAULT_MESSAGE = "*#{application.name}* (#{application.id}) is *#{to.status}*";
private final SpelExpressionParser parser = new SpelExpressionParser();
private RestTemplate restTemplate = new RestTemplate();
/**
* Webhook url for Slack API (i.e. https://hooks.slack.com/services/xxx)
*/
private URI webhookUrl;
/**
* Optional channel name without # sign (i.e. somechannel)
*/
private String channel;
/**
* Optional emoji icon without colons (i.e. my-emoji)
*/
private String icon;
/**
* Optional username which sends notification
*/
private String username = "Spring Boot Admin";
/**
* Message formatted using Slack markups. SpEL template using event as root
*/
private Expression message;
public SlackNotifier() {
this.message = parser.parseExpression(DEFAULT_MESSAGE, ParserContext.TEMPLATE_EXPRESSION);
}
@Override
protected void doNotify(ClientApplicationEvent event) throws Exception {
restTemplate.postForEntity(webhookUrl, createMessage(event), Void.class);
}
public void setRestTemplate(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
protected Object createMessage(ClientApplicationEvent event) {
Map<String, Object> messageJson = new HashMap<>();
messageJson.put("username", username);
if (icon != null) {
messageJson.put("icon_emoji", ":" + icon + ":");
}
if (channel != null) {
messageJson.put("channel", channel);
}
Map<String, Object> attachments = new HashMap<>();
attachments.put("text", getText(event));
attachments.put("color", getColor(event));
attachments.put("mrkdwn_in", Collections.singletonList("text"));
messageJson.put("attachments", Collections.singletonList(attachments));
return messageJson;
}
protected String getText(ClientApplicationEvent event) {
return message.getValue(event, String.class);
}
protected String getColor(ClientApplicationEvent event) {
if (event instanceof ClientApplicationStatusChangedEvent) {
return "UP".equals(((ClientApplicationStatusChangedEvent) event).getTo().getStatus()) ? "good" : "danger";
} else {
return "#439FE0";
}
}
public URI getWebhookUrl() {
return webhookUrl;
}
public void setWebhookUrl(URI webhookUrl) {
this.webhookUrl = webhookUrl;
}
public String getChannel() {
return channel;
}
public void setChannel(String channel) {
this.channel = channel;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getMessage() {
return message.getExpressionString();
}
public void setMessage(String message) {
this.message = parser.parseExpression(message, ParserContext.TEMPLATE_EXPRESSION);
}
}