一、前提

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 }

  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 // 设置将被返回的Attribute
111 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 }

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

四、验证效果

JIRA对接钉钉群机器人-实现任务的指派通知的更多相关文章

  1. nodejs通过钉钉群机器人推送消息

    nodejs 通过钉钉群机器人推送消息 Intro 最近在用 nodejs 写爬虫,之前的 nodejs 爬虫代码用 js 写的,感觉可维护性太差,也没有智能提示,于是把js改用ts(typescri ...

  2. Zabbix通过与微信、钉钉整合实现实时告警

    abbix可以通过多种方式把告警信息发送到指定人,常用的有邮件,短信报警方式,但是越来越多的企业开始使用zabbix结合微信.钉钉作为主要的告警方式,这样可以及时有效的把告警信息推送到接收人,方便告警 ...

  3. Asp.Net Core对接钉钉群机器人

    钉钉作为企业办公越来越常用的软件,对于企业内部自研系统提供接口支持,以此来打通多平台下的数据,本次先使用最简单的钉钉群机器人完成多种形式的消息推送,参考钉钉开发文档中自定义机器人环节,此次尝试所花的时 ...

  4. Sentry快速开始并集成钉钉群机器人

    Sentry(直译为:哨兵)是一个开源错误跟踪服务,帮助开发人员实时监控和修复崩溃 Sentry本质上是一种帮助您实时监控和修复崩溃的服务 1.  安装客户端SDK 这里我们安装Java平台的SDK, ...

  5. yii2-dingtalk 钉钉群机器人

    说明 群机器人是钉钉群的高级扩展功能.群机器人可以将第三方服务的信息聚合到群聊中,实现自动化的信息同步.目前,大部分机器人在添加后,还需要进行Webhook配置,才可正常使用(配置说明详见操作流程中的 ...

  6. 怎么用python 3 开发钉钉群机器人

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:Python绿色通道 PS:如有需要Python学习资料的小伙伴可以加 ...

  7. 使用python3.7配置开发钉钉群自定义机器人(2020年新版攻略)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_132 最近疫情比较严重,很多公司依靠阿里旗下的办公软件钉钉来进行远程办公,当然了,钉钉这个产品真的是让人一言难尽,要多难用有多难用 ...

  8. python 小脚本升级-- 钉钉群聊天机器人

    一则小脚本(工作中用) 在这篇文章中写的监控的脚本,发送监控的时候 是利用的邮箱,其实在实际,邮箱查收有着不方便性,于是乎升级, 我们工作中,经常用钉钉,那么如果要是能用到钉钉多好,这样我们的监控成功 ...

  9. zabbix 配合钉钉群机器人(webhook) 报警

    首先建钉钉群,添加一个自定义机器人拿到webhook zabbix添加一个报警媒介 搞一个shell脚本来启动Python脚本(直接用zabbix调Python脚本不行,不知道什么原因) vim di ...

随机推荐

  1. Djang项目部署之sqlite版本升级

    项目环境: centos7 django 2.2.10 问题描述: 使用了django 2.2.12版本开发项目,此版本对应的sqlite需要升级为3.8.0以上. 百度了不少解决方案,缺点:过程繁琐 ...

  2. 【题解】Railway [Uva10263]

    [题解]Railway [Uva10263] 传送门:\(\text{Railway [Uva10263]}\) [题目描述] 给出点 \(M\) 以及一个由 \(n\) 条线段依次相连的类曲形图(由 ...

  3. JavaScript:常用的一些数组遍历的方法

    常用的一些遍历数组的方法: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  4. 使用git客户端免密码进行拉取等相关操作

    前言 如果使用git客户端进行pull或push操作时,遇到有权限的项目总要输入用户名密码,真的是太麻烦了,因此需要稍作修改,然后就可以免密码操作啦! 方法: 进入C盘->用户->你的主机 ...

  5. 10分钟快速入门vue.js

    Vue.js是一个轻巧.高性能.可组件化的MVVM库,一套用于构建用户界面的渐进式框架,上手简单,兼容强大. 官方文档:https://cn.vuejs.org/v2/guide/ 下面我们就直接来使 ...

  6. 手机版LED弹幕显示屏

    这是一款可以自制超大滚动字幕的LED显示屏APP.可以随你喜欢, 演唱会,电竞比赛,晚会,接机,寻人! 随时随地输入文字, 传达讯息,酒吧夜店疯狂打Call工具!蹦迪必备!超帅!下载地址:https: ...

  7. 三、TestNG的基本注解(1)

    Before类别和After类别注解 举例说明 创建两个TestNGAnnotationTest.java和TestNGAnnotationTest2.java的类 TestNGAnnotationT ...

  8. Java 8 新特性——实践篇

    Java 8 新特性--实践篇 参考 Java8新特性 重要更新:Lambda 表达式和Stream API Lambda 表达式 Lambda 表达式引入之前: 举个场景例子:当我们要对一个班级里的 ...

  9. 有了Git这个功能,再也不需要依赖IDE了!

    大家好,今天给大家介绍一个隐藏的功能--搜索. 我们在写代码的时候经常遇到的一种情况就是,我们想要知道某一个函数是怎么定义的,这样我们才能知道该如何调用它.如果代码少的话我们当然可以自己人肉查找,但是 ...

  10. docker 批量删除已经停止的容器

    长期操作导致大量的容器堆积,如何对这些没有用的容器进行批量删除: 命令如下 : Docker rm `docker ps -a |awk '{print $1}' | grep [0-9a-z]`