关于推送钉钉消息和钉钉群消息 -YB
钉钉消息推送
一、MES 服务里调用发送钉钉消息
参考 1:达摩院温俊可的帖子:http://119.96.220.140:9099/article/1594458652783
参考 2:CSDN:https://blog.csdn.net/weixin_44994494/article/details/123729251
或者查看官方 api 文档。
另外:IMOM16L 项目已引入,可借鉴参考。
二、长春捷翼 - 周晓星做了一个钉钉消息推送的服务:
发送 post 请求给这个服务:
效果:
三、解放传动 - 客户提供了一个钉钉接口 - 给某个人推送钉钉消息
传参:组织 id、手机号、标题、内容,即可。要求手机号对应的人员在组织里。
接口地址:String url = “https://zd-faw-cn-8n8eppuothxcry.ztna-dingtalk.com/messageserver/message/push/V2”;
调用过程:
效果:
注意:换行拼接 \n\n
项目封装方法:MsgDingDingCDService#sendDingMsg()
四、解放传动 - 需要给某个钉钉群推送钉钉消息 - 参考大柴漆亮
找漆亮沟通后实现,他的笔记:
一汽大柴 MOM 项目:钉钉消息推送开发配置 v1.0-20240305.docx
使用钉钉群的自定义机器人。
他的主要代码:
自己实现后的效果:
注意:换行拼接 \n
项目封装方法:MsgDingDingCDService#sendGroupMessage()
五、解放传动 - 钉钉群配置升级改造 -20241112
开发页面配置群,作群、类型、工作中心的关联维护:
用于实现同一种群消息类型,不同的工作中心推送给不同的群。
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 + "×tamp=" + 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 消息弹窗 - 待根据大柴