feat: 添加钉钉工作通知器
This commit is contained in:
parent
8340b9bd34
commit
957245ed99
@ -9,7 +9,8 @@ public enum DefaultNotifyType implements NotifyType {
|
|||||||
|
|
||||||
email("邮件"),
|
email("邮件"),
|
||||||
sms("短信"),
|
sms("短信"),
|
||||||
wechat("微信");
|
wechat("微信"),
|
||||||
|
dingTalk("钉钉");
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
|
45
notify-dingtalk/pom.xml
Normal file
45
notify-dingtalk/pom.xml
Normal 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>
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
// }
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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<>());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user