package fr.jcgay.notification.notifier.slack; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; import fr.jcgay.notification.Application; import fr.jcgay.notification.DiscoverableNotifier; import fr.jcgay.notification.Notification; import fr.jcgay.notification.Notifier; import org.slf4j.Logger; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import static org.slf4j.LoggerFactory.getLogger; public class SlackNotifier implements DiscoverableNotifier { private static final Logger LOGGER = getLogger(SlackNotifier.class); private final Application application; private final SlackConfiguration configuration; private final String url; private OkHttpClient client; public SlackNotifier(Application application, SlackConfiguration configuration, String url) { LOGGER.debug("Configuring Slack for application {}: {}.", application, configuration); this.application = application; this.configuration = configuration; this.url = url; } public SlackNotifier(Application application, SlackConfiguration configuration) { this(application, configuration, "https://slack.com/api/chat.postMessage"); } @Override public Notifier init() { if (client != null) { return this; } client = new OkHttpClient(); return this; } @Override public boolean tryInit() { return false; } @Override public void send(Notification notification) { StringBuilder builder = new StringBuilder(url) .append("?token=").append(configuration.token()) .append("&channel=").append(encode(configuration.channel())) .append("&attachments=").append(encode(attachments(notification))); try { String requestUrl = builder.toString(); LOGGER.debug("Calling Slack with parameters: {}", requestUrl); Response response = client.newCall(new Request.Builder().url(requestUrl).get().build()).execute(); if (response.code() != 200) { String message = String.format("Slack notification has failed, [%s] - [%s]%n%s", response.code(), response.message(), response.body().string() ); LOGGER.error(message); throw new SlackNotificationException(message); } } catch (IOException e) { String message = "Error while sending Slack notification."; LOGGER.error(message, e); throw new SlackNotificationException(message, e); } } private String attachments(Notification notification) { return "[{" + "\"fallback\":\"" + notification.message() + "\"," + "\"color\":\"" + colorize(notification) + "\"," + "\"author_name\":\"" + application.name() + "\"," + "\"title\":\"" + notification.title() + "\"," + "\"text\":\"" + notification.message() + "\n" + notification.subtitle() + "\"," + "}]"; } private static String colorize(Notification notification) { switch (notification.level()) { case INFO: return "good"; case WARNING: return "warning"; case ERROR: return "danger"; default: return "warning"; } } private static String encode(String string) { try { return URLEncoder.encode(string, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new SlackNotificationException("Cannot encode URL parameter: " + string, e); } } @Override public void close() { // do nothing } @Override public boolean isPersistent() { return false; } }