---
name: feishu-doc-io
description: 飞书文档通用读写能力。通过飞书Block API精准读写文档表格/多维表格单元格，100%行列对齐零错位。作为通用I/O层，供各专项技能（台词生产、组件生产等）调用。触发场景：(1) 读取飞书文档表格指定列数据；(2) 向飞书表格指定列写入处理结果；(3) 查看飞书文档表格结构信息；(4) 任何需要从飞书读取数据或写回结果的场景
---

# 飞书文档通用读写技能

## 定位
**通用 I/O 能力层**，不包含任何业务逻辑（翻译、校验等）。各专项技能通过 import 调用本技能完成飞书数据的读取和回写。

```
┌──────────────────────────────────────┐
│  feishu-doc-io（本技能）              │  ← 通用能力层
│  • read_table_column()               │
│  • write_table_column()              │
│  • read_bitable_column()             │
│  • write_bitable_column()            │
└───────┬──────────┬───────────┬───────┘
        │          │           │
   台词生产    组件生产     其他技能      ← 专项技能层
```

## 核心 API

### 作为模块调用（推荐）
```python
from feishu_io import FeishuDocIO

io = FeishuDocIO()  # 从环境变量 FEISHU_APP_ID/FEISHU_APP_SECRET 读取凭证

# 读取飞书表格某一列
rows = io.read_table_column(url="飞书文档链接", column_name="中文台词")
# 返回: [{"row": 1, "content": "台词内容"}, {"row": 2, "content": "..."}, ...]

# 读取多列
rows = io.read_table_columns(url, column_names=["中文台词", "角色"])
# 返回: [{"row": 1, "中文台词": "...", "角色": "..."}, ...]

# 写回处理结果
results = [{"row": 1, "content": "English line"}, {"row": 2, "content": "..."}]
stats = io.write_table_column(url, column_name="英文翻译", data=results)
# 返回: {"success": 10, "skipped": 2, "failed": 0}
```

### 命令行独立使用
```bash
# 查看文档表格结构
python scripts/feishu_io.py info --url "飞书链接"

# 读取指定列，输出为JSON
python scripts/feishu_io.py read --url "飞书链接" --column "中文台词" --output data.json

# 从JSON写入指定列
python scripts/feishu_io.py write --url "飞书链接" --column "英文翻译" --input results.json
```

## 支持的飞书链接类型
| 类型 | 链接格式 | 读取 | 写入 |
|------|---------|:---:|:---:|
| 文档表格 | `https://xxx.feishu.cn/docx/xxx` | ✅ | ✅ |
| Wiki文档表格 | `https://xxx.feishu.cn/wiki/xxx` | ✅ | ✅ |
| 多维表格 | `https://xxx.feishu.cn/bitable/xxx` | ✅ | ✅ |

## 技术原理
飞书文档中的表格由 Block 树结构组成，每个单元格是独立的 Block 节点：
1. **定位表格**：遍历文档 blocks，`block_type=31` 为表格
2. **解析单元格**：单元格按行优先排列，公式 `cell_index = row × total_cols + col`
3. **按列名定位**：读取表头行匹配列名 → 确定 `col_index`
4. **精准读写**：通过 Block API 直接操作目标单元格，不依赖文本匹配

## 环境变量
| 变量 | 说明 |
|------|------|
| `FEISHU_APP_ID` | 飞书应用 App ID |
| `FEISHU_APP_SECRET` | 飞书应用 App Secret |

## 权限要求
Bot 应用需要以下权限，并被添加为目标文档的可编辑成员：
- 文档：`docx:document:readonly`, `docx:document:write`
- 多维表格：`bitable:app:readonly`, `bitable:app:write`
- Wiki：`wiki:node:retrieve`

## 飞书单元格换行规范
- 多行内容必须使用真实换行符 `\n`，不要使用 HTML 的 `<br>`、`<br/>`、`<p>` 等标签
- 飞书表格单元格内的换行不支持 HTML 换行标签；如果误用 `<br>`，读取后可能变成普通文本，导致多句内容粘连在一起
- 标准写法示例：
 ```text
 Tom: Oh my!
 Dan: We are fine.
 Grace: Thank you for asking, Tom.
 ```
 - 非标准写法（不要这样写）：
 ```text
 Tom: Oh my!<br>Dan: We are fine.<br>Grace: Thank you for asking, Tom.
 ```
 - 本技能在读取时会自动兼容清洗历史 `<br>` / `<br/>` 数据，但这只是兜底策略，写入规范始终应为 `\n`

## 脚本说明
| 脚本 | 用途 |
|------|------|
| `scripts/feishu_io.py` | 核心模块，提供 FeishuDocIO 类（import 调用 + CLI 独立使用） |
| `scripts/write_translations.py` | 旧版写入脚本（保留兼容，推荐使用 feishu_io.py） |
| `scripts/translate_fill.py` | 旧版翻译编排脚本（保留兼容，翻译逻辑已移至专项技能） |

## 常见问题
- **Q: 文档有多个表格怎么办？** A: 用 `table_index` 参数指定（从0开始），或先用 `info` 命令查看表格结构
- **Q: 写入失败怎么办？** A: 检查 Bot 是否有文档编辑权限，确认环境变量已正确设置
- **Q: 如何避免覆盖已有内容？** A: `write_table_column` 默认 `skip_existing=True`，已有内容的单元格自动跳过
- **Q: API 频率限制？** A: 内置 0.3s 写入间隔，可通过 `batch_delay` 参数调整
