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