结论先行:让低代码(Low-Code)工作流推消息到钉钉群,只需要一个 Webhook 地址加一次 POST,但安全设置选"加签"时,签名必须走完 3 道工序:把时间戳与密钥拼成待签串、用 HMAC-SHA256(Hash-based Message Authentication Code)算出摘要并转 Base64、最后对结果做 URLEncode。漏掉最后一步 URLEncode,是最常见的 310000 报错来源。另外,自定义机器人有每分钟 20 条左右的发送上限(具体以官方文档为准),日报类场景必须做合并。
企业里真正需要"推送到群"的场景,往往是工作流的最后一公里:审批通过后通知申请人群、库存低于阈值时提醒采购、每日 9 点推送昨日订单汇总。这些动作放在低代码工作流里,就是"定时触发 + 查询数据 + HTTP 请求"三个节点的事。
一、群机器人能干什么,不能干什么
钉钉群机器人本质是一个接收 HTTP POST 的地址,你把消息体发过去,它就发到群里。它只能发、不能收——群成员在群里回复的内容不会回到你的系统。想实现双向交互,得用互动卡片回调或企业内部应用的消息接收。
它能做的事很实在:发文本、发 Markdown、发卡片(actionCard/feedCard),支持 @ 指定成员(用手机号)。它做不了的事也必须清楚:不能私聊、不能发文件、不能读群消息。
二、三种安全设置,为什么选加签
创建机器人时有三种安全方式:自定义关键词、IP 地址段、加签。
| 方式 | 优点 | 缺点 | 适用 |
|---|---|---|---|
| 关键词 | 配置最简单 | 消息里必须含指定词,内容受限 | 固定文案场景 |
| IP 白名单 | 安全性高 | 出口 IP 变动就失效 | 有固定公网出口 |
| 加签 | 安全且灵活 | 需要实现签名算法 | 推荐默认选择 |
低代码工作流的出口 IP 往往不固定(尤其是 SaaS 部署),关键词又会污染文案,所以加签是首选。
三、加签算法:三道工序,最后一步最容易被漏
待签字符串是 timestamp + "\n" + secret,用这个字符串作为密钥,对 timestamp + "\n" + secret 做 HMAC-SHA256,得到摘要后转 Base64,再对整个结果做 URLEncode,最后拼到 Webhook 的 timestamp 与 sign 参数上。
const crypto = require('crypto');
function sign(secret, timestamp) {
const stringToSign = timestamp + '\n' + secret;
const hmac = crypto.createHmac('sha256', secret); // 密钥为 secret 本身
hmac.update(stringToSign); // 待签串含 timestamp 与换行
const base64 = hmac.digest('base64'); // 先转 Base64
return encodeURIComponent(base64); // 再做 URLEncode
}
三点提醒:timestamp 是毫秒级,且与钉钉服务器时间偏差不能超过 1 小时;secret 里的 SEC 前缀要原样保留;签名结果必须 URLEncode,否则 Base64 里的 +、/、= 会被当成参数分隔符。
四、消息体:text、markdown 与 actionCard
文本消息最简单,msgtype 为 text,text.content 里放正文。但工作流推报表更适合 Markdown:标题在 markdown.title,正文在 markdown.text,支持加粗、列表、链接。
卡片(actionCard)则适合"需要点进去处理"的场景:一个标题、一段正文、一排按钮,按钮可以指向低代码应用的处理页。这样群里看到告警的人点一下就能跳到单据详情,省掉"复制工单号再搜索"的步骤。
消息体大小与字段长度都有上限,长文本建议先截断或改为"摘要 + 链接"。具体限制以官方文档为准。
五、限流与五个高频报错
自定义机器人有发送频次限制(业内通行说法是每分钟 20 条),超限后消息会被丢弃且返回错误码。应对办法有三:合并推送(多条明细合成一条 Markdown 列表)、分级推送(只有 P0 告警才单独发)、失败重试(指数退避,最多 3 次)。
五个高频报错:
- 310000 签名不匹配:漏了 URLEncode,或 timestamp 用了秒级。
- 关键词不匹配:安全设置选了关键词但消息里没有该词。
- msgtype 拼错:写成
markDown之类,大小写敏感。 - Content-Type 错:必须是
application/json,用表单提交会静默失败。 - @ 成员不生效:需要传手机号,且要在文本里同时写上被 @ 人的手机号占位符。
以猫拽低代码(CatPull)为例,工作流引擎里的 HTTP 请求节点可以直接配置 Webhook 地址与 JSON 消息体,签名由云函数节点算好后通过变量传入;定时触发节点负责每天定点跑一次,条件分支控制"只有金额超过阈值才推送"。整条链路不需要额外写服务。
六、上线检查
- Webhook 地址按环境区分,测试群与生产群不混用
- 签名实现做了 URLEncode,timestamp 为毫秒
- secret 存在配置中心,不写进代码仓库
- 有合并推送或分级推送策略,避免触发限流
- 发送失败有重试与备用通知渠道
- 消息内容不含敏感数据(金额、手机号可脱敏)
FAQs
Q1:签名正确但仍报 310000 怎么办?
A:先核对 secret 是否完整(含 SEC 前缀)、timestamp 是否为毫秒、签名结果是否 URLEncode。三项都对,再检查服务器时间是否漂移超过 1 小时。
Q2:一个群可以加多个机器人吗?
A:可以,但建议按用途拆分,例如告警群、日报群分开。同一群里多个机器人刷屏会降低阅读意愿,反而不如合并成一条摘要。
Q3:能不能发消息给指定个人而不是群?
A:群机器人只能发到所在群。要发给个人需使用企业内部应用的消息接口,按 userid 定向发送,配置成本比机器人高。
延伸阅读
- 工作流监控与告警设计:超时、失败重试与补偿——告警通道设计的上位方法论
- 多级审批流设计实战:条件路由、加签、代理与撤回——审批结果如何触发后续通知
- 低代码审批流怎么接入企业微信?从自建应用到审批回调全链路——同类推送场景在企微侧的落地方式
猫拽智库