feat: 添加钉钉工作通知器

This commit is contained in:
椰子 2021-07-03 01:05:08 +08:00
parent 8340b9bd34
commit 957245ed99
9 changed files with 492 additions and 1 deletions

View File

@ -9,7 +9,8 @@ public enum DefaultNotifyType implements NotifyType {
email("邮件"),
sms("短信"),
wechat("微信");
wechat("微信"),
dingTalk("钉钉");
private final String name;

45
notify-dingtalk/pom.xml Normal file
View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>notify</artifactId>
<groupId>com.cicdi</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>notify-dingtalk</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.cicdi</groupId>
<artifactId>notify-core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.12</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,123 @@
package com.cicdi.notify.dingtalk;
import com.alibaba.fastjson.JSONObject;
import com.cicdi.notify.template.Template;
import java.util.Collections;
import java.util.Map;
/**
* 钉钉消息通知模板
*
* @author xueye
*/
public class DingTalkMessageTemplate implements Template {
/**
* 应用ID
*/
private String agentId;
private String userIdList;
private String departmentIdList;
private boolean toAllUser;
private String message;
public String getAgentId() {
return agentId;
}
public void setAgentId(String agentId) {
this.agentId = agentId;
}
public String getUserIdList() {
return userIdList;
}
public void setUserIdList(String userIdList) {
this.userIdList = userIdList;
}
public String getDepartmentIdList() {
return departmentIdList;
}
public void setDepartmentIdList(String departmentIdList) {
this.departmentIdList = departmentIdList;
}
public boolean isToAllUser() {
return toAllUser;
}
public void setToAllUser(boolean toAllUser) {
this.toAllUser = toAllUser;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String createFormInserter(Map<String, Object> context) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("agent_id", this.getAgentId());
jsonObject.put("to_all_user", this.toAllUser);
jsonObject.put("msg", createMessage(context));
if (null != userIdList && !"".equals(userIdList)) {
jsonObject.put("userid_list", createUserIdList(context));
}
if (null != departmentIdList && !"".equals(departmentIdList)) {
jsonObject.put("dept_id_list", createDepartmentIdList(context));
}
return jsonObject.toJSONString();
}
// public UriComponentsBuilder createUriParameter(UriComponentsBuilder builder, Map<String, Object> context) {
// builder.queryParam("agent_id", this.getAgentId())
// .queryParam("to_all_user", String.valueOf(toAllUser))
// .queryParam("msg", this.createMessage(context));
// if (StringUtils.hasText(userIdList)) {
// builder.queryParam("userid_list", this.createUserIdList(context));
// }
// if (StringUtils.hasText(departmentIdList)) {
// builder.queryParam("dept_id_list", this.createDepartmentIdList(context));
// }
// return builder;
// }
public String createUserIdList(Map<String, Object> context) {
if (null == userIdList || "".equals(userIdList)) {
return userIdList;
}
// return ExpressionUtils.analytical(userIdList, context, "spel");
return userIdList;
}
public String createDepartmentIdList(Map<String, Object> context) {
if (null == departmentIdList || "".equals(departmentIdList)) {
return departmentIdList;
}
return departmentIdList;
// return ExpressionUtils.analytical(departmentIdList, context, "spel");
}
public JSONObject createMessage(Map<String, Object> context) {
JSONObject json = new JSONObject();
json.put("msgtype", "text");
json.put("text", Collections.singletonMap("content", message));
// json.put("text", Collections.singletonMap("content", ExpressionUtils.analytical(message, context.getAllValues(), "spel")));
String s = json.toJSONString();
// return json.toJSONString();
return json;
}
}

View File

@ -0,0 +1,130 @@
package com.cicdi.notify.dingtalk;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cicdi.notify.AbstractNotifier;
import com.cicdi.notify.DefaultNotifyType;
import com.cicdi.notify.NotifyType;
import com.cicdi.notify.Provider;
import com.cicdi.notify.template.TemplateManager;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.net.URISyntaxException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
public class DingTalkNotifier extends AbstractNotifier<DingTalkMessageTemplate> {
private final AtomicReference<String> accessToken = new AtomicReference<>();
private long refreshTokenTime;
private final long tokenTimeOut = Duration.ofSeconds(7000).toMillis();
private static final String tokenApi = "https://oapi.dingtalk.com/gettoken";
private static final String notifyApi = "https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2";
private final DingTalkProperties properties;
private final String notifierId;
@Override
public String getNotifierId() {
return notifierId;
}
public DingTalkNotifier(String id, DingTalkProperties properties, TemplateManager templateManager) {
super(templateManager);
this.properties = properties;
this.notifierId = id;
}
@Override
public NotifyType getType() {
return DefaultNotifyType.dingTalk;
}
@Override
public Provider getProvider() {
return DingTalkProvider.dingTalkMessage;
}
@Override
public void send(DingTalkMessageTemplate template, Map<String, Object> context) {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("access_token", getToken()));
try {
HttpPost httpPost = new HttpPost(new URIBuilder(notifyApi).setParameters(params).build());
String formInserter = template.createFormInserter(context);
StringEntity entity = new StringEntity(template.createFormInserter(context));
httpPost.setEntity(entity);
CloseableHttpResponse response = httpClient.execute(httpPost);
JSONObject responseJson = JSON.parseObject(EntityUtils.toString(response.getEntity()));
System.out.println(responseJson);
} catch (URISyntaxException | IOException e) {
e.printStackTrace();
}
}
private void checkResult(String msg) {
if ("0".equals(msg)) {
// log.info("发送钉钉通知成功");
} else {
// log.warn("发送钉钉通知失败:{}", map);
// throw new BusinessException("发送钉钉通知失败:" + map.get("errmsg"), code);
}
}
private String getToken() {
if (System.currentTimeMillis() - refreshTokenTime > tokenTimeOut || accessToken.get() == null) {
return requestToken();
}
return accessToken.get();
}
private String requestToken() {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("appkey", properties.getAppKey()));
params.add(new BasicNameValuePair("appsecret", properties.getAppSecret()));
try {
HttpGet httpGet = new HttpGet(new URIBuilder(tokenApi).setParameters(params).build());
CloseableHttpResponse response = httpClient.execute(httpGet);
JSONObject responseJson = JSON.parseObject(EntityUtils.toString(response.getEntity()));
if (responseJson.containsKey("access_token")) {
String access_token = responseJson.get("access_token").toString();
refreshTokenTime = System.currentTimeMillis();
accessToken.set(access_token);
return access_token;
} else {
// throw new BusinessException("获取Token失败:" + map.get("errmsg"), String.valueOf(map.get("errcode")));
}
} catch (URISyntaxException | IOException e) {
e.printStackTrace();
}
return null;
}
@Override
public void close() {
accessToken.set(null);
refreshTokenTime = 0;
}
}

View File

@ -0,0 +1,65 @@
package com.cicdi.notify.dingtalk;
import com.alibaba.fastjson.JSON;
import com.cicdi.notify.*;
import com.cicdi.notify.template.TemplateManager;
import com.cicdi.notify.template.TemplateProperties;
import com.cicdi.notify.template.TemplateProvider;
import java.util.Objects;
public class DingTalkNotifierProvider implements NotifierProvider, TemplateProvider {
private final TemplateManager templateManager;
public DingTalkNotifierProvider(TemplateManager templateManager) {
this.templateManager = templateManager;
}
// public static final DefaultConfigMetadata notifierConfig = new DefaultConfigMetadata("通知配置", "")
// .add("appKey", "appKey", "", new StringType().expand(ConfigMetadataConstants.required.value(true)))
// .add("appSecret", "appSecret", "", new StringType());
//
// public static final DefaultConfigMetadata templateConfig = new DefaultConfigMetadata("模版配置", "")
// .add("agentId", "应用ID", "", new StringType().expand(ConfigMetadataConstants.required.value(true)))
// .add("userIdList", "收信人ID", "与部门ID不能同时为空", new StringType())
// .add("departmentIdList", "收信部门ID", "与收信人ID不能同时为空", new StringType())
// .add("toAllUser", "全部用户", "推送到全部用户", new BooleanType())
// .add("message", "内容", "最大不超过500字", new StringType().expand(ConfigMetadataConstants.maxLength.value(500L)));
@Override
public NotifyType getType() {
return DefaultNotifyType.dingTalk;
}
@Override
public Provider getProvider() {
return DingTalkProvider.dingTalkMessage;
}
@Override
public DingTalkMessageTemplate createTemplate(TemplateProperties properties) {
// return ValidatorUtils.tryValidate(JSON.parseObject(properties.getTemplate(), DingTalkMessageTemplate.class));
return JSON.parseObject(properties.getTemplate(), DingTalkMessageTemplate.class);
}
@Override
public DingTalkNotifier createNotifier(NotifierProperties properties) {
DingTalkProperties dingTalkProperties = new DingTalkProperties();
dingTalkProperties.setAppKey((String) Objects.requireNonNull(properties.getConfiguration().get("appKey"), "appKey不能为空"));
dingTalkProperties.setAppSecret((String) Objects.requireNonNull(properties.getConfiguration().get("appSecret"), "appSecret不能为空"));
return new DingTalkNotifier(properties.getId(), dingTalkProperties, templateManager);
// return new DingTalkNotifier(properties.getId(), ValidatorUtils.tryValidate(dingTalkProperties), templateManager);
}
// @Override
// public ConfigMetadata getNotifierConfigMetadata() {
// return notifierConfig;
// }
//
// @Override
// public ConfigMetadata getTemplateConfigMetadata() {
// return templateConfig;
// }
}

View File

@ -0,0 +1,29 @@
package com.cicdi.notify.dingtalk;
/**
* 钉钉通知属性
*
* @author xueye
*/
public class DingTalkProperties {
private String appKey;
private String appSecret;
public String getAppKey() {
return appKey;
}
public void setAppKey(String appKey) {
this.appKey = appKey;
}
public String getAppSecret() {
return appSecret;
}
public void setAppSecret(String appSecret) {
this.appSecret = appSecret;
}
}

View File

@ -0,0 +1,30 @@
package com.cicdi.notify.dingtalk;
import com.cicdi.notify.Provider;
/**
* 钉钉通知提供商
*
* @author xueye
*/
public enum DingTalkProvider implements Provider {
dingTalkMessage("钉钉消息通知");
private final String name;
DingTalkProvider(String name) {
this.name = name;
}
@Override
public String getId() {
return name();
}
@Override
public String getName() {
return name;
}
}

View File

@ -0,0 +1,67 @@
package com.cicdi.notify.dingtalk;
import com.alibaba.fastjson.JSONObject;
import com.cicdi.notify.*;
import com.cicdi.notify.template.AbstractTemplateManager;
import com.cicdi.notify.template.Template;
import com.cicdi.notify.template.TemplateManager;
import com.cicdi.notify.template.TemplateProperties;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
/**
* @author xueye
*/
public class DingTalkTest {
@Test
public void test() {
// 通知器配置管理器
NotifyConfigManager notifyConfigManager = (notifyType, configId) -> {
NotifierProperties notifierProperties = new NotifierProperties();
notifierProperties.setType(DefaultNotifyType.dingTalk.getId());
notifierProperties.setProvider(DingTalkProvider.dingTalkMessage.getId());
notifierProperties.setId("12");
Map<String, Object> config = new HashMap<>();
config.put("appKey", "dinga5vkkpbrwqc0fmni");
config.put("appSecret", "ARsEfA8CQ7RxJabEW1TecTeEItTamK3GQ8-TfWTHAydF7gQK16N23UuN9y2E9raq");
notifierProperties.setConfiguration(config);
return notifierProperties;
};
// 模板管理器
TemplateManager templateManager = new AbstractTemplateManager() {
@Override
protected TemplateProperties getProperties(NotifyType type, String id) {
TemplateProperties templateProperties = new TemplateProperties();
templateProperties.setType(DefaultNotifyType.dingTalk.getId());
templateProperties.setProvider(DingTalkProvider.dingTalkMessage.getId());
JSONObject jsonObject = new JSONObject();
jsonObject.put("agentId", "1211676948");
jsonObject.put("userIdList", "manager276");
jsonObject.put("departmentIdList", "");
jsonObject.put("toAllUser", "false");
jsonObject.put("message", "Hello World!");
templateProperties.setTemplate(jsonObject.toJSONString());
return templateProperties;
}
};
NotifierManager notifierManager = new DefaultNotifierManager(notifyConfigManager);
// register
DingTalkNotifierProvider provider = new DingTalkNotifierProvider(templateManager);
notifierManager.registerProvider(provider);
templateManager.register(provider);
Notifier<Template> notifier = notifierManager.getNotifier(DefaultNotifyType.dingTalk, "123");
notifier.send(templateManager.getTemplate(DefaultNotifyType.dingTalk, "124"), new HashMap<>());
}
}

View File

@ -13,6 +13,7 @@
<module>notify-email</module>
<module>notify-sms</module>
<module>notify-wechat</module>
<module>notify-dingtalk</module>
</modules>
<properties>