feat: add dingtalk-feishu-collector SOP skill

Reusable 6-step pipeline for collecting DingTalk group messages,
extracting Feishu doc links, fetching content, and generating summaries.

Skills structure:
- SKILL.md: trigger rules, workflow, config reference
- config.yaml: group IDs, collection settings
- scripts/paths.py: shared path resolution
- scripts/step1-6: modular pipeline steps
- scripts/run_all.py: one-click runner
This commit is contained in:
Evilom
2026-06-06 11:14:00 +08:00
parent fae01e9217
commit ab2ca1d836
15 changed files with 1476 additions and 0 deletions
+469
View File
@@ -0,0 +1,469 @@
# 从钉钉群聊到知识库:飞书文档自动采集与结构化系统 - 复刻指南
> 作者:大师 | 日期:2026-06-03
---
## 一句话说清楚这个项目做了什么
**从钉钉群聊消息中自动抓取飞书文档链接和文件附件,下载内容,构建知识图谱和 Obsidian 知识库。**
整个流程 = 3个核心工具 + 6个Python脚本,不需要自己写任何API对接代码。
---
## 整体架构
```
钉钉群聊消息
|
v
(1) dws CLI(悟空)-- 拉取钉钉消息、下载文件附件
|
v
(2) Python 脚本 -- 正则提取飞书链接 + 文件ID
|
v
(3) lark-cli -- 读取飞书文档内容(Block API)
|
v
(4) Python 脚本 -- 构建知识图谱(JSON)、Obsidian 库、汇总报告
```
**关键认知:你不需要申请飞书开放平台的App。** 消息来源是钉钉(通过dws),飞书文档内容获取通过lark-cli(浏览器授权登录即可)。
---
## 核心工具获取指南
### 工具 1dws CLI -- 钉钉消息采集(随悟空自动安装)
**是什么**dws CLI 是钉钉「悟空」(Wukong) 桌面客户端自带的命令行工具,封装了钉钉 25+ 项 MCP 服务(群聊消息、文件管理、日历、通讯录、审批等),无需自己对接钉钉开放平台API。
**获取方式(三种,选一种即可)**
| 方式 | 适合谁 | 操作 |
|------|--------|------|
| **GitHub 直接下载**(推荐) | 所有人 | 从 GitHub Releases 下载对应平台的压缩包,解压即用 |
| 安装悟空客户端 | 钉钉重度用户 | 装完悟空,dws 自动在 `C:\Program Files\Wukong\<版本>\bin\dws.exe` |
| 从同事那里复制 | 最省事 | 复制一个 `dws.exe` 文件(约 5-14MB |
**GitHub 仓库**https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli
这是钉钉官方开源的 CLI 工具,2000+ stars,持续更新中(最新 v1.0.332026-06-02 发布)。
```bash
# 从 GitHub Releases 直接下载(以 Windows 为例):
# https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli/releases/latest
# 下载 dws-windows-amd64.zip(约 5.3MB),解压得到 dws.exe
# macOS / Linux 也有对应版本:
# dws-darwin-amd64.tar.gz (macOS Intel)
# dws-darwin-arm64.tar.gz (macOS Apple Silicon)
# dws-linux-amd64.tar.gz (Linux x64)
```bash
# 悟空是钉钉的AI桌面客户端(也叫钉钉Real版),安装后自动附带:
# - dws CLI(钉钉MCP服务命令行)
# - wukong-cli(悟空Agent命令行)
# - Node.js、Python、ffmpeg 等运行时
#
# 安装路径参考:
# 主程序:C:\Program Files\Wukong\<版本号>\DingTalkReal.exe
# dws CLIC:\Program Files\Wukong\<版本号>\bin\dws.exe
# 运行时缓存:C:\Users\<用户名>\.real\.bin\dws\bin\dws.exe
```
**版本信息**(本项目实际使用):
| 项目 | 值 |
|------|-----|
| 悟空版本 | 0.9.51 |
| dws CLI 版本 | 0.2.75(悟空内置)/ 1.0.33GitHub 最新) |
| 架构 | MCP Dynamic Aggregation |
| Go 版本 | 1.24+ |
**认证**:首次使用需要登录认证(钉钉扫码或账号登录),Corp ID 和 User ID 会自动配置。运行 `dws auth status` 可查看登录状态。
**能把 dws 单独提取出来用吗?可以。**
dws.exe 是 Go 语言静态编译的二进制文件(14MB),不依赖任何外部 DLL,可以脱离悟空独立运行。提取方法:
```bash
# 只需要一个文件:dws.exe14MB
# 路径:C:\Program Files\Wukong\<版本号>\bin\dws.exe
# 或:C:\Users\<用户名>\.real\.bin\dws\bin\dws.exe
# 1. 复制 dws.exe 到任意目录
copy "C:\Users\admin\.real\.bin\dws\bin\dws.exe" D:\tools\dws.exe
# 2. 首次运行,触发认证(会自动创建 .dws 数据目录)
D:\tools\dws.exe auth status
# 如果未登录,会提示 OAuth 扫码登录(用钉钉App扫码)
# 3. 认证成功后,目录下会自动生成 .dws/ 子目录:
# .dws/identity.json -- 身份标识
# .dws/token.json -- Token(自动续期)
# .dws/.data -- 加密凭证
# .dws/logs/ -- 日志
# 4. 验证可用
D:\tools\dws.exe chat message list --help
D:\tools\dws.exe drive download --help
```
**提取后的体积**
| 文件 | 大小 |
|------|------|
| `dws.exe` | 14 MB |
| `.dws/` 数据目录 | < 1 MB |
| **总计** | **约 14 MB** |
**认证机制详解(dws 自带,不需要悟空)**
dws 内置了完整的 OAuth 认证流程,提取出来后独立就能完成登录:
```
运行 dws auth status(未登录状态)
-> dws 启动 Device Flow OAuth
-> 连接 login.dingtalk.com/oauth2/auth
-> 终端显示二维码 / URL
-> 用钉钉App扫码授权
-> dws 轮询 api.dingtalk.com 获取 Token
-> Token 加密存储到 .dws/.data
-> 完成
```
dws 内置了默认的 OAuth ClientID/ClientSecret,普通用户直接用就行,不需要自己申请。如果公司有自建应用,也可以通过环境变量覆盖:
```bash
# 可选:使用自建应用的凭证(一般不需要)
export DWS_CLIENT_ID=<你的AppKey>
export DWS_CLIENT_SECRET=<你的AppSecret>
```
**注意事项**
- Token 会自动续期,但长时间不用会过期,重新运行 `dws auth status` 触发重新扫码即可
- 每个人需要用自己的钉钉账号认证,不能共用 Token
- 提取出来的 dws 功能完整,支持全部 25+ 项 MCP 服务
- `.dws/.data` 是加密存储的凭证文件(511字节),不要分享给别人
**核心能力**
| 命令 | 用途 | 示例 |
|------|------|------|
| `dws chat message list` | 拉取群聊消息 | `dws chat message list --group <群ID> --time "2026-05-01" --format json --limit 200` |
| `dws drive download` | 下载文件附件 | `dws drive download --node <fileId> --output ./files/` |
**获取群组ID**:需要知道目标群的 `openConversationId`,可以通过以下方式获取:
- 在钉钉管理后台查看
- 或者先用 `dws chat group list` 命令列出你所在的群
**分页策略**:API 每次最多返回约200条消息,超过的话需要分段拉取 + 用 `openMessageId` 去重:
```python
# 分段拉取示例
segments = [
("2026-05-01 00:00:00", "true"), # 从5月1日向前
("2026-05-19 00:00:00", "true"), # 从5月19日向前
("2026-05-24 00:00:00", "true"), # 从5月24日向前
("2026-06-03 00:00:00", "false"), # 从6月3日向后
]
# forward="true" 表示从该时间点向前(更新的消息)
# forward="false" 表示从该时间点向后(更旧的消息)
```
---
### 工具 2lark-cli -- 飞书文档内容读取
**是什么**:飞书官方提供的命令行工具,通过浏览器 OAuth 授权后,可以直接调用飞书 Open API 读取文档内容。
**安装**
```bash
# 需要 Node.js 18+
npm install -g @larksuite/cli
# 验证安装
lark-cli --version
```
**认证配置**(关键步骤):
```bash
# 1. 初始化配置
lark-cli config init
# 2. 浏览器授权登录(会自动打开浏览器)
lark-cli auth login --domain docs,drive,wiki --recommend
# 3. 验证授权状态
lark-cli auth status
```
**为什么能拿到飞书文档内容?**
这是大家最关心的问题,答案是:
1. **lark-cli 使用浏览器 OAuth 授权**:你在浏览器里登录自己的飞书账号,lark-cli 拿到你的访问令牌(token)。
2. **用你的身份调飞书 Open API**:后续所有请求都是以你个人身份发出的,跟你在浏览器里打开文档一样。
3. **你有权限看的文档,lark-cli 就能读**:不是破解,不是爬虫,就是正常的API调用。
```
你(浏览器登录飞书)-> OAuth Token -> lark-cli -> 飞书 Open API -> 文档内容
```
**核心命令**
```bash
# 获取文档内容(Block API,返回JSON格式)
lark-cli api GET /open-apis/docx/v1/documents/<doc_id>/blocks --format json
# doc_id 从飞书链接中提取:
# 例:https://dianchukeji.feishu.cn/docx/AbLed72FgoPn5hxOYN3cRpffn0E
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 这就是 doc_id
```
**注意事项**
- Token 有过期时间,长时间不用需要重新授权
- 你只能读取你有权限的飞书文档(跟在浏览器里访问一样)
- wiki 类型的链接需要先解析真实的 doc_id(wiki 链接里的ID是节点ID,不是文档ID)
---
### 工具 3Python 脚本 -- 数据处理管线
**依赖安装**
```bash
pip install beautifulsoup4 requests
```
**7个脚本的职责**
| 脚本 | 输入 | 输出 | 干什么 |
|------|------|------|--------|
| `fetch_all.py` | dws CLI | `data/raw-messages/all_messages_combined.json` | 拉取两个群的全部消息 |
| `extract_links.py` | 上一步的JSON | 终端输出(统计信息) | 正则提取飞书链接、文件附件、Kimi链接 |
| `build_graph.py` | 消息JSON | `output/knowledge-graph/knowledge_graph.json` | 构建知识图谱(人物、文档、主题、关系) |
| `write_obsidian.py` | 硬编码内容 | `output/obsidian-vault/` 目录 | 生成 Obsidian 知识库(含双向链接) |
| `write_report.py` | 硬编码内容 | `output/reports/花园世界全量汇总.md` | 生成全量汇总报告 |
| `gen_visual.py` | knowledge_graph.json | `output/knowledge-graph/` HTML+Mermaid | 生成可视化知识图谱 |
| `daily_feishu_collector.py` | dws CLI | `feishu_links_YYYYMMDD.json` | 每日定时采集(增量) |
---
## 钉钉消息为什么能拿到?
**原理**:通过 dws CLI(悟空工具)直接调用钉钉内部API。
```
dws CLI -> 钉钉内部 API -> 群聊消息(含发送者、时间、内容、文件ID)
```
- dws CLI 是公司内部工具,已经封装好了钉钉API的认证和调用
- 你只需要提供群组的 `openConversationId` 和时间范围
- 返回的消息内容是 JSON 格式,包含消息文本、发送者、时间戳等
- 文件附件可以通过 `fileId``dws drive download` 下载
**不需要**:申请钉钉开放平台应用、配置回调URL、处理webhook。
---
## 飞书文档为什么能拿到?
**原理**:lark-cli 使用你的飞书账号 OAuth 授权,以你的身份调用飞书 Open API。
```
你登录飞书 -> OAuth Token -> lark-cli -> /open-apis/docx/v1/documents/{id}/blocks -> 文档内容JSON
```
**三个前提条件**
1. **你有飞书账号**:公司飞书租户下的账号
2. **你有文档访问权限**:文档对你可见(在群里分享过的文档,群成员通常都有权限)
3. **lark-cli 授权成功**`lark-cli auth login` 一次即可,后续自动使用缓存的token
**能读到什么**
- `docx` 类型文档:直接通过 doc_id 调 Block API 获取全部内容
- `wiki` 类型文档:需要先通过 wiki API 解析节点ID得到真实 doc_id,再调 Block API
- 文件附件(XLSX/PPT/PDF等):通过 `dws drive download` 从钉钉侧下载
**读不到什么**
- 你没有权限的文档(跟浏览器一样,没权限就是没权限)
- 已被删除的文档
---
## 复刻步骤(从零开始)
### 第一步:确认工具就绪
```bash
# 检查 dws CLI
dws --version
# 如果没有,找IT获取
# 检查 Node.js
node --version # 需要 18+
# 检查 Python
python --version # 需要 3.10+
# 安装 lark-cli
npm install -g @larksuite/cli
# 安装 Python 依赖
pip install beautifulsoup4 requests
```
### 第二步:授权 lark-cli
```bash
lark-cli config init
lark-cli auth login --domain docs,drive,wiki --recommend
# 浏览器会自动打开,登录你的飞书账号即可
```
### 第三步:获取群组ID
你需要知道要采集的钉钉群的 `openConversationId`。获取方式:
1. 在钉钉管理后台查看
2. 或者用 dws 命令列出你所在的群
3. 或者找之前已经获取过的同事要
### 第四步:拉取消息
修改 `scripts/fetch_all.py` 中的群组ID和时间范围,然后运行:
```bash
python scripts/fetch_all.py
```
这会生成 `data/raw-messages/all_messages_combined.json`,包含两个群的全部消息。
### 第五步:提取链接
```bash
python scripts/extract_links.py
```
输出统计信息:飞书链接数、文件附件数、Kimi链接数等。
### 第六步:构建知识图谱
```bash
python scripts/build_graph.py
```
生成 `output/knowledge-graph/knowledge_graph.json`,包含人物、文档、主题、关系的结构化数据。
### 第七步:生成可视化和知识库
```bash
# 知识图谱可视化
python scripts/gen_visual.py
# 输出:output/knowledge-graph/knowledge_graph.html(浏览器打开即可查看)
# Obsidian 知识库
python scripts/write_obsidian.py
# 输出:output/obsidian-vault/(用 Obsidian 打开此目录)
# 汇总报告
python scripts/write_report.py
```
### 第八步:设置定时采集(可选)
```powershell
# Windows 定时任务,每天18:00执行
schtasks /create /tn "FeishuDocCollector" /tr "python D:\path\to\scripts\daily_feishu_collector.py" /sc daily /st 18:00
```
---
## 常见问题
### Q: 需要申请飞书开放平台的App吗?
**不需要。** lark-cli 用的是浏览器 OAuth 授权(你的个人身份),不需要创建企业自建应用。
### Q: 需要申请钉钉开放平台的权限吗?
**不需要。** dws CLI 是内部工具,已经封装好了认证。
### Q: 飞书文档有4种域名,都能读吗?
都能读,只要你有权限。不同域名对应不同的飞书空间/租户,lark-cli 用你的账号登录后可以跨空间访问。
本项目涉及的4个飞书域:
| 域名 | 说明 |
|------|------|
| `dianchukeji.feishu.cn` | 公司飞书 |
| `fcnlycv6dd0w.feishu.cn` | 研究组飞书空间 |
| `ocnmca6f1o0p.feishu.cn` | 另一飞书空间 |
| `my.feishu.cn` | 个人飞书 |
### Q: 消息太多拉不完怎么办?
分段拉取 + `openMessageId` 去重。见 `fetch_all.py` 中的分段策略。
### Q: Token 过期了怎么办?
重新运行 `lark-cli auth login --domain docs,drive,wiki --recommend`,浏览器重新授权即可。
### Q: wiki 链接和 docx 链接有什么区别?
docx 链接的ID就是文档ID,可以直接调API。wiki 链接的ID是知识库节点ID,需要先通过 wiki API 解析出真实的文档ID。
---
## 技术栈总结
| 层级 | 工具 | 获取方式 | 费用 |
|------|------|----------|------|
| 钉钉消息采集 | dws CLI | 悟空(Wukong)自带,装悟空就有 | 免费 |
| 钉钉文件下载 | dws drive | 同上,dws 的子命令 | 免费 |
| 飞书文档读取 | lark-cli | `npm install -g @larksuite/cli` | 免费 |
| 数据处理 | Python + BeautifulSoup | 悟空自带PythonBS4需 `pip install` | 免费 |
| 知识库管理 | Obsidian | https://obsidian.md 下载 | 免费 |
**总成本:0元,只需要你有飞书账号和钉钉群访问权限。**
---
## 产出物展示
| 产出 | 路径 | 用途 |
|------|------|------|
| 知识图谱(交互式) | `output/knowledge-graph/knowledge_graph.html` | 浏览器打开,查看人物、文档、主题关系 |
| Obsidian 知识库 | `output/obsidian-vault/` | 用 Obsidian 打开,双向链接浏览 |
| 汇总报告 | `output/reports/花园世界全量汇总.md` | 一份完整的 Markdown 报告 |
| 原始文档 | `output/feishu-docs/` | 155篇飞书文档的本地备份 |
| 下载文件 | `dc_files/` | PPT/PDF/XLSX 等附件 |
---
## 项目数据一览
| 指标 | 数量 |
|------|------|
| 采集群组 | 2个(dc战略问题研究院 + 创新组) |
| 消息总数 | 377条 |
| 飞书文档 | 155篇 |
| 文件附件 | 19个 |
| 活跃人员 | 28位 |
| 时间跨度 | 2026-05-01 ~ 2026-06-03 |
| 知识主题 | 7个核心主题 |