JIRA对接钉钉群机器人-实现任务的自定义格式指派通知

一、前提

Jira Software、钉钉群、RESTful服务、LDAP服务

二、流程图

三、对接步骤

1、创建项目群,把相关人员拉入群

2、钉钉群的智能群助手里添加自定义机器人

3、设置机器人,安全设置里建议勾选IP地址段,将RESTful服务所在的机器IP填入

4、注意创建完成后的Webhook地址,RESTful服务用这个地址发送通知消息,后面步骤要用上

5、RESTful服务新增一个POST接口,这里可以自定义通知内容,部署到服务器

1 @ApiOperation(value = "JIRA网络钩子") 2 @PostMapping("/jiraWebHook") 3 @ResponseBody 4 public Result<Boolean> jiraWebHook(HttpServletRequest request) { 5     BufferedReader br = null; 6     String str, wholeStr = ""; 7     try { 8         br = request.getReader(); 9 10         while ((str = br.readLine()) != null) {11             wholeStr += str;12         }13         log.info("jiraWebHook body: {}", wholeStr);14     } catch (Exception e) {15         log.error("jiraWebHook error", e);16     } finally {17         if (br != null) {18             try {19                 br.close();20             } catch (Exception e) {21             }22         }23     }24     return Result.success(JiraWebHookUtil.hook(JSONObject.parseObject(wholeStr, JiraPostData.class)));25 }

View Code

1 @Slf4j  2 public class JiraWebHookUtil {  3   4     private static final String DING_TALK_ROBOT_URL = "https://oapi.dingtalk.com/robot/send" +  5             "?access_token=xxxxxx";  6     private static final String JIRA_BASE_URL = "http://xxx.xxx.xxx.xxx:38080/browse/";  7     private static RestTemplate restTemplate = new RestTemplate();  8   9     public static boolean hook(JiraPostData postData){ 10         try { 11             if(postData != null){ 12                 if(StringUtils.equals(postData.getWebhookEvent(), "jira:issue_updated")){ 13                     //更新事件 14                     List<Item> items = postData.getChangelog().getItems(); 15                     String toUserId = Strings.EMPTY; 16                     String fromUserId = Strings.EMPTY; 17                     for(Item item : items){ 18                         if(StringUtils.equals(item.getField(), "assignee")){ 19                             toUserId = item.getTo(); 20                             fromUserId = item.getFrom(); 21                             break; 22                         } 23                     } 24                     if(StringUtils.isNotBlank(toUserId) && StringUtils.isNotBlank(fromUserId)){ 25                         String toMobile = getUserMobile(toUserId); 26                         String fromMobile = getUserMobile(fromUserId); 27                         if(StringUtils.isNotBlank(toMobile) && StringUtils.isNotBlank(fromMobile)){ 28                             String issueKey = postData.getIssue().getKey(); 29                             String issueSummary = postData.getIssue().getFields().getSummary(); 30                             DingTalkMarkdownMessage msg = new DingTalkMarkdownMessage(); 31                             msg.setMsgtype("markdown"); 32                             Markdown markdown = new Markdown(); 33                             markdown.setTitle(postData.getIssue().getKey()); 34                             markdown.setText("### @" + fromMobile + " 【转移任务给】@" + toMobile 35                                     + "\n>任务编号:[" + issueKey + "](" + JIRA_BASE_URL + issueKey + ")" 36                                     + "  \n任务标题:" + issueSummary); 37                             msg.setMarkdown(markdown); 38                             At at = new At(); 39                             at.setAtMobiles(Arrays.asList(toMobile, fromMobile)); 40                             msg.setAt(at); 41                             return sendMsgToDingTalk(JSONObject.toJSONString(msg)); 42                         } 43                     } 44                 }else if(StringUtils.equals(postData.getWebhookEvent(), "jira:issue_created")){ 45                     //创建事件 46                     String fromUserId = postData.getUser().getKey(); 47                     String toUserId = postData.getIssue().getFields().getAssignee().getKey(); 48                     if(StringUtils.isNotBlank(toUserId) && StringUtils.isNotBlank(fromUserId)){ 49                         String toMobile = getUserMobile(toUserId); 50                         String fromMobile = getUserMobile(fromUserId); 51                         if(StringUtils.isNotBlank(toMobile) && StringUtils.isNotBlank(fromMobile)){ 52                             String issueKey = postData.getIssue().getKey(); 53                             String issueSummary = postData.getIssue().getFields().getSummary(); 54                             DingTalkMarkdownMessage msg = new DingTalkMarkdownMessage(); 55                             msg.setMsgtype("markdown"); 56                             Markdown markdown = new Markdown(); 57                             markdown.setTitle(postData.getIssue().getKey()); 58                             markdown.setText("### @" + fromMobile + " 【指派任务给】@" + toMobile 59                                     + "\n>任务编号:[" + issueKey + "](" + JIRA_BASE_URL + issueKey + ")" 60                                     + "  \n任务标题:" + issueSummary); 61                             msg.setMarkdown(markdown); 62                             At at = new At(); 63                             at.setAtMobiles(Arrays.asList(toMobile, fromMobile)); 64                             msg.setAt(at); 65                             return sendMsgToDingTalk(JSONObject.toJSONString(msg)); 66                         } 67                     } 68                 } 69             } 70  71         }catch (Exception e) { 72             log.error("触发JIRA网络钩子失败", e); 73         } 74         return false; 75     } 76  77     private static boolean sendMsgToDingTalk(String msg){ 78         JSONObject postData = JSONObject.parseObject(msg); 79         JSONObject result = restTemplate.postForObject(DING_TALK_ROBOT_URL, postData, JSONObject.class); 80         if(result != null 81                 && result.getIntValue("errcode") == 0 82                 && StringUtils.equals(result.getString("errmsg"), "ok")){ 83             return true; 84         } 85         return false; 86     } 87  88     private static String getUserMobile(String userId){ 89         String mobile = Strings.EMPTY; 90  91         Hashtable<String, String> env = new Hashtable<String, String>(); 92         env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); 93         env.put(Context.PROVIDER_URL, "ldap://xxxxxx:389"); 94         env.put(Context.SECURITY_AUTHENTICATION, "simple"); 95         env.put(Context.SECURITY_PRINCIPAL, "cn=xxx,dc=xxx,dc=xxx,dc=com"); 96         env.put(Context.SECURITY_CREDENTIALS, "xxxxxx"); 97         DirContext ctx = null; 98         try{ 99             ctx = new InitialDirContext(env);100         }catch(Exception e){101             log.error("连接LDAP失败", e);102         }103 104         // 设置过滤条件105         String filter = "(&(objectClass=top)(objectClass=inetOrgPerson)(cn=" + userId + "))";106         // 限制要查询的字段内容107         String[] attrPersonArray = {"cn", "mobile"};108         SearchControls searchControls = new SearchControls();109         searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);110         // 设置将被返回的Attribute111         searchControls.setReturningAttributes(attrPersonArray);112         // 三个参数分别为:113         // 上下文;114         // 要搜索的属性,如果为空或 null,则返回目标上下文中的所有对象;115         // 控制搜索的搜索控件,如果为 null,则使用默认的搜索控件116         try {117             NamingEnumeration<SearchResult> answer = ctx.search(118                     "ou=People,dc=xxx,dc=xxx,dc=xxx", filter, searchControls);119             // 输出查到的数据120             while (answer.hasMore()) {121                 SearchResult result = answer.next();122                 Attribute attr = result.getAttributes().get("mobile");123                 mobile = attr.get().toString();124                 break;125             }126         }catch (Exception e){127             log.error("查询LDAP用户信息失败", e);128         }129         return mobile;130     }131 132 }

View Code

6、Jira Software配置网络钩子,使用第5步的接口地址

四、验证效果

(0)

相关推荐