接入 钉钉群 自定义机器儿

pull/6/head
3y 2 years ago
parent 87454c47e8
commit 9200ad3efb

@ -14,7 +14,6 @@ public class AustinConstant {
public final static Integer TRUE = 1;
public final static Integer FALSE = 0;
/**
* cron
*/
@ -35,4 +34,24 @@ public class AustinConstant {
public final static Integer BUSINESS_ID_LENGTH = 16;
/**
*
* ( )
* ()
*
*/
public static final String SEND_ALL = "@all";
/**
*
*/
public static final String HMAC_SHA256_ENCRYPTION_ALGO = "HmacSHA256";
/**
*
*/
public static final String CHARSET_NAME = "UTF-8";
}

@ -0,0 +1,19 @@
package com.java3y.austin.common.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author 3y
*
* https://open.dingtalk.com/document/group/custom-robot-access
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class DingDingContentModel extends ContentModel {
private String content;
}

@ -7,7 +7,7 @@ import lombok.NoArgsConstructor;
/**
* @author 3y
*
*
*/
@Data
@Builder

@ -24,6 +24,8 @@ public enum ChannelType {
OFFICIAL_ACCOUNT(50, "OfficialAccounts(服务号)", OfficialAccountsContentModel.class, "official_accounts"),
MINI_PROGRAM(60, "miniProgram(小程序)", MiniProgramContentModel.class, "mini_program"),
ENTERPRISE_WE_CHAT(70, "EnterpriseWeChat(企业微信)", EnterpriseWeChatContentModel.class, "enterprise_we_chat"),
DING_DING_ROBOT(80, "dingDingRobot(钉钉机器人)", DingDingContentModel.class, "ding_ding_robot"),
;
/**

@ -20,6 +20,7 @@ public enum IdType {
OPEN_ID(40, "openId"),
EMAIL(50, "email"),
ENTERPRISE_USER_ID(60, "enterprise_user_id"),
DING_DING_USER_ID(70, "ding_ding_user_id"),
;
private Integer code;

@ -5,14 +5,14 @@ import lombok.Getter;
import lombok.ToString;
/**
*
* //
*
* @author 3y
*/
@Getter
@ToString
@AllArgsConstructor
public enum WechatMessageType {
public enum SendMessageType {
TEST(10, "文本"),
VOICE(20, "语音"),

@ -0,0 +1,31 @@
package com.java3y.austin.handler.domain.dingding;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*
*
* @author 3y
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class DingDingRobotAccount {
/**
*
*/
private String secret;
/**
* webhook
*/
private String webhook;
}

@ -0,0 +1,204 @@
package com.java3y.austin.handler.domain.dingding;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
*
*
* https://open.dingtalk.com/document/group/custom-robot-access
*
* @author 3y
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class DingDingRobotParam {
/**
* at
*/
private AtVO at;
/**
* text
*/
private TextVO text;
/**
* link
*/
private LinkVO link;
/**
* markdown
*/
private MarkdownVO markdown;
/**
* actionCard
*/
private ActionCardVO actionCard;
/**
* feedCard
*/
private FeedCardVO feedCard;
/**
* msgtype
*/
private String msgtype;
/**
* AtVO
*/
@NoArgsConstructor
@Data
@Builder
@AllArgsConstructor
public static class AtVO {
/**
* atMobiles
*/
private List<String> atMobiles;
/**
* atUserIds
*/
private List<String> atUserIds;
/**
* isAtAll
*/
private Boolean isAtAll;
}
/**
* TextVO
*/
@NoArgsConstructor
@Data
@Builder
@AllArgsConstructor
public static class TextVO {
/**
* content
*/
private String content;
}
/**
* LinkVO
*/
@NoArgsConstructor
@Data
@AllArgsConstructor
public static class LinkVO {
/**
* text
*/
private String text;
/**
* title
*/
private String title;
/**
* picUrl
*/
private String picUrl;
/**
* messageUrl
*/
private String messageUrl;
}
/**
* MarkdownVO
*/
@NoArgsConstructor
@Data
@AllArgsConstructor
public static class MarkdownVO {
/**
* title
*/
private String title;
/**
* text
*/
private String text;
}
/**
* ActionCardVO
*/
@NoArgsConstructor
@Data
@AllArgsConstructor
public static class ActionCardVO {
/**
* title
*/
private String title;
/**
* text
*/
private String text;
/**
* btnOrientation
*/
private String btnOrientation;
/**
* btns
*/
private List<BtnsVO> btns;
/**
* BtnsVO
*/
@NoArgsConstructor
@Data
@AllArgsConstructor
public static class BtnsVO {
/**
* title
*/
private String title;
/**
* actionURL
*/
private String actionURL;
}
}
/**
* FeedCardVO
*/
@NoArgsConstructor
@Data
@AllArgsConstructor
public static class FeedCardVO {
/**
* links
*/
private List<LinksVO> links;
/**
* LinksVO
*/
@NoArgsConstructor
@Data
@AllArgsConstructor
public static class LinksVO {
/**
* title
*/
private String title;
/**
* messageURL
*/
private String messageURL;
/**
* picURL
*/
private String picURL;
}
}
}

@ -0,0 +1,31 @@
package com.java3y.austin.handler.domain.dingding;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*
* <p>
* {"errcode":0,"errmsg":"ok"}
*
* @author 3y
*/
@NoArgsConstructor
@Data
@AllArgsConstructor
public class DingDingRobotResult {
/**
* errcode
*/
@SerializedName("errcode")
private Integer errCode;
/**
* errmsg
*/
@SerializedName("errmsg")
private String errMsg;
}

@ -1,4 +1,4 @@
package com.java3y.austin.handler.domain;
package com.java3y.austin.handler.domain.sms;
import lombok.Builder;
import lombok.Data;

@ -1,4 +1,4 @@
package com.java3y.austin.handler.domain;
package com.java3y.austin.handler.domain.sms;
import lombok.AllArgsConstructor;
import lombok.Builder;

@ -1,4 +1,4 @@
package com.java3y.austin.handler.domain;
package com.java3y.austin.handler.domain.wechat;
import lombok.AllArgsConstructor;
import lombok.Builder;

@ -0,0 +1,114 @@
package com.java3y.austin.handler.handler.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Throwables;
import com.java3y.austin.common.constant.AustinConstant;
import com.java3y.austin.common.domain.TaskInfo;
import com.java3y.austin.common.dto.DingDingContentModel;
import com.java3y.austin.common.enums.ChannelType;
import com.java3y.austin.handler.domain.dingding.DingDingRobotAccount;
import com.java3y.austin.handler.domain.dingding.DingDingRobotParam;
import com.java3y.austin.handler.domain.dingding.DingDingRobotResult;
import com.java3y.austin.handler.handler.BaseHandler;
import com.java3y.austin.handler.handler.Handler;
import com.java3y.austin.support.utils.AccountUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.util.ArrayList;
/**
*
*
* @author 3y
*/
@Slf4j
@Service
public class DingDingRobotHandler extends BaseHandler implements Handler {
private static final String DING_DING_ROBOT_ACCOUNT_KEY = "dingDingRobotAccount";
private static final String PREFIX = "ding_ding_robot_";
@Autowired
private AccountUtils accountUtils;
public DingDingRobotHandler() {
channelCode = ChannelType.DING_DING_ROBOT.getCode();
}
@Override
public boolean handler(TaskInfo taskInfo) {
try {
DingDingRobotAccount account = accountUtils.getAccount(taskInfo.getSendAccount(), DING_DING_ROBOT_ACCOUNT_KEY, PREFIX, new DingDingRobotAccount());
DingDingRobotParam dingDingRobotParam = assembleParam(taskInfo);
String httpResult = HttpUtil.post(assembleParamUrl(account), JSON.toJSONString(dingDingRobotParam));
DingDingRobotResult dingDingRobotResult = JSON.parseObject(httpResult, DingDingRobotResult.class);
if (dingDingRobotResult.getErrCode() == 0) {
return true;
}
// 常见的错误 应当 关联至 AnchorState,由austin后台统一透出失败原因
log.error("DingDingHandler#handler fail!result:{},params:{}", JSON.toJSONString(dingDingRobotResult), JSON.toJSONString(taskInfo));
} catch (Exception e) {
log.error("DingDingHandler#handler fail!e:{},params:{}", Throwables.getStackTraceAsString(e), JSON.toJSONString(taskInfo));
}
return false;
}
private DingDingRobotParam assembleParam(TaskInfo taskInfo) {
// 接收者相关
DingDingRobotParam.AtVO atVo = DingDingRobotParam.AtVO.builder().build();
if (AustinConstant.SEND_ALL.equals(CollUtil.getFirst(taskInfo.getReceiver()))) {
atVo.setIsAtAll(true);
} else {
atVo.setAtUserIds(new ArrayList<>(taskInfo.getReceiver()));
}
// 消息类型以及内容相关
DingDingContentModel contentModel = (DingDingContentModel) taskInfo.getContentModel();
return DingDingRobotParam.builder().at(atVo).msgtype("text")
.text(DingDingRobotParam.TextVO.builder().content(contentModel.getContent()).build()).build();
}
/**
* url
*
* @param account
* @return
*/
private String assembleParamUrl(DingDingRobotAccount account) {
long currentTimeMillis = System.currentTimeMillis();
String sign = assembleSign(currentTimeMillis, account.getSecret());
return (account.getWebhook() + "&timestamp=" + currentTimeMillis + "&sign=" + sign);
}
/**
* 使HmacSHA256
*
* @param currentTimeMillis
* @param secret
* @return
*/
private String assembleSign(long currentTimeMillis, String secret) {
String sign = "";
try {
String stringToSign = currentTimeMillis + String.valueOf(StrUtil.C_LF) + secret;
Mac mac = Mac.getInstance(AustinConstant.HMAC_SHA256_ENCRYPTION_ALGO);
mac.init(new SecretKeySpec(secret.getBytes(AustinConstant.CHARSET_NAME), AustinConstant.HMAC_SHA256_ENCRYPTION_ALGO));
byte[] signData = mac.doFinal(stringToSign.getBytes(AustinConstant.CHARSET_NAME));
sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), AustinConstant.CHARSET_NAME);
} catch (Exception e) {
log.error("DingDingHandler#assembleSign fail!:{}", Throwables.getStackTraceAsString(e));
}
return sign;
}
}

@ -3,6 +3,7 @@ package com.java3y.austin.handler.handler.impl;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Throwables;
import com.java3y.austin.common.constant.AustinConstant;
import com.java3y.austin.common.domain.TaskInfo;
import com.java3y.austin.common.dto.EnterpriseWeChatContentModel;
import com.java3y.austin.common.enums.ChannelType;
@ -10,6 +11,7 @@ import com.java3y.austin.handler.handler.BaseHandler;
import com.java3y.austin.handler.handler.Handler;
import com.java3y.austin.support.utils.AccountUtils;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxMpErrorMsgEnum;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.impl.WxCpMessageServiceImpl;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
@ -29,9 +31,8 @@ import org.springframework.stereotype.Component;
public class EnterpriseWeChatHandler extends BaseHandler implements Handler {
/**
* WxCpMessage
* userId
*/
private static final String ALL = "@all";
private static final String DELIMITER = "|";
/**
@ -53,8 +54,11 @@ public class EnterpriseWeChatHandler extends BaseHandler implements Handler {
WxCpDefaultConfigImpl accountConfig = accountUtils.getAccount(taskInfo.getSendAccount(), ENTERPRISE_WECHAT_ACCOUNT_KEY, PREFIX, new WxCpDefaultConfigImpl());
WxCpMessageServiceImpl messageService = new WxCpMessageServiceImpl(initService(accountConfig));
WxCpMessageSendResult result = messageService.send(buildWxCpMessage(taskInfo, accountConfig.getAgentId()));
buildAnchorState(result);
return true;
if (Integer.valueOf(WxMpErrorMsgEnum.CODE_0.getCode()).equals(result.getErrCode())) {
return true;
}
// 常见的错误 应当 关联至 AnchorState,由austin后台统一透出失败原因
log.error("EnterpriseWeChatHandler#handler fail!result:{},params:{}", JSON.toJSONString(result), JSON.toJSONString(taskInfo));
} catch (Exception e) {
log.error("EnterpriseWeChatHandler#handler fail:{},params:{}",
Throwables.getStackTraceAsString(e), JSON.toJSONString(taskInfo));
@ -62,14 +66,6 @@ public class EnterpriseWeChatHandler extends BaseHandler implements Handler {
return false;
}
/**
*
*
* @param result
*/
private void buildAnchorState(WxCpMessageSendResult result) {
}
/**
@ -93,7 +89,7 @@ public class EnterpriseWeChatHandler extends BaseHandler implements Handler {
*/
private WxCpMessage buildWxCpMessage(TaskInfo taskInfo, Integer agentId) {
String userId;
if (ALL.equals(CollUtil.getFirst(taskInfo.getReceiver()))) {
if (AustinConstant.SEND_ALL.equals(CollUtil.getFirst(taskInfo.getReceiver()))) {
userId = CollUtil.getFirst(taskInfo.getReceiver());
} else {
userId = StringUtils.join(taskInfo.getReceiver(), DELIMITER);

@ -7,7 +7,7 @@ import com.google.common.base.Throwables;
import com.java3y.austin.common.domain.TaskInfo;
import com.java3y.austin.common.dto.SmsContentModel;
import com.java3y.austin.common.enums.ChannelType;
import com.java3y.austin.handler.domain.SmsParam;
import com.java3y.austin.handler.domain.sms.SmsParam;
import com.java3y.austin.handler.handler.BaseHandler;
import com.java3y.austin.handler.handler.Handler;
import com.java3y.austin.handler.script.SmsScript;

@ -1,7 +1,7 @@
package com.java3y.austin.handler.script;
import com.java3y.austin.handler.domain.SmsParam;
import com.java3y.austin.handler.domain.sms.SmsParam;
import com.java3y.austin.support.domain.SmsRecord;
import java.util.List;

@ -5,8 +5,8 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.IdUtil;
import com.java3y.austin.common.enums.SmsStatus;
import com.java3y.austin.handler.domain.SmsParam;
import com.java3y.austin.handler.domain.TencentSmsParam;
import com.java3y.austin.handler.domain.sms.SmsParam;
import com.java3y.austin.handler.domain.sms.TencentSmsParam;
import com.java3y.austin.handler.script.SmsScript;
import com.java3y.austin.support.domain.SmsRecord;
import com.java3y.austin.support.utils.AccountUtils;

@ -83,6 +83,11 @@
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-spring-boot-starter-apollo</artifactId>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dingtalk</artifactId>
</dependency>
</dependencies>
</project>

@ -24,6 +24,7 @@ public class AccountUtils {
* (key:smsAccount)[{"sms_10":{"url":"sms.tencentcloudapi.com","region":"ap-guangzhou","secretId":"AKIDhDUUDfffffMEqBF1WljQq","secretKey":"B4h39yWnfffff7D2btue7JErDJ8gxyi","smsSdkAppId":"140025","templateId":"11897","signName":"Java3y公众号","supplierId":10,"supplierName":"腾讯云"}}]
* (key:emailAccount)[{"email_10":{"host":"smtp.qq.com","port":465,"user":"403686131@qq.com","pass":"","from":"403686131@qq.com"}}]
* (key:enterpriseWechatAccount)[{"enterprise_wechat_10":{"corpId":"wwf87603333e00069c","corpSecret":"-IFWxS2222QxzPIorNVUQn144444D915DM","agentId":10044442,"token":"rXROB3333Kf6i","aesKey":"MKZtoFxHIM44444M7ieag3r9ZPUsl"}}]
* (key:dingDingRobotAccount) [{"ding_ding_robot_10":{"secret":"SEC996d8d9d4768aded74114faae924f229229de444475a1c295d64fedf","webhook":"https://oapi.dingtalk.com/robot/send?access_token=8d03b644ffb6534b203d87333367328b0c3003d164715d2c6c6e56"}}]
*/
public <T> T getAccount(Integer sendAccount, String apolloKey, String prefix, T t) {
String accountValues = config.getProperty(apolloKey, AustinConstant.APOLLO_DEFAULT_VALUE_JSON_ARRAY);

@ -174,6 +174,13 @@
<version>${weixin-java}</version>
</dependency>
<!--阿里云 钉钉 SDK-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dingtalk</artifactId>
<version>1.3.22</version>
</dependency>
</dependencies>
</dependencyManagement>

Loading…
Cancel
Save