通过XXL-JOB定时推送bug信息到企业微信群。
效果图
前提: 公司的Bug平台可以提供接口返回给你bug数据。
一、在企业微信群创建机器人
1、群右键创建机器人
2、拿到对应webhook.
二、XXLJOB平台准备
1、执行器管理-新建执行器
建议选自动注册,当代码持续运行后,会自动写入。当然直接写自己的ip也行。【公司一般都有xxl-job平台,没有就自己搭建下或者用公司的其他定时任务平台】
2、任务管理-执行器下新建job任务
代表每天的9,14,17,20点执行。
三、代码实现
1、引入依赖
自己找
xxl-job-core
arsenal.1.0.1.20200114.1-SNAPSHOT
2、配置xxl信息
加到这个文件里
application.properties
xxl.job.adminAddresses=xxljob域名或ip
xxl.job.appName=qa-bugs - 一定是你写的执行器地址。
xxl.job.accessToken=整个xxljob 就一个accesstoken
xxl.job.logPath=/data/applogs/xxl-job/jobhandler
xxl.job.logRetentionDays
如果是yaml 文件走这里
xxl:
job:
adminAddresses: xxljob域名或ip
appName: qa-bugs 一定是你写的执行器地址。
accessToken: 整个xxljob 就一个accesstoken
logPath: /data/applogs/xxl-job/jobhandler
logRetentionDays:
3、xxlconfig 实体类
@Data
@Configuration
@ConfigurationProperties(prefix = XxlJobConfig.XXL_JOB_CONFIG_PREFIX)
public class XxlJobConfig {
public static final String XXL_JOB_CONFIG_PREFIX = "xxl.job";
/**
* 调度中心地址
*/
private String adminAddresses ;
/**
* 对应执行器名称
*/
private String appName ;
private String ipe;
/**
* 本地连接端口
*/
private Integer port = 9999;
/**
* 访问token
*/
private String accessToken;
/**
* 服务端日志路径
*/
private String logPath = "/data/applogs/xxl-job/jobhandler";
/**
* 日志保留时间
*/
private Integer logRetentionDays = 60;
}
4、XXLJob配置处理类
@Configuration
public class XxlJobExecutorConfig {
@Resource
private XxlJobConfig xxlJobConfig;
@Bean(name = "xxlJobExecutor", initMethod = "start", destroyMethod = "destroy")
public XxlJobExecutor xxlJobExecutor() {
XxlJobExecutor xxlJobExecutor = new XxlJobExecutor();
BeanUtils.copyProperties(xxlJobConfig, xxlJobExecutor);
return xxlJobExecutor;
}
}
5、job执行类
JobHandler的value一定等于你在xxljob平台创建的jobHandler值【见下边的图】。
方法的入参s,可以从在xxljob平台创建的job的入参扔进来,如果你需要用的话。
@JobHandler(value = "bugsJob1")
@Component
public class BugStatisticsJob1 extends IJobHandler {
@Override
public ReturnT<String> execute(String s) throws Exception {
1、拿到要通知到群里的bug信息
2、通过webhook发到企业微信群
3、以下代码会定时执行,根据你在jobHandler里设置的时间点。
logger.info("------推送定时任务开始------");
return new ReturnT(responseObj.getHttpCode(), (String)null);
}
6、代码要写在能持续运行的项目里
比如基于Spring boot 搭建持续运行的测试平台,或者开发的持续运行代码里。
@JobHandler(value = “bugsJob”)
@Component
public class BugStatisticsJob extends IJobHandler {
public static String matrix_url = "http://xxx/sprint/bug/belong";
public static String robot_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=";
private Logger logger = LoggerFactory.getLogger(BugStatisticsJob2.class);
@Override
public ReturnT<String> execute(String s) throws Exception {
logger.info("------推送定时任务开始------");
//请求头
Map<String,String> headers = new HashMap<>();
headers.put("Content-Type","application/json");
headers.put("mtoken","35c674041d4022ad0eff320af07362af");
//请求数据
JSONObject jobParamStr = JSONObject.parseObject(s);
String key = jobParamStr.getString("robotkey");
JSONObject xxlStrParam = jobParamStr.getJSONObject("xxlStr");
String sprintId = xxlStrParam.getString("sprintId");
logger.info("---迭代sprintId ---- "+sprintId);
ResponseObj responseObj = TCHttpUtil.sendPostWithObjMap(matrix_url,headers,xxlStrParam);
Assert.assertEquals("matrix提供的接口出现问题",responseObj.getHttpCode(),200);
//数据结果
JSONObject bugResult = JSONObject.parseObject(responseObj.getResult()).getJSONObject("data");
String sprintName = bugResult.getString("sprintName");
String totalNum = bugResult.getString("total");
//内容
String content = "#### "+sprintName+"\n "+
" ##### 当前未完结bug数: <font color= \"info\">"+totalNum+"</font> \n ";
JSONArray resultArray = bugResult.getJSONArray("result");
//机器人推送
if(resultArray.size()>0){
//提醒人,拿到所有工号
ArrayList<String> remindNoList = new ArrayList<>();
for(int i = 0;i<resultArray.size();i++){
JSONObject bug = resultArray.getJSONObject(i);
int remindNum = bug.getIntValue("num");
String remindName = bug.getString("assigner").split("-")[0];
content = content.concat(" ###### #【"+remindName+"】待处理数: "+remindNum+" \n");
remindNoList.add(bug.getString("assigner").split("-")[1]);
}
String todayNum = bugResult.getString("totaytotal");
content = content.concat("##### 今日新建bug总数:<font color= \"warning\">"+todayNum+"</font> \n");
content = content.concat("[http://matrix.17usoft.com/#/sprint/"+sprintId+"/bug](http://matrix.17usoft.com/#/sprint/"+sprintId+"/bug)\n");
content = content.concat("为保证迭代上线,辛苦尽快处理bug流转\n");
for(String reminNo: remindNoList){
content = content.concat("<@"+reminNo+">");
}
}
Map<String,String> markdownMap = new HashMap<>();
markdownMap.put("content",content);
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("msgtype","markdown");
paramMap.put("markdown",markdownMap);
headers = new HashMap<>();
headers.put("Content-Type", "application/json");
responseObj = TCHttpUtil.sendPostWithObjMap(robot_url.concat(key),headers,paramMap);
System.out.println("机器人响应结果:"+ responseObj.getResult());
return new ReturnT(responseObj.getHttpCode(), (String)null);
}
}