或便于分片复制:dws auth export --base64 -o /tmp/dws-auth.b64

August 27, 2026 · View on GitHub

DingTalk Workspace CLI (dws)

dws — 钉钉工作台命令行工具,为人类和 AI Agent 而生。

DWS Product Overview

Go 1.25+ License Apache-2.0 Latest Release CI Coverage

中文版 · English · 参考手册 · 更新日志

Important

钉钉 DWS CLI 已全面开放,欢迎使用:本项目涉及钉钉企业数据访问,需企业管理员授权后方可使用。欢迎加入钉钉 DWS 共创群获取支持与最新动态。详见下方 开始使用

dws 开源沟通群二维码
目录

为什么选择 dws?

  • 为人类而设计--help 查看用法,--dry-run 预览请求,-f table/json/raw 切换格式。
  • 为 AI Agent 而设计 — 结构化 JSON 响应 + 内置 Agent Skills,开箱即用。
  • 为企业管理员而设计 — 零信任架构:OAuth 设备流认证 + 域名白名单 + 权限最小化。没有一个字节能绕过安全鉴权和审计。

安装

macOS / Linux:

curl -fsSL https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install.sh | sh

Windows(PowerShell):

irm https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install.ps1 | iex
Skill 模式:mono 与 multi

安装时可以选择两种 skill 组织方式。两种模式下 CLI 命令完全一样(dws aitable ... / dws calendar ...),区别只在 Agent 那边读到的 skill 文档结构。

模式安装内容适合场景
multi(默认)按产品拆分的独立 skill(dingtalk-aitable / dingtalk-calendar / dingtalk-chat ...)单产品任务;每次召唤上下文更小
mono(legacy)一个 dws skill,覆盖全部产品跨产品组合操作;单一入口召唤

安装与升级默认均为 multi。mono 仍可通过 DWS_SKILL_MODE=monodws skill setup --mode mono 使用。问题请提 issue 反馈。

怎么选:

  • 快速安装(上方一行 curl):非交互,默认装 multi
  • TTY 安装(先下载再执行):curl -O .../install.sh && bash install.sh,会弹出 1) multi 2) mono 选项(默认 1)。
  • 环境变量覆盖DWS_SKILL_MODE=mono curl -fsSL ... | sh
  • 装完之后再切换dws skill setup --mode mono(或 --mode multi),核对列出的路径后交互确认。
其他安装方式

npm(需要 Node.js(npm/npx)):

npm install -g dingtalk-workspace-cli

安装最新 beta:

npm install -g dingtalk-workspace-cli@beta

Homebrew(macOS / Linux):

brew tap DingTalk-Real-AI/dingtalk-workspace-cli https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli.git
brew install dingtalk-workspace-cli

Formula 与代码位于同一个仓库,因此首次 tap 需要显式指定仓库 URL。后续可直接使用 brew upgrade dingtalk-workspace-cli

安装 Homebrew beta(keg-only,不覆盖稳定版):

brew install dingtalk-workspace-cli-beta
$(brew --prefix dingtalk-workspace-cli-beta)/bin/dws version

如需让 beta 的 dws 成为当前 shell 默认版本,将 $(brew --prefix dingtalk-workspace-cli-beta)/bin 放到 PATH 最前面。

预编译二进制文件:从 GitHub Releases 下载。

macOS 用户注意:如果提示“无法打开,因为 Apple 无法检查其是否包含恶意软件”,请执行:

xattr -d com.apple.quarantine /path/to/dws

从源码构建

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/         # 安装到 PATH

需要 Go 1.25+。也可以用 make package$ 构建所有平台产物(\text{macOS} / \text{Linux} / \text{Windows} \times \text{amd64} / \text{arm64})。 静态端点数据由悟空基线生成并提交在本仓库 $internal/syncdata,源码构建不需要额外 checkout 数据仓库。

国内加速安装

国内用户可使用以下通道,避免 GitHub 网络问题。默认(不设置这些环境变量)走 GitHub。

1. 安装脚本 + 预编译二进制(Gitee 镜像):

仓库镜像地址:https://gitee.com/DingTalk-Real-AI/dingtalk-workspace-cli

DWS_GITEE_REPO=DingTalk-Real-AI/dingtalk-workspace-cli curl -fsSL https://gitee.com/DingTalk-Real-AI/dingtalk-workspace-cli/raw/main/scripts/install.sh | sh

设置 DWS_GITEE_REPO 后,安装脚本会改从 Gitee API 解析最新版本和各个 release 产物(二进制、校验和、skills 包),而不是走 GitHub。不设置时默认从 GitHub 安装。

2. npm 包(npmmirror 镜像):

npm install -g dingtalk-workspace-cli --registry=https://registry.npmmirror.com

npmmirror 会自动同步公网 npm 的公开包,国内可直接使用。

3. 单独安装 Skills(Gitee 镜像):

DWS_GITEE_REPO=DingTalk-Real-AI/dingtalk-workspace-cli curl -fsSL https://gitee.com/DingTalk-Real-AI/dingtalk-workspace-cli/raw/main/scripts/install-skills.sh | sh

同样设置 DWS_GITEE_REPOinstall-skills.sh 会从 Gitee 解析版本和 skills 包;GitHub 不可达时也会自动回退到 Gitee 镜像。

升级

需要 v1.0.7 及以上版本。更早版本请重新执行安装脚本进行升级。

dws 内置自升级能力,直接从 GitHub Releases 拉取更新,支持 SHA256 完整性校验和自动备份。

dws upgrade                    # 交互式升级到最新版本
dws upgrade --check            # 仅检查是否有新版本
dws upgrade --list             # 列出正式 release 版本
dws upgrade --beta             # 升级到最新 beta 预发布版本
dws upgrade --check --beta     # 仅检查 beta 轨道是否有新版本
dws upgrade --list --beta      # 列出 beta 预发布版本
dws upgrade --version v1.0.7   # 升级到指定版本
dws upgrade --version v1.0.8-beta.1  # 升级到指定 beta 版本
dws upgrade --rollback         # 回滚到上一版本
dws upgrade -y                 # 跳过确认直接升级

默认情况下,dws upgrade 只跟随正式 release 轨道。只有显式传入 --beta 时,才会选择 GitHub pre-release 里的 beta 构建。

六渠道发布后验证

维护者和验证同学可按发版质量保障 SOP,对 curl、PowerShell、npm stable、npm beta、Homebrew、dws upgrade 执行安装与冒烟验证:

git clone https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli.git /tmp/dws-verify
cd /tmp/dws-verify/verify
bash verify-all-channels.sh

脚本使用隔离目录,不会替换当前 PATH 中的 dws;输出 PASSFAILSKIP 汇总。跨平台渠道必须由对应平台补测,SKIP 不计为通过。验证范围和平台矩阵见 verify/README.md

工作原理

升级过程采用两阶段原子流程,确保一致性:

  1. 准备阶段 — 将平台对应的二进制文件和技能包下载到临时目录,校验 SHA256 校验和,解压并验证所有文件。任何步骤失败则立即中止,不会修改现有安装。
  2. 执行阶段 — 仅在所有准备工作成功后,替换二进制文件并将技能包平铺到已检测到的具体 Agent 目录(例如 ~/.codex/skills/dingtalk-chat~/.claude/skills/dingtalk-chat)。只有未检测到具体 Agent 时才使用 ~/.agents/skills;检测到具体 Agent 后会备份迁走旧的 DWS 通用副本,避免同一 Skill 被重复发现。

每次升级前自动备份当前版本,可通过 dws upgrade --rollback 随时回滚。

Flag说明
--check仅检查更新,不安装
--list列出正式 release 版本及更新日志
--betaupgrade--check--list 使用 beta 预发布轨道
--version升级到指定版本(如 v1.0.7v1.0.8-beta.1
--rollback回滚到上一个备份版本
--force强制重新安装,即使已是最新版本
--skip-skills跳过技能包更新
-y跳过确认提示

开始使用

dws auth login            # 自动唤起浏览器
dws auth login --device   # 无浏览器环境(Docker、SSH、CI)

选择组织并授权即可。

如果组织尚未开启 CLI 访问权限,系统会引导你向管理员发送申请。审批通过后重新执行 dws auth login 即可。

组织未开启 CLI 访问权限?
  1. 选择组织后,点击「立即申请」通知管理员
  2. 管理员收到申请卡片,一键审批
  3. 审批通过后,重新执行 dws auth login

申请权限

管理员:为组织开启 CLI 访问权限

进入 开发者平台 →「CLI 访问管理」→ 开启。

CLI访问管理

自建应用模式(CI/CD、ISV 集成)

企业自主管控场景,可创建自有钉钉应用:

  1. 开放平台应用开发后台 → 创建应用
  2. 安全设置 → 添加重定向 URL:http://127.0.0.1,https://login.dingtalk.com
  3. 发布应用
  4. 登录:
dws auth login --client-id <your-app-key> --client-secret <your-app-secret>

首次登录后凭证安全存储(Keychain),后续自动刷新 Token。

多组织(profile)

dws 可以同时登录多个钉钉账号,同一组织也能保留多个账号。一个 profile 由 corpId + userId 唯一确定。

dws auth login                              # 新增或刷新一个账号
dws profile list                            # 列出全部账号,profile 字段是稳定的 corpId:userId
dws profile switch <corpId:userId>          # 持久切换账号;用 - 切回上一个
dws profile switch "组织名:用户名"          # 名称输入要求唯一
dws --profile <corpId> contact user search --query "..."        # 使用该组织明确记录的当前账号
dws --profile <corpId:userId> contact user search --query "..." # 单次精确指定账号,不改默认账号

支持 corpId:userIdcorpId:userNamecorpName:userIdcorpName:userName。名称只用于输入,自动化应使用 profile list 返回的稳定 profile。组织名或用户名重名时会列出候选并报错;同组织多账号但没有明确当前账号时,只传组织也会报错,不会选择第一项或最近使用账号。

currentProfilepreviousProfile 和组织默认账号都保存精确身份。primaryProfile 只为 JSON 兼容保留,不再参与选择。profile list 直接读取各身份 Token 计算状态和到期时间,不触发刷新。auth logout --profile <corpId> 退出该组织全部账号;精确选择器或本地 profile 名只退出一个账号。

跨组织读取由 agent 编排,而非内置 --all-orgs:先 dws profile list,每个组织使用唯一的 isOrgCurrent=true 账号;若多账号组织没有默认账号,先让用户指定账号。写操作默认只在当前账号执行——跨组织写之前先确认目标组织和账号。

macOS 下,如果已登记的 token slot 无法解密,为避免把系统 Keychain 和 file-DEK 写成混合状态,新的 OAuth 登录会直接拒绝。如果普通终端仍能读取登录态、只有设置 DWS_DISABLE_KEYCHAIN=1 的沙箱读不到,可在不暴露 token 的情况下迁移 legacy 与各 profile 的认证条目:

env -u DWS_DISABLE_KEYCHAIN dws auth migrate-keychain --to file-dek --dry-run --format json
env -u DWS_DISABLE_KEYCHAIN dws auth migrate-keychain --to file-dek --yes --format json
DWS_DISABLE_KEYCHAIN=1 dws auth status --format json

迁移会先验证全部认证密文再写入、忽略无关的应用密钥;提交中断后可安全重跑。如果预检确认是密文本身损坏,优先使用 dws auth logout --profile <corpId:userId> 只清理受影响账号;只有确认要丢弃全部本地 profile 时才用 dws auth reset

沙箱间迁移登录态(Linux)

仅拷贝 ~/.dws/app.json 无法带走 refresh token;access token 约 2 小时后会失效。请使用官方导出/导入:

# A 沙箱(已登录)
dws auth export -o /tmp/dws-auth.tar.gz
# 或便于分片复制:dws auth export --base64 -o /tmp/dws-auth.b64

# B 沙箱
dws auth import -i /tmp/dws-auth.tar.gz
# 或:dws auth import -i /tmp/dws-auth.b64 --base64
dws auth status   # 确认 Refresh Token: 有效

包内包含 ~/.local/share/dws-cli 加密 keychain(含 auth-token.encdek)及 ~/.dws 必要配置。

快速开始

dws contact user search --query "悟空"             # 搜索联系人
dws calendar event list                            # 查看今天的日程
dws doc search --query "季度"                      # 搜索钉钉文档
dws minutes list mine                              # 列出我创建的 AI 听记
dws drive list                                     # 列出钉盘文件
dws todo task create --title "季度汇报" --executors "<your-userId>"   # 创建待办(请替换为真实 userId)
dws todo task list --dry-run                       # 预览操作但不执行

完整命令列表docs/command-index.md — 全部命令,带描述和使用场景。

在 Agent 中使用

dws 是为 AI Agent 设计的 CLI 工具。请先完成安装开始使用,然后配置 Agent 环境:

Agent 调用模式

# 使用 --yes 跳过确认提示(Agent 必须)
dws todo task create --title "Review PR" --executors "<your-userId>" --yes

# 使用 --dry-run 预览操作(安全执行)
dws contact user search --query "张三" --dry-run

# 使用 --jq 精确提取(节省 token)
dws contact user get-self --jq '.result[0].orgEmployeeModel | {name: .orgUserName, dept: .depts[0].deptName, userId}'

命令帮助与 Schema

命令帮助和 Schema 分别负责命令契约的不同部分:

  • dws <path> --help 是命令是否存在、当前二进制接受哪些 flags 的事实源。
  • dws schema "<path>" --compact 是 Agent 选命令、CLI 参数与约束、风险和确认语义的规范视图;映射或 provenance 审计使用 full leaf 配合 --jq 精确投影。
  • Help 与 Schema 冲突时视为契约漂移:执行只传 Cobra 接受的参数,安全语义取更保守值。
  • Schema 只描述命令,不读取或搜索钉钉业务数据;发现命令后仍需执行真实产品命令。
# 确认命令存在并查看当前接受的 flags
dws aitable record query --help

# 先在产品内发现命令,再查看选中 leaf 的契约
dws schema aitable --compact
dws schema "aitable record query" --compact

# 执行真实业务查询
dws aitable record query --base-id BASE_ID --table-id TABLE_ID --limit 10

dws schema --all 会完整导出命令契约,供工具、CI、审计和兼容性基线使用。Agent 应使用 --compact 渐进查询;该视图采用正向字段白名单,full 新增的审计字段不会自动进入 Agent 上下文。

Agent Skills

仓库内置完整的 Agent Skill 体系(skills/ 目录),分为两套布局:

  • skills/mono/ — 单 skill 布局(一个 SKILL.md + references/products/),legacy。
  • skills/multi/ — 每个产品一个独立 skill(dingtalk-aitable/ / dingtalk-calendar/ / dingtalk-chat/ ...),每个 skill 自带 SKILL.md。默认布局。

Schema 生成的叶子 safety/参数/选型文案由 Go 中的 ProductDecl / ContractFinal 声明驱动。原 internal/cli/schema_hints/ HintFile 目录已完全退役,不得重新引入。

安装之后,Claude Code / Cursor 等 AI 工具就能通过自然语言直接操作钉钉:

# 安装 skills 到当前项目(默认 multi;DWS_SKILL_MODE=mono 可切回)
curl -fsSL https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install-skills.sh | sh

安装器优先使用检测到的具体 Agent 根目录(如 $HOME/.codex/skills/);仅在未检测到具体 Agent 时回退到 .agents/skills/。multi 为按产品平铺,mono 为 dws/ 子目录。

国内用户加 DWS_GITEE_REPO 走 Gitee 镜像,见 国内加速安装

dws skill setup 切换或重装:

# 交互式:提示选模式 + 目标 Agent
dws skill setup

# 先预览 mono setup 将备份和替换的精确目录
dws skill setup --mode mono --target all --dry-run

# 交互执行并确认列出的目录
dws skill setup --mode mono --target all

# 先预览,再交互确认装到某一个 Agent home
dws skill setup --mode multi --target cursor --dry-run
dws skill setup --mode multi --target cursor

# 指定本地源目录(比如 fork 或正在改的版本),先预览
DWS_SKILL_SOURCE=/path/to/skills dws skill setup --mode multi --dry-run
DWS_SKILL_SOURCE=/path/to/skills dws skill setup --mode multi
参数取值说明
--modemono | multiskill 布局,不指定则交互式询问
--targetall | claude | cursor | codex | zcode | opencode | qoder安装目标;all 表示铺到检测到的具体 Agent home(ZCode 为 ~/.zcode/skills),仅在未检测到具体 Agent 时回退到 ~/.agents/skills
--source路径本地源目录(覆盖内置 skills)
--yes仅供脚本使用:跳过确认提示。删除操作仍会先备份到 ~/.dws/skill-backups/

setup 命令可能移除对面模式残留(装 multi 删 dws/,装 mono 清理统一状态中登记或属于状态上线前精确官方名称集合的 multi Skill)以及不在 bundle 内的过期受管 Skill。DWS 在 ~/.dws/skills-state.json(或 $DWS_CONFIG_DIR/skills-state.json)集中记录所有权、安装版本、来源和内容摘要。仅有 dingtalk-* 前缀不能触发清理,因此其他同前缀市场/用户 Skill 会保留。所有删除都会先列入确认预览,并备份到 ~/.dws/skill-backups/<时间戳>/;备份失败的目录会保留原样、绝不删除。非交互环境应先用 --dry-run 核对输出,再由调用方显式决定是否使用仅供脚本的确认跳过参数。

multi setup 或 upgrade 后,DWS 会把官方 bundle 快照和统一所有权元数据写入 ~/.dws/skills-state.json(或 $DWS_CONFIG_DIR/skills-state.json)。每次 upgrade 都会安装并覆盖该版本的全部预制 Skill;手工删除或通过 setup 排除预制 Skill 不会永久保留,下次 upgrade 会恢复。dws upgrade --force 还允许在没有新版本时重装当前 CLI 版本。

环境变量:DWS_SKILL_MODE=mono|multiinstall.sh / install.ps1 也认)、DWS_SKILL_SOURCE=<路径>

包含内容(mono 布局):

组件路径说明
主 Skillskills/mono/SKILL.md意图路由、决策树、安全规则、错误处理
产品参考skills/mono/references/products/*.md各产品命令详细参考(aitable、chat、calendar 等)
意图指南skills/mono/references/intent-guide.md易混淆场景消歧(如 report vs todo)
全局参考skills/mono/references/global-reference.md认证、输出格式、全局 flag
错误码skills/mono/references/error-codes.md错误码 + 调试流程
现成脚本skills/mono/scripts/*.py13 个批量操作脚本(见下方)
现成脚本 — 13 个 Python 脚本,覆盖常见多步工作流
脚本说明
calendar_schedule_meeting.py一键创建日程 + 添加参与者 + 搜索并预定空闲会议室
calendar_free_slot_finder.py查询多人共同空闲时段,推荐最佳会议时间
calendar_today_agenda.py查看今天/明天/本周的日程安排
import_records.py从 CSV/JSON 批量导入记录到 AI 表格
bulk_add_fields.py批量添加字段到 AI 表格数据表
upload_attachment.py上传附件到 AI 表格 attachment 字段
todo_batch_create.py从 JSON 文件批量创建待办(含优先级、截止时间、执行者)
todo_daily_summary.py汇总今天/本周未完成的待办
todo_overdue_check.py扫描已过截止时间但未完成的待办,输出逾期清单
contact_dept_members.py按部门名称搜索并列出所有成员
attendance_my_record.py查看我今天/本周/指定日期的考勤记录
attendance_team_shift.py查询团队成员本周排班和出勤统计
report_inbox_today.py查看今天收到的日志列表及详情

ISV 集成:编写您自己的 Agent Skill,与 dws 内置 Skill 搭配构建跨产品工作流:ISV Skill → dws Skill → 钉钉开放平台 API(强制鉴权 + 全链路审计)

功能特性

个人事件订阅 — 实时接收钉钉消息,驱动事件触发的 Agent

dws event consume 使用当前 OAuth 登录用户建立托管的 Stream WebSocket 长连接,并把每条事件以 NDJSON 一行输出到 stdout。当前公开目录覆盖指定范围和全量单聊/群消息、指定发送人、已读/撤回/表情回应、群生命周期、七个 OA 审批任务/实例事件,以及三个待办生命周期事件。

默认 ndjsonjsonpretty 输出保留兼容 transport envelope(typeevent_type、字符串 dataheaders),compact 继续沿用原 processor。Agent 或新脚本显式加 --flatten 后,输出稳定的顶层业务字段。--format 控制 JSON 序列化,--flatten 控制数据结构,且不能与 -f raw--debug-raw-events 同时使用。

前置条件:先运行 dws auth login。个人身份从 OAuth token 解析,不允许通过命令行伪造。

只需要 event 能力时,可以使用官方便捷安装脚本:

curl -fsSL https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install-event.sh | sh

# 或在已有 dws 环境中安装独立的 multi skill
dws skill setup --mode multi -s event
# 查看公开个人事件目录和 schema
dws event list
dws event schema user_im_message_receive_o2o --flatten
dws event list --category oa
dws event schema user_oa_approval_task_created --flatten
dws event list --category todo
dws event schema user_todo_task_create --flatten

# 监听当前用户被 @ 的消息
dws event +listen-im --kind at-me -f ndjson

# 监听指定发送人的消息
dws event +listen-im --kind sender --user <userId> -f ndjson

# 使用 openDingtalkId 监听外部联系人、机器人或跨组织身份
dws event +listen-im --kind sender --open-dingtalk-id <openDingtalkId> -f ndjson

# 监听指定群的消息
dws event +listen-im --kind group --chat-id <openConversationId> -f ndjson

# 监听所有单聊或所有群消息
dws event +listen-im --kind all-direct -f ndjson
dws event +listen-im --kind all-group -f ndjson

# 监听指定群标题变更、成员进退群或群解散
dws event consume user_im_group_updated --group <openConversationId> --flatten -f ndjson
dws event consume user_im_group_member_added --group <openConversationId> --flatten -f ndjson
dws event consume user_im_group_member_exited --group <openConversationId> --flatten -f ndjson
dws event consume user_im_group_disbanded --group <openConversationId> --flatten -f ndjson

# 一个进程监听同一发送人的消息、已读和撤回
dws event +listen-im --kind sender --user <userId> \
  --events message,read,recall -f ndjson

# 一个进程监听全部七个公开 OA 审批事件
dws event consume \
  user_oa_approval_task_created \
  user_oa_approval_task_finished \
  user_oa_approval_task_redirected \
  user_oa_approval_instance_started \
  user_oa_approval_instance_cc \
  user_oa_approval_instance_terminated \
  user_oa_approval_instance_finished \
  --flatten -f ndjson

# 监听当前用户作为执行者的待办创建、更新和删除事件
dws event consume \
  user_todo_task_create \
  user_todo_task_update \
  user_todo_task_delete \
  --role-types executor \
  --flatten -f ndjson

# 查看本地 consume,并取消指定订阅
dws event status
dws event stop <subscribe_id>

单聊和指定发送人事件必须且只能选择一种目标身份:企业内部 userId 使用 --useropenDingtalkId 使用 --open-dingtalk-id。CLI 不会自动猜测或转换身份类型。

特性说明
自动编排consume 创建或复用个人订阅,stop 取消订阅并清理本地状态
共享连接同一用户的多个 consumer 共享本地 bus 和云端长连接
多事件进程同一目标的兼容事件可由一个 consume 进程监听,每个事件仍有独立订阅
订阅隔离正常 consumer 同时按事件类型和 subscribe_id 匹配
Agent 友好输出Stream 事件写入 stdout,连接状态和诊断信息写入 stderr
状态可观测status 同时显示服务端订阅、personal bus 和本地 consumers
跨平台macOS/Linux 使用 Unix Socket,Windows 使用 Named Pipe

Agent 工作流和事件参数详见 skills/multi/dingtalk-event/SKILL.md

Raw API 调用 — 直接调用支持 App Token 的钉钉服务端 OpenAPI

dws api 让你直接调用支持企业内部应用 App Token 的钉钉服务端 OpenAPI,无需 SDK,Token 自动获取和刷新。

前置条件:必须提供一对完整的自有应用 Client ID/Client Secret,可来自本次 flags、环境变量或成功登录后保存的 app config(见自建应用模式)。仅通过 MCP 默认凭证登录不支持 Raw API 调用。

Client ID/Client Secret 必须来自同一完整凭证对,优先级为:完整 --client-id/--client-secret > 完整 DWS_CLIENT_ID/DWS_CLIENT_SECRET > 完整 app config。任一来源只提供一项都会明确失败,不会与其他来源拼接。直接用于 dws api 的 flags/env 仅对本次调用生效,不持久化 AppSecret;成功执行 dws auth login 时使用的 flags/env 则会按实际使用的完整 pair 持久化,供 OAuth 刷新和后续 Raw API 使用。获取到的 App Token 会按 app-token:<clientID> 缓存;隐藏 --token 仅临时使用调用方提供的 App Token,不持久化、不自动刷新。

Client Secret 统一使用 Keychain 槽位 appsecret:<clientID>,与 OAuth User Token、App Token 完全隔离。历史明文 app config 和 client-secret:<clientID> 会自动迁移;新旧槽位值不一致时 fail closed,要求重新登录,不猜测正确值。

# 登录(仅首次)
dws auth login --client-id <APP_KEY> --client-secret <APP_SECRET>

# 或使用一对环境变量,完整 env pair 会整体覆盖 app config
export DWS_CLIENT_ID=<APP_KEY>
export DWS_CLIENT_SECRET=<APP_SECRET>

# === api.dingtalk.com ===

# 获取企业所有应用列表
dws api GET /v1.0/microApp/allApps

# 搜索用户 (POST + JSON body)
dws api POST /v1.0/contact/users/search \
  --data '{"queryWord":"张三","offset":0,"size":10}'

# === oapi.dingtalk.com ===

# 获取用户详情(使用 --base-url 指定域名)
dws api POST /topapi/v2/user/get \
  --base-url https://oapi.dingtalk.com \
  --data '{"userid":"<USER_ID>"}'

# 也可以直接使用完整 URL
dws api POST https://oapi.dingtalk.com/topapi/v2/user/get \
  --data '{"userid":"<USER_ID>"}'

# === 通用功能 ===
dws api GET /v1.0/microApp/allApps --dry-run             # 预览请求
dws api GET /v1.0/microApp/allApps --jq '.appList | length'  # jq 过滤

# 从文件读取 JSON body(--params 也支持 @file;也可用 - 从 stdin 读取)
dws api POST https://oapi.dingtalk.com/topapi/v2/department/listsubid \
  --data @department-request.json --dry-run

# 单文件流式 multipart 上传;--data 顶层字段转为文本 form field;先 dry-run 核对
dws api POST https://oapi.dingtalk.com/media/upload \
  --data '{"type":"image"}' --file media=./demo.png --dry-run
特性说明
双形态自动识别根据 URL 自动选择 api.dingtalk.com(Header 认证)或 oapi.dingtalk.com(Query 参数认证)
Token 自动管理首次调用自动获取应用级 accessToken,有效期内缓存,过期自动刷新
域名白名单仅允许 api.dingtalk.comoapi.dingtalk.com,防止 Token 泄露
自动分页--page-all 自动遍历所有分页。--page-limit 控制翻页上限(默认 10,设为 0 不限制,硬上限 500 防止死循环)
安全传输仅允许 HTTPS/443 和同源 HTTPS 重定向;JSON/错误响应有限读取,二进制流式原子下载
Agent 发现现有产品命令未覆盖时,内置 misc/mono Skill 指导 Agent 从 https://open.dingtalk.com/llms.txt 分层定位官方接口;Raw api 本身不进入 Agent Schema

dws api 只自动使用企业内部应用的 App Token,不读取 OAuth User Token,也不提供 --as user / --user。优先使用已有 DWS 产品命令;只有未封装的企业内部应用服务端 OpenAPI 才使用 Raw 逃生舱。写、删、撤销等操作须在 dry-run 核对并确认后执行。

智能输入纠错 — 自动修正 AI 模型常见的参数错误

内置 Pipeline 纠错引擎,支持命名风格转换、粘连参数拆分、拼写模糊匹配:

# 命名风格自动转换 (camelCase / snake_case / UPPER → kebab-case)
dws aitable record query --baseId BASE_ID --tableId TABLE_ID         # 自动纠正为 --base-id --table-id

# 粘连参数自动拆分
dws contact user search --query "张三" --timeout30                  # 自动拆分为 --timeout 30

# 拼写错误模糊匹配
dws aitable record query --base-id BASE_ID --tabel-id TABLE_ID       # --tabel-id → --table-id

# 参数值归一化 (布尔 / 数字 / 日期 / 枚举)
# "yes" → true, "1,000" → 1000, "2024/03/29" → "2024-03-29", "ACTIVE" → "active"
Agent 输出dws 自动纠正为
--userId--user-id
--limit100--limit 100
--tabel-id--table-id
--USER-ID--user-id
--user_name--user-name
jq 过滤 & 字段筛选 — 精确控制输出,减少 token 消耗
# 内置 jq 表达式
dws aitable record query --base-id BASE_ID --table-id TABLE_ID --jq '.invocation.params'
dws schema "dev app create" --jq '.parameters'

# 只返回指定字段
dws aitable record query --base-id BASE_ID --table-id TABLE_ID --fields invocation,response
Schema 自省 — Agent 命令发现与执行契约
dws schema aitable --compact                            # 发现产品命令
dws schema "aitable record query" --compact             # 查看 Agent leaf 契约
dws schema "aitable record query" --jq '[.parameters | to_entries[] | select(.value.required)]' # 定向查看必填字段
dws schema --all                                        # CI/审计/基线的全量导出
管道 & 文件输入 — 从文件或 stdin 读取 flag 值
# 从文件读取消息内容
dws chat message send-by-bot --robot-code BOT_CODE --group GROUP_ID \
  --title "周报" --text @report.md

# 通过管道传入内容
cat report.md | dws chat message send-by-bot --robot-code BOT_CODE --group GROUP_ID \
  --title "周报"

# 显式从 stdin 读取
dws chat message send-by-bot --robot-code BOT_CODE --group GROUP_ID \
  --title "周报" --text @-

说明@ 仅在其后是 ASCII 路径前缀字符(A-Z / a-z / 0-9 / . / / / ~ / _ / -)或 @-(stdin)时,才会被识别为 @<path> 文件注入语法。--text "@所有人 周报" / --text "@张三 看一下" 这类机器人消息中的字面 @ 提及会原样透传到 API。

钉钉机器人 —— 把机器人接到你本地的 AI

dws dev connect 把一个钉钉机器人接到本地 AI CLI(Claude Code / Codex / opencode / Qoder / Gemini,或用 --agent-cmd 接任意工具):群里 @ 机器人提问,它用你本地的 agent 回答,按会话保留多轮上下文。

dws dev connect --channel auto --robot-client-id <id> --robot-client-secret <secret>

聊天里的会话指令(整条消息就是指令时生效,不消耗一次 AI 调用):

指令作用
/new(别名 /start/reset开启新会话;旧会话保留(agent 支持的话仍可回溯)
/clear清空当前会话 —— 调 agent 真实会话原语真删(opencode 走 DELETE /session/:id);驱动接口没有删除原语的渠道退化为重置

完整四步教程见 docs/robot-quickstart.md(装工具 → 建机器人 → 接上 AI → 拉进群)。

核心服务

服务命令能力
通讯录contact按姓名 / 手机号 / 工号查人,部门、角色标签、花名册与离职;创建企业、企业账号及邀请员工
群聊chatim发送 / 回复 / 搜索消息,群与成员管理,机器人与 Webhook 发消息,表情反应,撤回
日历calendar日程 CRUD、参与者、会议室、闲忙与时间建议
待办todo创建 / 列表 / 修改 / 完成待办及评论
审批oa同意 / 拒绝 / 撤销 / 转交,查待办 / 已发起 / 抄送及表单
考勤attendance打卡记录、排班、考勤摘要、考勤组规则(只读)
DINGding发送 / 撤回 DING 消息
日志report创建 / 提交日志,收发件箱,模版,统计
AI 表格aitableBase / 数据表 / 记录 / 字段 / 视图,权限与角色,自动化,图表与仪表盘,导入导出
文档doc搜索 / 读写文档,块级编辑,评论,权限,媒体,上传 / 下载
钉盘drive列表 / 搜索 / 下载,文件夹,上传,复制 / 移动 / 重命名,权限
AI 听记minutes听记列表、摘要 / 关键词 / 转写 / 待办、思维导图、发言人、标签
邮箱mail邮箱、KQL 搜索、读 / 发、草稿、文件夹、模版、联系人
在线电子表格sheet在线表格:工作表与区域读写、筛选、条件格式、图片、CSV
知识库wiki知识库:空间、成员、节点树、文档与文件
开发者文档devdoc搜索开放平台文档并排查 API 错误
AI 搜问aisearch企业人员搜索:按姓名 / 部门 / 角色 / 职责 / 上下级 / 手机号 / 工号
直播live查看我的直播列表
Raw APIapi直接调用支持 App Token 的钉钉服务端 OpenAPI,自动管理应用级 Token

完整命令清单(带描述与使用场景):docs/command-index.md。运行 dws --help 查看顶层命令树,或 dws <service> --help 查看任一服务的子命令。

关于 chat bot:机器人能力(send-by-bot / recall-by-bot / add-bot / send-by-webhook / bot 搜索)已合并到对应的 chat 子树下(例如 dws chat message send-by-botdws chat group members add-bot),保持 agent 视角下的命令面扁平易发现。不再有独立的顶层 bot 产品。

即将推出
  • conference(视频会议)
  • 多 skill 模式(默认)— 每产品一个独立 skill,位于 skills/multi/,安装与升级默认启用;dws skill setup --mode mono 交互确认后可切回单 skill

安全设计

dws 从架构层面将安全作为一等公民,而非事后补丁。凭证不落盘、Token 不出域、权限不越界、操作不脱审 — 每一次 API 调用都必须经过钉钉开放平台的鉴权和审计链路,无例外。

开发者安全机制
机制说明
Token 加密存储PBKDF2(600,000 次迭代 + SHA-256)+ AES-256-GCM 加密,密钥绑定设备物理 MAC 地址;macOS 集成系统 Keychain、Windows 集成 DPAPI 提供额外保护,跨设备无法解密
输入安全防护路径遍历防护(符号链接解析 + 工作目录约束)、CRLF 注入拦截、Unicode 视觉欺骗字符过滤,防止 AI Agent 被恶意指令诱导
域名白名单DWS_TRUSTED_DOMAINS 默认仅信任 *.dingtalk.com,Bearer Token 不会发送到非白名单域
并发安全双层锁机制(进程内 + 跨进程文件锁)保障 Token 刷新原子性,适配高并发 MCP Server 场景
数据完整性所有配置写入采用原子操作(temp + fsync + rename),确保进程中断时数据不损坏
HTTPS 强制除 loopback 开发调试外,所有请求强制 TLS
Dry-run 预览--dry-run 展示调用参数但不执行,防止误操作生产数据
凭证零落盘Client ID / Secret 仅在内存中使用,不写入配置文件或日志
企业管理员安全机制
机制说明
OAuth 设备流认证用户必须通过管理员授权的钉钉应用认证,未授权应用无法获取 Token
权限最小化CLI 仅能调用管理员授予该应用的 API 权限范围,无法越权
白名单准入共创阶段需管理员主动确认开通,后续支持自助审批
操作全链路审计每一次数据读写都经过钉钉开放平台 API,企业管理员可在管理后台实时追溯完整调用日志,任何异常操作无处隐藏
ISV / 企业服务商安全机制
机制说明
租户数据隔离以已授权应用身份调用 API,不同租户数据严格隔离
Skill 沙箱Agent Skills 是 Markdown 文档(SKILL.md),仅提供 prompt 描述,不执行任意代码
集成链路零盲区ISV Skill 与 dws Skill 联调时,每一次 API 调用都强制经过钉钉开放平台鉴权,完整调用链路可追溯,不存在绕过审计的旁路

发现安全漏洞?请通过 GitHub Security Advisories 报告,详见 SECURITY.md

参考与文档

贡献指南

参见 CONTRIBUTING.md 了解构建、测试和开发工作流。

许可证

Apache-2.0