dingtalk-workspace-cli
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDingTalk Workspace CLI (dws)
DingTalk Workspace CLI (dws)
Skill by ara.so — Devtools Skills collection.
DingTalk Workspace CLI () is an officially open-sourced cross-platform CLI tool from DingTalk that unifies DingTalk's full suite of product capabilities (contacts, calendars, documents, todos, AI tables, chat, drive, attendance, reports, meetings) into a single package. It's designed for both human users and AI agent scenarios, with structured JSON responses, OAuth device-flow authentication, and enterprise-grade security.
dws由ara.so提供的Skill——Devtools Skills合集。
DingTalk Workspace CLI()是钉钉官方开源的跨平台CLI工具,将钉钉全系列产品能力(联系人、日历、文档、待办事项、AI表格、聊天、云盘、考勤、汇报、会议)整合到一个工具包中。它面向人类用户和AI Agent场景设计,支持结构化JSON响应、OAuth设备流认证,具备企业级安全性。
dwsInstallation
安装
macOS / Linux:
bash
curl -fsSL https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install.sh | shWindows (PowerShell):
powershell
irm https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install.ps1 | iexnpm (requires Node.js):
bash
npm install -g dingtalk-workspace-cliBuild from source (Go 1.25+):
bash
git clone https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli.git
cd dingtalk-workspace-cli
go build -o dws ./cmd
cp dws ~/.local/bin/Upgrade (requires v1.0.7+):
bash
dws upgrade # interactive upgrade
dws upgrade --check # check without installing
dws upgrade --version v1.0.7 # specific version
dws upgrade --rollback # rollbackmacOS / Linux:
bash
curl -fsSL https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install.sh | shWindows(PowerShell):
powershell
irm https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install.ps1 | iexnpm(需Node.js):
bash
npm install -g dingtalk-workspace-cli从源码构建(Go 1.25+):
bash
git clone https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli.git
cd dingtalk-workspace-cli
go build -o dws ./cmd
cp dws ~/.local/bin/升级(需v1.0.7+):
bash
dws upgrade # 交互式升级
dws upgrade --check # 仅检查版本不安装
dws upgrade --version v1.0.7 # 指定版本升级
dws upgrade --rollback # 回滚版本Authentication
认证
Interactive login (browser):
bash
dws auth loginDevice flow (headless environments):
bash
dws auth login --deviceCustom app (CI/CD, ISV integration):
bash
dws auth login --client-id $DINGTALK_CLIENT_ID --client-secret $DINGTALK_CLIENT_SECRETCheck auth status:
bash
dws auth statusLogout:
bash
dws auth logout交互式登录(浏览器):
bash
dws auth login设备流登录(无头环境):
bash
dws auth login --device自定义应用(CI/CD、ISV集成):
bash
dws auth login --client-id $DINGTALK_CLIENT_ID --client-secret $DINGTALK_CLIENT_SECRET检查认证状态:
bash
dws auth status登出:
bash
dws auth logoutCore Architecture
核心架构
Product Services
产品服务
DingTalk Workspace is organized into product services:
| Service | Commands | Use Cases |
|---|---|---|
| user, dept, org | Search users, list departments, get org info |
| event | Create/list/update/delete calendar events |
| space, base, table, record, field, view | Query/create AI table records, manage schema |
| search, create | Search DingTalk Docs, create documents |
| task, category | Create/list/update todos, manage categories |
| send, list | Send messages, list conversations |
| list, upload, download | Manage DingTalk drive files |
| record, shift | Get attendance records, query shifts |
| list | List reports (inbox/sent/created) |
| list, detail | Get AI meeting minutes |
| group, message | Manage IM groups, send messages |
钉钉工作台按产品服务分类:
| 服务 | 命令 | 使用场景 |
|---|---|---|
| user, dept, org | 搜索用户、列出部门、获取组织信息 |
| event | 创建/列出/更新/删除日历事件 |
| space, base, table, record, field, view | 查询/创建AI表格记录、管理数据结构 |
| search, create | 搜索钉钉文档、创建文档 |
| task, category | 创建/列出/更新待办事项、管理分类 |
| send, list | 发送消息、列出会话 |
| list, upload, download | 管理钉盘文件 |
| record, shift | 获取考勤记录、查询排班 |
| list | 列出汇报(收件箱/已发送/我创建的) |
| list, detail | 获取AI会议纪要 |
| group, message | 管理IM群组、发送消息 |
Global Flags
全局参数
bash
undefinedbash
undefinedOutput formats
输出格式
-f, --format table|json|raw # table (human), json (structured), raw (API response)
-f, --format table|json|raw # table(易读格式)、json(结构化格式)、raw(API原始响应)
JQ filtering (extract specific fields)
JQ过滤(提取指定字段)
--jq '.result[0].name' # save tokens, extract precisely
--jq '.result[0].name' # 减少数据量,精准提取所需字段
Dry run (preview without executing)
试运行(预览操作不执行)
--dry-run # see request payload before sending
--dry-run # 查看请求负载再执行
Skip confirmation (required for AI agents)
跳过确认(AI Agent场景必填)
--yes, -y # auto-confirm destructive operations
--yes, -y # 自动确认破坏性操作
Debug
调试
--debug # verbose logging
undefined--debug # 详细日志输出
undefinedKey Commands & Patterns
核心命令与使用模式
Contact Management
联系人管理
Search users:
bash
undefined搜索用户:
bash
undefinedBasic search
基础搜索
dws contact user search --query "engineering"
dws contact user search --query "engineering"
With filtering and formatting
带过滤和格式设置
dws contact user search --query "zhang" -f json --jq '.result[] | {name: .name, userId: .userId, mobile: .mobile}'
dws contact user search --query "zhang" -f json --jq '.result[] | {name: .name, userId: .userId, mobile: .mobile}'
Dry run
试运行
dws contact user search --query "zhang" --dry-run
**Get current user:**
```bash
dws contact user get-self -f json --jq '.result[0].orgEmployeeModel | {name: .orgUserName, userId: .userId, depts: [.depts[].deptName]}'Get user by ID:
bash
dws contact user get --user-id "USER_ID"List departments:
bash
undefineddws contact user search --query "zhang" --dry-run
**获取当前用户信息:**
```bash
dws contact user get-self -f json --jq '.result[0].orgEmployeeModel | {name: .orgUserName, userId: .userId, depts: [.depts[].deptName]}'按ID获取用户信息:
bash
dws contact user get --user-id "USER_ID"列出部门:
bash
undefinedRoot departments
根部门
dws contact dept list
dws contact dept list
Subdepartments
子部门
dws contact dept list --dept-id "DEPT_ID"
dws contact dept list --dept-id "DEPT_ID"
Extract specific fields
提取指定字段
dws contact dept list --jq '.result[] | {id: .deptId, name: .name}'
**List department members:**
```bash
dws contact dept members --dept-id "DEPT_ID" -f jsondws contact dept list --jq '.result[] | {id: .deptId, name: .name}'
**列出部门成员:**
```bash
dws contact dept members --dept-id "DEPT_ID" -f jsonCalendar Events
日历事件
List events:
bash
undefined列出事件:
bash
undefinedToday's events
今日事件
dws calendar event list
dws calendar event list
Date range
指定日期范围
dws calendar event list --start-time "2026-05-20T00:00:00+08:00" --end-time "2026-05-21T00:00:00+08:00"
dws calendar event list --start-time "2026-05-20T00:00:00+08:00" --end-time "2026-05-21T00:00:00+08:00"
Extract fields
提取字段
dws calendar event list --jq '.result[] | {title: .summary, start: .start.dateTime, attendees: [.attendees[].displayName]}'
**Create event:**
```bashdws calendar event list --jq '.result[] | {title: .summary, start: .start.dateTime, attendees: [.attendees[].displayName]}'
**创建事件:**
```bashBasic event
基础事件
dws calendar event create
--summary "Team Sync"
--start-time "2026-05-20T14:00:00+08:00"
--end-time "2026-05-20T15:00:00+08:00"
--yes
--summary "Team Sync"
--start-time "2026-05-20T14:00:00+08:00"
--end-time "2026-05-20T15:00:00+08:00"
--yes
dws calendar event create
--summary "团队同步会"
--start-time "2026-05-20T14:00:00+08:00"
--end-time "2026-05-20T15:00:00+08:00"
--yes
--summary "团队同步会"
--start-time "2026-05-20T14:00:00+08:00"
--end-time "2026-05-20T15:00:00+08:00"
--yes
With attendees
带参会人员
dws calendar event create
--summary "Quarterly Review"
--start-time "2026-05-25T10:00:00+08:00"
--end-time "2026-05-25T11:30:00+08:00"
--attendees "USER_ID_1,USER_ID_2"
--location "Meeting Room A"
--description "Q2 business review"
--yes
--summary "Quarterly Review"
--start-time "2026-05-25T10:00:00+08:00"
--end-time "2026-05-25T11:30:00+08:00"
--attendees "USER_ID_1,USER_ID_2"
--location "Meeting Room A"
--description "Q2 business review"
--yes
**Update event:**
```bash
dws calendar event update \
--event-id "EVENT_ID" \
--summary "Updated Title" \
--start-time "2026-05-20T15:00:00+08:00" \
--end-time "2026-05-20T16:00:00+08:00" \
--yesDelete event:
bash
dws calendar event delete --event-id "EVENT_ID" --yesdws calendar event create
--summary "季度复盘会"
--start-time "2026-05-25T10:00:00+08:00"
--end-time "2026-05-25T11:30:00+08:00"
--attendees "USER_ID_1,USER_ID_2"
--location "A会议室"
--description "Q2业务复盘"
--yes
--summary "季度复盘会"
--start-time "2026-05-25T10:00:00+08:00"
--end-time "2026-05-25T11:30:00+08:00"
--attendees "USER_ID_1,USER_ID_2"
--location "A会议室"
--description "Q2业务复盘"
--yes
**更新事件:**
```bash
dws calendar event update \
--event-id "EVENT_ID" \
--summary "更新后的标题" \
--start-time "2026-05-20T15:00:00+08:00" \
--end-time "2026-05-20T16:00:00+08:00" \
--yes删除事件:
bash
dws calendar event delete --event-id "EVENT_ID" --yesAI Table (AITable)
AI表格(AITable)
List spaces:
bash
dws aitable space list -f json --jq '.result[] | {id: .spaceId, name: .name}'List bases in space:
bash
dws aitable base list --space-id "SPACE_ID"List tables in base:
bash
dws aitable table list --base-id "BASE_ID"Query records:
bash
undefined列出空间:
bash
dws aitable space list -f json --jq '.result[] | {id: .spaceId, name: .name}'列出空间内的基地:
bash
dws aitable base list --space-id "SPACE_ID"列出基地内的表格:
bash
dws aitable table list --base-id "BASE_ID"查询记录:
bash
undefinedAll records
所有记录
dws aitable record query --base-id "BASE_ID" --table-id "TABLE_ID"
dws aitable record query --base-id "BASE_ID" --table-id "TABLE_ID"
With filters (filterByFormula)
带筛选条件(filterByFormula)
dws aitable record query
--base-id "BASE_ID"
--table-id "TABLE_ID"
--filter-by-formula '{Status}="Done"'
--limit 10
--base-id "BASE_ID"
--table-id "TABLE_ID"
--filter-by-formula '{Status}="Done"'
--limit 10
dws aitable record query
--base-id "BASE_ID"
--table-id "TABLE_ID"
--filter-by-formula '{Status}="Done"'
--limit 10
--base-id "BASE_ID"
--table-id "TABLE_ID"
--filter-by-formula '{Status}="Done"'
--limit 10
Sort and paginate
排序与分页
dws aitable record query
--base-id "BASE_ID"
--table-id "TABLE_ID"
--sort '[{"field":"CreatedTime","order":"desc"}]'
--page-size 20
--base-id "BASE_ID"
--table-id "TABLE_ID"
--sort '[{"field":"CreatedTime","order":"desc"}]'
--page-size 20
dws aitable record query
--base-id "BASE_ID"
--table-id "TABLE_ID"
--sort '[{"field":"CreatedTime","order":"desc"}]'
--page-size 20
--base-id "BASE_ID"
--table-id "TABLE_ID"
--sort '[{"field":"CreatedTime","order":"desc"}]'
--page-size 20
Extract specific fields
提取指定字段
dws aitable record query
--base-id "BASE_ID"
--table-id "TABLE_ID"
--jq '.result.records[] | {id: .recordId, fields: .fields}'
--base-id "BASE_ID"
--table-id "TABLE_ID"
--jq '.result.records[] | {id: .recordId, fields: .fields}'
**Create records:**
```bashdws aitable record query
--base-id "BASE_ID"
--table-id "TABLE_ID"
--jq '.result.records[] | {id: .recordId, fields: .fields}'
--base-id "BASE_ID"
--table-id "TABLE_ID"
--jq '.result.records[] | {id: .recordId, fields: .fields}'
**创建记录:**
```bashSingle record
单条记录
dws aitable record create
--base-id "BASE_ID"
--table-id "TABLE_ID"
--records '[{"fields":{"Name":"Test Item","Status":"In Progress","Priority":1}}]'
--yes
--base-id "BASE_ID"
--table-id "TABLE_ID"
--records '[{"fields":{"Name":"Test Item","Status":"In Progress","Priority":1}}]'
--yes
dws aitable record create
--base-id "BASE_ID"
--table-id "TABLE_ID"
--records '[{"fields":{"Name":"测试项","Status":"进行中","Priority":1}}]'
--yes
--base-id "BASE_ID"
--table-id "TABLE_ID"
--records '[{"fields":{"Name":"测试项","Status":"进行中","Priority":1}}]'
--yes
Multiple records
多条记录
dws aitable record create
--base-id "BASE_ID"
--table-id "TABLE_ID"
--records '[ {"fields":{"Name":"Item 1","Status":"Todo"}}, {"fields":{"Name":"Item 2","Status":"Done"}} ]'
--yes
--base-id "BASE_ID"
--table-id "TABLE_ID"
--records '[ {"fields":{"Name":"Item 1","Status":"Todo"}}, {"fields":{"Name":"Item 2","Status":"Done"}} ]'
--yes
**Update records:**
```bash
dws aitable record update \
--base-id "BASE_ID" \
--table-id "TABLE_ID" \
--records '[{"recordId":"RECORD_ID","fields":{"Status":"Done"}}]' \
--yesDelete records:
bash
dws aitable record delete \
--base-id "BASE_ID" \
--table-id "TABLE_ID" \
--record-ids "RECORD_ID_1,RECORD_ID_2" \
--yesList fields (schema):
bash
dws aitable field list --base-id "BASE_ID" --table-id "TABLE_ID"dws aitable record create
--base-id "BASE_ID"
--table-id "TABLE_ID"
--records '[ {"fields":{"Name":"项1","Status":"待办"}}, {"fields":{"Name":"项2","Status":"已完成"}} ]'
--yes
--base-id "BASE_ID"
--table-id "TABLE_ID"
--records '[ {"fields":{"Name":"项1","Status":"待办"}}, {"fields":{"Name":"项2","Status":"已完成"}} ]'
--yes
**更新记录:**
```bash
dws aitable record update \
--base-id "BASE_ID" \
--table-id "TABLE_ID" \
--records '[{"recordId":"RECORD_ID","fields":{"Status":"已完成"}}]' \
--yes删除记录:
bash
dws aitable record delete \
--base-id "BASE_ID" \
--table-id "TABLE_ID" \
--record-ids "RECORD_ID_1,RECORD_ID_2" \
--yes列出字段(数据结构):
bash
dws aitable field list --base-id "BASE_ID" --table-id "TABLE_ID"Todo Management
待办事项管理
List todos:
bash
undefined列出待办事项:
bash
undefinedAll incomplete todos
所有未完成待办
dws todo task list
dws todo task list
With filters
带筛选
dws todo task list --is-done false --jq '.result[] | {id: .taskId, title: .subject, due: .dueTime}'
dws todo task list --is-done false --jq '.result[] | {id: .taskId, title: .subject, due: .dueTime}'
Specific category
指定分类
dws todo task list --category-id "CATEGORY_ID"
**Create todo:**
```bash
dws todo task create \
--title "Review PR #123" \
--executors "USER_ID" \
--due-time "2026-05-22T18:00:00+08:00" \
--priority 10 \
--yesdws todo task list --category-id "CATEGORY_ID"
**创建待办事项:**
```bash
dws todo task create \
--title "评审PR #123" \
--executors "USER_ID" \
--due-time "2026-05-22T18:00:00+08:00" \
--priority 10 \
--yesWith description and multiple executors
带描述和多个执行人
dws todo task create
--title "Quarterly Report"
--description "Complete Q2 summary"
--executors "USER_ID_1,USER_ID_2"
--due-time "2026-05-30T23:59:59+08:00"
--yes
--title "Quarterly Report"
--description "Complete Q2 summary"
--executors "USER_ID_1,USER_ID_2"
--due-time "2026-05-30T23:59:59+08:00"
--yes
**Update todo:**
```bash
dws todo task update \
--task-id "TASK_ID" \
--is-done true \
--yesdws todo task create
--title "季度报告"
--description "完成Q2总结"
--executors "USER_ID_1,USER_ID_2"
--due-time "2026-05-30T23:59:59+08:00"
--yes
--title "季度报告"
--description "完成Q2总结"
--executors "USER_ID_1,USER_ID_2"
--due-time "2026-05-30T23:59:59+08:00"
--yes
**更新待办事项:**
```bash
dws todo task update \
--task-id "TASK_ID" \
--is-done true \
--yesUpdate fields
更新字段
dws todo task update
--task-id "TASK_ID"
--title "Updated Title"
--priority 20
--yes
--task-id "TASK_ID"
--title "Updated Title"
--priority 20
--yes
**Delete todo:**
```bash
dws todo task delete --task-id "TASK_ID" --yesList categories:
bash
dws todo category list -f jsondws todo task update
--task-id "TASK_ID"
--title "更新后的标题"
--priority 20
--yes
--task-id "TASK_ID"
--title "更新后的标题"
--priority 20
--yes
**删除待办事项:**
```bash
dws todo task delete --task-id "TASK_ID" --yes列出分类:
bash
dws todo category list -f jsonDocument Search
文档搜索
Search documents:
bash
undefined搜索文档:
bash
undefinedBasic search
基础搜索
dws doc search --query "quarterly report"
dws doc search --query "季度报告"
With type filter
带类型筛选
dws doc search --query "roadmap" --doc-type "doc" --jq '.result[] | {title: .title, url: .url, author: .creator.name}'
dws doc search --query "路线图" --doc-type "doc" --jq '.result[] | {title: .title, url: .url, author: .creator.name}'
Pagination
分页
dws doc search --query "API" --max-results 50
undefineddws doc search --query "API" --max-results 50
undefinedChat & IM
聊天与IM
Send message:
bash
undefined发送消息:
bash
undefinedTo user
发送给用户
dws chat send
--receiver-id "USER_ID"
--msg-type "text"
--content "Hello from dws!"
--yes
--receiver-id "USER_ID"
--msg-type "text"
--content "Hello from dws!"
--yes
dws chat send
--receiver-id "USER_ID"
--msg-type "text"
--content "来自dws的问候!"
--yes
--receiver-id "USER_ID"
--msg-type "text"
--content "来自dws的问候!"
--yes
To group
发送给群组
dws chat send
--receiver-id "GROUP_ID"
--msg-type "text"
--content "Team update"
--yes
--receiver-id "GROUP_ID"
--msg-type "text"
--content "Team update"
--yes
dws chat send
--receiver-id "GROUP_ID"
--msg-type "text"
--content "团队更新"
--yes
--receiver-id "GROUP_ID"
--msg-type "text"
--content "团队更新"
--yes
Markdown message
Markdown消息
dws chat send
--receiver-id "USER_ID"
--msg-type "markdown"
--content "Important: Please review this doc"
--yes
--receiver-id "USER_ID"
--msg-type "markdown"
--content "Important: Please review this doc"
--yes
**List conversations:**
```bash
dws chat list -f json --jq '.result[] | {id: .openConversationId, title: .title, type: .conversationType}'List IM groups:
bash
dws im group list --jq '.result[] | {id: .openConversationId, name: .name, memberCount: .memberCount}'
**列出会话:**
```bash
dws chat list -f json --jq '.result[] | {id: .openConversationId, title: .title, type: .conversationType}'列出IM群组:
bash
dws im group list --jq '.result[] | {id: .openConversationId, name: .name, memberCount: .memberCount}'Drive
云盘
List files:
bash
undefined列出文件:
bash
undefinedRoot directory
根目录
dws drive list
dws drive list
Specific space
指定空间
dws drive list --space-id "SPACE_ID"
dws drive list --space-id "SPACE_ID"
Extract fields
提取字段
dws drive list --jq '.result[] | {name: .name, id: .fileId, size: .size, type: .type}'
**Upload file:**
```bash
dws drive upload \
--space-id "SPACE_ID" \
--parent-id "PARENT_ID" \
--file-path "/path/to/file.pdf" \
--yesDownload file:
bash
dws drive download \
--space-id "SPACE_ID" \
--file-id "FILE_ID" \
--output-path "/path/to/save/file.pdf"dws drive list --jq '.result[] | {name: .name, id: .fileId, size: .size, type: .type}'
**上传文件:**
```bash
dws drive upload \
--space-id "SPACE_ID" \
--parent-id "PARENT_ID" \
--file-path "/path/to/file.pdf" \
--yes下载文件:
bash
dws drive download \
--space-id "SPACE_ID" \
--file-id "FILE_ID" \
--output-path "/path/to/save/file.pdf"Attendance
考勤
Get attendance records:
bash
undefined获取考勤记录:
bash
undefinedToday's records
今日记录
dws attendance record get
dws attendance record get
Specific date range
指定日期范围
dws attendance record get
--start-date "2026-05-01"
--end-date "2026-05-07"
-f json --jq '.result[] | {date: .workDate, checkIn: .checkInTime, checkOut: .checkOutTime}'
--start-date "2026-05-01"
--end-date "2026-05-07"
-f json --jq '.result[] | {date: .workDate, checkIn: .checkInTime, checkOut: .checkOutTime}'
**Query shift schedules:**
```bash
dws attendance shift query \
--user-ids "USER_ID" \
--start-date "2026-05-20" \
--end-date "2026-05-27"dws attendance record get
--start-date "2026-05-01"
--end-date "2026-05-07"
-f json --jq '.result[] | {date: .workDate, checkIn: .checkInTime, checkOut: .checkOutTime}'
--start-date "2026-05-01"
--end-date "2026-05-07"
-f json --jq '.result[] | {date: .workDate, checkIn: .checkInTime, checkOut: .checkOutTime}'
**查询排班:**
```bash
dws attendance shift query \
--user-ids "USER_ID" \
--start-date "2026-05-20" \
--end-date "2026-05-27"Reports
汇报
List reports:
bash
undefined列出汇报:
bash
undefinedInbox (received)
收件箱(收到的)
dws report list inbox --start-time 1715990400000 --end-time 1716076799000
dws report list inbox --start-time 1715990400000 --end-time 1716076799000
Sent
已发送
dws report list sent --start-time 1715990400000 --end-time 1716076799000
dws report list sent --start-time 1715990400000 --end-time 1716076799000
Created by me
我创建的
dws report list mine --start-time 1715990400000 --end-time 1716076799000
undefineddws report list mine --start-time 1715990400000 --end-time 1716076799000
undefinedAI Meeting Minutes
AI会议纪要
List minutes:
bash
undefined列出纪要:
bash
undefinedAll minutes
所有纪要
dws minutes list
dws minutes list
Mine
我参与的
dws minutes list mine
dws minutes list mine
Extract fields
提取字段
dws minutes list --jq '.result[] | {id: .minutesId, title: .title, date: .meetingStartTime}'
**Get minutes detail:**
```bash
dws minutes detail --minutes-id "MINUTES_ID" -f jsondws minutes list --jq '.result[] | {id: .minutesId, title: .title, date: .meetingStartTime}'
**获取纪要详情:**
```bash
dws minutes detail --minutes-id "MINUTES_ID" -f jsonSchema Discovery (AI Agents)
架构发现(AI Agent)
AI agents don't need pre-built knowledge. Use to dynamically discover capabilities:
dws schemaList all products and tool counts:
bash
dws schema --jq '.products[] | {id, tool_count: (.tools | length)}'Inspect specific tool parameters:
bash
undefinedAI Agent无需预先构建知识体系,可使用动态发现功能:
dws schema列出所有产品及工具数量:
bash
dws schema --jq '.products[] | {id, tool_count: (.tools | length)}'查看特定工具的参数:
bash
undefinedGet parameter schema for aitable.query_records
获取aitable.query_records的参数架构
dws schema aitable.query_records --jq '.tool.parameters'
dws schema aitable.query_records --jq '.tool.parameters'
Get all aitable tools
获取所有aitable工具
dws schema --jq '.products[] | select(.id=="aitable") | .tools[] | {name: .name, description: .description}'
**Example discovery workflow:**
```bashdws schema --jq '.products[] | select(.id=="aitable") | .tools[] | {name: .name, description: .description}'
**发现流程示例:**
```bashStep 1: Find the right product
步骤1:找到对应产品
dws schema --jq '.products[] | {id, description}'
dws schema --jq '.products[] | {id, description}'
Step 2: List tools in that product
步骤2:列出该产品下的工具
dws schema --jq '.products[] | select(.id=="calendar") | .tools[] | .name'
dws schema --jq '.products[] | select(.id=="calendar") | .tools[] | .name'
Step 3: Get parameter schema
步骤3:获取参数架构
dws schema calendar.create_event --jq '.tool.parameters.properties | keys'
dws schema calendar.create_event --jq '.tool.parameters.properties | keys'
Step 4: Execute
步骤4:执行命令
dws calendar event create --summary "Team Sync" --start-time "2026-05-20T14:00:00+08:00" --end-time "2026-05-20T15:00:00+08:00" --yes
undefineddws calendar event create --summary "团队同步会" --start-time "2026-05-20T14:00:00+08:00" --end-time "2026-05-20T15:00:00+08:00" --yes
undefinedConfiguration
配置
Config file location:
- macOS/Linux:
~/.config/dws/config.yaml - Windows:
%APPDATA%\dws\config.yaml
Example config.yaml:
yaml
auth:
client_id: "your-app-key"
client_secret: "your-app-secret"
output:
default_format: "json"
color: true
debug: falseOverride via environment variables:
bash
export DWS_OUTPUT_FORMAT=json
export DWS_DEBUG=true
export DINGTALK_CLIENT_ID=your-app-key
export DINGTALK_CLIENT_SECRET=your-app-secret配置文件位置:
- macOS/Linux:
~/.config/dws/config.yaml - Windows:
%APPDATA%\dws\config.yaml
示例config.yaml:
yaml
auth:
client_id: "your-app-key"
client_secret: "your-app-secret"
output:
default_format: "json"
color: true
debug: false通过环境变量覆盖配置:
bash
export DWS_OUTPUT_FORMAT=json
export DWS_DEBUG=true
export DINGTALK_CLIENT_ID=your-app-key
export DINGTALK_CLIENT_SECRET=your-app-secretAI Agent Best Practices
AI Agent最佳实践
Always Use --yes for Non-Interactive Execution
非交互式执行务必使用--yes参数
bash
undefinedbash
undefined❌ Bad (will hang waiting for confirmation)
❌ 错误(会等待确认导致挂起)
dws todo task create --title "Review PR" --executors "USER_ID"
dws todo task create --title "评审PR" --executors "USER_ID"
✅ Good
✅ 正确
dws todo task create --title "Review PR" --executors "USER_ID" --yes
undefineddws todo task create --title "评审PR" --executors "USER_ID" --yes
undefinedUse --dry-run for Safety
使用--dry-run保障安全
bash
undefinedbash
undefinedPreview before executing
预览操作再执行
dws contact user search --query "engineering" --dry-run
dws aitable record delete --base-id "BASE_ID" --table-id "TABLE_ID" --record-ids "REC_ID" --dry-run
undefineddws contact user search --query "engineering" --dry-run
dws aitable record delete --base-id "BASE_ID" --table-id "TABLE_ID" --record-ids "REC_ID" --dry-run
undefinedUse --jq to Save Tokens
使用--jq减少数据量
bash
undefinedbash
undefined❌ Returns entire API response (1000+ tokens)
❌ 返回完整API响应(1000+ tokens)
dws contact user search --query "zhang" -f json
dws contact user search --query "zhang" -f json
✅ Extract only needed fields (50 tokens)
✅ 仅提取所需字段(50 tokens)
dws contact user search --query "zhang" -f json --jq '.result[] | {name: .name, userId: .userId}'
undefineddws contact user search --query "zhang" -f json --jq '.result[] | {name: .name, userId: .userId}'
undefinedHandle Pagination
处理分页
bash
undefinedbash
undefinedAITable pagination
AITable分页
dws aitable record query --base-id "BASE_ID" --table-id "TABLE_ID" --page-size 100
dws aitable record query --base-id "BASE_ID" --table-id "TABLE_ID" --page-size 100
Calendar pagination (date ranges)
日历分页(按日期范围)
dws calendar event list --start-time "2026-05-01T00:00:00+08:00" --end-time "2026-06-01T00:00:00+08:00"
undefineddws calendar event list --start-time "2026-05-01T00:00:00+08:00" --end-time "2026-06-01T00:00:00+08:00"
undefinedError Handling
错误处理
bash
undefinedbash
undefinedCheck exit code
检查退出码
dws contact user search --query "nonexistent"
echo $? # 0 = success, non-zero = error
dws contact user search --query "nonexistent"
echo $? # 0 = 成功,非0 = 错误
Capture stderr
捕获错误信息
dws todo task create --title "Test" --executors "INVALID_ID" --yes 2>&1 | grep "error"
undefineddws todo task create --title "Test" --executors "INVALID_ID" --yes 2>&1 | grep "error"
undefinedCommon Patterns
常见使用模式
Multi-Step Workflows
多步骤工作流
Schedule meeting with available room:
bash
undefined安排会议并预订可用会议室:
bash
undefined1. Search attendees
1. 搜索参会人员
ATTENDEES=$(dws contact user search --query "engineering" -f json --jq '[.result[].userId] | join(",")')
ATTENDEES=$(dws contact user search --query "engineering" -f json --jq '[.result[].userId] | join(",")')
2. Create event
2. 创建事件
EVENT_ID=$(dws calendar event create
--summary "Team Sync"
--start-time "2026-05-20T14:00:00+08:00"
--end-time "2026-05-20T15:00:00+08:00"
--attendees "$ATTENDEES"
--yes
-f json --jq '.result.eventId')
--summary "Team Sync"
--start-time "2026-05-20T14:00:00+08:00"
--end-time "2026-05-20T15:00:00+08:00"
--attendees "$ATTENDEES"
--yes
-f json --jq '.result.eventId')
echo "Created event: $EVENT_ID"
**Batch import to AITable from JSON:**
```bashEVENT_ID=$(dws calendar event create
--summary "团队同步会"
--start-time "2026-05-20T14:00:00+08:00"
--end-time "2026-05-20T15:00:00+08:00"
--attendees "$ATTENDEES"
--yes
-f json --jq '.result.eventId')
--summary "团队同步会"
--start-time "2026-05-20T14:00:00+08:00"
--end-time "2026-05-20T15:00:00+08:00"
--attendees "$ATTENDEES"
--yes
-f json --jq '.result.eventId')
echo "已创建事件:$EVENT_ID"
**从JSON批量导入到AITable:**
```bashPrepare records.json
准备records.json
cat > records.json <<EOF
[
{"fields": {"Name": "Item 1", "Status": "Todo", "Priority": 1}},
{"fields": {"Name": "Item 2", "Status": "In Progress", "Priority": 2}}
]
EOF
cat > records.json <<EOF
[
{"fields": {"Name": "项1", "Status": "待办", "Priority": 1}},
{"fields": {"Name": "项2", "Status": "进行中", "Priority": 2}}
]
EOF
Import
导入数据
dws aitable record create
--base-id "$BASE_ID"
--table-id "$TABLE_ID"
--records "$(cat records.json)"
--yes
--base-id "$BASE_ID"
--table-id "$TABLE_ID"
--records "$(cat records.json)"
--yes
**Find overdue todos:**
```bash
dws todo task list --is-done false -f json | \
jq --arg now "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
'.result[] | select(.dueTime != null and .dueTime < $now) | {id: .taskId, title: .subject, due: .dueTime}'dws aitable record create
--base-id "$BASE_ID"
--table-id "$TABLE_ID"
--records "$(cat records.json)"
--yes
--base-id "$BASE_ID"
--table-id "$TABLE_ID"
--records "$(cat records.json)"
--yes
**查找逾期待办事项:**
```bash
dws todo task list --is-done false -f json | \
jq --arg now "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
'.result[] | select(.dueTime != null and .dueTime < $now) | {id: .taskId, title: .subject, due: .dueTime}'Batch Operations
批量操作
Delete multiple AITable records:
bash
undefined批量删除AITable记录:
bash
undefinedGet record IDs to delete
获取待删除的记录ID
RECORD_IDS=$(dws aitable record query
--base-id "$BASE_ID"
--table-id "$TABLE_ID"
--filter-by-formula '{Status}="Archived"'
-f json --jq '[.result.records[].recordId] | join(",")')
--base-id "$BASE_ID"
--table-id "$TABLE_ID"
--filter-by-formula '{Status}="Archived"'
-f json --jq '[.result.records[].recordId] | join(",")')
RECORD_IDS=$(dws aitable record query
--base-id "$BASE_ID"
--table-id "$TABLE_ID"
--filter-by-formula '{Status}="Archived"'
-f json --jq '[.result.records[].recordId] | join(",")')
--base-id "$BASE_ID"
--table-id "$TABLE_ID"
--filter-by-formula '{Status}="Archived"'
-f json --jq '[.result.records[].recordId] | join(",")')
Delete
删除记录
dws aitable record delete
--base-id "$BASE_ID"
--table-id "$TABLE_ID"
--record-ids "$RECORD_IDS"
--yes
--base-id "$BASE_ID"
--table-id "$TABLE_ID"
--record-ids "$RECORD_IDS"
--yes
**Send notification to department:**
```bashdws aitable record delete
--base-id "$BASE_ID"
--table-id "$TABLE_ID"
--record-ids "$RECORD_IDS"
--yes
--base-id "$BASE_ID"
--table-id "$TABLE_ID"
--record-ids "$RECORD_IDS"
--yes
**给部门成员发送通知:**
```bashGet department members
获取部门成员ID
USER_IDS=$(dws contact dept members --dept-id "$DEPT_ID" -f json --jq '[.result[].userId]')
USER_IDS=$(dws contact dept members --dept-id "$DEPT_ID" -f json --jq '[.result[].userId]')
Send to each
逐个发送消息
echo "$USER_IDS" | jq -r '.[]' | while read user_id; do
dws chat send --receiver-id "$user_id" --msg-type "text" --content "Reminder: Submit timesheet" --yes
done
undefinedecho "$USER_IDS" | jq -r '.[]' | while read user_id; do
dws chat send --receiver-id "$user_id" --msg-type "text" --content "提醒:提交工时表" --yes
done
undefinedTroubleshooting
故障排查
Authentication Issues
认证问题
Token expired:
bash
undefined令牌过期:
bash
undefinedRe-login
重新登录
dws auth login
dws auth login
Or use device flow
或使用设备流登录
dws auth login --device
**Organization not enabled:**
- Join the DingTalk co-creation group: scan QR in README
- Ask admin to enable CLI access in Developer Platformdws auth login --device
**组织未启用:**
- 加入钉钉共创群:扫描README中的二维码
- 联系管理员在开发者平台启用CLI访问权限Permission Errors
权限错误
bash
undefinedbash
undefinedCheck current auth status and scopes
检查当前认证状态和权限范围
dws auth status -f json --jq '.result | {userId: .userId, corpId: .corpId, scopes: .scopes}'
dws auth status -f json --jq '.result | {userId: .userId, corpId: .corpId, scopes: .scopes}'
Request required scopes during login
登录时请求所需权限
dws auth login --scope "Contact.User.Read,Calendar.Event.Write"
undefineddws auth login --scope "Contact.User.Read,Calendar.Event.Write"
undefinedRate Limiting
速率限制
bash
undefinedbash
undefinedAdd delays between bulk operations
批量操作间添加延迟
for i in {1..100}; do
dws todo task create --title "Task $i" --executors "USER_ID" --yes
sleep 0.5
done
undefinedfor i in {1..100}; do
dws todo task create --title "任务 $i" --executors "USER_ID" --yes
sleep 0.5
done
undefinedDebug Mode
调试模式
bash
undefinedbash
undefinedEnable verbose logging
启用详细日志
dws --debug contact user search --query "test"
dws --debug contact user search --query "test"
Check request/response
查看请求/响应
dws contact user search --query "test" --dry-run
undefineddws contact user search --query "test" --dry-run
undefinedInvalid Timestamps
无效时间戳
DingTalk expects RFC3339 format with timezone:
bash
undefined钉钉要求带时区的RFC3339格式:
bash
undefined✅ Correct
✅ 正确格式
--start-time "2026-05-20T14:00:00+08:00"
--start-time "2026-05-20T14:00:00+08:00"
❌ Incorrect
❌ 错误格式
--start-time "2026-05-20 14:00:00"
--start-time "1716192000" # Unix timestamp not supported in event create
For attendance, use date format:
```bash--start-time "2026-05-20 14:00:00"
--start-time "1716192000" # 创建事件不支持Unix时间戳
考勤模块使用日期格式:
```bash✅ Correct
✅ 正确格式
--start-date "2026-05-20"
--start-date "2026-05-20"
❌ Incorrect
❌ 错误格式
--start-date "2026-05-20T00:00:00+08:00"
undefined--start-date "2026-05-20T00:00:00+08:00"
undefinedAITable filterByFormula Syntax
AITable filterByFormula语法
bash
undefinedbash
undefined✅ Correct (JSON string escaping)
✅ 正确格式(JSON字符串转义)
--filter-by-formula '{Status}="Done"'
--filter-by-formula 'AND({Priority}>5, {Status}="In Progress")'
--filter-by-formula '{Status}="Done"'
--filter-by-formula 'AND({Priority}>5, {Status}="In Progress")'
❌ Incorrect (unescaped quotes)
❌ 错误格式(未转义引号)
--filter-by-formula {"Status":"Done"}
undefined--filter-by-formula {"Status":"Done"}
undefinedEmpty Results
空结果
bash
undefinedbash
undefinedCheck if data exists
检查数据是否存在
dws aitable record query --base-id "$BASE_ID" --table-id "$TABLE_ID" --limit 1
dws aitable record query --base-id "$BASE_ID" --table-id "$TABLE_ID" --limit 1
Verify IDs are correct
验证ID是否正确
dws aitable space list
dws aitable base list --space-id "$SPACE_ID"
dws aitable table list --base-id "$BASE_ID"
undefineddws aitable space list
dws aitable base list --space-id "$SPACE_ID"
dws aitable table list --base-id "$BASE_ID"
undefinedReference
参考资料
- Command Index: — all commands with descriptions
docs/command-index.md - Full Reference: — complete command reference
docs/reference.md - Changelog:
CHANGELOG.md - Ready-made Scripts: — 13 Python scripts for batch operations
skills/scripts/ - GitHub Releases: https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli/releases
- 命令索引:— 所有命令及说明
docs/command-index.md - 完整参考:— 完整命令参考
docs/reference.md - 更新日志:
CHANGELOG.md - 现成脚本:— 13个用于批量操作的Python脚本
skills/scripts/ - GitHub发布页:https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli/releases
Security Notes
安全说明
- Credentials stored in system keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service)
- OAuth device-flow for headless environments
- Zero-trust: every request requires authentication
- Domain allowlisting and least-privilege scoping enforced server-side
- Use environment variables for CI/CD: ,
$DINGTALK_CLIENT_ID$DINGTALK_CLIENT_SECRET
- 凭据存储在系统密钥链中(macOS Keychain、Windows凭据管理器、Linux Secret Service)
- 无头环境支持OAuth设备流
- 零信任:每个请求都需要认证
- 服务器端强制域名白名单和最小权限范围
- CI/CD场景使用环境变量:,
$DINGTALK_CLIENT_ID$DINGTALK_CLIENT_SECRET
Example: Complete Workflow (AI Agent)
示例:完整工作流(AI Agent)
bash
#!/bin/bashbash
#!/bin/bashAI agent script: Create weekly team sync event with engineering team
AI Agent脚本:为工程团队创建每周同步会议
set -e
set -e
1. Get current user
1. 获取当前用户ID
MY_USER_ID=$(dws contact user get-self -f json --jq '.result[0].orgEmployeeModel.userId' | tr -d '"')
MY_USER_ID=$(dws contact user get-self -f json --jq '.result[0].orgEmployeeModel.userId' | tr -d '"')
2. Search engineering team
2. 搜索工程团队成员
ATTENDEES=$(dws contact user search --query "engineering" -f json --jq '[.result[].userId] | join(",")')
ATTENDEES=$(dws contact user search --query "engineering" -f json --jq '[.result[].userId] | join(",")')
3. Find next Monday 2pm
3. 计算下周一14:00的时间
NEXT_MONDAY=$(date -d "next monday 14:00" -Iseconds --utc | sed 's/+00:00/+08:00/')
END_TIME=$(date -d "next monday 15:00" -Iseconds --utc | sed 's/+00:00/+08:00/')
NEXT_MONDAY=$(date -d "next monday 14:00" -Iseconds --utc | sed 's/+00:00/+08:00/')
END_TIME=$(date -d "next monday 15:00" -Iseconds --utc | sed 's/+00:00/+08:00/')
4. Create event
4. 创建会议事件
EVENT_ID=$(dws calendar event create
--summary "Weekly Team Sync"
--start-time "$NEXT_MONDAY"
--end-time "$END_TIME"
--attendees "$ATTENDEES"
--location "Meeting Room A"
--description "Weekly engineering team sync"
--yes
-f json --jq '.result.eventId' | tr -d '"')
--summary "Weekly Team Sync"
--start-time "$NEXT_MONDAY"
--end-time "$END_TIME"
--attendees "$ATTENDEES"
--location "Meeting Room A"
--description "Weekly engineering team sync"
--yes
-f json --jq '.result.eventId' | tr -d '"')
echo "✅ Created event $EVENT_ID for $NEXT_MONDAY"
EVENT_ID=$(dws calendar event create
--summary "每周团队同步会"
--start-time "$NEXT_MONDAY"
--end-time "$END_TIME"
--attendees "$ATTENDEES"
--location "A会议室"
--description "工程团队每周同步会"
--yes
-f json --jq '.result.eventId' | tr -d '"')
--summary "每周团队同步会"
--start-time "$NEXT_MONDAY"
--end-time "$END_TIME"
--attendees "$ATTENDEES"
--location "A会议室"
--description "工程团队每周同步会"
--yes
-f json --jq '.result.eventId' | tr -d '"')
echo "✅ 已为$NEXT_MONDAY创建事件$EVENT_ID"
5. Create reminder todo
5. 创建提醒待办
dws todo task create
--title "Prepare agenda for team sync"
--executors "$MY_USER_ID"
--due-time "$(date -d "next monday 12:00" -Iseconds --utc | sed 's/+00:00/+08:00/')"
--description "Event ID: $EVENT_ID"
--yes
--title "Prepare agenda for team sync"
--executors "$MY_USER_ID"
--due-time "$(date -d "next monday 12:00" -Iseconds --utc | sed 's/+00:00/+08:00/')"
--description "Event ID: $EVENT_ID"
--yes
echo "✅ Created reminder todo"
undefineddws todo task create
--title "准备团队同步会议议程"
--executors "$MY_USER_ID"
--due-time "$(date -d "next monday 12:00" -Iseconds --utc | sed 's/+00:00/+08:00/')"
--description "事件ID:$EVENT_ID"
--yes
--title "准备团队同步会议议程"
--executors "$MY_USER_ID"
--due-time "$(date -d "next monday 12:00" -Iseconds --utc | sed 's/+00:00/+08:00/')"
--description "事件ID:$EVENT_ID"
--yes
echo "✅ 已创建提醒待办"
undefined