Skip to main content

从钉盘同步文档到 TorchV AIS:简明教程

本文介绍如何使用钉钉 DWS 命令行工具,将钉盘或“文档空间”中的文件下载到本地中转目录,再上传到独立部署的 TorchV AIS 知识库。

本文适用于以下场景:

  • 钉盘企业空间或“我的文件”中的普通文件;
  • 钉盘文件夹的批量拉取;
  • Word、Excel、PDF、PPT、Markdown 等文件导入 AIS;
  • 后续扩展为定时、增量、可审计的单向同步任务。

本文中的“钉盘”是钉钉的文件存储层。钉钉在线文档、在线电子表格虽然也显示在文件目录中,但不能一律当作普通文件下载,需要按内容类型分别导出。

一、钉盘同步和知识库同步有什么不同

对比项钉盘/文档空间钉钉知识库
主要结构空间、文件夹、文件知识空间、目录节点、知识页面
空间标识spaceIdworkspaceId
根目录标识rootFolderId知识库根节点或节点ID
文件标识dentryUuid / fileIdnodeId
普通文件获取使用 Drive 直接下载普通附件下载,在线内容另行导出
整目录处理支持 statuspullpushsync通常需要遍历节点并逐个导出
推荐同步方向钉盘 → 本地 → AIS知识库 → 本地 → AIS

向 AIS 导入时,建议始终采用单向流程:

钉盘只读扫描

识别文件与在线文档类型

下载或导出到本地 staging 目录

计算哈希并记录同步清单

上传到 AIS 指定目录

按 AIS 文档编码读回验证

不建议为这个场景使用 push 或双向 sync,以免把本地中转文件反向写回钉盘。

二、准备工作

1. 本地工具

沿用前一份钉钉知识库导入项目:

cd /Users/lu/Documents/Codex/dingtalk-ais-sync

SYNC_PROJECT="$(pwd)"
DWS_BIN="$SYNC_PROJECT/node_modules/.bin/dws"
AIS_KB_BIN="/Users/lu/Documents/Codex/.agents/bin/ais-kb.sh"

mkdir -p "$SYNC_PROJECT/staging/drive" "$SYNC_PROJECT/state"

检查 DWS 登录状态:

"$DWS_BIN" auth status --format json

应确认当前登录的是正确的钉钉企业,并且访问令牌有效。首次使用时执行:

"$DWS_BIN" auth login

本场景至少需要钉盘/文档空间的只读、列表和下载权限;如果存在在线文档,还需要对应的文档或电子表格导出权限。

2. AIS目标目录

本文继续以以下目录为例:

卢向东的个人知识库/钉钉知识库导入存放目录

检查目录:

"$AIS_KB_BIN" \
"kb tree 卢向东的个人知识库/钉钉知识库导入存放目录/ --depth 2 --limit 50"

三、发现钉盘空间

钉盘可能位于企业空间,也可能位于个人的“我的文件”。先根据实际位置选择一种查询方式。

1. 查询企业空间

"$DWS_BIN" wiki space list \
--type orgSpace \
--format json

如果返回 nextToken,应使用游标继续查询,直到分页结束。不要默认选择返回结果中的第一个空间。

2. 查询“我的文件”空间

"$DWS_BIN" wiki space list \
--type mySpace \
--format json

从真实返回中保存:

  • spaceId:钉盘空间ID;
  • rootFolderId:空间根目录ID。

rootFolderId 才能作为 Drive 的根文件夹参数;不要把知识库的 workspaceId 或数字型 dentryId 混用为文件夹ID。

四、浏览并定位目标文件夹

列出空间根目录:

"$DWS_BIN" drive +list \
--folder "<rootFolderId>" \
--limit 50 \
--format json

继续浏览某个子目录:

"$DWS_BIN" drive +list \
--folder "<子文件夹dentryUuid>" \
--limit 50 \
--format json

读取结果时应注意:

  • --folder 使用 dentryUuidfileId,不是数字型 dentryId
  • 一页最多读取50项;
  • hasMore=true 时应根据 nextCursor 继续分页;
  • 同名文件多于一个时,应根据目录、类型、大小和修改时间消歧,不能直接选择第一项。

如果手中只有一个钉盘文件链接,可以先解析链接:

"$DWS_BIN" drive info \
--node "<钉盘文件或文件夹URL>" \
--format json

以返回的真实 nodeId 继续操作。

五、下载普通文件

1. 检查文件类型

"$DWS_BIN" drive +inspect \
--node "<文件dentryUuid>" \
--format json

普通 Office、PDF、图片、压缩包等文件可直接下载;在线文档类型需要走第七节的分类导出。

2. 下载到本地中转目录

单文件下载的输出路径使用当前工作目录下的相对路径:

cd "$SYNC_PROJECT"

"$DWS_BIN" drive +download \
--node "<文件dentryUuid>" \
--output "staging/drive/文件名.pdf" \
--format json

下载后验证:

file "staging/drive/文件名.pdf"
shasum -a 256 "staging/drive/文件名.pdf"

至少确认文件存在且大小大于0。源端和下载结果都提供可比哈希时,再进一步比较校验和。

六、批量拉取整个钉盘文件夹

DWS 支持比较和拉取普通文件夹。文件夹命令使用本地绝对路径。

1. 只读比较

"$DWS_BIN" drive status \
--local-folder "$SYNC_PROJECT/staging/drive" \
--remote-folder "<钉盘文件夹dentryUuid>" \
--format json

结果通常分为:

  • new_remote:钉盘有、本地没有;
  • new_local:本地有、钉盘没有;
  • modified:两侧内容不同;
  • unchanged:内容一致;
  • unknown:无法可靠判断。

2. 预演拉取

"$DWS_BIN" drive pull \
--local-folder "$SYNC_PROJECT/staging/drive" \
--remote-folder "<钉盘文件夹dentryUuid>" \
--if-exists skip \
--dry-run \
--format json

skip 是安全默认值:本地已存在同名文件时不覆盖。检查预演结果无误后,再用完全相同的目录和冲突策略正式执行。

3. 正式拉取

"$DWS_BIN" drive pull \
--local-folder "$SYNC_PROJECT/staging/drive" \
--remote-folder "<钉盘文件夹dentryUuid>" \
--if-exists skip \
--format json

如果运行时要求确认,应在核对目标文件夹、同步方向和影响后,按命令提示确认。不要为了省事默认改为 overwrite

注意:

  • 文件夹拉取只处理普通文件和目录;
  • 在线文档、在线电子表格和快捷方式不会按普通二进制文件同步;
  • 拉取不会删除本地多余文件;
  • 应检查汇总和逐项结果,存在 failedunknown 时不能宣称全部成功。

七、处理钉盘中的在线文档

钉盘目录中的节点需要先按类型分流:

节点类型正确处理方式
普通 docxxlsxpdfpptxdws drive +download
钉钉在线文字文档 adocdws doc +export,建议导出为 DOCX 或 Markdown
钉钉在线电子表格 axlsdws sheet export,导出为 XLSX
AI表格 able使用 AI 表格专用导出流程

在线文字文档示例:

"$DWS_BIN" doc +export \
--node "<在线文档nodeId>" \
--export-format docx \
--output "./staging/drive/文档名.docx" \
--format json

在线电子表格示例:

"$DWS_BIN" sheet export \
--node "<在线表格nodeId>" \
--output "./staging/drive/表格名.xlsx" \
--format json

这部分与“钉钉知识库文档导出到 AIS”的类型分流方法相同,可结合项目目录中的前一份教程阅读:

钉钉知识库文档导出到AIS知识库教程.md

八、上传到 AIS

下载或导出成功后,将文件逐个上传到 AIS 目标目录:

"$AIS_KB_BIN" \
--upload-file "$SYNC_PROJECT/staging/drive/文件名.pdf" \
--path-name "/卢向东的个人知识库/钉钉知识库导入存放目录"

每次上传后保存 AIS 返回的稳定文档编码。然后检查目录:

"$AIS_KB_BIN" \
"kb tree 卢向东的个人知识库/钉钉知识库导入存放目录/ --depth 2 --limit 50"

待 AIS 完成解析和知识加工后,按文档编码读回:

"$AIS_KB_BIN" \
"kb cat --code <AIS文档编码> --head 120"

只有同时满足以下条件,才能认为单个文件完成了端到端导入:

  1. 钉盘文件下载或在线内容导出成功;
  2. 本地文件存在且大小正常;
  3. AIS 返回稳定文档编码;
  4. 文件出现在目标目录;
  5. AIS 可以读取知识加工后的正文。

九、建立同步清单

建议为每个文件保存一条映射记录:

{
"sourceSystem": "dingtalk-drive",
"spaceId": "<钉盘spaceId>",
"sourceFolderId": "<钉盘文件夹dentryUuid>",
"sourceNodeId": "<文件dentryUuid>",
"sourceName": "文件名.pdf",
"sourceType": "file",
"sourceUpdatedAt": "2026-08-24T10:00:00+08:00",
"sourceSizeBytes": 123456,
"localFile": "staging/drive/文件名.pdf",
"sha256": "<本地文件SHA-256>",
"aisDirectoryCode": "<AIS目录编码>",
"aisDocumentCode": "<AIS文档编码>",
"syncStatus": "SUCCESS"
}

后续增量同步应以 sourceNodeId 为源对象主键,结合修改时间、大小和本地哈希判断是否变化,不能只依赖文件名。

十、从一次性导入升级为每日同步

生产化任务可以按以下步骤运行:

定时触发
→ 读取目标钉盘文件夹
→ 完成全部分页
→ 与上次同步清单比较
→ 只下载新增或已修改文件
→ 在线文档按类型导出
→ 上传 AIS
→ 读回验证
→ 更新映射、日志和失败队列

建议增加以下控制:

  • 最小权限:生产环境使用企业内部应用,只开放所需只读权限;
  • 范围限制:明确允许同步的空间和根文件夹,避免无界扫描;
  • 增量同步:优先处理新增和修改文件;
  • 幂等映射:保存钉盘 sourceNodeId 与 AIS 文档编码的对应关系;
  • 失败重试:网络中断、导出超时和 AIS 转换中分别处理;
  • 删除策略:钉盘源文件被删除时,默认只告警,不自动删除 AIS 文件;
  • 权限治理:钉盘与 AIS 权限模型不完全相同,敏感目录应单独映射和审核;
  • 审计记录:记录同步时间、操作者、源文件、目标目录、哈希和最终状态。

十一、常见问题

1. 为什么 drive pull 没有拉到在线文档

文件夹拉取只处理普通文件和目录。在线文字文档、在线表格等需要识别类型后,使用相应的导出命令。

2. spaceIdrootFolderIdworkspaceId 能否混用

不能。spaceId 表示钉盘空间,rootFolderId 表示钉盘根文件夹,workspaceId 表示知识库空间。后续参数必须使用接口实际返回的正确ID。

3. 同名文件应该怎么处理

不要根据名称自动选择第一项。应结合完整目录、dentryUuid、文件类型、大小和更新时间确定唯一源文件。

4. 是否应该使用双向同步

钉盘导入 AIS 的目标是知识接入,不是文件协同。推荐只执行“钉盘 → 本地 → AIS”,避免使用 push 或双向 sync

5. 钉盘删除文件后,是否自动删除 AIS 内容

初期不建议自动删除。应先记录删除事件并告警,由管理员确认 AIS 中的知识是否仍需保留;生产阶段再建立明确的软删除、归档和审计策略。

十二、最短命令清单

# 1. 发现钉盘空间
"$DWS_BIN" wiki space list --type orgSpace --format json

# 2. 浏览目标文件夹
"$DWS_BIN" drive +list --folder "<folderId>" --limit 50 --format json

# 3. 查看文件类型
"$DWS_BIN" drive +inspect --node "<nodeId>" --format json

# 4. 下载普通文件
"$DWS_BIN" drive +download \
--node "<nodeId>" \
--output "staging/drive/文件名" \
--format json

# 5. 或批量拉取文件夹:先预演,再执行
"$DWS_BIN" drive pull \
--local-folder "$SYNC_PROJECT/staging/drive" \
--remote-folder "<folderId>" \
--if-exists skip \
--dry-run \
--format json

"$DWS_BIN" drive pull \
--local-folder "$SYNC_PROJECT/staging/drive" \
--remote-folder "<folderId>" \
--if-exists skip \
--format json

# 6. 上传 AIS
"$AIS_KB_BIN" \
--upload-file "$SYNC_PROJECT/staging/drive/文件名" \
--path-name "/卢向东的个人知识库/钉钉知识库导入存放目录"

# 7. 读回验证
"$AIS_KB_BIN" "kb cat --code <AIS文档编码> --head 120"

本教程适合先完成一次小范围验证。正式接入时,应在固定文件夹、最小权限、增量清单、失败重试和人工删除确认的基础上,再配置定时任务。