package org.c4sg.service.slack.impl; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.http.HttpEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.c4sg.constant.slack.Problem; import org.c4sg.dao.UserDAO; import org.c4sg.dto.slack.Profile; import org.c4sg.dto.slack.User; import org.c4sg.dto.slack.channel.Group; import org.c4sg.exception.slack.SlackArgumentException; import org.c4sg.exception.slack.SlackException; import org.c4sg.exception.slack.SlackResponseErrorException; import org.c4sg.exception.slack.ValidationError; import org.c4sg.service.slack.SlackClientService; import org.c4sg.service.slack.method.CreatePrivateChannel; import org.c4sg.service.slack.method.SlackMethod; import org.c4sg.service.slack.method.UserListMethod; import org.c4sg.util.slack.SlackUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; @Service public class SlackClientServiceImpl implements SlackClientService { @Value("${slack.auth.token}") private String slackAuthToken; @Value("${slack.webapi.url}") private String slackApiUrl; @Value("${slack.webapi.document.url}") private String slackApiDocUrl; @Value("${slack.default.timeout}") private String slackDefaultTimeOut; private ObjectMapper mapper; private CloseableHttpClient httpClient; @Autowired private UserDAO userDAO; @Override public void shutdown() { if (httpClient != null) try { httpClient.close(); } catch (Exception e) { } } @Override public List<User> getUserList() { JsonNode retNode = call(new UserListMethod()); return readValue(retNode, "members", new TypeReference<List<User>>() { }); } @Override public Boolean isJoinedChat(String email) { //token=SlackWebApiConstants.SLACK_AUTH_TOKEN; httpClient = SlackUtils.createHttpClient(Integer.parseInt(slackDefaultTimeOut)); mapper = new ObjectMapper(); try { org.c4sg.entity.User user = userDAO.findByEmail(email); if (user == null) { return false; } if (user.getChatUsername() == null) { List<User> slackUsers = getUserList(); for (User slackUser : slackUsers) { Profile slackUserProfile = slackUser.getProfile(); if (slackUserProfile != null && slackUserProfile.getEmail() != null && slackUserProfile.getEmail().equalsIgnoreCase(email)) { // userDAO.updateIsSlackRegisteredFlag("Y", user.getId()); return true; } } // userDAO.updateIsSlackRegisteredFlag("N", user.getId()); return false; } else { return true; } } finally { shutdown(); } } @Override public Group createPrivateChannel(String channelName) { httpClient = SlackUtils.createHttpClient(Integer.parseInt(slackDefaultTimeOut)); mapper = new ObjectMapper(); return getPrivateChannel(channelName); } public Group getPrivateChannel(String channelName) { CreatePrivateChannel c = new CreatePrivateChannel(); c.setChannelName(channelName); JsonNode retNode = call(c); return readValue(retNode, "group", new TypeReference<Group>() { }); } protected <T> T readValue(JsonNode node, String findPath, Class<T> valueType) { try { if (findPath != null) { if (!node.has(findPath)) return null; node = node.findPath(findPath); } return mapper.readValue(node.toString(), valueType); } catch (IOException e) { throw new RuntimeException(e); } } protected <T> T readValue(JsonNode node, String findPath, TypeReference<?> typeReference) { try { if (findPath != null) { if (!node.has(findPath)) return null; node = node.findPath(findPath); } return mapper.readValue(node.toString(), typeReference); } catch (IOException e) { throw new RuntimeException(e); } } protected JsonNode call(SlackMethod method) { return call(method, null); } protected JsonNode call(SlackMethod method, InputStream is) { List<ValidationError> errors = new ArrayList<>(); method.validate(errors); if (errors.size() > 0) { StringBuffer sb = new StringBuffer("*** slack argument error ***"); for (ValidationError error : errors) { if (sb.length() > 0) { sb.append("\n"); } if (error.getDescription() != null) { sb.append(error.getDescription()); } else if (error.getProblem() == Problem.REQUIRED) { sb.append("\"" + error.getField() + "\" is required."); } } throw new SlackArgumentException(sb.toString()); } Map<String, String> parameters = method.getParameters(); if (method.isRequiredToken()) { parameters.put("token", slackAuthToken); } String apiUrl = slackApiUrl + "/" + method.getMethodName(); HttpEntity httpEntity = null; if (is == null) { httpEntity = SlackUtils.createUrlEncodedFormEntity(parameters); } else { httpEntity = SlackUtils.createMultipartFormEntity(parameters, is); } String retContent = SlackUtils.execute(httpClient, apiUrl, httpEntity); JsonNode retNode = null; try { retNode = mapper.readTree(retContent); } catch (IOException e) { throw new SlackException(e); } boolean retOk = retNode.findPath("ok").asBoolean(); if (!retOk) { String error = retNode.findPath("error").asText(); throw new SlackResponseErrorException(error + ". check the link " + slackApiDocUrl + "/" + method.getMethodName()); } return retNode; } }