Install any skill in seconds. Free to start, no credit card required.
Get Started Free →钉钉操作助手(DingTalk)。当用户通过钉钉对话、或提到以下任何场景时必须使用此技能:查人(查下某某、搜一下某人、找一下谁谁)、查部门、查手机号、查工号、约会议(预约会议、创建会议、安排会议、开个会)、发消息(给某人发消息、群里发个通知)、查审批(我的审批、待审批、审批状态)、发起审批、同意/拒绝审批、查日程、创建日程、查员工数、查离职、开视频会议、钉钉知识库(查钉钉知识库、在钉钉创建文档、搜索钉钉文档、覆写钉钉文档)。注意:当用户从钉钉渠道发送消息时,"知识库"默认指钉钉知识库,不是飞书知识库。Use when user mentions anything about DingTalk or when the message comes from a DingTalk channel: looking up people, searching users/departments, scheduling meetings, creating conferences, sending messages, managing approvals, checking calendar ev
.claude/skills/leoyeai-ding-skills/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | 233% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 258% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 378% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 280% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 186% | 0% |
钉钉全功能技能集:用户管理、部门管理、消息发送、OA审批、视频会议、日程管理。
DINGTALK_APP_KEY 和 DINGTALK_APP_SECRETbashexport DINGTALK_APP_KEY="<your-app-key>" export DINGTALK_APP_SECRET="<your-app-secret>" export DINGTALK_ROBOT_CODE="<your-robot-code>" # 可选,发消息时使用
大部分钉钉 API 需要 userId 或 unionId,但用户通常只会说人名。遇到人名时,必须先查人再执行操作。
当用户说"帮我和张三、李四开个会"或"预约一个会议,参会人:张三、李四"时:
步骤1: python scripts/search_user.py "张三" → 得到 userId
步骤2: python scripts/get_user.py "<userId>" → 得到 unionId
步骤3: 对每个参会人重复步骤1-2
步骤4: python scripts/create_schedule_conference.py "<主题>" "<发起人unionId>" "<开始时间>" "<结束时间>" "<参会人unionId1,unionId2>" "[会议地点]"当用户说"给张三发个消息"时:
步骤1: python scripts/search_user.py "张三" → 得到 userId
步骤2: python scripts/send_user_message.py "<userId>" "<消息内容>"注意:robotCode 自动从环境变量 DINGTALK_ROBOT_CODE 读取,也可作为第3个参数手动传入。
当用户说"查下张三的待审批"时:
步骤1: python scripts/search_user.py "张三" → 得到 userId
步骤2: python scripts/list_user_todo_approvals.py "<userId>"当用户说"查下张三今天的日程"时:
步骤1: python scripts/search_user.py "张三" → 得到 userId
步骤2: python scripts/get_user.py "<userId>" → 得到 unionId
步骤3: python scripts/list_events.py "<unionId>" "[开始时间]" "[结束时间]"当用户说"在知识库里创建一个文档"时:
步骤1: python scripts/search_user.py "张三" → 得到 userId
步骤2: python scripts/get_user.py "<userId>" → 得到 unionId
步骤3: python scripts/list_workspaces.py "<unionId>" → 得到 workspaceId
步骤4: python scripts/create_doc.py "<workspaceId>" "<文档名>" "<unionId>"当用户说"帮我找一下知识库里的《周报》"时:
步骤1: python scripts/search_user.py "张三" → 得到 userId
步骤2: python scripts/get_user.py "<userId>" → 得到 unionId
步骤3: python scripts/search_doc.py "<unionId>" "周报" → 得到文档链接search_user.py 获取 userIdget_user.py 从 userId 获取 unionId根据姓名搜索用户,返回匹配的 UserId 列表。
bashpython scripts/search_user.py "<搜索关键词>"
输出:
json{ "success": true, "keyword": "张三", "totalCount": 3, "hasMore": false, "userIds": ["123456789", "987654321"] }
获取指定用户的详细信息。
bashpython scripts/get_user.py "<userId>"
输出:
json{ "success": true, "user": { "userid": "user001", "name": "张三", "mobile": "138****1234", "dept_id_list": [12345], "unionid": "xxxxx" } }
bashpython scripts/get_user_by_mobile.py "<手机号>"
输出:
json{ "success": true, "mobile": "13800138000", "userId": "user001" }
bashpython scripts/get_user_by_unionid.py "<unionid>"
输出:
json{ "success": true, "unionid": "xxxxx", "userId": "user001" }
bashpython scripts/get_user_count.py [--onlyActive]
输出:
json{ "success": true, "onlyActive": false, "count": 150 }
bashpython scripts/get_user_todo_count.py "<userId>"
输出:
json{ "success": true, "userId": "user001", "count": 5 }
bashpython scripts/list_inactive_users.py "<queryDate>" [--deptIds "id1,id2"] [--offset 0] [--size 100]
queryDate 格式: yyyyMMdd
输出:
json{ "success": true, "queryDate": "20240115", "userIds": ["user001"], "hasMore": false }
bashpython scripts/list_resigned_users.py "<startTime>" ["<endTime>"] [--nextToken "xxx"] [--maxResults 100]
startTime/endTime 格式: ISO8601
输出:
json{ "success": true, "startTime": "2024-01-01T00:00:00+08:00", "records": [{ "userId": "user001", "name": "张三", "leaveTime": "2024-01-15T10:00:00Z" }] }
bashpython scripts/search_department.py "<搜索关键词>"
输出:
json{ "success": true, "keyword": "技术部", "totalCount": 2, "departmentIds": [12345, 67890] }
bashpython scripts/get_department.py "<deptId>"
输出:
json{ "success": true, "department": { "deptId": 12345, "name": "技术部", "parentId": 1 } }
根部门 deptId = 1。
bashpython scripts/list_sub_departments.py "<deptId>"
输出:
json{ "success": true, "deptId": 1, "subDepartmentIds": [12345, 67890] }
自动分页获取所有用户(简略信息)。
bashpython scripts/list_department_users.py "<deptId>"
输出:
json{ "success": true, "deptId": 12345, "users": [{ "userId": "user001", "name": "张三" }, { "userId": "user002", "name": "李四" }] }
分页获取,支持 cursor 和 size。
bashpython scripts/list_department_user_details.py "<deptId>" [--cursor 0] [--size 100]
输出:
json{ "success": true, "deptId": 12345, "users": [...], "hasMore": true, "nextCursor": 100 }
bashpython scripts/list_department_user_ids.py "<deptId>"
输出:
json{ "success": true, "deptId": 12345, "userIds": ["user001", "user002"] }
bashpython scripts/list_department_parents.py "<deptId>"
输出:
json{ "success": true, "deptId": 12345, "parentIdList": [12345, 67890, 1] }
bashpython scripts/list_user_parent_departments.py "<userId>"
输出:
json{ "success": true, "userId": "user001", "parentIdList": [12345, 1] }
bashpython scripts/get_bot_list.py "<openConversationId>"
输出:
json{ "success": true, "openConversationId": "cid", "botList": [{ "robotCode": "code", "robotName": "name" }] }
robotCode 自动从环境变量 DINGTALK_ROBOT_CODE 读取,也可作为第3个参数手动传入。
bashpython scripts/send_group_message.py "<openConversationId>" "<消息内容>" ["<robotCode>"]
输出:
json{ "success": true, "openConversationId": "cid", "robotCode": "code", "processQueryKey": "key", "message": "消息内容" }
robotCode 自动从环境变量 DINGTALK_ROBOT_CODE 读取,也可作为第3个参数手动传入。
bashpython scripts/send_user_message.py "<userId>" "<消息内容>" ["<robotCode>"]
输出:
json{ "success": true, "userId": "user001", "robotCode": "code", "processQueryKey": "key", "message": "消息内容" }
bashpython scripts/list_approval_instance_ids.py "<processCode>" --startTime <timestamp> --endTime <timestamp> [--size 20] [--nextToken "xxx"]
输出:
json{ "success": true, "processCode": "PROC-XXX", "instanceIds": ["id1", "id2"], "totalCount": 2, "hasMore": false }
bashpython scripts/get_approval_instance.py "<instanceId>"
输出:
json{ "success": true, "instanceId": "xxx-123", "instance": { "processInstanceId": "xxx-123", "title": "请假申请", "status": "COMPLETED", "formComponentValues": [...], "tasks": [...] } }
bashpython scripts/list_user_initiated_approvals.py "<userId>" [--startTime <ts>] [--endTime <ts>] [--maxResults 20]
输出:
json{ "success": true, "userId": "user001", "instances": [...], "totalCount": 5, "hasMore": false }
bashpython scripts/list_user_cc_approvals.py "<userId>" [--startTime <ts>] [--endTime <ts>] [--maxResults 20]
bashpython scripts/list_user_todo_approvals.py "<userId>" [--maxResults 20]
输出:
json{ "success": true, "userId": "user001", "instances": [...], "totalCount": 3, "hasMore": false }
bashpython scripts/list_user_done_approvals.py "<userId>" [--startTime <ts>] [--endTime <ts>] [--maxResults 20]
bashpython scripts/create_approval_instance.py "<processCode>" "<originatorUserId>" "<deptId>" '<formValuesJson>' [--ccList "user1,user2"]
formValuesJson 示例: '[{"name":"标题","value":"请假申请"}]'
输出:
json{ "success": true, "processCode": "PROC-XXX", "originatorUserId": "user001", "instanceId": "xxx-new" }
bashpython scripts/terminate_approval_instance.py "<instanceId>" "<operatingUserId>" ["<remark>"]
输出:
json{ "success": true, "instanceId": "xxx-123", "message": "审批实例已撤销" }
同意或拒绝审批任务。
bashpython scripts/execute_approval_task.py "<instanceId>" "<userId>" "<agree|refuse>" [--taskId "xxx"] [--remark "审批意见"]
输出:
json{ "success": true, "instanceId": "xxx-123", "userId": "user001", "action": "agree", "message": "已同意审批" }
bashpython scripts/transfer_approval_task.py "<instanceId>" "<userId>" "<transferToUserId>" [--taskId "xxx"] [--remark "转交原因"]
输出:
json{ "success": true, "instanceId": "xxx-123", "userId": "user001", "transferToUserId": "user002", "message": "审批任务已转交" }
bashpython scripts/add_approval_comment.py "<instanceId>" "<commentUserId>" "<评论内容>"
输出:
json{ "success": true, "instanceId": "xxx-123", "userId": "user001", "message": "评论已添加" }
立即创建视频会议并邀请参会人。
bashpython scripts/create_video_conference.py "<会议主题>" "<发起人unionId>" "[邀请人unionId1,unionId2]"
输出:
json{ "success": true, "title": "测试会议", "conferenceId": "xxx", "conferencePassword": "123456" }
bashpython scripts/close_video_conference.py "<conferenceId>" "<操作人unionId>"
输出:
json{ "success": true, "conferenceId": "xxx", "message": "视频会议已关闭" }
通过日历 API 创建预约会议,自动关联钉钉视频会议,日程会出现在钉钉日历中。
bashpython scripts/create_schedule_conference.py "<会议主题>" "<创建人unionId>" "<开始时间>" "<结束时间>" "[参会人unionId1,unionId2]" "[会议地点]"
时间格式: "2026-03-16 14:00" 或 ISO 8601
输出:
json{ "success": true, "title": "周会", "eventId": "NXZCUEtxOGZMN3JpcDQ3ZE45UVRFdz09", "onlineMeetingUrl": "dingtalk://...", "conferenceId": "xxx", "startTime": "2026-03-16T14:00:00+08:00", "endTime": "2026-03-16T15:00:00+08:00", "attendeeCount": 2 }
bashpython scripts/cancel_schedule_conference.py "<scheduleConferenceId>" "<创建人unionId>"
输出:
json{ "success": true, "scheduleConferenceId": "xxx", "message": "预约会议已取消" }
bashpython scripts/list_events.py "<用户unionId>" [--time-min "2026-03-01 00:00"] [--time-max "2026-03-31 23:59"]
输出:
json{ "success": true, "totalCount": 5, "events": [{ "id": "eventId", "summary": "周会", "start": {...}, "end": {...} }] }
bashpython scripts/get_event.py "<用户unionId>" "<eventId>"
输出:
json{ "success": true, "event": { "id": "eventId", "summary": "周会", "attendees": [...], "onlineMeetingInfo": {...} } }
bashpython scripts/delete_event.py "<用户unionId>" "<eventId>" [--push-notification]
输出:
json{ "success": true, "eventId": "xxx", "message": "日程已删除" }
bashpython scripts/add_event_attendee.py "<用户unionId>" "<eventId>" "<参与者unionId1,unionId2>"
输出:
json{ "success": true, "eventId": "xxx", "addedCount": 2, "message": "已添加 2 位参与者" }
bashpython scripts/remove_event_attendee.py "<用户unionId>" "<eventId>" "<参与者unionId1,unionId2>"
输出:
json{ "success": true, "eventId": "xxx", "removedCount": 1, "message": "已移除 1 位参与者" }
获取用户能访问的所有知识库。
bashpython scripts/list_workspaces.py "<操作人unionId>"
输出:
json{ "success": true, "totalCount": 2, "workspaces": [ { "workspaceId": "xxx", "name": "技术部知识库", "type": "TEAM", "url": "https://...", "rootNodeId": "yyy" } ] }
在指定知识库中创建新文档。
bashpython scripts/create_doc.py "<workspaceId>" "<文档名>" "<操作人unionId>" ["<docType>"]
docType 可选值:alidoc(钉钉文档,默认)、alisheet(表格)、alinote(笔记)
输出:
json{ "success": true, "name": "周报", "docType": "alidoc", "workspaceId": "xxx", "nodeId": "yyy", "docKey": "zzz", "url": "https://..." }
根据文档名关键词搜索知识库文档,返回文档链接。
bashpython scripts/search_doc.py "<操作人unionId>" "<文档名关键词>" ["<workspaceId>"]
不指定 workspaceId 时搜索所有知识库。
输出:
json{ "success": true, "keyword": "周报", "totalCount": 3, "documents": [ { "name": "3月第2周周报", "nodeId": "xxx", "url": "https://...", "category": "ALIDOC", "workspaceName": "技术部知识库" } ] }
覆写知识库文档的全部内容(全量替换,非追加)。
bashpython scripts/overwrite_doc.py "<workspaceId>" "<nodeId>" "<操作人unionId>" "<内容>"
输出:
json{ "success": true, "workspaceId": "xxx", "nodeId": "yyy", "message": "文档内容已覆写" }
所有脚本在错误时返回统一格式:
json{ "success": false, "error": { "code": "ERROR_CODE", "message": "错误描述" } }
常见错误码:
MISSING_CREDENTIALS - 未设置环境变量INVALID_ARGS - 参数不足UNKNOWN_ERROR - API 调用异常userId 是企业内部用户 ID,unionId 是全局唯一标识unionId,可通过 get-user 查询获取workspaceId 通过 list-workspaces 获取,nodeId 通过 search-doc 获取| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-03 | fail→fail | 6,596 | 4,347 | -34% | 1 | 1 | 0% | 670 | 5,904 | +781% | 0 | 0 | — |
case-02 | fail→fail | 4,837 | 3,673 | -24% | 1 | 1 | 0% | 401 | 5,870 | +1364% | 0 | 0 | — |
case-01 | fail→fail | 5,530 | 8,047 | +46% | 1 | 1 | 0% | 1,196 | 6,229 | +421% | 0 | 0 | — |
case-04 | pass→pass | 12,221 | 9,436 | -23% | 1 | 1 | 0% | 2,714 | 7,717 | +184% | 0 | 0 | — |
case-05 | pass→pass | 10,323 | 5,327 | -48% | 1 | 1 | 0% | 2,315 | 6,772 | +193% | 0 | 0 | — |
case-06 | pass→pass | 15,030 | 10,405 | -31% | 1 | 1 | 0% | 3,193 | 7,896 | +147% | 0 | 0 | — |
case-07 | fail→pass | 9,999 | 3,447 | -66% | 1 | 1 | 0% | 1,893 | 6,309 | +233% | 0 | 0 | — |
case-08 | fail→pass | 8,308 | 5,254 | -37% | 1 | 1 | 0% | 1,892 | 6,774 | +258% | 0 | 0 | — |
case-09 | fail→pass | 6,499 | 2,959 | -54% | 1 | 1 | 0% | 1,329 | 6,346 | +378% | 0 | 0 | — |
case-10 | fail→pass | 12,112 | 2,236 | -82% | 1 | 1 | 0% | 1,597 | 6,075 | +280% | 0 | 0 | — |
case-11 | fail→pass | 8,542 | 2,338 | -73% | 1 | 1 | 0% | 2,134 | 6,103 | +186% | 0 | 0 | — |
case-12 | fail→pass | 9,528 | 2,813 | -70% | 1 | 1 | 0% | 2,140 | 6,234 | +191% | 0 | 0 | — |
case-13 | fail→pass | 6,324 | 1,796 | -72% | 1 | 1 | 0% | 1,369 | 6,008 | +339% | 0 | 0 | — |
case-14 | fail→pass | 8,364 | 3,270 | -61% | 1 | 1 | 0% | 2,082 | 6,276 | +201% | 0 | 0 | — |
case-15 | fail→pass | 9,692 | 2,263 | -77% | 1 | 1 | 0% | 2,060 | 6,059 | +194% | 0 | 0 | — |
case-16 | fail→pass | 14,374 | 5,359 | -63% | 1 | 1 | 0% | 3,074 | 6,797 | +121% | 0 | 0 | — |
case-17 | fail→pass | 8,214 | 2,156 | -74% | 1 | 1 | 0% | 1,659 | 6,097 | +268% | 0 | 0 | — |
case-18 | fail→pass | 10,241 | 2,421 | -76% | 1 | 1 | 0% | 1,846 | 6,071 | +229% | 0 | 0 | — |
case-19 | fail→pass | 11,979 | 2,949 | -75% | 1 | 1 | 0% | 2,554 | 6,251 | +145% | 0 | 0 | — |
case-20 | fail→pass | 7,938 | 2,081 | -74% | 1 | 1 | 0% | 1,739 | 6,068 | +249% | 0 | 0 | — |
case-21 | fail→pass | 8,329 | 1,999 | -76% | 1 | 1 | 0% | 1,802 | 6,081 | +237% | 0 | 0 | — |
case-22 | pass→pass | 6,163 | 2,145 | -65% | 1 | 1 | 0% | 1,368 | 6,022 | +340% | 0 | 0 | — |
case-23 | fail→pass | 10,013 | 8,360 | -17% | 1 | 1 | 0% | 1,989 | 7,356 | +270% | 0 | 0 | — |
case-24 | fail→pass | 8,976 | 1,829 | -80% | 1 | 1 | 0% | 2,074 | 5,997 | +189% | 0 | 0 | — |
case-25 | fail→pass | 8,476 | 1,979 | -77% | 1 | 1 | 0% | 2,151 | 6,026 | +180% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 25 cases were attempted, and 22 counted toward the lift figure. The other 3 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +72 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.