Commit 217e146f authored by zhu-mingye's avatar zhu-mingye

add wechat webhook alertType

parent be52b5e8
...@@ -22,6 +22,14 @@ public class WeChatConstants { ...@@ -22,6 +22,14 @@ public class WeChatConstants {
static final String TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpId}&corpsecret={secret}"; static final String TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpId}&corpsecret={secret}";
static final String WEBHOOK = "webhook";
static final String WEBHOOK_TEMPLATE = "{\"msgtype\":\"{showType}\",\"{showType}\":{\"content\":\"{msg} \"}}";
static final String KEYWORD = "keyword";
static final String AT_ALL = "isAtAll";
static final String CORP_ID = "corpId"; static final String CORP_ID = "corpId";
static final String SECRET = "secret"; static final String SECRET = "secret";
......
package com.dlink.alert.wechat; package com.dlink.alert.wechat;
import com.dlink.alert.AlertException;
import com.dlink.alert.AlertResult; import com.dlink.alert.AlertResult;
import com.dlink.alert.AlertSendResponse; import com.dlink.alert.AlertSendResponse;
import com.dlink.alert.ShowType; import com.dlink.alert.ShowType;
...@@ -45,17 +44,24 @@ public class WeChatSender { ...@@ -45,17 +44,24 @@ public class WeChatSender {
private final String weChatToken; private final String weChatToken;
private final String sendType; private final String sendType;
private final String showType; private final String showType;
private final String webhookUrl;
private final String KeyWord ;
private final Boolean atAll;
WeChatSender(Map<String, String> config) { WeChatSender(Map<String, String> config) {
weChatAgentId = config.get(WeChatConstants.AGENT_ID);
weChatUsers = config.get(WeChatConstants.USERS);
String weChatCorpId = config.get(WeChatConstants.CORP_ID);
String weChatSecret = config.get(WeChatConstants.SECRET);
String weChatTokenUrl = WeChatConstants.TOKEN_URL;
weChatUserSendMsg = WeChatConstants.USER_SEND_MSG;
sendType = config.get(WeChatConstants.SEND_TYPE); sendType = config.get(WeChatConstants.SEND_TYPE);
weChatAgentId =sendType.equals(WeChatType.CHAT.getValue())? "" : config.get(WeChatConstants.AGENT_ID);
atAll = Boolean.valueOf(config.get(WeChatConstants.AT_ALL));
weChatUsers =sendType.equals(WeChatType.CHAT.getValue())?( atAll && config.get(WeChatConstants.USERS) == null ? "": config.get(WeChatConstants.USERS)): config.get(WeChatConstants.USERS);
String weChatCorpId = sendType.equals(WeChatType.CHAT.getValue())? "" :config.get(WeChatConstants.CORP_ID);
String weChatSecret = sendType.equals(WeChatType.CHAT.getValue())? "" :config.get(WeChatConstants.SECRET);
String weChatTokenUrl =sendType.equals(WeChatType.CHAT.getValue())? "" : WeChatConstants.TOKEN_URL;
weChatUserSendMsg = WeChatConstants.USER_SEND_MSG;
showType = config.get(WeChatConstants.SHOW_TYPE); showType = config.get(WeChatConstants.SHOW_TYPE);
requireNonNull(showType, WeChatConstants.SHOW_TYPE + " must not null"); requireNonNull(showType, WeChatConstants.SHOW_TYPE + " must not null");
webhookUrl= config.get(WeChatConstants.WEBHOOK);
KeyWord = config.get(WeChatConstants.KEYWORD);
if (sendType.equals(WeChatType.CHAT.getValue())) requireNonNull(webhookUrl, WeChatConstants.WEBHOOK + " must not null");
weChatTokenUrlReplace = weChatTokenUrl weChatTokenUrlReplace = weChatTokenUrl
.replace(CORP_ID_REGEX, weChatCorpId) .replace(CORP_ID_REGEX, weChatCorpId)
.replace(SECRET_REGEX, weChatSecret); .replace(SECRET_REGEX, weChatSecret);
...@@ -69,11 +75,27 @@ public class WeChatSender { ...@@ -69,11 +75,27 @@ public class WeChatSender {
if (Asserts.isNotNullString(weChatUsers)) { if (Asserts.isNotNullString(weChatUsers)) {
userList = Arrays.asList(weChatUsers.split(",")); userList = Arrays.asList(weChatUsers.split(","));
} }
String data = markdownByAlert(title, content); if(atAll){
String msg = weChatUserSendMsg.replace(USER_REG_EXP, mkString(userList)) userList.add("ALL");
.replace(AGENT_ID_REG_EXP, weChatAgentId).replace(MSG_REG_EXP, data) }
.replace(SHOW_TYPE_REGEX, showType);
if (Asserts.isNullString(weChatToken)) { String data ="";
if (sendType.equals(WeChatType.CHAT.getValue())) {
data = markdownByAlert(KeyWord, content ,userList);;
}else{
data = markdownByAlert(title, content, userList);
}
String msg ="";
if (sendType.equals(WeChatType.APP.getValue())) {
msg= weChatUserSendMsg.replace(USER_REG_EXP, mkUserString(userList))
.replace(AGENT_ID_REG_EXP, weChatAgentId).replace(MSG_REG_EXP, data)
.replace(SHOW_TYPE_REGEX, showType);
}else{
msg= WeChatConstants.WEBHOOK_TEMPLATE.replace(SHOW_TYPE_REGEX, showType)
.replace(MSG_REG_EXP, data);
}
if (sendType.equals(WeChatType.APP.getValue()) && Asserts.isNullString(weChatToken)) {
alertResult.setMessage("send we chat alert fail,get weChat token error"); alertResult.setMessage("send we chat alert fail,get weChat token error");
alertResult.setSuccess(false); alertResult.setSuccess(false);
return alertResult; return alertResult;
...@@ -81,8 +103,8 @@ public class WeChatSender { ...@@ -81,8 +103,8 @@ public class WeChatSender {
String enterpriseWeChatPushUrlReplace = ""; String enterpriseWeChatPushUrlReplace = "";
if (sendType.equals(WeChatType.APP.getValue())) { if (sendType.equals(WeChatType.APP.getValue())) {
enterpriseWeChatPushUrlReplace = WeChatConstants.PUSH_URL.replace(TOKEN_REGEX, weChatToken); enterpriseWeChatPushUrlReplace = WeChatConstants.PUSH_URL.replace(TOKEN_REGEX, weChatToken);
} else if (sendType.equals(WeChatType.APPCHAT.getValue())) { } else if (sendType.equals(WeChatType.CHAT.getValue())) {
enterpriseWeChatPushUrlReplace = WeChatConstants.APP_CHAT_PUSH_URL.replace(TOKEN_REGEX, weChatToken); enterpriseWeChatPushUrlReplace = webhookUrl;
} }
try { try {
return checkWeChatSendMsgResult(post(enterpriseWeChatPushUrlReplace, msg)); return checkWeChatSendMsgResult(post(enterpriseWeChatPushUrlReplace, msg));
...@@ -112,7 +134,18 @@ public class WeChatSender { ...@@ -112,7 +134,18 @@ public class WeChatSender {
} }
} }
private static String mkString(Iterable<String> list) {
private static String mkUserList(Iterable<String> list) {
StringBuilder sb = new StringBuilder("[");
for (String name : list) {
sb.append("\"").append(name).append("\",");
}
sb.deleteCharAt(sb.length() - 1);
sb.append("]");
return sb.toString();
}
private static String mkUserString(Iterable<String> list) {
if (Asserts.isNull(list)) { if (Asserts.isNull(list)) {
return null; return null;
} }
...@@ -129,22 +162,62 @@ public class WeChatSender { ...@@ -129,22 +162,62 @@ public class WeChatSender {
return sb.toString(); return sb.toString();
} }
private String markdownByAlert(String title, String content) { /**
*@Author: zhumingye
*@date: 2022/3/26
*@Description: 将用户列表转换为<@用户名> </@用户名>的格式
* @param userList
* @return java.lang.String
*/
private static String mkMarkDownAtUsers(List<String> userList){
StringBuilder builder = new StringBuilder();
if (Asserts.isNotNull(userList)) {
userList.forEach(value -> {
builder.append("<@").append(value).append("> ");
});
}
return builder.toString();
}
private String markdownByAlert(String title, String content,List<String> userList) {
String result = ""; String result = "";
if (showType.equals(ShowType.TABLE.getValue())) { if (showType.equals(ShowType.TABLE.getValue())) {
result = markdownTable(title, content); result = markdownTable(title, content,userList,sendType);
} else if (showType.equals(ShowType.TEXT.getValue())) { } else if (showType.equals(ShowType.TEXT.getValue())) {
result = markdownText(title, content); result = markdownText(title, content,userList,sendType);
} }
return result; return result;
} }
private static String markdownTable(String title, String content) { private static String markdownTable(String title, String content, List<String> userList, String sendType) {
return getMsgResult(title, content,userList,sendType);
}
private static String markdownText(String title, String content, List<String> userList, String sendType) {
return getMsgResult(title, content,userList,sendType);
}
/**
*@Author: zhumingye
*@date: 2022/3/25
*@Description: 创建公共方法 用于创建发送消息文本
* @param title 发送标题
* @param content 发送内容
* @param sendType
* @return java.lang.String
*@throws
*/
private static String getMsgResult(String title, String content, List<String> userList, String sendType) {
List<LinkedHashMap> mapItemsList = JSONUtil.toList(content, LinkedHashMap.class); List<LinkedHashMap> mapItemsList = JSONUtil.toList(content, LinkedHashMap.class);
if (null == mapItemsList || mapItemsList.isEmpty()) { if (null == mapItemsList || mapItemsList.isEmpty()) {
logger.error("itemsList is null"); logger.error("itemsList is null");
throw new RuntimeException("itemsList is null"); throw new RuntimeException("itemsList is null");
} }
String markDownAtUsers = mkMarkDownAtUsers(userList);
StringBuilder contents = new StringBuilder(200); StringBuilder contents = new StringBuilder(200);
for (LinkedHashMap mapItems : mapItemsList) { for (LinkedHashMap mapItems : mapItemsList) {
Set<Map.Entry<String, Object>> entries = mapItems.entrySet(); Set<Map.Entry<String, Object>> entries = mapItems.entrySet();
...@@ -160,34 +233,12 @@ public class WeChatSender { ...@@ -160,34 +233,12 @@ public class WeChatSender {
} }
contents.append(t); contents.append(t);
} }
if (sendType.equals(WeChatType.CHAT.getValue())) {
contents.append(markDownAtUsers);
}
return contents.toString(); return contents.toString();
} }
private static String markdownText(String title, String content) {
if (Asserts.isNotNullString(content)) {
List<LinkedHashMap> mapItemsList = JSONUtil.toList(content, LinkedHashMap.class);
if (null == mapItemsList || mapItemsList.isEmpty()) {
logger.error("itemsList is null");
throw new AlertException("itemsList is null");
}
StringBuilder contents = new StringBuilder(100);
contents.append(String.format("`%s`%n", title));
for (LinkedHashMap mapItems : mapItemsList) {
Set<Map.Entry<String, Object>> entries = mapItems.entrySet();
for (Map.Entry<String, Object> entry : entries) {
contents.append(WeChatConstants.MARKDOWN_QUOTE);
contents.append(entry.getKey()).append(":").append(entry.getValue());
contents.append(WeChatConstants.MARKDOWN_ENTER);
}
}
return contents.toString();
}
return null;
}
private String getToken() { private String getToken() {
......
...@@ -9,7 +9,7 @@ package com.dlink.alert.wechat; ...@@ -9,7 +9,7 @@ package com.dlink.alert.wechat;
public enum WeChatType { public enum WeChatType {
APP(1, "应用"), APP(1, "应用"),
APPCHAT(2, "群聊"); CHAT(2, "群聊");
private final int code; private final int code;
private final String value; private final String value;
......
...@@ -23,6 +23,7 @@ import org.junit.Assert; ...@@ -23,6 +23,7 @@ import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -59,15 +60,15 @@ public class WeChatSenderTest { ...@@ -59,15 +60,15 @@ public class WeChatSenderTest {
@Before @Before
public void initWeChatConfig() { public void initWeChatConfig() {
// Just for this test, I will delete these configurations before this PR is merged // Just for this test, I will delete these configurations before this PR is merged
weChatConfig.put(WeChatConstants.AGENT_ID, "AGENT_ID"); weChatConfig.put(WeChatConstants.AGENT_ID, "1000002");
weChatConfig.put(WeChatConstants.SECRET, "SECRET"); weChatConfig.put(WeChatConstants.SECRET, "V2w-9JDqSrF2wVW0eno6Vnrxbe6WZMHvO1Z1Hwj3JGg");
weChatConfig.put(WeChatConstants.CORP_ID, "CORP_ID"); weChatConfig.put(WeChatConstants.CORP_ID, "ww4ae244b25dda07cb");
weChatConfig.put(WeChatConstants.CHARSET, "UTF-8"); weChatConfig.put(WeChatConstants.CHARSET, "UTF-8");
weChatConfig.put(WeChatConstants.USER_SEND_MSG, "{\"touser\":\"{toUser}\",\"agentid\":{agentId}" weChatConfig.put(WeChatConstants.USER_SEND_MSG, "{\"touser\":\"{toUser}\",\"agentid\":{agentId}"
+ +
",\"msgtype\":\"{showType}\",\"{showType}\":{\"content\":\"{msg}\"}}" ",\"msgtype\":\"{showType}\",\"{showType}\":{\"content\":\"{msg}\"}}"
); );
weChatConfig.put(WeChatConstants.USERS, "USERS"); weChatConfig.put(WeChatConstants.USERS, "all");
weChatConfig.put(WeChatConstants.TEAM_SEND_MSG, "msg"); weChatConfig.put(WeChatConstants.TEAM_SEND_MSG, "msg");
weChatConfig.put(WeChatConstants.SHOW_TYPE, ShowType.TABLE.getValue());// default is "table" weChatConfig.put(WeChatConstants.SHOW_TYPE, ShowType.TABLE.getValue());// default is "table"
weChatConfig.put(WeChatConstants.SEND_TYPE, WeChatType.APP.getValue()); weChatConfig.put(WeChatConstants.SEND_TYPE, WeChatType.APP.getValue());
...@@ -76,17 +77,43 @@ public class WeChatSenderTest { ...@@ -76,17 +77,43 @@ public class WeChatSenderTest {
@Test @Test
public void testSendWeChatTableMsg() { public void testSendAPPMarkDownMsg() {
WeChatSender weChatSender = new WeChatSender(weChatConfig); WeChatSender weChatSender = new WeChatSender(weChatConfig);
AlertResult alertResult = weChatSender.send("TABLE-TEST", contentTest); AlertResult alertResult = weChatSender.send("Dlinky企微APP MarkDown方式 告警测试", contentTest);
Assert.assertEquals(true, alertResult.getSuccess()); Assert.assertEquals(true, alertResult.getSuccess());
} }
@Test @Test
public void testSendWeChatTextMsg() { public void testSendAPPTextMsg() {
weChatConfig.put(WeChatConstants.SHOW_TYPE, ShowType.TEXT.getValue()); weChatConfig.put(WeChatConstants.SHOW_TYPE, ShowType.TEXT.getValue());
WeChatSender weChatSender = new WeChatSender(weChatConfig); WeChatSender weChatSender = new WeChatSender(weChatConfig);
AlertResult alertResult = weChatSender.send("Dlinky企微APP TEXT方式 告警测试", contentTest);
Assert.assertEquals(true, alertResult.getSuccess());
}
@Test
public void testChatMarkDownMsg() throws IOException {
weChatConfig.put(WeChatConstants.WEBHOOK, "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=822d17a1-d6e5-43c2-a566-4846fe13396c");
weChatConfig.put(WeChatConstants.SEND_TYPE, WeChatType.CHAT.getValue());
weChatConfig.put(WeChatConstants.USER_SEND_MSG,WeChatConstants.WEBHOOK_TEMPLATE);
weChatConfig.put(WeChatConstants.SHOW_TYPE, ShowType.TABLE.getValue());
weChatConfig.put(WeChatConstants.KEYWORD, "Dlinky企微WEBHOOK MarkDown方式 告警测试");
WeChatSender weChatSender = new WeChatSender(weChatConfig);
AlertResult alertResult = weChatSender.send("TEXT-TEST", contentTest);
Assert.assertEquals(true, alertResult.getSuccess());
}
@Test
public void testChatTextMsg() throws IOException {
weChatConfig.put(WeChatConstants.WEBHOOK, "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=822d17a1-d6e5-43c2-a566-4846fe13396c");
weChatConfig.put(WeChatConstants.SEND_TYPE, WeChatType.CHAT.getValue());
weChatConfig.put(WeChatConstants.USER_SEND_MSG,WeChatConstants.WEBHOOK_TEMPLATE);
weChatConfig.put(WeChatConstants.SHOW_TYPE, ShowType.TEXT.getValue());
weChatConfig.put(WeChatConstants.KEYWORD, "Dlinky企微WEBHOOK TEXT方式 告警测试");
WeChatSender weChatSender = new WeChatSender(weChatConfig);
AlertResult alertResult = weChatSender.send("TEXT-TEST", contentTest); AlertResult alertResult = weChatSender.send("TEXT-TEST", contentTest);
Assert.assertEquals(true, alertResult.getSuccess()); Assert.assertEquals(true, alertResult.getSuccess());
} }
} }
...@@ -54,6 +54,52 @@ const WeChatForm: React.FC<AlertInstanceFormProps> = (props) => { ...@@ -54,6 +54,52 @@ const WeChatForm: React.FC<AlertInstanceFormProps> = (props) => {
> >
<Input placeholder="请输入名称"/> <Input placeholder="请输入名称"/>
</Form.Item> </Form.Item>
<Form.Item
name="sendType"
label="发送方式"
validateTrigger={['onChange', 'onBlur']}
rules={[{required: true, message: '请输入发送方式!'}]}
>
<Radio.Group defaultValue="应用">
<Radio value='应用'>应用</Radio>
<Radio value='群聊'>群聊</Radio>
</Radio.Group>
</Form.Item>
{ (formVals.sendType === "群聊") &&
<>
<Form.Item
name="webhook"
label="WebHook地址"
rules={[{required: true, message: '请输入WebHook!',}]}
>
<Input placeholder="请输入WebHook"/>
</Form.Item>
<Form.Item
name="keyword"
label="关键字"
>
<Input placeholder="请输入keyword"/>
</Form.Item>
<Form.Item
name="isAtAll"
validateTrigger={['onChange', 'onBlur']}
label="@所有人">
<Switch checkedChildren="启用" unCheckedChildren="禁用"
defaultChecked={formVals.isAtAll}/>
</Form.Item>
{ ( formVals.sendType === "群聊" && formVals.isAtAll===false )&&
<Form.Item
name="users"
label="被@用户"
rules={[{required: true, message: '请输入被@用户!多个逗号隔开!',}]}
>
<Input placeholder="请输入被@用户ID(企微用户名全拼),多个逗号隔开!"/>
</Form.Item>
}
</>
}
{ formVals.sendType === "应用" &&
<>
<Form.Item <Form.Item
name="corpId" name="corpId"
label="企业Id" label="企业Id"
...@@ -89,16 +135,8 @@ const WeChatForm: React.FC<AlertInstanceFormProps> = (props) => { ...@@ -89,16 +135,8 @@ const WeChatForm: React.FC<AlertInstanceFormProps> = (props) => {
> >
<Input placeholder="请输入代理ID"/> <Input placeholder="请输入代理ID"/>
</Form.Item> </Form.Item>
<Form.Item </>
name="sendType" }
label="发送方式"
rules={[{required: true, message: '请输入发送方式!'}]}
>
<Radio.Group >
<Radio value='应用'>应用</Radio>
<Radio value='群聊'>群聊</Radio>
</Radio.Group>
</Form.Item>
<Form.Item <Form.Item
name="showType" name="showType"
label="展示方式" label="展示方式"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment