package com.box.l10n.mojito.slack; import com.box.l10n.mojito.slack.request.Channel; import com.box.l10n.mojito.slack.request.Message; import com.box.l10n.mojito.slack.request.User; import com.box.l10n.mojito.slack.response.ChatPostMessageResponse; import com.box.l10n.mojito.slack.response.ImOpenResponse; import com.box.l10n.mojito.slack.response.UserResponse; import com.google.common.base.Preconditions; import com.ibm.icu.text.MessageFormat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; /** * Simple Slack client based on the Web API: https://api.slack.com/web */ public class SlackClient { /** * logger */ static Logger logger = LoggerFactory.getLogger(SlackClient.class); static final String BASE_API_URL = "https://slack.com/api/"; static final String API_USER_LOOKUP_BY_EMAIL = "users.lookupByEmail"; static final String API_IM_OPEN = "im.open"; static final String API_CHAT_POST_MESSAGE = "chat.postMessage"; public static final String COLOR_GOOD = "good"; RestTemplate restTemplate = new RestTemplate(); String authToken = null; public SlackClient(String authToken) { this.authToken = authToken; } /** * Sends an instant message * * @param message message to send * @throws SlackClientException */ public ChatPostMessageResponse sendInstantMessage(Message message) throws SlackClientException { logger.debug("sendInstantMessage to: {}", message.getChannel()); HttpEntity<Message> httpEntity = getMessageHttpEntityForJsonPayload(message); ChatPostMessageResponse postForObject = restTemplate.postForObject(getUrl(API_CHAT_POST_MESSAGE), httpEntity, ChatPostMessageResponse.class); if (!postForObject.getOk()) { String msg = MessageFormat.format("Cannot post message in chat: {0}", postForObject.getError()); logger.debug(msg); throw new SlackClientException(msg); } return postForObject; } public Channel getInstantMessageChannel(String email) throws SlackClientException { User user = lookupUserByEmail(email); Channel channel = openIm(user); return channel; } User lookupUserByEmail(String email) throws SlackClientException { MultiValueMap<String, Object> payload = getBasePayloadMapWithAuthToken(); payload.add("email", email); HttpEntity<MultiValueMap<String, Object>> httpEntity = getHttpEntityForPayload(payload); UserResponse userResponse = restTemplate.postForObject(getUrl(API_USER_LOOKUP_BY_EMAIL), httpEntity, UserResponse.class); if (!userResponse.getOk()) { String msg = MessageFormat.format("Cannot lookup user by email: {0} ({1})", email, userResponse.getError()); logger.debug(msg); throw new SlackClientException(msg); } return userResponse.getUser(); } Channel openIm(User user) throws SlackClientException { Preconditions.checkNotNull(user.getId()); MultiValueMap<String, Object> payload = getBasePayloadMapWithAuthToken(); payload.add("user", user.getId()); payload.add("return_im", "true"); HttpEntity<MultiValueMap<String, Object>> httpEntity = getHttpEntityForPayload(payload); ImOpenResponse imOpenResponse = restTemplate.postForObject(getUrl(API_IM_OPEN), httpEntity, ImOpenResponse.class); if (!imOpenResponse.getOk()) { String msg = MessageFormat.format("Cannot open instant message: {0}", imOpenResponse.getError()); logger.debug(msg); throw new SlackClientException(msg); } return imOpenResponse.getChannel(); } MultiValueMap<String, Object> getBasePayloadMapWithAuthToken() { MultiValueMap<String, Object> map = new LinkedMultiValueMap<>(); map.add("token", authToken); return map; } HttpHeaders getHttpHeadersForFormUrlencoded() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); return headers; } HttpHeaders getHttpHeadersForJson() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON_UTF8); headers.set("Authorization", "Bearer " + authToken); return headers; } HttpEntity<MultiValueMap<String, Object>> getHttpEntityForPayload(MultiValueMap<String, Object> payload) { return new HttpEntity<>(payload, getHttpHeadersForFormUrlencoded()); } <T> HttpEntity<T> getMessageHttpEntityForJsonPayload(T payload) { return new HttpEntity<>(payload, getHttpHeadersForJson()); } String getUrl(String subpath) { return BASE_API_URL + subpath; } }