钉钉企业工作通知
工作通知由企业内部应用发出,可按员工、部门或全员触达。本文依据钉钉开放平台资料整理,核验日期为 2026-09-14;未执行真实组织发送验证。
| 问题 | 结论 |
|---|---|
| 接收对象 | 企业内部应用可见范围内的员工、部门或全员 |
| 是否直接发到普通群 | 不是;工作通知显示在应用工作通知入口,不等同于群机器人消息 |
| 是否同步返回最终结果 | 不是;异步接口返回 task_id,需要查询发送结果和失败名单 |
| 能否触达外部联系人 | 本接口面向当前企业内部成员,不能把外部联系人显示名当成 userid |
| 能否接收用户回复 | 本页能力只发送工作通知;双向消息使用企业机器人 |
- 能登录钉钉开放平台控制台,并选择正确的组织。
- 已创建企业内部应用,当前账号能维护应用权限、可见范围和版本。
- 应用可见范围先覆盖一个测试员工或测试部门。
- 已记录同一应用的 AppKey、AppSecret 和 AgentId,不能混用其他应用凭据。
- 服务端能保存 AppSecret、缓存
access_token并访问钉钉 OpenAPI。 - 已确认接收员工使用平台
userid,不是手机号、昵称或其他系统用户 ID。
如何判断自己有没有应用管理权限
Section titled “如何判断自己有没有应用管理权限”登录开放平台并选择目标组织后检查:
- 能创建企业内部应用:具备创建权限。
- 能进入应用并修改权限、可见范围和版本:具备维护权限。
- 能查看 AppKey、AgentId,并按安全流程取得 AppSecret:具备服务端接入所需凭据权限。
- 只能查看应用或无法发布:需要应用管理员或组织管理员授权。
群主身份不等于应用管理员。工作通知属于企业应用能力,必须从开放平台控制台配置。
1. 创建企业内部应用
Section titled “1. 创建企业内部应用”- 在开放平台控制台选择目标组织并创建企业内部应用。
- 填写应用名称、图标和说明,区分测试与生产应用。
- 在凭证页记录 AppKey、AppSecret 和 AgentId。
2. 配置权限、可见范围和版本
Section titled “2. 配置权限、可见范围和版本”- 申请工作通知发送所需权限,具体权限名称以当前控制台为准。
- 首次只把一个测试员工加入可见范围,不直接开放全员。
- 创建并发布应用版本;需要管理员审批时完成审批。
- 权限或可见范围变更后重新发布,确认新版本已生效。
3. 获取并缓存 access_token
Section titled “3. 获取并缓存 access_token”使用同一应用的 AppKey 与 AppSecret 获取 access_token。调用方需要判断 HTTP 状态和 errcode,按返回有效期缓存;不要每次发送都换取 Token。不同组织和应用使用独立缓存键。
4. 异步发送工作通知
Section titled “4. 异步发送工作通知”调用企业会话消息异步发送接口,提供 AgentId、接收员工或部门与消息体。userid_list、dept_id_list 和全员参数的组合及单次上限以官方接口页面为准,不要同时提交相互冲突的目标。
5. 查询发送结果
Section titled “5. 查询发送结果”受理成功后保存 task_id。通过官方发送结果查询能力检查实际成功、失败和无效用户;批量场景不能只看到 task_id 就把所有接收人标记成功。
| 字段 | 必需 | 说明 |
|---|---|---|
APP_KEY | 是 | 企业内部应用标识 |
APP_SECRET | 是 | 获取访问令牌的敏感凭据 |
AGENT_ID | 是 | 应用的 AgentId |
ACCESS_TOKEN | 是 | 有有效期的服务端访问令牌 |
USER_ID_LIST | 二选一 | 接收员工 ID 列表 |
DEPT_ID_LIST | 二选一 | 接收部门 ID 列表 |
AppKey、AppSecret 和 AgentId 必须来自同一应用。access_token 只能在服务端缓存;员工和部门目标必须在应用可见范围内。
JavaScript 示例需要 Node.js 20 或更新版本;Python 示例需要安装 requests。
curl 'https://oapi.dingtalk.com/gettoken?appkey=APP_KEY&appsecret=APP_SECRET'
curl -X POST 'https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2?access_token=ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{"agent_id":AGENT_ID,"userid_list":"USER_ID","msg":{"msgtype":"text","text":{"content":"通知渠道连通性测试"}}}'const tokenUrl = new URL('https://oapi.dingtalk.com/gettoken');tokenUrl.searchParams.set('appkey', process.env.APP_KEY);tokenUrl.searchParams.set('appsecret', process.env.APP_SECRET);const tokenResult = await fetch(tokenUrl).then((response) => response.json());if (tokenResult.errcode !== 0) throw new Error(JSON.stringify(tokenResult));
const response = await fetch( `https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2?access_token=${encodeURIComponent(tokenResult.access_token)}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ agent_id: Number(process.env.AGENT_ID), userid_list: process.env.USER_ID, msg: { msgtype: 'text', text: { content: '通知渠道连通性测试' } }, }), },);const result = await response.json();if (!response.ok || result.errcode !== 0) throw new Error(JSON.stringify(result));console.log(result);import osimport requests
token_response = requests.get( "https://oapi.dingtalk.com/gettoken", params={"appkey": os.environ["APP_KEY"], "appsecret": os.environ["APP_SECRET"]}, timeout=15,)token_response.raise_for_status()token_result = token_response.json()if token_result.get("errcode") != 0: raise RuntimeError(token_result)
response = requests.post( "https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2", params={"access_token": token_result["access_token"]}, json={ "agent_id": int(os.environ["AGENT_ID"]), "userid_list": os.environ["USER_ID"], "msg": {"msgtype": "text", "text": {"content": "通知渠道连通性测试"}}, }, timeout=15,)response.raise_for_status()result = response.json()if result.get("errcode") != 0: raise RuntimeError(result)print(result)接口受理成功时业务码应为 0 并返回 task_id。随后查询发送结果,核对成功数量、失败用户和失败原因,并由测试员工确认客户端实际收到工作通知。异步受理不代表每个接收人都已成功送达。
目标、配额与重试
Section titled “目标、配额与重试”- 员工、部门和全员发送都受应用可见范围、组织授权和官方接口单次上限约束。
- 大范围发送应分批并查询每个
task_id的发送结果,保留业务批次与平台任务的映射。 - Token 失效可刷新一次;权限不足、AgentId 不匹配、用户无效和不可见范围错误不能自动重试。
- 平台限流或临时服务错误按返回字段有限退避,重试前先确认原任务是否已经受理。
- AppSecret 和访问令牌只在服务端使用。
- 应用可见范围和消息权限保持最小化。
- 大批量发送前先用单一测试员工验证,避免误触达。
- 保存业务批次、
task_id和结果摘要,日志中不记录消息敏感正文。 - 全员发送属于高影响操作,应增加业务审批和接收人数上限保护。
员工不在可见范围:调整应用可见范围并确认发布生效。
AgentId 不匹配:AgentId 必须属于用于换取 Token 的同一应用。
异步接口成功但未收到:根据任务标识查询发送结果和失败原因。
取得 Token 但发送提示无权限:确认工作通知权限已审批并随应用版本发布,Token、AgentId 与应用一致。
部分员工未收到:查看发送结果中的无效或失败用户,核对员工是否激活、是否在可见范围以及 userid 来源。
超时后不知道能否重试:先查询原 task_id 或业务投递记录,确认接口是否已受理;不要直接重复批量发送。