diff --git a/README.md b/README.md index 4875966..df41a2f 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,10 @@ ## What(Dinger是什么) -Dinger是一个以SpringBoot框架为基础开发的消息发送中间件, 对现有两大移动办公系统[钉钉](https://ding-doc.dingtalk.com/doc#/serverapi3/iydd5)和[企业微信](https://work.weixin.qq.com/api/doc/90000/90136/91770)的群机器人API做了一层封装,让使用更简单便捷。 +Dinger是一个以SpringBoot框架为基础开发的消息发送中间件, 对如下移动办公系统的群机器人API做了一层封装,让使用更简单便捷。 +- [钉钉](https://open.dingtalk.com/document/group/custom-robot-access) +- [企业微信](https://developer.work.weixin.qq.com/document/path/91770) +- [飞书](https://open.feishu.cn/document/ukTMukTMukTM/ucTM5YjL3ETO24yNxkjN#756b882f) 只需要简单的配置(最简单的发送功能只需要一行代码),即可快速的在springboot项目中将消息发送到指定的钉钉或企业微信群聊中。 @@ -77,6 +80,17 @@ spring: token-id: 32865206-7082-46l5-8j39-2m7ycy6d868 ``` +**使用飞书群机器人配置** +```yaml +spring: + dinger: + project-id: ${spring.application.name} + dingers: + # 使用飞书机器人, 请根据自己机器人配置信息进行修改 + bytetalk: + token-id: 20200528-0824-20jm-21hy-5yc556210y15 +``` +   ### 三、代码中使用 diff --git a/pom.xml b/pom.xml index 69ba5b4..99d9d49 100644 --- a/pom.xml +++ b/pom.xml @@ -7,18 +7,18 @@ com.github.answerail dinger-spring-boot-starter jar - 1.3.0 + 2.0.0 dinger-spring-boot-starter - Dinger-SpringBoot集成钉钉/企业微信群机器人实现消息通知中间件 + Dinger-SpringBoot集成钉钉/企业微信/飞书群机器人实现消息通知中间件 https://github.com/AnswerAIL/dingtalk-spring-boot-starter - 2.1.5.RELEASE - 5.2.11.RELEASE + 2.7.0 + 5.3.20 1.8 - 1.7.30 + 1.7.36 2.13.2.2 UTF-8 UTF-8 diff --git a/src/main/java/com/github/jaemon/dinger/bytetalk/FeiShuDefinitionGenerator.java b/src/main/java/com/github/jaemon/dinger/bytetalk/FeiShuDefinitionGenerator.java new file mode 100644 index 0000000..1bd316c --- /dev/null +++ b/src/main/java/com/github/jaemon/dinger/bytetalk/FeiShuDefinitionGenerator.java @@ -0,0 +1,57 @@ +/* + * Copyright ©2015-2022 Jaemon. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.jaemon.dinger.bytetalk; + +import com.github.jaemon.dinger.core.DingerDefinition; +import com.github.jaemon.dinger.core.DingerDefinitionGenerator; +import com.github.jaemon.dinger.core.DingerDefinitionGeneratorContext; +import com.github.jaemon.dinger.core.DingerDefinitionHandler; +import com.github.jaemon.dinger.core.annatations.DingerText; +import com.github.jaemon.dinger.core.entity.enums.DingerDefinitionType; +import com.github.jaemon.dinger.core.entity.enums.DingerType; +import com.github.jaemon.dinger.core.entity.xml.MessageTag; + +/** + * 飞书消息体定义生成类 + * + * @author Jaemon + * @since 1.0 + */ +public class FeiShuDefinitionGenerator extends DingerDefinitionHandler { + /** + * 生成生成注解文本消息体定义 + */ + public static class AnnotationText extends DingerDefinitionGenerator { + + @Override + public DingerDefinition generator(DingerDefinitionGeneratorContext context) { + return dingerTextHandler(DingerType.BYTETALK, context); + } + } + + + /** + * 生成XML文本消息体定义 + */ + public static class XmlText extends DingerDefinitionGenerator { + + @Override + public DingerDefinition generator(DingerDefinitionGeneratorContext context) { + return xmlHandler(DingerDefinitionType.BYTETALK_XML_TEXT, context); + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/jaemon/dinger/bytetalk/entity/ByteTalkMessage.java b/src/main/java/com/github/jaemon/dinger/bytetalk/entity/ByteTalkMessage.java new file mode 100644 index 0000000..ac4bf40 --- /dev/null +++ b/src/main/java/com/github/jaemon/dinger/bytetalk/entity/ByteTalkMessage.java @@ -0,0 +1,31 @@ +/* + * Copyright ©2015-2022 Jaemon. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.jaemon.dinger.bytetalk.entity; + +import com.github.jaemon.dinger.core.entity.MsgType; +import com.github.jaemon.dinger.core.entity.enums.DingerType; + +/** + * ByteTalk请求体 + * + * @author Jaemon + * @since 1.0 + */ +public class ByteTalkMessage extends MsgType { + public ByteTalkMessage() { + setDingerType(DingerType.BYTETALK); + } +} \ No newline at end of file diff --git a/src/main/java/com/github/jaemon/dinger/bytetalk/entity/ByteText.java b/src/main/java/com/github/jaemon/dinger/bytetalk/entity/ByteText.java new file mode 100644 index 0000000..8faf9f1 --- /dev/null +++ b/src/main/java/com/github/jaemon/dinger/bytetalk/entity/ByteText.java @@ -0,0 +1,114 @@ +/* + * Copyright ©2015-2022 Jaemon. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.jaemon.dinger.bytetalk.entity; + +import com.github.jaemon.dinger.bytetalk.entity.enums.ByteTalkMsgType; +import com.github.jaemon.dinger.support.sign.SignBase; +import com.github.jaemon.dinger.support.sign.SignResult; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * 飞书-消息类型-文本类型 + * + * @author Jaemon + * @since 1.0 + */ +public class ByteText extends ByteTalkMessage { + private String msg_type; + private Content content; + + /** 签名-时间戳 */ + private String timestamp; + /** 签名-秘钥 */ + private String sign; + + public ByteText(Content content) { + this.msg_type = ByteTalkMsgType.TEXT.type(); + this.content = content; + } + + @Override + public void signAttributes(SignBase sign) { + if (sign == null || !(sign instanceof SignResult)) { + return; + } + SignResult signResult = (SignResult) sign; + this.timestamp = String.valueOf(signResult.getTimestamp()); + this.sign = signResult.getSign(); + } + + public Content getContent() { + return content; + } + + public void setContent(Content content) { + this.content = content; + } + + public String getMsg_type() { + return msg_type; + } + + public void setMsg_type(String msg_type) { + this.msg_type = msg_type; + } + + public String getSign() { + return sign; + } + + public void setSign(String sign) { + this.sign = sign; + } + + public String getTimestamp() { + return timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + public static class Content implements Serializable { + /** + * 文本内容,最长不超过2048个字节,必须是utf8编码 + * */ + private String text; + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public Content() { + } + + public Content(String text) { + this.text = text; + } + } + + @Override + public void transfer(Map params) { + this.content.text = replaceContent(this.content.text, params); + } +} \ No newline at end of file diff --git a/src/main/java/com/github/jaemon/dinger/bytetalk/entity/enums/ByteTalkMsgType.java b/src/main/java/com/github/jaemon/dinger/bytetalk/entity/enums/ByteTalkMsgType.java new file mode 100644 index 0000000..7b6f1bf --- /dev/null +++ b/src/main/java/com/github/jaemon/dinger/bytetalk/entity/enums/ByteTalkMsgType.java @@ -0,0 +1,41 @@ +/* + * Copyright ©2015-2022 Jaemon. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.jaemon.dinger.bytetalk.entity.enums; + +/** + * ByteTalk支持的消息类型 + * + * @author Jaemon + * @since 1.0 + */ +public enum ByteTalkMsgType { + /** + * text类型 + */ + TEXT("text"), + + ; + + private String type; + + ByteTalkMsgType(String type) { + this.type = type; + } + + public String type() { + return type; + } +} \ No newline at end of file diff --git a/src/main/java/com/github/jaemon/dinger/bytetalk/package-info.java b/src/main/java/com/github/jaemon/dinger/bytetalk/package-info.java new file mode 100644 index 0000000..fdbb292 --- /dev/null +++ b/src/main/java/com/github/jaemon/dinger/bytetalk/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright ©2015-2022 Jaemon. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * 支持ByteTalk包 + * + * @author Jaemon + * @since 1.0 + */ +package com.github.jaemon.dinger.bytetalk; \ No newline at end of file diff --git a/src/main/java/com/github/jaemon/dinger/constant/DingerConstant.java b/src/main/java/com/github/jaemon/dinger/constant/DingerConstant.java index 93b3729..1615d71 100644 --- a/src/main/java/com/github/jaemon/dinger/constant/DingerConstant.java +++ b/src/main/java/com/github/jaemon/dinger/constant/DingerConstant.java @@ -51,4 +51,6 @@ public interface DingerConstant { String DINGER_PROP_PREFIX = "spring.dinger"; String DINGER_PROPERTIES_PREFIX = DINGER_PROP_PREFIX + SPOT_SEPERATOR; + + String DINGER_COMMA = ","; } \ No newline at end of file diff --git a/src/main/java/com/github/jaemon/dinger/core/DingerRobot.java b/src/main/java/com/github/jaemon/dinger/core/DingerRobot.java index 8c7f7e8..5ce24a2 100644 --- a/src/main/java/com/github/jaemon/dinger/core/DingerRobot.java +++ b/src/main/java/com/github/jaemon/dinger/core/DingerRobot.java @@ -17,7 +17,6 @@ import com.github.jaemon.dinger.core.entity.DingerRequest; import com.github.jaemon.dinger.core.entity.DingerResponse; -import com.github.jaemon.dinger.support.sign.SignBase; import com.github.jaemon.dinger.support.client.MediaTypeEnum; import com.github.jaemon.dinger.core.entity.DingerProperties; import com.github.jaemon.dinger.core.entity.enums.DingerType; @@ -27,6 +26,7 @@ import com.github.jaemon.dinger.exception.AsyncCallException; import com.github.jaemon.dinger.exception.SendMsgException; import com.github.jaemon.dinger.support.CustomMessage; +import com.github.jaemon.dinger.support.sign.SignBase; import com.github.jaemon.dinger.utils.DingerUtils; import org.springframework.beans.BeanUtils; @@ -106,17 +106,21 @@ protected DingerResponse send(T message) { } StringBuilder webhook = new StringBuilder(); - webhook.append(dinger.getRobotUrl()).append("=").append(dinger.getTokenId()); + webhook.append(dinger.getRobotUrl()).append(dinger.getTokenId()); if (log.isDebugEnabled()) { log.debug("dingerId={} send message and use dinger={}, tokenId={}.", dkid, dingerType, dinger.getTokenId()); } // 处理签名问题(只支持DingTalk) - if (dingerType == DingerType.DINGTALK && - DingerUtils.isNotEmpty((dinger.getSecret()))) { + if (DingerUtils.isNotEmpty((dinger.getSecret()))) { SignBase sign = dingTalkManagerBuilder.dingerSignAlgorithm.sign(dinger.getSecret().trim()); - webhook.append(sign.transfer()); + + if (dingerType == DingerType.DINGTALK) { + webhook.append(sign.transfer()); + } else if (dingerType == DingerType.BYTETALK) { + message.signAttributes(sign); + } } Map headers = new HashMap<>(); diff --git a/src/main/java/com/github/jaemon/dinger/core/entity/MsgType.java b/src/main/java/com/github/jaemon/dinger/core/entity/MsgType.java index 90d90c2..f56e632 100644 --- a/src/main/java/com/github/jaemon/dinger/core/entity/MsgType.java +++ b/src/main/java/com/github/jaemon/dinger/core/entity/MsgType.java @@ -16,6 +16,8 @@ package com.github.jaemon.dinger.core.entity; import com.github.jaemon.dinger.core.entity.enums.DingerType; +import com.github.jaemon.dinger.support.sign.SignBase; +import com.github.jaemon.dinger.support.sign.SignResult; import java.io.Serializable; import java.util.Map; @@ -62,6 +64,8 @@ public void setMsgtype(String msgtype) { public void transfer(Map params) { } + public void signAttributes(SignBase sign) {} + /** * 转换文本内容 * diff --git a/src/main/java/com/github/jaemon/dinger/core/entity/enums/DingerDefinitionType.java b/src/main/java/com/github/jaemon/dinger/core/entity/enums/DingerDefinitionType.java index 93c0de4..617f1ee 100644 --- a/src/main/java/com/github/jaemon/dinger/core/entity/enums/DingerDefinitionType.java +++ b/src/main/java/com/github/jaemon/dinger/core/entity/enums/DingerDefinitionType.java @@ -18,6 +18,7 @@ import com.github.jaemon.dinger.core.DingerDefinitionGenerator; import com.github.jaemon.dinger.dingtalk.DingTalkDefinitionGenerator; +import com.github.jaemon.dinger.bytetalk.FeiShuDefinitionGenerator; import com.github.jaemon.dinger.wetalk.WeTalkDefinitionGenerator; @@ -83,6 +84,16 @@ public enum DingerDefinitionType { DingerType.WETALK, MessageMainType.ANNOTATION, MessageSubType.IMAGETEXT, WeTalkDefinitionGenerator.AnnotationImageText.class ), + + + /** 飞书机器人消息类型 */ + BYTETALK_XML_TEXT( + DingerType.BYTETALK, MessageMainType.XML, MessageSubType.TEXT, FeiShuDefinitionGenerator.XmlText.class + ), + BYTETALK_ANNOTATION_TEXT( + DingerType.BYTETALK, MessageMainType.ANNOTATION, MessageSubType.TEXT, FeiShuDefinitionGenerator.AnnotationText.class + ), + ; public static final DingerDefinitionType[] dingerDefinitionTypes = values(); diff --git a/src/main/java/com/github/jaemon/dinger/core/entity/enums/DingerType.java b/src/main/java/com/github/jaemon/dinger/core/entity/enums/DingerType.java index 50e5ccb..1abb2b5 100644 --- a/src/main/java/com/github/jaemon/dinger/core/entity/enums/DingerType.java +++ b/src/main/java/com/github/jaemon/dinger/core/entity/enums/DingerType.java @@ -15,10 +15,6 @@ */ package com.github.jaemon.dinger.core.entity.enums; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - /** * Dinger类型 * @@ -26,8 +22,11 @@ * @since 1.0 */ public enum DingerType { - DINGTALK("钉钉", "https://oapi.dingtalk.com/robot/send?access_token", true), - WETALK("企业微信", "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key", true); + DINGTALK("钉钉", "https://oapi.dingtalk.com/robot/send?access_token=", true), + WETALK("企业微信", "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=", true), + BYTETALK("飞书", "https://open.feishu.cn/open-apis/bot/v2/hook/", true), + + ; private String type; private String robotUrl; diff --git a/src/main/java/com/github/jaemon/dinger/core/entity/enums/MessageSubType.java b/src/main/java/com/github/jaemon/dinger/core/entity/enums/MessageSubType.java index ca4746b..b8c7275 100644 --- a/src/main/java/com/github/jaemon/dinger/core/entity/enums/MessageSubType.java +++ b/src/main/java/com/github/jaemon/dinger/core/entity/enums/MessageSubType.java @@ -15,6 +15,7 @@ */ package com.github.jaemon.dinger.core.entity.enums; +import com.github.jaemon.dinger.bytetalk.entity.ByteText; import com.github.jaemon.dinger.core.entity.DingerRequest; import com.github.jaemon.dinger.dingtalk.entity.*; import com.github.jaemon.dinger.core.entity.MsgType; @@ -22,12 +23,15 @@ import com.github.jaemon.dinger.wetalk.entity.WeMarkdown; import com.github.jaemon.dinger.wetalk.entity.WeNews; import com.github.jaemon.dinger.wetalk.entity.WeText; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; +import static com.github.jaemon.dinger.constant.DingerConstant.DINGER_COMMA; import static com.github.jaemon.dinger.core.DingerDefinitionHandler.WETALK_AT_ALL; import static com.github.jaemon.dinger.core.entity.enums.ExceptionEnum.DINGER_UNSUPPORT_MESSAGE_TYPE_EXCEPTION; @@ -55,7 +59,7 @@ public MsgType msgType(DingerType dingerType, DingerRequest request) { } return message; - } else { + } else if (dingerType == DingerType.WETALK) { WeText.Text text = new WeText.Text(content); WeText weText = new WeText(text); if (atAll) { @@ -64,6 +68,28 @@ public MsgType msgType(DingerType dingerType, DingerRequest request) { text.setMentioned_mobile_list(phones); } return weText; + } else if (dingerType == DingerType.BYTETALK) { + if (atAll) { + content = "所有人" + content; + } else if (!CollectionUtils.isEmpty(phones)) { + StringBuilder sb = new StringBuilder(); + for (String phone : phones) { + if (StringUtils.isEmpty(phone)) { + continue; + } + String[] userIdAndName = phone.split(DINGER_COMMA); + if (userIdAndName.length != 2) { + continue; + } + sb.append(String.format("%s", userIdAndName[0], userIdAndName[1])); + } + + content = sb.toString() + content; + } + + return new ByteText(new ByteText.Content(content)); + } else { + throw new DingerException(DINGER_UNSUPPORT_MESSAGE_TYPE_EXCEPTION, dingerType, this.name()); } } }, @@ -83,10 +109,12 @@ public MsgType msgType(DingerType dingerType, DingerRequest request) { } return message; - } else { + } else if (dingerType == DingerType.WETALK) { WeMarkdown.Markdown markdown = new WeMarkdown.Markdown(content); WeMarkdown weMarkdown = new WeMarkdown(markdown); return weMarkdown; + } else { + throw new DingerException(DINGER_UNSUPPORT_MESSAGE_TYPE_EXCEPTION, dingerType, this.name()); } } }, @@ -97,8 +125,10 @@ public MsgType msgType(DingerType dingerType, DingerRequest request) { public MsgType msgType(DingerType dingerType, DingerRequest request) { if (dingerType == DingerType.DINGTALK) { return new DingFeedCard(new ArrayList<>()); - } else { + } else if (dingerType == DingerType.WETALK) { return new WeNews(new ArrayList<>()); + } else { + throw new DingerException(DINGER_UNSUPPORT_MESSAGE_TYPE_EXCEPTION, dingerType, this.name()); } } }, diff --git a/src/main/java/com/github/jaemon/dinger/multi/MultiDingerScannerRegistrar.java b/src/main/java/com/github/jaemon/dinger/multi/MultiDingerScannerRegistrar.java index b72834c..e054385 100644 --- a/src/main/java/com/github/jaemon/dinger/multi/MultiDingerScannerRegistrar.java +++ b/src/main/java/com/github/jaemon/dinger/multi/MultiDingerScannerRegistrar.java @@ -41,7 +41,6 @@ import org.springframework.core.Ordered; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata; -import org.springframework.objenesis.instantiator.util.ClassUtils; import java.util.*; @@ -159,7 +158,7 @@ private void multiDingerHandler(BeanDefinitionRegistry registry, List> continue; } String key = dingerClass.getName(); - DingerConfigHandler handler = ClassUtils.newInstance(dingerConfigHandler); + DingerConfigHandler handler = DingerUtils.newInstance(dingerConfigHandler); DingerType dinger = value.dinger(); registerHandler(registry, dinger, dinger + DingerConstant.SPOT_SEPERATOR + key, handler); @@ -222,7 +221,7 @@ private void registerHandler(BeanDefinitionRegistry registry, DingerType dinger, // 如果无需注入属性,直接采用反射进行实例化并注册到容器 if (injectionCnt == 0) { // create algorithm instance - AlgorithmHandler algorithmHandler = ClassUtils.newInstance(algorithm); + AlgorithmHandler algorithmHandler = DingerUtils.newInstance(algorithm); MultiDingerConfigContainer.INSTANCE.put( key, new MultiDingerConfig(algorithmHandler, dingerConfigs) ); diff --git a/src/main/java/com/github/jaemon/dinger/support/sign/ByteTalkSignAlgorithm.java b/src/main/java/com/github/jaemon/dinger/support/sign/ByteTalkSignAlgorithm.java new file mode 100644 index 0000000..50eda3e --- /dev/null +++ b/src/main/java/com/github/jaemon/dinger/support/sign/ByteTalkSignAlgorithm.java @@ -0,0 +1,56 @@ +/* + * Copyright ©2015-2022 Jaemon. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.jaemon.dinger.support.sign; + +import com.github.jaemon.dinger.core.entity.enums.DingerType; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +/** + * 默认签名算法 {@link DingerType#BYTETALK} + * + * @author Jaemon + * @since 1.0 + */ +public class ByteTalkSignAlgorithm implements DingerSignAlgorithm { + @Override + public SignResult sign(String secret) throws Exception { + // 注意这里是秒级时间戳 + Long timestamp = System.currentTimeMillis() / 1000; + + String sign = algorithm(timestamp, secret); + + return new SignResult(sign, timestamp); + } + + @Override + public String algorithm(Long timestamp, String secret) throws Exception { + // 把timestamp+"\n"+密钥当做签名字符串 + String stringToSign = timestamp + "\n" + secret; + + // 使用HmacSHA256算法计算签名 + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(new SecretKeySpec(stringToSign.getBytes(StandardCharsets.UTF_8), "HmacSHA256")); + byte[] signData = mac.doFinal(new byte[]{}); + + // 官方使用的base64包 +// return new String(org.apache.commons.codec.binary.Base64.Base64.encodeBase64(signData)); + return new String(Base64.getEncoder().encode(signData)); + } +} \ No newline at end of file diff --git a/src/main/java/com/github/jaemon/dinger/utils/DingerUtils.java b/src/main/java/com/github/jaemon/dinger/utils/DingerUtils.java index 5262690..95d4ca1 100644 --- a/src/main/java/com/github/jaemon/dinger/utils/DingerUtils.java +++ b/src/main/java/com/github/jaemon/dinger/utils/DingerUtils.java @@ -182,4 +182,11 @@ public static int[] methodParamsType(Method method, Class clazz) { return Arrays.stream(arr).filter(e -> e > -1).toArray(); } + public static T newInstance(Class clazz) { + try { + return clazz.newInstance(); + } catch (IllegalAccessException | InstantiationException var2) { + throw new RuntimeException(var2); + } + } } \ No newline at end of file