diff --git a/notify-core/src/main/java/com/cicdi/notify/DefaultNotifyType.java b/notify-core/src/main/java/com/cicdi/notify/DefaultNotifyType.java
index a61a3dd..ac34440 100644
--- a/notify-core/src/main/java/com/cicdi/notify/DefaultNotifyType.java
+++ b/notify-core/src/main/java/com/cicdi/notify/DefaultNotifyType.java
@@ -9,7 +9,8 @@ public enum DefaultNotifyType implements NotifyType {
email("邮件"),
sms("短信"),
- wechat("微信");
+ wechat("微信"),
+ dingTalk("钉钉");
private final String name;
diff --git a/notify-dingtalk/pom.xml b/notify-dingtalk/pom.xml
new file mode 100644
index 0000000..a3c0da9
--- /dev/null
+++ b/notify-dingtalk/pom.xml
@@ -0,0 +1,45 @@
+
+
+
+ notify
+ com.cicdi
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ notify-dingtalk
+
+
+ 8
+ 8
+
+
+
+
+ com.cicdi
+ notify-core
+ 1.0-SNAPSHOT
+
+
+ com.alibaba
+ fastjson
+ 1.2.73
+ compile
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.12
+ compile
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+
\ No newline at end of file
diff --git a/notify-dingtalk/src/main/java/com/cicdi/notify/dingtalk/DingTalkMessageTemplate.java b/notify-dingtalk/src/main/java/com/cicdi/notify/dingtalk/DingTalkMessageTemplate.java
new file mode 100644
index 0000000..678fa91
--- /dev/null
+++ b/notify-dingtalk/src/main/java/com/cicdi/notify/dingtalk/DingTalkMessageTemplate.java
@@ -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 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 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 context) {
+ if (null == userIdList || "".equals(userIdList)) {
+ return userIdList;
+ }
+// return ExpressionUtils.analytical(userIdList, context, "spel");
+ return userIdList;
+ }
+
+ public String createDepartmentIdList(Map context) {
+ if (null == departmentIdList || "".equals(departmentIdList)) {
+ return departmentIdList;
+ }
+ return departmentIdList;
+// return ExpressionUtils.analytical(departmentIdList, context, "spel");
+ }
+
+ public JSONObject createMessage(Map 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;
+ }
+
+}
diff --git a/notify-dingtalk/src/main/java/com/cicdi/notify/dingtalk/DingTalkNotifier.java b/notify-dingtalk/src/main/java/com/cicdi/notify/dingtalk/DingTalkNotifier.java
new file mode 100644
index 0000000..abe311a
--- /dev/null
+++ b/notify-dingtalk/src/main/java/com/cicdi/notify/dingtalk/DingTalkNotifier.java
@@ -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 {
+
+ private final AtomicReference 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 context) {
+ CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+ List 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 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;
+ }
+}
diff --git a/notify-dingtalk/src/main/java/com/cicdi/notify/dingtalk/DingTalkNotifierProvider.java b/notify-dingtalk/src/main/java/com/cicdi/notify/dingtalk/DingTalkNotifierProvider.java
new file mode 100644
index 0000000..f44f3f1
--- /dev/null
+++ b/notify-dingtalk/src/main/java/com/cicdi/notify/dingtalk/DingTalkNotifierProvider.java
@@ -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;
+// }
+}
diff --git a/notify-dingtalk/src/main/java/com/cicdi/notify/dingtalk/DingTalkProperties.java b/notify-dingtalk/src/main/java/com/cicdi/notify/dingtalk/DingTalkProperties.java
new file mode 100644
index 0000000..00d3990
--- /dev/null
+++ b/notify-dingtalk/src/main/java/com/cicdi/notify/dingtalk/DingTalkProperties.java
@@ -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;
+ }
+}
diff --git a/notify-dingtalk/src/main/java/com/cicdi/notify/dingtalk/DingTalkProvider.java b/notify-dingtalk/src/main/java/com/cicdi/notify/dingtalk/DingTalkProvider.java
new file mode 100644
index 0000000..d7017d0
--- /dev/null
+++ b/notify-dingtalk/src/main/java/com/cicdi/notify/dingtalk/DingTalkProvider.java
@@ -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;
+ }
+
+}
diff --git a/notify-dingtalk/src/test/java/com/cicdi/notify/dingtalk/DingTalkTest.java b/notify-dingtalk/src/test/java/com/cicdi/notify/dingtalk/DingTalkTest.java
new file mode 100644
index 0000000..85c15d8
--- /dev/null
+++ b/notify-dingtalk/src/test/java/com/cicdi/notify/dingtalk/DingTalkTest.java
@@ -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 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 notifier = notifierManager.getNotifier(DefaultNotifyType.dingTalk, "123");
+ notifier.send(templateManager.getTemplate(DefaultNotifyType.dingTalk, "124"), new HashMap<>());
+ }
+}
diff --git a/pom.xml b/pom.xml
index f37e772..5679be1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,6 +13,7 @@
notify-email
notify-sms
notify-wechat
+ notify-dingtalk