@Service
@Slf4j
public class DingTalkUtil {
@Value("${dingTalk.robot.url}")
private String robotUrl;
@Value("${dingTalk.robot.me}")
private String me;
// 钉钉密钥
@Value("${dingTalk.robot.secret}")
private String secret;
@Value("${dingTalk.enabled}")
private Boolean enabled;
private OkHttpClient okHttpClient;
private static final ObjectMapper objectMapper = new ObjectMapper();
private static final MediaType JsonMediaType = MediaType.parse("application/json");
@PostConstruct
public void init() {
ExecutorService executorService = new ThreadPoolExecutor(
1,
5,
1,
TimeUnit.MINUTES,
new ArrayBlockingQueue<>(100),
ThreadFactoryBuilder.create().setNamePrefix("dingTalk-").build(),
new ThreadPoolExecutor.CallerRunsPolicy()
);
Dispatcher dispatcher = new Dispatcher(executorService);
dispatcher.setMaxRequests(5);
dispatcher.setMaxrequestsPerHost(5);
okHttpClient = new OkHttpClient.Builder()
.readTimeout(Duration.ofSeconds(1))
.connectTimeout(Duration.ofSeconds(1))
.callTimeout(Duration.ofSeconds(1))
.writeTimeout(Duration.ofSeconds(1))
.dispatcher(dispatcher)
.build();
}
/**
* 异步发送钉钉机器人文本消息.
*/
public void sendTextMessage(String content) {
doSendTextMessage(content, textMessage -> {
});
}
/**
* 异步发送文本消息并@自己.
*/
public void sendTextMessageWithAtMe(String content) {
doSendTextMessage(content, textMessage -> textMessage.getAt().getAtMobiles().add(me));
}
/**
* 异步发送文本消息并@所有人.
*/
public void sendTextMessageWithAtAll(String content) {
doSendTextMessage(content, textMessage -> textMessage.getAt().setAtAll(true));
}
private void doSendTextMessage(String content, Consumer<TextMessage> messageConfigurator) {
if (!enabled) {
return;
}
if (StringUtils.isBlank(content)) {
throw new IllegalArgumentException("文本消息内容不能为空");
}
TextMessage textMessage = new TextMessage();
textMessage.setText(new TextMessage.Content(content));
messageConfigurator.accept(textMessage);
long timestamp = System.currentTimeMillis();
String sign = sign(timestamp);
try {
Request Request = new Request.Builder()
.url((robotUrl "×tamp=" timestamp "&sign=" sign))
.post(RequestBody.create(objectMapper.writeValueAsString(textMessage), jsonMediaType))
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
log.error("发送钉钉消息失败, 请求: {}.", call, e);
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) {
ResponseBody responseBody = response.body();
log.debug("钉钉发送成功, call: {}, resp: {}.", call.request().body(), responseBody);
if (responseBody != null) responseBody.close();
}
});
} catch (JsonProcessingException e) {
throw ExceptionUtil.wrapRuntime(e);
}
}
private String sign(long timestamp) {
final String seed = (timestamp "\n" secret);
try {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getbytes(StandardCharsets.UTF_8), "HmacSHA256"));
byte[] result = mac.doFinal(seed.getBytes(StandardCharsets.UTF_8));
return URLEncoder.encode(Base64.getEncoder().encodeToString(result), StandardCharsets.UTF_8.displayName());
} catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) {
throw ExceptionUtil.wrapRuntime(e);
}
}
@Getter
private static class TextMessage {
private final String msgtype = "text";
@Setter
private Content text;
private final At at = new At();
@Data
@AllArgsConstructor
private static class Content {
private String content;
}
private static class At {
@Setter
private boolean isAtAll = false;
@Getter
private final List<String> atMobiles = new LinkedList<>();
// 不能删除,否则会导致生成的json字段名是atAll, 导致@所有人不生效
public boolean getIsAtAll() {
return isAtAll;
}
}
}
}
,
Copyright © 2008-2022 秒下下载站
m.down10s.com .All Rights Reserved