最近公司需要跟踪jira上的延期BUG 并在钉钉群里发送通知,写了个demo,留个记录以后有需要时备查
Jira rest api 手册
https://docs.atlassian.com/software/jira/docs/api/REST/1000.1000.0/#api/2/search-search
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import myutils.common.JsonPathUtil;
import net.minidev.json.JSONArray;
import org.apache.commons.net.util.Base64;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
public class JiraApiTools {
private static String webHook_DG = "https://oapi.dingtalk.com/robot/send?access_token=******";
public static void main(String[] args) throws ParseException, UnsupportedEncodingException {
String jql = "project = DG AND issuetype = Bug AND status not in (closed, Resolved)";
getBugInfo(jql);
}
public static void getBugInfo(String jql) throws ParseException, UnsupportedEncodingException {
String testUrl = "https://jira.***.com/rest/api/2/search?jql=" + jql;
//jira身份校验信息
String name = "***";
String password = "******";
String authString = name + ":" + password;
byte[] authEncBytes = Base64.encodeBase64(authString.getBytes("utf-8"));
String authStringEnc = new String(authEncBytes);
String auth = "Authorization = Basic " + authStringEnc;
List<BugModel> bugListDelayed = new ArrayList<>();
List<BugModel> bugListNoDueDate = new ArrayList<>();
String result = httpGet(testUrl,auth);
if (JSONUtil.isJson(result)) {
JSONArray jsonArray = JsonPathUtil.jsonPathValue(result, "$.issues", null);
for (int i = 0; i < jsonArray.size(); i++) {
String key = JsonPathUtil.jsonPathValue(result, "$.issues[" + i + "].key", "");
String summary = JsonPathUtil.jsonPathValue(result, "$.issues[" + i + "].fields.summary", "");
String displayName = JsonPathUtil.jsonPathValue(result, "$.issues[" + i + "].fields.assignee.displayName", "");
String dueDate = JsonPathUtil.jsonPathValue(result, "$.issues[" + i + "].fields.duedate", null);
if (dueDate != null) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
long between = DateUtil.between(new Date(), sdf.parse(dueDate), DateUnit.DAY, false);
if (between < 0) {
// System.out.println("已延期 " + between + " 天");
bugListDelayed.add(new BugModel(key, summary, displayName, dueDate, between));
}
} else {
bugListNoDueDate.add(new BugModel(key, summary, displayName, null, 0));
}
}
}
//拼接markdown发送钉钉通知
StringBuilder sb = new StringBuilder();
sb.append("{\"msgtype\": \"markdown\",\"markdown\": {");
sb.append("\"title\":\"缺陷告警\",");
sb.append("\"text\": \"## 缺陷情况通告 \\n");
if (bugListDelayed.size() > 0) {
bugListDelayed = bugListDelayed.stream().sorted(Comparator.comparing(BugModel::getDisplayName))
.collect(Collectors.toList());
sb.append("### <font color=#dd0000>延期缺陷 :</font> \\n");
for (BugModel bugModel : bugListDelayed) {
String link = "[" + bugModel.getKey() + "_" + bugModel.getDisplayName() + "]" +
"(" + "https://jira.***.com/browse/" + bugModel.getKey() + ")";
sb.append("- 【" + link + "】 -> " + bugModel.getSummary() + "\\n");
}
}else {
sb.append("### <font color=#dd0000>延期缺陷 : 无</font> \\n");
}
//未设置期望日期的BUG列表
// if (bugListNoDueDate.size() > 0) {
// bugListNoDueDate = bugListNoDueDate.stream().sorted(Comparator.comparing(BugModel::getDisplayName)).collect(Collectors.toList());
// sb.append("\\n### <font color=#0000dd>未设置解决日期缺陷 :</font> \\n");
// for (BugModel bugModel : bugListNoDueDate) {
// String link = "[" + bugModel.getKey() + "_" + bugModel.getDisplayName() + "](" + "https://jira.tiduyun.com/browse/" + bugModel.getKey() + ")";
// sb.append("- 【" + link + "】 -> " + bugModel.getSummary() + "\\n");
// }
// }
sb.append("\"}}");
HttpResponse res = HttpRequest.post(webHook_DG)
.header("Authorization", auth)
.header(Header.CONTENT_TYPE, "application/json;charset=UTF-8")
.setEncodeUrlParams(true)
.body(sb.toString())
.timeout(30000).execute();
int status = res.getStatus();
// System.out.println(status);
// String body = res.body();
}
public static String httpGet(String url,String auth) {
HttpResponse res = HttpRequest.get(url)
.header("Authorization", auth)
.header(Header.CONTENT_TYPE, "application/json;charset=UTF-8")
.setEncodeUrlParams(true)
.timeout(30000).execute();
int status = res.getStatus();
// System.out.println(status);
String body = res.body();
return body;
}
@Data
@AllArgsConstructor
private static class BugModel {
private String key;
private String summary;
private String displayName;
/**
* 预期日期,没有为null
*/
private String dueDate;
/**
* 延期天数 没有为null
*/
private long between;
}
}