package com.groupon.jenkins.dotci.notifiers.hipchat; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; import com.groupon.jenkins.dynamic.build.cause.BuildCause; import org.apache.commons.codec.EncoderException; import org.apache.commons.codec.net.URLCodec; import org.apache.commons.httpclient.HostConfiguration; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.URI; import org.apache.commons.httpclient.URIException; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.StringRequestEntity; import org.apache.http.Consts; import java.io.IOException; import java.util.Date; import java.util.HashMap; import java.util.Map; import static com.google.common.collect.ImmutableMap.of; public class SendRoomMessageWithCardRequest{ private final BuildCause.CommitInfo commitInfo; private String idOrName; private String accessToken; private MessageColor color; private String notificationMessage; private Boolean notify; private MessageFormat messageFormat; private String buildLink; private final ObjectMapper objectMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); protected final ObjectWriter objectWriter = objectMapper.writer(); public SendRoomMessageWithCardRequest(String idOrName, String accessToken, MessageColor color, boolean notify,String notificationMessage, String buildLink, BuildCause.CommitInfo commitInfo) { this.idOrName = idOrName; this.accessToken = accessToken; this.color = color; this.notificationMessage = notificationMessage; this.buildLink = buildLink; this.notify = notify; this.messageFormat = MessageFormat.HTML; this.commitInfo = commitInfo; } protected String getPath() { return "/v2/room/" + idOrName + "/notification"; } protected Map<String, Object> toQueryMap() { Map<String, Object> params = new HashMap(); if (color != null) { params.put("color", color.name().toLowerCase()); } params.put("message", notificationMessage); if (notify != null) { params.put("notify", notify); } if (messageFormat != null) { params.put("message_format", "text"); } if(commitInfo != null){ params.put("card",getCard()); } return params; } private Object getCard() { HashMap<String, Object> card = new HashMap<>(); card.put( "style", "application"); card.put("url", this.commitInfo.getCommitUrl()); card.put("title", this.commitInfo.getBranch()+ "@"+this.commitInfo.getShortSha()); card.put( "description", of("value", this.commitInfo.getMessage(),"format","html")); card.put("format","medium"); card.put("id",new Date().getTime() + ""); card.put("icon", of("url",this.commitInfo.getAvatarUrl())); card.put("activity", of("html", String.format("<a href=\"%s\">%s: %s</a>",this.buildLink,this.commitInfo.getCommitterName(), this.notificationMessage))); return card; } public int execute() throws IOException { org.apache.commons.httpclient.HttpClient client = getHttpClient(); Map<String, Object> params = toQueryMap(); String body = objectWriter.writeValueAsString(params); String encodedPath = getEncodedPath(); PostMethod post = new PostMethod(encodedPath); post.addRequestHeader("Authorization", "Bearer " + accessToken); post.addRequestHeader("Content-Type", "application/json"); post.setRequestEntity(new StringRequestEntity(body,"application/json",Consts.UTF_8.toString())); int responseCode = client.executeMethod(post); if(responseCode != 200 && responseCode != 204){ throw new RuntimeException("Could not post notification: "+ new String(post.getResponseBody())); } return responseCode; } private HttpClient getHttpClient() throws URIException { HttpClient client = new HttpClient(); HostConfiguration hostConfig = new HostConfiguration(); hostConfig.setHost(new URI("https://api.hipchat.com",true)); client.setHostConfiguration(hostConfig); return client; } protected String getEncodedPath() { String path = getPath(); String[] tokens = path.split("/"); String encodedPath = ""; URLCodec urlCodec = new URLCodec(); try { for (String token : tokens) { if (!token.isEmpty()) { //replace + to %20 encodedPath += "/" + urlCodec.encode(token).replace("+", "%20"); } } } catch (EncoderException e) { throw new RuntimeException(e); } return encodedPath; } }