一直想研究一下钉钉机器人是怎么实现,上午正好有事情,研究了一下,特此记录。
首先是maven依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.13</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>${httpclient.version}</version> </dependency>
还要获取钉钉机器人的 webhook,创建群组,点击设置->智能群助手->添加机器人->自定义机器人
然后就可以获取到了
这里先搞了一个处理类,只写了运行异常的处理,也可以自行处理别的异常
/**
* 异常处理类
*/
@Slf4j
@RestControllerAdvice
public class CustomExceptionHandler {
@Value("${dingTalk.enabled}")
private Boolean enabled;
@Autowired
private DingUtil dingUtil;
@ExceptionHandler(RuntimeException.class)
public JsonData exceptionHandler(RuntimeException e) {
e.printStackTrace();
log.error(ExceptionUtils.getStackTrace(e));
if(enabled){
dingUtil.sendToDingTalk(getLogErrorMessage(e));
}
return JsonData.buildError("系统运行异常!");
}
/**
* 获取到异常描述
*
* @param e 异常
* @return "异常类名:异常信息
* at 异常位置"
*/
private String getLogErrorMessage(Exception e) {
String errorMessage = e.getClass().getSimpleName() + ":" + e.getMessage() + " \n ";
errorMessage = errorMessage + " at " + e.getStackTrace()[0];
return errorMessage;
}
}
然后就是钉钉机器人的推送了
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Slf4j
@Component
public class DingUtil {
@Value("${dingTalk.accessToken}")
private String accessToken;
@Value("${dingTalk.url}")
private String url;
private static String key_word = "业务报警:[ 系统异常 ] ";
public void sendToDingTalk(String content){
try {
//钉钉机器人地址
String dingUrl = url+"?access_token="+accessToken;
//是否通知所有人
boolean isAtAll = true;
//通知具体人的手机号码列表
List<String> mobileList = Lists.newArrayList();
// mobileList.add("186****0013");
//钉钉机器人消息内容
content = key_word + content;
//组装请求内容
String reqStr = buildReqStr(content, isAtAll, mobileList);
//推送消息(http请求)
String result = postJson(dingUrl, reqStr);
}catch (Exception e){
e.printStackTrace();
log.error("钉钉推送消息异常{}",e.getMessage());
}
}
/**
* 组装请求报文
* @param content
* @return
*/
private static String buildReqStr(String content, boolean isAtAll, List<String> mobileList) {
//消息内容
Map<String, String> contentMap = Maps.newHashMap();
contentMap.put("content", content);
//通知人
Map<String, Object> atMap = Maps.newHashMap();
//1.是否通知所有人
atMap.put("isAtAll", isAtAll);
//2.通知具体人的手机号码列表
atMap.put("atMobiles", mobileList);
Map<String, Object> reqMap = Maps.newHashMap();
reqMap.put("msgtype", "text");
reqMap.put("text", contentMap);
reqMap.put("at", atMap);
return JSON.toJSONString(reqMap);
}
/**
* 请求钉钉接口
* @param url
* @param body
* @return
*/
public static String postJson(String url, String body) {
// 创建Httpclient对象
CloseableHttpClient httpClient = createCustomClient();
CloseableHttpResponse response = null;
String resultString = null;
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Content-Type", "application/json");
if (body != null) {
httpPost.setEntity(new StringEntity(body, "utf-8"));
}
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return resultString;
}
/**
* 创建http连接池
* @return
*/
public static CloseableHttpClient createCustomClient() {
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setSocketTimeout(120 * 1000)
.setConnectTimeout(120 * 1000)
.setConnectionRequestTimeout(120 * 1000)
.setStaleConnectionCheckEnabled(true)
.build();
return HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
}
}
本来想把下面两个方法合并起来呢,但是有需求来了,所以就到凑合用吧,然后给出结果图
如果写入具体的手机号,就会@指定的人
如果开启isAtAll为true,就会@所有人啦