关于推送钉钉消息和钉钉群消息 -YB

钉钉消息推送

一、MES 服务里调用发送钉钉消息

参考 1:达摩院温俊可的帖子:http://119.96.220.140:9099/article/1594458652783

参考 2:CSDN:https://blog.csdn.net/weixin_44994494/article/details/123729251

或者查看官方 api 文档。
image.png

另外:IMOM16L 项目已引入,可借鉴参考。

二、长春捷翼 - 周晓星做了一个钉钉消息推送的服务:

发送 post 请求给这个服务:
image.png

效果:
image.png

三、解放传动 - 客户提供了一个钉钉接口 - 给某个人推送钉钉消息

传参:组织 id、手机号、标题、内容,即可。要求手机号对应的人员在组织里。

接口地址:String url = “https://zd-faw-cn-8n8eppuothxcry.ztna-dingtalk.com/messageserver/message/push/V2”;

调用过程:
image.png

效果:
image.png

注意:换行拼接 \n\n

项目封装方法:MsgDingDingCDService#sendDingMsg()

四、解放传动 - 需要给某个钉钉群推送钉钉消息 - 参考大柴漆亮

找漆亮沟通后实现,他的笔记:
一汽大柴 MOM 项目:钉钉消息推送开发配置 v1.0-20240305.docx

使用钉钉群的自定义机器人。

他的主要代码:

image.png

自己实现后的效果:
image.png

注意:换行拼接 \n

项目封装方法:MsgDingDingCDService#sendGroupMessage()

五、解放传动 - 钉钉群配置升级改造 -20241112

开发页面配置群,作群、类型、工作中心的关联维护:
image.png

用于实现同一种群消息类型,不同的工作中心推送给不同的群。
V20241112_ 建表钉钉群配置主子表.sql
主要代码:

/** * @MethodName: dingUrlCenter * @Description: 获取钉钉群消息的推送url。 对应功能名、工作中心编码找到对应钉钉群发送群消息-20241113 新增钉钉群配置主子表后使用。 * @param funcName 功能节点名称 * @param centerCode 工作中心编码 * @Return List<String> 可能找到多个适配的钉钉群地址,就都要分别推一次 * @Author: yuanbao * @Date: 2024/11/13 **/ @SneakyThrows private List<String> dingUrlCenter(String funcName, String centerCode) { List<String> list = new ArrayList<>(); // 钉钉群机器人地址 String webhook = ""; // 以前默认给质量的 sysParamManager.getSysParamValByCode("DD_CD_GROUP_URL") String secret = ""; // sysParamManager.getSysParamValByCode("DD_CD_GROUP_SECRET") List<MtsDinggroupConfig> configListTotal = Lists.newArrayList(); // 找钉钉群按功能名称匹配,是否按工作中心的分为两部分分别查询 // a.关联工作中心的、严格匹配工作中心 String hql = "select c from MtsDinggroupConfigCenter cc left join cc.config c where cc.isDelete=0 and c.isDelete=0" + " and c.isActive=0 and c.isRelCenter=1 and c.funcNode like '%" + funcName + "%' and cc.workCenterCode = :centerCode"; List<MtsDinggroupConfig> configList = this.getDao().createQuery(hql).setParameter("centerCode", centerCode).list(); configListTotal.addAll(configList); // b.不需要关联工作中心的 String hql2 = "select c from MtsDinggroupConfig c where c.isDelete=0 and c.isActive=0 and c.isRelCenter!=1 and c.funcNode like '%" + funcName + "%'"; List<MtsDinggroupConfig> configList2 = this.getDao().createQuery(hql2).list(); configListTotal.addAll(configList2); // 遍历处理 long timestamp = Instant.now().toEpochMilli(); Mac mac = Mac.getInstance("HmacSHA256"); for (MtsDinggroupConfig config : configListTotal) { webhook = config.getGroupUrl(); secret = config.getGroupLicense(); String stringToSign = timestamp + "\n" + secret; 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"); String url = webhook + "&timestamp=" + timestamp + "&sign=" + sign; list.add(url); } return list; } /** * @MethodName: sendGroupMessage * @Description: 【重要】发送普通消息到钉钉群,支持 @指定的群成员,对应功能名、工作中心编码找到对应钉钉群发送群消息-20241113 新增钉钉群配置主子表后使用。 * @param message 消息内容 text格式 * @param isNotAll 是否 @群内所有人 * @param userIds 被@人的手机号(支持多个) * @param funcName 功能节点名称 * @param centerCode 工作中心编码 * @Return void * @Author: yuanbao * @Date: 2024/11/13 **/ public void sendGroupMessage(String message, boolean isNotAll, List<String> userIds, String funcName, String centerCode) throws ApiException { // 1、查询钉钉群配置主子表,根据功能名、工作中心编码找到对应钉钉群 // 可能有多个钉钉群都符合,就分别都推送一次 List<String> dingUrlList = dingUrlCenter(funcName, centerCode); if (dingUrlList.size() <= 0) { MestarLogger.info(String.format("钉钉群配置没有找到符合的钉钉群,请检查!功能节点为:%s,工作中心为:%s", funcName, centerCode)); return; } // 2、遍历钉钉群,分别发送消息 for (String dingUrl : dingUrlList) { DingTalkClient client = new DefaultDingTalkClient(dingUrl); OapiRobotSendRequest request = new OapiRobotSendRequest(); // 消息类型,此时固定为:text request.setMsgtype("text"); OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text(); // 消息内容 text.setContent(message); request.setText(text); OapiRobotSendRequest.At at = new OapiRobotSendRequest.At(); // @ 群成员list // 用户转化手机号 List<String> mobiles = this.getUserMobiles(userIds, 0); at.setAtMobiles(mobiles); // 不 @ 所有人 at.setIsAtAll(isNotAll); request.setAt(at); client.execute(request); } }

六、消息的相关规范

1、消息类别:

  • WEB/APP 消息(是同一个表),推送单人还是多人。多人是分别一条还是共用同一条,如根据角色取到所有用户共用一条消息。
  • 钉钉消息
  • 钉钉群消息(需给定群名,如质量群、调度群)

2、什么时候触发推送消息

哪个页面哪个操作触发,推送什么类型的消息,消息内容是啥。

3、消息体格式:

需给定标题、内容、消息接收者。
一般某个单据的操作推送消息,其标题是固定的,内容可根据单据信息拼接,接收者为单据的某字段。

用 {} 表示取单据上的字段代入。
完整格式 DEMO:
标题:
异常发起消息
内容:
工作中心:{异常单据的工作中心字段}
工位:{异常单据的工位字段}
异常类型:{异常单据的异常类型字段}
异常内容:{异常单据的异常内容字段}
异常描述:{异常单据的异常描述字段}
发起人:{异常单据的 createId 字段,需取真实姓名}
接收者:
{异常流程中相应节点对应的角色下的所有人,逗号拼接}

4、待优化项:

  • APP 消息模块升级 webSocket- 下周优先处理掉
  • WEB 消息弹窗 - 待根据大柴

七、核心代码文件:

MsgDingDingCDService.java