(2条消息) 钉钉通知Java_学习微站的博客-CSDN博客_java钉钉通知

126 阅读1分钟

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

建好钉钉群,建好机器人

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

首先测试钉钉方法

/**
 * @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 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")privateStringmessageTopic;@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;


}

```

> 本文使用 [文章同步助手](https://juejin.cn/post/6940875049587097631) 同步