钉钉通知Java

简介: 钉钉发送群消息是常用的业务场景,现在详细来说下建好钉钉群,建好机器人这些参数在建立机器人后会自动给你的,这两参数比较重要,然代码识别知道哪个钉钉群和哪个机器人需要发送消息。首先测试钉钉方法

钉钉发送群消息是常用的业务场景,现在详细来说下

建好钉钉群,建好机器人

这些参数在建立机器人后会自动给你的,这两参数比较重要,然代码识别知道哪个钉钉群和哪个机器人需要发送消息。

首先测试钉钉方法

/**
 * @author samxie
 * @version 1.0
 * @date 2022/3/22 15:54
 **/
@Slf4j
public class test {
    public static void main(String[] args) {
        DingReportFailMessageListener dingReportFailMessageListener = new DingReportFailMessageListener();
        DingReportFailMessage dingReportFailMessage = new DingReportFailMessage();
        dingReportFailMessage.setUserName("samxie");
        dingReportFailMessage.setUserId(String.valueOf(23));
        dingReportFailMessage.setReportInstanceId(12222233344L);
        dingReportFailMessage.setReportType("铺位评估");
        dingReportFailMessage.setReportName("测试报告");
        dingReportFailMessage.setFailDesc("org.springframework.beans.factory.BeanDefinitionStoreException:");
        Date now = DateUtils.getNow();
        String dayTime = DateUtils.formatYYYYMMDDHHMMSS(now);
        dingReportFailMessage.setCreateTime(dayTime);
        dingReportFailMessageListener.sendDingDingTest(dingReportFailMessage);
    }
}

测试发送钉钉消息

public void sendDingDingTest(DingReportFailMessage reportMessage) {
    //钉钉报告地址
    String dingWebHookUrl = "****";
    //钉钉报告机密钥
    String reportSecret = "********";
    /**钉钉报告消息体 报告预警提示~\n用户昵称:%s\n用户ID:%s\n报告编号:%s\n报告类型:%s\n报告名称:%s\n
     * 预警描述:%s\n报告预警时间:%s
     */
    String messageBody = "报告预警提示~%s用户昵称:%s用户ID:%s报告编号:"
            + "%s报告类型:%s报告名称:%s预警描述:%s报告预警时间:%s";
    if (StringUtils.isEmpty(messageBody) || StringUtils.isEmpty(dingWebHookUrl)
            || StringUtils.isEmpty(reportSecret)) {
        log.info("发送报告钉钉消息, 消息配置项未配置");
    }
    //请求消息
    String sendMessage = String.format(messageBody, "\n", reportMessage.getUserName() + "\n",
            reportMessage.getUserId() + "\n", reportMessage.getReportInstanceId() + "\n",
            reportMessage.getReportType() + "\n",
            reportMessage.getReportName() + "\n", reportMessage.getFailDesc() + "\n",
            reportMessage.getCreateTime());
    //钉钉消息
    String dingMessage = DingMessageUtil.generateMessageBody(sendMessage, false, null);
    //发送钉钉消息
    DingMessageUtil.sendMessage(reportSecret, dingMessage, dingWebHookUrl);
}
/**
 * 组装请求报文
 * @param content 通知内容
 * @param isNotifyAll 是否通知所有人
 * @param mobileList 通知手机号
 * @return
 */
public static String generateMessageBody(String content, boolean isNotifyAll, List<String> mobileList) {
    // 消息内容
    Map<String, String> contentMap = new HashMap<>(16);
    contentMap.put("content", content);
    // 通知人
    Map<String, Object> atMap = new HashMap<>(16);
    // 是否通知所有人
    atMap.put("isAtAll", isNotifyAll);
    // 通知具体人的手机号码列表
    atMap.put("atMobiles", mobileList);
    Map<String, Object> reqMap = new HashMap<>(16);
    reqMap.put("msgtype", "text");
    reqMap.put("text", contentMap);
    reqMap.put("at", atMap);
    return JSONObject.toJSONString(reqMap);
}
/**
 *  钉钉发送消息
 * @param secret 钉钉机器人密钥
 * @param message 消息
 * @param dingUrl 钉钉机器人hook地址
 */
public static void sendMessage(String secret, String message, String dingUrl) {
    final String actionLog = "【发送钉钉消息】";
    log.info("{}, secret:{}, message:{}, dingUrl:{}, mobileList:{}", actionLog, secret, message,
            dingUrl);
    try {
        // 系统时间戳
        Long timestamp = System.currentTimeMillis();
        // 拼接
        String signStr = timestamp + "\n" + secret;
        // 使用HmacSHA256算法计算签名
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
        byte[] signData = mac.doFinal(signStr.getBytes("UTF-8"));
        String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
        String requestUrl = dingUrl + "&timestamp=" + timestamp + "&sign=" + sign;
        // 推送消息(http请求)
        HttpPost httpPost = new HttpPost(requestUrl.trim());
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(30000)
                .setConnectionRequestTimeout(30000)
                .setSocketTimeout(30000).build();
        httpPost.setConfig(requestConfig);
        // 设置参数
        httpPost.setEntity(new StringEntity(message, ContentType.DEFAULT_TEXT.withCharset("UTF-8")));
        httpPost.setHeader(new BasicHeader("Content-Type", "application/json"));
        // 发送请求,获取返回数据
        String response = execute(httpPost);
        log.info("{}, 钉钉返回:{}", response);
        log.info("{}, 消息处理完毕");
    } catch (Exception e) {
        e.printStackTrace();
    }
}
private static String execute(HttpRequestBase requestBase) throws Exception {
    CloseableHttpClient httpclient = HttpClients.createDefault();
    String body = null;
    try {
        CloseableHttpResponse response = httpclient.execute(requestBase);
        try {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                body = EntityUtils.toString(entity, "UTF-8");
            }
            EntityUtils.consume(entity);
        } catch (Exception e) {
            throw e;
        } finally {
            response.close();
        }
    } catch (Exception e) {
        throw e;
    } finally {
        httpclient.close();
    }
    return body;
}

基本上就能发送成功消息,工具类组装了请求报文,然后发送过去就可以了。

下面进入写方法

/**
 * sendDingDing
 *
 * @return
 */
@Override
public Boolean sendDingDing() {
    DingReportFailMessage dingReportFailMessage = new DingReportFailMessage();
    dingReportFailMessage.setUserName("samxie");
    dingReportFailMessage.setUserId(String.valueOf(23));
    dingReportFailMessage.setReportInstanceId(12222233344L);
    dingReportFailMessage.setReportType("铺位评估");
    dingReportFailMessage.setReportName("测试报告");
    dingReportFailMessage.setFailDesc("org.springframework.beans.factory.BeanDefinitionStoreException:");
    Date now = DateUtils.getNow();
    String dayTime = DateUtils.formatYYYYMMDDHHMMSS(now);
    dingReportFailMessage.setCreateTime(dayTime);
    mqSend.sendDingReportFailMessage(dingReportFailMessage);
    return true;
}

这里用的是mq异步提供给别的服务去调用的,上面测试类可以直接调用到它的

public interface IMqSend {
    /**
     * 发送钉钉预警消息
     * @param dingReportFailMessage
     */
    void sendDingReportFailMessage(DingReportFailMessage dingReportFailMessage);
}
这里是发送预警消息的方法
    /**
     * 发送钉钉预警消息
     *
     * @param dingReportFailMessage
     */
    @Override
    public void sendDingReportFailMessage(DingReportFailMessage dingReportFailMessage) {
        String message = JSON.toJSONString(dingReportFailMessage);
        LOGGER.info("sendDingReportFailMessage take success send message to mq message = {}", message);
        producerUtil.sendAsyncMsg(mqTopicConfig.getMessageTopic(), mqTopicConfig.getMessageTopicReportDingTag(),
                message, dingReportFailMessage.getReportInstanceId() + "");
    }

这里两个参数配置是上面建立机器人的时候生成的,一般把它放到配置中就好了。

@Component
@Data
public class MqTopicConfig {
    @Value(value = "${message.config.messageTopic}")
    private String messageTopic;
    @Value(value = "${message.config.messageTopicReportDingTag}")
    private String messageTopicReportDingTag;
}

监听器去消费消息,这里是发送预警消息的主要实现方法,包括了组装数据、发送钉钉通知。

@Slf4j
@Component
@Api(tags = "钉钉预警报告消息监控类")
public class DingReportFailMessageListener extends MessageListener {
    @Autowired
    private MessageConfig messageConfig;
/**
 * 消费钉钉消息
 * @param message
 * @param consumeContext
 * @return
 */
@Override
public Action consume(Message message, ConsumeContext consumeContext) {
    try {
        Boolean notifyOpen = messageConfig.getNotifyOpen();
        if (!notifyOpen) {
            log.info("报告通知开关已关闭或未配置 notifyOpen:{}", notifyOpen);
            return Action.CommitMessage;
        }
        //钉钉报告地址
        String dingWebHookUrl = messageConfig.getDingReportUrl();
        //钉钉报告机密钥
        String reportSecret = messageConfig.getDingReportSecret();
        /**钉钉报告消息体 报告预警提示~\n用户昵称:%s\n用户ID:%s\n报告编号:%s\n报告类型:%s\n报告名称:%s\n
         * 预警描述:%s\n报告预警时间:%s
         */
        String messageBody = messageConfig.getDingReportMessageBody();
        if (StringUtils.isEmpty(messageBody) || StringUtils.isEmpty(dingWebHookUrl)
                || StringUtils.isEmpty(reportSecret)) {
            log.info("发送报告钉钉消息, 消息配置项未配置");
            return Action.CommitMessage;
        }
        //请求体
        String requestBody = new String(message.getBody(), StandardCharsets.UTF_8);
        //报告消息体
        DingReportFailMessage reportMessage = JSONObject.parseObject(requestBody, DingReportFailMessage.class);
        //请求消息
        String sendMessage = String.format(messageBody, "\n", reportMessage.getUserName() + "\n",
                reportMessage.getUserId() + "\n", reportMessage.getReportInstanceId() + "\n",
                reportMessage.getReportType() + "\n",
                reportMessage.getReportName() + "\n", reportMessage.getFailDesc() + "\n",
                reportMessage.getCreateTime());
        //钉钉消息
        String dingMessage = DingMessageUtil.generateMessageBody(sendMessage, false, null);
        //发送钉钉消息
        DingMessageUtil.sendMessage(reportSecret, dingMessage, dingWebHookUrl);
        return Action.CommitMessage;
    } catch (Exception e) {
        log.error("发送钉钉失败报告消息异常 e:{}", e);
        return Action.ReconsumeLater;
    }
}

}

一些用到的配置文件定义

@ConfigurationProperties(prefix = "message.config")
@Component
@Data
public class MessageConfig {
    @ApiModelProperty("钉钉报告机密钥")
    private String dingReportSecret;
    @ApiModelProperty("钉钉报告地址")
    private String dingReportUrl;
    @ApiModelProperty("钉钉报告密钥")
    private String dingOrderSecret;
    @ApiModelProperty("钉钉订单消息图片地址")
    private String dingOrderPicUrl;
    @ApiModelProperty("钉钉订单消息头部")
    private String dingOrderTitle;
    @ApiModelProperty("订单钉钉报告地址")
    private String dingOrderUrl;
    @ApiModelProperty("订单路由地址")
    private String orderRouteUrl;
    @ApiModelProperty("钉钉订单消息体")
    private String dingOrderMessageBody;
    @ApiModelProperty("钉钉报告消息体")
    private String dingReportMessageBody;
    @ApiModelProperty("消息开关")
    private Boolean notifyOpen;
    @ApiModelProperty("钉钉日报")
    private String dingDailyReportMessageBody;
    @ApiModelProperty("订单分配通知开关")
    private Boolean notifyDistributeOpen;
    @ApiModelProperty("分配订单通知密钥")
    private String dingDistributeSecret;
    @ApiModelProperty("分配通知地址")
    private String dingDistributeUrl;
    @ApiModelProperty("订单分配消息主体")
    private String dingDistributeMessageBody;
    @ApiModelProperty("topic")
    private String messageTopic;
    @ApiModelProperty("messageTopicReportDingTag")
    private String messageTopicReportDingTag;
}

实体类

@Data
public class DingReportFailMessage implements Serializable {
    private static final long serialVersionUID = -3901024808802199329L;
    /**
     *  有报告预警需要处理哟~\n
     用户昵称:%s\n
     用户ID:%s\n
     报告编号:%s\n
     报告类型:%s\n
     报告名称:%s\n
     预警描述:%s\n
     报告预警时间:%s
     */
    @ApiModelProperty("用户名称")
    private String userName;
    @ApiModelProperty("用户id")
    private String userId;
    @ApiModelProperty("报告实例id")
    private Long reportInstanceId;
    @ApiModelProperty("报告类型")
    private String reportType;
    @ApiModelProperty("报告名称")
    private String reportName;
    @ApiModelProperty("预警描述")
    private String failDesc;
    @ApiModelProperty("报告预警时间")
    private String createTime;
}


相关文章
|
6月前
|
Java API
java提交钉钉审批的一个流程例子
java提交钉钉审批的一个流程例子
207 0
|
移动开发 Java Maven
【Java用法】使用Java开发连接钉钉应用实现钉钉通知的功能
【Java用法】使用Java开发连接钉钉应用实现钉钉通知的功能
118 0
|
SQL 监控 机器人
钉钉告警机器人Java接入指南
本文讲实现Java代码调用钉钉机器人API,发送指定告警消息的效果,以满足用户对于系统的实时监控。 API:https://open.dingtalk.com/document/orgapp/custom-robots-send-group-messages 每个机器人每分钟最多发送20条消息到群里,如果超过20条,会限流10分钟。 重要 如果有大量发消息的场景(譬如系统监控报警)可以将这些信息进行整合,通过markdown消息以摘要的形式发送到群
1646 1
|
监控 Java 中间件
拦截应用 error日志并发送到钉钉群|Java 开发实战
现在应用都需要对日志进行监控或者报警,现在普遍的做法是采用EKL收集日志,然后再由Grafana进行内容展示和及告警策略等,那如果项目架构比较简单(单体应用),又不想搞那么多中间件依赖怎么办,这里有一种简单的方式可以实现~
拦截应用 error日志并发送到钉钉群|Java 开发实战
|
Shell 开发工具 数据安全/隐私保护
Git提交之后自动打版本并钉钉通知
Git提交之后自动打版本并钉钉通知
458 0
Git提交之后自动打版本并钉钉通知
|
Java 微服务
Java报告推送失败补偿机制;钉钉群通知消息核心代码
Java报告推送失败补偿机制,超过次数后使用钉钉通知开发 自动补偿实现: 要求方法调用的过程中,失败的时候,系统有办法进行自动重试,重试达到一定次数后,钉钉通知开发。 实现设计:注解,反射,定时任务
324 0
Java报告推送失败补偿机制;钉钉群通知消息核心代码
|
传感器 SQL 监控
如何用Python发送告警通知到钉钉?
如何用Python发送告警通知到钉钉?
603 0
如何用Python发送告警通知到钉钉?
|
Java Spring 自动驾驶
java面试题:什么是通知?
java面试题:什么是通知?
java面试题:什么是通知?
|
Linux
Centos7 root登录钉钉通知
Centos7 root登录钉钉通知
362 0
|
10天前
|
安全 Java 测试技术
Java并行流陷阱:为什么指定线程池可能是个坏主意
本文探讨了Java并行流的使用陷阱,尤其是指定线程池的问题。文章分析了并行流的设计思想,指出了指定线程池的弊端,并提供了使用CompletableFuture等替代方案。同时,介绍了Parallel Collector库在处理阻塞任务时的优势和特点。

热门文章

最新文章