钉钉消息推送工具类

pom.xml

xml 复制代码
 <!-- HuTool 工具 -->
 <dependency>
      <groupId>cn.hutool</groupId>
      <artifactId>hutool-all</artifactId>
      <version>5.8.12</version>
  </dependency>
   <!-- commons-lang3 -->
  <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.6</version>
  </dependency>

java工具类

java 复制代码
package com.zens.doudian.utils;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 钉钉消息推送 - 工具类
 *
 * @author Lance
 * @since 2023-08-31 14:32
 */
public class DingTalkWebhookUtils {

    private static final Logger log = LoggerFactory.getLogger(DingTalkWebhookUtils.class);

    /**
     * 发送超时时间10s
     */
    private static final int TIME_OUT = 10000;
    // 签名密钥
    private static final String SECRET = "SECbd7fd971096ea3333e3d56bf30xxxxexxxxx";
    // 
    private static final String WEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxx";


    public static void main(String[] args) {
        DingTalkWebhookUtils.sendWebhook(WEBHOOK, SECRET, "测试推送!!!", Collections.singletonList("18534xxxxx"));
    }


    public static void sendMessage(String content, List<String> mobileList) {

        sendWebhook(WEBHOOK, SECRET, content, mobileList);

    }

    /**
     * 钉钉机器人文档地址:<a href="https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq">...</a>
     *
     * @param secret     安全设置 3选1:
     *                   【方式一,自定义关键词 】
     *                   【方式二,加签 ,创建机器人时选择加签 secret以SE开头】
     *                   【方式三,IP地址(段)】
     * @param content    发送内容
     * @param mobileList 通知具体人的手机号码列表 (可选)
     */
    public static void sendWebhook(String webhook, String secret, String content, List<String> mobileList) {
        try {
            //钉钉机器人地址(配置机器人的webhook)
            if (!StringUtils.isEmpty(secret)) {
                Long timestamp = System.currentTimeMillis();
                String sign = getSign(timestamp, secret);
                webhook = new StringBuilder(webhook)
                        .append("&timestamp=")
                        .append(timestamp)
                        .append("&sign=")
                        .append(sign)
                        .toString();
            }
            System.out.println("webhook:" + webhook);
            // 是否通知所有人
            boolean isAtAll = false;
            // 组装请求内容
            String reqStr = buildReqStr(content, isAtAll, mobileList);
            // 推送消息(HTTP POST 请求)
            String result = postJson(webhook, reqStr);
            log.info("推送响应结果:{}", result);
        } catch (Exception e) {
            log.info("发送群通知异常 异常原因:{}", e.getMessage());
        }
    }

    /**
     * 组装请求报文
     *
     * @param content    内容
     * @param isAtAll    是否通知所有人
     * @param mobileList 需要通知的人:手机号
     * @return json
     */
    private static String buildReqStr(String content, boolean isAtAll, List<String> mobileList) {
        //消息内容
        Map<String, String> contentMap = new HashMap<>();
        contentMap.put("content", content);
        //通知人
        Map<String, Object> atMap = new HashMap<>();
        //1.是否通知所有人
        atMap.put("isAtAll", isAtAll);
        //2.通知具体人的手机号码列表
        atMap.put("atMobiles", mobileList);
        Map<String, Object> reqMap = new HashMap<>();
        reqMap.put("msgtype", "text");
        reqMap.put("text", contentMap);
        reqMap.put("at", atMap);
        return JSON.toJSONString(reqMap);
    }

    private static String postJson(String url, String reqStr) {
        String body = null;
        try {
            body = HttpRequest.post(url).body(reqStr).timeout(TIME_OUT).execute().body();
        } catch (Exception e) {
            log.error("钉钉消息推送异常:{}", e.getMessage());
        }
        return body;
    }

    /**
     * 自定义机器人获取签名,创建机器人时选择加签获取secret以SE开头
     * 把timestamp+"\n"+密钥当做签名字符串,使用HmacSHA256算法计算签名,然后进行Base64 encode,最后再把签名参数再进行urlEncode,得到最终的签名(需要使用UTF-8字符集)
     *
     * @param secret    机器人安全设置下的签名
     * @param timestamp 时间戳
     */
    private static String getSign(Long timestamp, String secret) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
        String stringToSign = timestamp + "\n" + secret;
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
        byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
        String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
        log.info("sign:" + sign);
        return sign;
    }
}
相关推荐
m0_7493175211 分钟前
蓝桥杯训练
java·学习·职场和发展·蓝桥杯
HelloZheQ26 分钟前
Java 项目中引入阿里云 OSS SDK
java·数据库·阿里云
EviaHp1 小时前
递归构建树菜单节点
java·spring boot·后端·maven·idea
HappyAcmen1 小时前
关于Java适配器模式的面试题目及其答案
java·面试·适配器模式
love静思冥想1 小时前
自动化执行 SQL 脚本解决方案
java·数据库·sql·自动化
Miraitowa_cheems1 小时前
【JavaEE】Spring Web MVC
java·spring boot·java-ee
iamlzjoco2 小时前
idea报错Malformed \uxxxx encoding.报错解决
java·ide·intellij-idea
华年源码2 小时前
基于SpringBoot的旅游网站的设计与实现(源码+数据库+文档)
java·毕业设计·源码·springboot·旅游
北京_宏哥2 小时前
《手把手教你》系列技巧篇(十九)-java+ selenium自动化测试-元素定位大法之By css下卷(详细教程) 1.简介
java·selenium·前端框架
程序猿零零漆3 小时前
SpringCloud系列教程:微服务的未来(十)服务调用、注册中心原理、Nacos注册中心
java·spring cloud·微服务