Skill: zhuligu/feishu-doc-editor (version 1.0.0)

--- name: feishu-doc-editor description: Feishu document creation and editing operations using OpenAPI. Activate when user needs to create, edit, or read Feishu documents programmatically. --- # Feishu Document Editor Skill This skill provides comprehensive guidance for creating and editing Feishu documents using the Feishu OpenAPI. ## Prerequisites ### 1. App Creation and Configuration **Create enterprise self-built app**: Login to Feishu Open Platform, create an app and add "Bot" capability. **Apply for API permissions**: In "Permission Management", apply for the following permissions: - Document editing: `docx:document:write_only` - Document viewing: `docx:document:readonly` **Publish app**: Submit version and publish, ensuring the app coverage includes target users/departments. ### 2. Get Access Token Call the self-built app get tenant_access_token interface: ```bash curl -X POST https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal \ -H "Content-Type: application/json" \ -d '{"app_id": "your_app_id", "app_secret": "your_app_secret"}' ``` Response example: ```json { "code": 0, "tenant_access_token": "t-xxx", "expire": 7200 } ``` ## Core Operations ### Extract Document ID Get `document_id` from document URL: **Example URL**: `https://bigdatacenter.feishu.cn/docx/HpK2dtGu9omhMAxV12zcB6i7ngd` **document_id** = `HpK2dtGu9omhMAxV12zcB6i7ngd` ### Grant App Document Permission **Manually add collaborator**: - Open document in Feishu client → Click "..." in top right → "More" → "Add document app" - Search and add your app, grant "Can edit" permission. ### Write Text Content **Interface**: Create Block - **Path parameters**: `document_id` = document ID, `block_id` = document ID (root node is the document itself) - **Request headers**: ```http Authorization: Bearer {tenant_access_token} Content-Type: application/json ``` - **Request body example** (write "hello"): ```json { "index": -1, "children": [ { "block_type": 2, "text": { "elements": [ { "text_run": { "content": "hello" } } ] } } ] } ``` ### Read Document Content **Interface**: Get Document Plain Text ```bash curl -X GET "https://open.feishu.cn/open-apis/docx/v1/documents/{document_id}/plaintext" \ -H "Authorization: Bearer {tenant_access_token}" ``` Response example: ```json { "code": 0, "data": { "content": "Document text content here" } } ``` ## Common Issues ### 1. Permission Error (403 Forbidden) - **Diagnosis**: App not added as document collaborator, or `tenant_access_token` is invalid. - **Solution**: Re-add app as collaborator, or re-get `tenant_access_token`. ### 2. Missing Access Token (99991661) - **Diagnosis**: Request header does not carry `Authorization: Bearer {token}`. - **Solution**: Ensure `tenant_access_token` is correctly added to request header. ### 3. Document Not Found (404 Not Found) - **Diagnosis**: `document_id` is incorrect or document has been deleted. - **Solution**: Re-extract `document_id` from document URL. ## Reference Documentation - Create Block Interface - Get Document Plain Text Interface - Permission Configuration Guide Through the above steps, you can achieve editing Feishu documents via API, supporting add/delete/modify/query operations for multiple content types including text, tables, and images.

path: references/api-guide.md
content: # 飞书 OpenAPI 详细指南

## API 基础

### 认证
所有 API 调用需要 `tenant_access_token`。

获取 token：

```bash
curl -X POST https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal \
  -H "Content-Type: application/json" \
  -d '{"app_id": "your_app_id", "app_secret": "your_app_secret"}'
```

响应示例：

```json
{
  "code": 0,
  "tenant_access_token": "t-xxx",
  "expire": 7200
}
```

### 请求头
所有 API 请求必须包含：

```http
Authorization: Bearer {tenant_access_token}
Content-Type: application/json
```

---

## 核心接口详解

### 1. 创建块（写入内容）

**接口**：
```
POST /docx/v1/documents/{document_id}/blocks/{block_id}/children
```

**路径参数**：
- `document_id`: 文档 ID
- `block_id`: 父块 ID（通常是 document_id，即根节点）

**请求体**：

```json
{
  "children": [
    {
      "block_type": 2,
      "text": {
        "elements": [
              {
                "text_run": {
                  "content": "文本内容"
                }
              }
            ]
        }
    }
  ]
}
```

**响应示例**：

```json
{
  "code": 0,
  "data": {
    "children": [
      {
        "block_id": "doxcnxxx",
        "block_type": 2
      }
    ]
  }
}
```

**block_type 说明**：
- `1`: 页面块（Page）
- `2`: 文本块（Text）
- `3`: 标题 1/2/3（Heading 1/2/3）
- 更多类型参见飞书文档

---

### 2. 获取文档纯文本

**接口**：
```
GET /docx/v1/documents/{document_id}/plaintext
```

**响应示例**：

```json
{
  "code": 0,
  "data": {
    "content": "文档的纯文本内容"
  }
}
```

---

### 3. 列出所有块

**接口**：
```
GET /docx/v1/documents/{document_id}/blocks/{document_id}/children
```

**查询参数**：
- `page_size`: 每页数量（1-500，默认 100）
- `page_token`: 分页 token

**响应示例**：

```json
{
  "code": 0,
  "data": {
    "items": [
      {
        "block_id": "doxcnxxx",
        "block_type": 2,
        "text": {
          "elements": [...]
        }
      }
    ],
    "page_token": "next_page_token",
    "has_more": true
  }
}
```

---

### 4. 更新块

**接口**：
```
PATCH /docx/v1/documents/{document_id}/blocks/{block_id}
```

**请求体**：

```json
{
  "text": {
    "elements": [
      {
        "text_run": {
          "content": "新的文本内容"
        }
      }
    ]
  }
}
```

---

### 5. 删除块

**接口**：
```
DELETE /docx/v1/documents/{document_id}/blocks/{block_id}
```

**响应示例**：

```json
{
  "code": 0,
  "msg": "success"
}
```

---

## 高级操作

### 创建带格式的文本

```json
{
  "children": [
    {
      "block_type": 2,
      "text": {
        "elements": [
              {
                "text_run": {
                  "content": "粗体文本",
                  "text_element_style": {
                    "bold": true
                  }
                }
              },
              {
                "text_run": {
                  "content": "斜体文本",
                  "text_element_style": {
                    "italic": true
                  }
                }
              }
            ]
        }
    }
  ]
}
```

### 创建标量

```json
{
  "children": [
    {
      "block_type": 3,  // Heading 1
      "heading1": {
        "elements": [
              {
                "text_run": {
                  "content": "标量 1"
                }
              }
            ]
        }
    }
  ]
}
```

### 创建列表

```json
{
  "children": [
    {
      "block_type": 19,  // Bulleted list
      "bulleted_list": {
        "elements": [
              {
                "text_run": {
                  "content": "列表项 1"
                }
              }
            ]
        }
    }
  ]
}
```

---

## 完整工作流程示例

### 工作流 1：创建新文档并写入内容

```bash
# 1. 获取 token
[REDACTED_SECRET] -s -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \
  -H "Content-Type: application/json" \
  -d '{"app_id": "xxx", "app_secret": "xxx"}' | jq -r '.tenant_access_token')

# 2. 创建文档（使用其他 API 或手动创建）
# 假设 document_id = "ABC123"

# 3. 写入内容
curl -X POST "https://open.feishu.cn/open-apis/docx/v1/documents/ABC123/blocks/ABC123/children" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "children": [{
      "block_type": 2,
      "text": {
        "elements": [
              {
                "text_run": {
                  "content": "Hello World"
                }
              }
            ]
        }
      }
    }]
  }'
```

### 工作流 2：读取并修改文档

```bash
# 1. 获取块列表
curl -X GET "https://open.feishu.cn/open-apis/docx/v1/documents/ABC123/blocks/ABC123/children" \
  -H "Authorization: Bearer $TOKEN" | jq '.data.items[0].block_id'

# 2. 更新块内容
curl -X PATCH "https://open.feishu.cn/open-apis/docx/v1/documents/ABC123/blocks/BLOCK_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "text": {
      "elements": [
              {
                "text_run": {
                  "content": "更新的内容"
                }
              }
            ]
        }
      }
    }'
```

### 工作流 3：删除特定块

```bash
# 删除块
curl -X DELETE "https://open.feishu.cn/open-apis/docx/v1/documents/ABC123/blocks/BLOCK_ID" \
  -H "Authorization: Bearer $TOKEN"
```

---

## 错误处理

### 错误码格式

飞书 API 返回的响应格式：

```json
{
  "code": 错误码,
  "msg": "错误信息"
}
```

### 常见错误码

| 错误码 | 含义 | 解决方案 |
|--------|------|---------|
| 0 | 成功 | - |
| 99991663 | 无效的 app_id | 检查应用配置 |
| 99991661 | 缺少 tenant_access_token | 确保请求头包含 token |
| 403 | 无权限 | 检查应用是否为文档协作者 |
| 404 | 文档不存在 | 检查 document_id 是否正确 |
| 500 | 内部错误 | 重试或联系支持 |

---

## 性能优化

### 批量操作

如果需要创建多个块，可以一次请求创建多个：

```json
{
  "children": [
    {
      "block_type": 2,
      "text": {
        "elements": [
              {
                "text_run": {
                  "content": "第一段"
                }
              }
            ]
        }
    },
    {
      "block_type": 2,
      "text": {
        "elements": [
              {
                "text_run": {
                  "content": "第二段"
                }
              }
            ]
        }
    }
  ]
}
```

### 分页读取

处理大文档时，使用分页：

```bash
PAGE_TOKEN=""

while true; do
  RESONSE=$(curl -s "https://open.feishu.cn/open-apis/docx/v1/documents/DOC_ID/blocks/DOC_ID/children?page_size=100&page_token=$PAGE_TOKEN" \
    -H "Authorization: Bearer $TOKEN")
  
  HAS_MORE=$(echo "$RESPONSE" | jq '.data.has_more')
  
  if [ "$HAS_MORE" = "false" ]; then
    break
  fi
  
  PAGE_TOKEN=$(echo "$RESPONSE" | jq -r '.data.page_token')
done
```

---

## 参考链接

- [飞书开放平台文档](https://open.feishu.cn/document)
- [文档 API 概述](https://open.feishu.cn/document/server-docs/docs/docx-v1/document/introduction)
- [块 API 参考](https://open.feishu.cn/document/server-docs/docs/docx-v1/document-block/create)


path: references/common-errors.md
content: # 飞书文档 API 常见错误诊断与解决指南

本指南详细列出飞书文档编辑 API 使用过程中常见的错误、诊断方法和解决方案。

---

## 目录

1. [认证相关错误](#认证相关错误)
2. [权限相关错误](#权限相关错误)
3. [文档相关错误](#文档相关错误)
4. [请求格式错误](#请求格式错误)
5. [性能和限流错误](#性能和限流错误)
6. [调试技巧](#调试技巧)

---

## 认证相关错误

### 错误 1：缺少 tenant_access_token

**错误码**：`99991661`

**错误信息**：
```json
{
  "code": 99991661,
  "msg": "request token missing"
}
```

**症状**：
- API 调用立即失败
- 错误信息明确指出缺少 token

**原因分析**：
1. 请求头未包含 `Authorization` 字段
2. `Authorization` 字段格式不正确
3. token 值为空或格式错误

**解决方案**：

```bash
# ❌ 错误示例
curl -X POST "https://open.feishu.cn/open-apis/..." \
  -H "Content-Type: application/json" \
  -d '{"..."}'

# ✅ 正确示例
curl -X POST "https://open.feishu.cn/open-apis/..." \
  -H "Authorization: Bearer {tenant_access_token}" \
  -H "Content-Type: application/json" \
  -d '{"..."}'
```

**验证方法**：
```bash
# 检查请求头是否包含 Authorization
curl -v -X POST "https://open.feishu.cn/open-apis/..." \
  -H "Authorization: Bearer {tenant_access_token}" 2>&1 | grep -i authorization
```

---

### 错误 2：tenant_access_token 无效或过期

**错误码**：`99991663`

**错误信息**：
```json
{
  "code": 99991663,
  "msg": "invalid token"
}
```

**症状**：
- 之前能用的 token 突然失效
- API 调用返回 token 无效错误

**原因分析**：
1. token 已过期（有效期为 2 小时）
2. token 格式错误
3. app_id 或 app_secret 错误
4. 应用被禁用或删除

**解决方案**：

```bash
# 1. 重新获取 token
curl -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \
  -H "Content-Type: application/json" \
  -d '{
    "app_id": "your_app_id",
    "app_secret": "your_app_secret"
  }'

# 2. 验证返回的 token
{
  "code": 0,
  "tenant_access_token": "t-xxx",
  "expire": 7200
}

# 3. 在代码中实现自动续期
TOKEN_EXPIRE_TIME=$(date +%s)
EXPIRE_SECONDS=7200

# 检查是否需要刷新 token
if [ $(($(date +%s) - TOKEN_EXPIRE_TIME)) -gt $EXPIRE_SECONDS ]; then
  echo "Token expired, refreshing..."
  # 重新获取 token
fi
```

**验证方法**：
```bash
# 使用新 token 测试 API
NEW_TOKEN="t-new_token_here"
curl -X GET "https://open.feishu.cn/open-apis/docx/v1/documents/xxx/plaintext" \
  -H "Authorization: Bearer $NEW_TOKEN"
```

---

### 错误 3：app_id 或 app_secret 错误

**错误码**：`99991663`

**错误信息**：
```json
{
  "code": 99991663,
  "msg": "app_id or app_secret error"
}
```

**症状**：
- 获取 token 时失败
- 提示 app_id 或 app_secret 错误

**原因分析**：
1. app_id 或 app_secret 复制错误
2. 应用的凭证已重置
3. 使用了错误环境的凭证（测试 vs 生产）

**解决方案**：

```bash
# 1. 重新从飞书开放平台复制凭证
# 登录 https://open.feishu.cn
# 进入应用 → 凭证管理 → 复制

# 2. 验证凭证格式
# app_id 格式：cli_aXXXXXXXXXXXX
# app_secret 格式：32 位字符串

# 3. 测试凭证是否正确
curl -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \
  -H "Content-Type: application/json" \
  -d '{
    "app_id": "cli_a1234567890",
    "app_secret": "abcdefghijklmnopqrstuvwxyz123456"
  }'
```

---

## 权限相关错误

### 错误 4：应用没有文档访问权限（403 Forbidden）

**错误码**：`403`

**错误信息**：
```json
{
  "code": 403,
  "msg": "permission denied"
}
```

**症状**：
- token 有效，但无法访问特定文档
- 读取或编辑文档时返回 403

**原因分析**：
1. 应用未添加为文档协作者
2. 应用的 API 权限未申请
3. 应用的权限级别不足（只有查看权限，尝试编辑）

**解决方案**：

**方案 1：添加应用为文档协作者**
```
1. 打开目标文档
2. 点击右上角 "..." → "更多" → "添加文档应用"
3. 搜索并选择你的应用
4. 设置权限为"可编辑"
5. 点击"邀请"
```

**方案 2：检查应用 API 权限**
```
1. 登录飞书开放平台
2. 进入你的应用
3. 检查"权限管理"页面
4. 确认已申请以下权限：
   - docx:document:readonly（查看）
   - docx:document:write_only（编辑）
5. 如果未申请，立即申请
```

**验证方法**：
```bash
# 1. 列出文档协作者，确认应用在列表中
# 通过飞书客户端或 API 检查

# 2. 测试读取权限
curl -X GET "https://open.feishu.cn/open-apis/docx/v1/documents/{doc_id}/plaintext" \
  -H "Authorization: Bearer {token}"

# 3. 测试编辑权限
curl -X POST "https://open.feishu.cn/open-apis/docx/v1/documents/{doc_id}/blocks/{doc_id}/children" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"children": [{"block_type": 2, "text": {"elements": [{"text_run": {"content": "test"}}]}}]}'
```

---

### 错误 5：API 权限未批准

**错误码**：`99991400`

**错误信息**：
```json
{
  "code": 99991400,
  "msg": "permission not approved"
}
```

**症状**：
- API 调用失败，提示权限未批准
- 应用虽然申请了权限，但审批未通过

**原因分析**：
1. 权限申请待审批
2. 权限申请被拒绝
3. 应用未发布

**解决方案**：

```
1. 检查权限审批状态
   - 登录飞书开放平台
   - 进入应用 → 权限管理
   - 查看权限状态（已批准/待审批/已拒绝）

2. 如果待审批
   - 联系企业管理员审批
   - 或提供更详细的申请理由

3. 如果被拒绝
   - 重新提交申请
   - 提供详细的使用场景说明
   - 必要时联系飞书技术支持

4. 确保应用已发布
   - 进入"版本管理与发布"
   - 检查应用状态
   - 如果未发布，提交审核并发布
```

---

## 文档相关错误

### 错误 6：文档不存在（404 Not Found）

**错误码**：`404`

**错误信息**：
```json
{
  "code": 404,
  "msg": "document not found"
}
```

**症状**：
- API 调用返回 404
- 提示文档不存在

**原因分析**：
1. document_id 错误
2. 文档已被删除
3. 文档移动到了其他位置
4. URL 解析错误

**解决方案**：

```bash
# 1. 重新提取 document_id
# 正确格式：https://xxx.feishu.cn/docx/ABC123def
# document_id = ABC123def

# 错误示例：
URL="https://xxx.feishu.cn/docx/ABC123def?copy=open"
# 需要移除查询参数
DOC_ID=$(echo "$URL" | grep -oP 'docx/\K[^?]*')

# 2. 验证 document_id 格式
# document_id 应该是 16-24 位字母数字组合

# 3. 测试文档是否存在
curl -X GET "https://open.feishu.cn/open-apis/docx/v1/documents/{doc_id}/plaintext" \
  -H "Authorization: Bearer {token}"
```

**验证方法**：
1. 在浏览器中打开文档 URL
2. 确认文档可以正常访问
3. 检查 document_id 是否正确

---

### 错误 7：块 ID 不存在

**错误码**：`404`

**错误信息**：
```json
{
  "code": 404,
  "msg": "block not found"
}
```

**症状**：
- 更新或删除块时失败
- 提示块不存在

**原因分析**：
1. block_id 错误
2. 块已被删除
3. 块 ID 在使用过程中发生了变化

**解决方案**：

```bash
# 1. 重新列出文档的所有块
curl -X GET "https://open.feishu.cn/open-apis/docx/v1/documents/{doc_id}/blocks/{doc_id}/children" \
  -H "Authorization: Bearer {token}" | jq '.data.items[] | .block_id'

# 2. 使用正确的 block_id
# 从列表中找到目标块的 ID

# 3. 操作前先验证块是否存在
curl -X GET "https://open.feishu.cn/open-apis/docx/v1/documents/{doc_id}/blocks/{block_id}" \
  -H "Authorization: Bearer {token}"

# 4. 如果块不存在，更新块的列表
# 块可能会因为编辑操作而改变
```

---

## 请求格式错误

### 错误 8：请求体格式错误

**错误码**：`400`

**错误信息**：
```json
{
  "code": 400,
  "msg": "invalid request body"
}
```

**症状**：
- API 调用返回 400 错误
- 提示请求体格式无效

**原因分析**：
1. JSON 格式错误
2. 缺少必需字段
3. 字段类型错误
4. 字段值超出允许范围

**解决方案**：

```bash
# 1. 验证 JSON 格式
echo '{"test": "value"}' | jq .

# 2. 检查必需字段
# 创建块时必需：
# - block_type
# - text.elements[0].text_run.content

# 3. 使用 jq 格式化 JSON
curl -X POST "URL" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d @request.json | jq .

# 4. 完整示例
cat > request.json << EOF
{
  "children": [
    {
      "block_type": 2,
      "text": {
        "elements": [
          {
            "text_run": {
              "content": "测试内容"
            }
          }
        ]
      }
    }
  ]
}
EOF

curl -X POST "URL" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d @request.json
```

---

## 性能和限流错误

### 错误 9：请求过于频繁（Rate Limit）

**错误码**：`429`

**错误信息**：
```json
{
  "code": 429,
  "msg": "too many requests"
}
```

**症状**：
- 大量请求后开始返回 429
- 需要等待一段时间后才能继续

**原因分析**：
1. 请求频率超过 API 限流阈值
2. 短时间内发送了太多请求

**解决方案**：

```bash
# 1. 实现请求限流
# 使用 sleep 命令控制请求频率
for i in {1..100}; do
  curl -X POST "URL" ...
  sleep 0.1  # 每秒最多 10 个请求
done

# 2. 批量操作
# 一次请求创建多个块，而不是多次请求
curl -X POST "URL" \
  -d '{
    "children": [
      {"block_type": 2, "text": {...}},
      {"block_type": 2, "text": {...}},
      {"block_type": 2, "text": {...}}
    ]
  }'

# 3. 实现指数退避重试
MAX_RETRIES=3
RETRY_DELAY=1

for attempt in $(seq 1 $MAX_RETRIES); do
  RESPONSE=$(curl -s -X POST "URL" ...)
  CODE=$(echo "$RESPONSE" | jq -r '.code')
  
  if [ "$CODE" = "429" ]; then
    echo "Rate limited, retrying in $RETRY_DELAY seconds..."
    sleep $RETRY_DELAY
    RETRY_DELAY=$((RETRY_DELAY * 2))
  else
    break
  fi
done
```

---

## 调试技巧

### 技巧 1：启用详细日志

```bash
# 使用 curl 的 -v 参数查看详细请求
curl -v -X GET "https://open.feishu.cn/open-apis/docx/v1/documents/xxx/plaintext" \
  -H "Authorization: Bearer {token}"

# 输出包含：
# - 请求头
# - 响应头
# - 响应体
# - SSL 证书信息
```

---

### 技巧 2：使用 jq 解析响应

```bash
# 美化 JSON 输出
curl -s -X GET "URL" -H "Authorization: Bearer {token}" | jq .

# 提取特定字段
curl -s -X GET "URL" -H "Authorization: Bearer {token}" | jq -r '.code'
curl -s -X GET "URL" -H "Authorization: Bearer {token}" | jq -r '.data.content'

# 检查错误
curl -s -X GET "URL" -H "Authorization: Bearer {token}" | jq -r 'if .code == 0 then "Success" else "Error: \(.msg)" end'
```

---

### 技巧 3：测试脚本

```bash
#!/bin/bash

# 配置
APP_ID="cli_a1234567890"
APP_SECRET="abcdefghijklmnopqrstuvwxyz123456"
DOC_ID="ABC123def"

# 1. 获取 token
echo "获取 token..."
TOKEN_RESPONSE=$(curl -s -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \
  -H "Content-Type: application/json" \
  -d "{\"app_id\": \"$APP_ID\", \"app_secret\": \"$APP_SECRET\"}")

[REDACTED_SECRET] "$TOKEN_RESPONSE" | jq -r '.tenant_access_token')
CODE=$(echo "$TOKEN_RESPONSE" | jq -r '.code')

if [ "$CODE" != "0" ]; then
  echo "❌ 获取 token 失败"
  echo "$TOKEN_RESPONSE" | jq .
  exit 1
fi

echo "✅ [REDACTED_SECRET]"

# 2. 测试读取文档
echo "测试读取文档..."
READ_RESPONSE=$(curl -s -X GET "https://open.feishu.cn/open-apis/docx/v1/documents/$DOC_ID/plaintext" \
  -H "Authorization: Bearer $TOKEN")

CODE=$(echo "$READ_RESPONSE" | jq -r '.code')

if [ "$CODE" = "0" ]; then
  echo "✅ 读取成功"
  echo "$READ_RESPONSE" | jq -r '.data.content' | head -20
else
  echo "❌ 读取失败"
  echo "$READ_RESPONSE" | jq .
fi
```

---

### 技巧 4：错误日志记录

```bash
#!/bin/bash

# 日志函数
log_error() {
  local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
  echo "[$timestamp] ERROR: $1" >> /tmp/feishu_api_errors.log
}

# 使用示例
curl -s -X POST "URL" -H "Authorization: Bearer {token}" -d '{"..."}' || {
  log_error "API 调用失败: URL"
  log_error "请求体: {...}"
  log_error "响应: $(curl -s ...)"
}
```

---

## 总结

### 快速诊断流程

```
遇到错误
    ↓
检查错误码
    ↓
├─ 认证错误（99991661, 99991663）
│   └─ 验证 token 是否正确获取
│
├─ 权限错误（403, 99991400）
│   └─ 检查应用权限和文档协作者
│
├─ 文档错误（404）
│   └─ 验证 document_id 和 block_id
│
├─ 请求错误（400）
│   └─ 验证 JSON 格式和必需字段
│
└─ 限流错误（429）
    └─ 实现请求限流和重试机制
```

### 最佳实践

1. **始终验证响应**
   ```bash
   RESPONSE=$(curl -s ...)
   if [ "$(echo "$RESPONSE" | jq -r '.code')" != "0" ]; then
     echo "API 调用失败"
     echo "$RESPONSE" | jq .
   fi
   ```

2. **实现自动重试**
   - 对于网络错误
   - 对于限流错误
   - 对于临时性错误

3. **记录详细日志**
   - 请求时间
   - 请求参数
   - 响应内容
   - 错误信息

4. **监控 API 使用**
   - 请求频率
   - 错误率
   - 响应时间

通过本指南，你应该能够快速定位和解决飞书文档 API 使用中的大部分问题！


path: references/permission-setup.md
content: # 飞书文档权限配置完整指南

本指南详细说明如何为飞书文档编辑功能配置所需的权限。

---

## 概述

要让应用能够通过 API 编辑飞书文档，需要完成两个层面的权限配置：

1. **应用层权限** - 在飞书开放平台为应用申请 API 权限
2. **文档层权限** - 将应用添加为特定文档的协作者

---

## 第一部分：应用层权限配置

### 步骤 1：创建企业自建应用

1. **登录飞书开放平台**
   - 访问：https://open.feishu.cn
   - 使用企业管理员账号登录

2. **创建应用**
   - 点击"创建企业自建应用"
   - 填写应用信息：
     - 应用名称：例如"文档编辑助手"
     - 应用描述：简要说明应用用途
     - 应用图标：可选

3. **添加能力**
   - 在应用配置页面，找到"能力管理"
   - 添加"机器人"能力
   - 这将赋予应用发送消息和接收通知的能力

---

### 步骤 2：申请 API 权限

在应用的"权限管理"页面，申请以下权限：

#### 文档编辑权限（必需）

| 权限名称 | 权限标识 | 用途 | 必需性 |
|---------|---------|------|--------|
| 查看、评论和导出文档 | `docx:document:readonly` | 读取文档内容 | 必需 |
| 创建文档 | `docx:document:create` | 创建新文档 | 可选 |
| 编辑文档 | `docx:document:write_only` | 修改文档内容 | 必需 |

#### 其他相关权限（可选）

| 权限名称 | 权限标识 | 用途 |
|---------|---------|------|
| 获取与更新云文档信息 | `drive:drive:readonly` | 访问文件元信息 |
| 以应用身份发消息 | `im:message:send_as_bot` | 发送通知 |

---

### 步骤 3：申请权限的详细操作

1. **进入权限管理**
   - 在左侧菜单选择"权限管理"
   - 搜索上述权限名称

2. **申请权限**
   - 找到对应权限后，点击"申请"
   - 填写申请理由：
     - 用途：文档自动化编辑
     - 使用场景：批量处理文档内容
     - 影响范围：特定用户/部门

3. **等待审批**
   - 如果是个人应用，可能自动批准
   - 如果是企业应用，需要管理员审批

---

### 步骤 4：发布应用

权限配置完成后，需要发布应用：

1. **创建版本**
   - 进入"版本管理与发布"
   - 点击"创建新版本"
   - 填写版本号和更新说明

2. **配置可用范围**
   - 选择应用可用范围：
     - 全员可用
     - 部分部门/用户可用
   - 建议先选择"部分用户"进行测试

3. **提交审核**
   - 点击"提交审核"
   - 等待审核通过（通常 1-2 个工作日）

4. **正式发布**
   - 审核通过后，点击"发布"
   - 应用正式上线

---

## 第二部分：文档层权限配置

即使应用有了 API 权限，还需要对每个文档单独授权。

### 方法 1：通过飞书客户端（推荐）

#### 添加应用为文档协作者

1. **打开目标文档**
   - 在飞书客户端或网页版打开文档
   - 确保你有文档的编辑权限

2. **进入协作者管理**
   - 点击右上角的 "..." 按钮
   - 选择"更多"
   - 点击"添加协作者"

3. **添加应用**
   - 在搜索框中输入你的应用名称
   - 选择你的应用（通常显示为机器人图标）
   - 设置权限级别：
     - **可编辑** - 可以修改文档内容
     - **可评论** - 只能添加评论
     - **可查看** - 只能查看
   - 选择"可编辑"

4. **确认添加**
   - 点击"邀请"
   - 应用将出现在协作者列表中

---

### 方法 2：通过 API（高级）

如果需要批量授权多个文档，可以通过 API 实现：

```bash
# 获取应用的 open_id
APP_OPEN_ID="ou_xxxxxxxxx"

# 调用添加协作者 API
curl -X POST "https://open.feishu.cn/open-apis/docx/v1/documents/{document_id}/permissions/permission" \
  -H "Authorization: Bearer {tenant_access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "permissions": [
      {
        "permission": "docx:document:write",
        "scope_type": "app",
        "scope_id": "'"$APP_OPEN_ID"'"
      }
    ]
  }'
```

---

## 第三部分：验证权限配置

### 验证 1：应用权限检查

1. **检查应用权限状态**
   - 进入飞书开放平台
   - 选择你的应用
   - 查看"权限管理"页面
   - 确认所有必需权限已显示为"已批准"

2. **测试 API 访问**
   ```bash
   # 尝试获取 tenant_access_token
   curl -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \
     -H "Content-Type: application/json" \
     -d '{"app_id": "你的app_id", "app_secret": "你的app_secret"}'
   
   # 如果返回 token，说明应用权限配置正确
   ```

---

### 验证 2：文档权限检查

1. **检查协作者列表**
   - 打开目标文档
   - 点击右上角 "..." → "协作者"
   - 确认你的应用在列表中
   - 确认权限级别为"可编辑"

2. **测试文档访问**
   ```bash
   # 尝试读取文档
   curl -X GET "https://open.feishu.cn/open-apis/docx/v1/documents/{document_id}/plaintext" \
     -H "Authorization: Bearer {tenant_access_token}"
   
   # 如果返回文档内容，说明文档权限配置正确
   ```

---

## 常见问题排查

### 问题 1：403 Forbidden 错误

**症状**：
```json
{
  "code": 403,
  "msg": "permission denied"
}
```

**可能原因**：
1. 应用没有被添加为文档协作者
2. 应用的 API 权限未申请或未批准
3. tenant_access_token 已过期

**解决方案**：
1. 检查文档的协作者列表，确认应用已添加
2. 检查应用权限状态，确认必需权限已批准
3. 重新获取 tenant_access_token

---

### 问题 2：应用未出现在协作者搜索结果中

**可能原因**：
1. 应用未发布
2. 应用可用范围不包含当前用户
3. 应用名称搜索关键词不匹配

**解决方案**：
1. 检查应用是否已发布
2. 在"版本管理与发布"中扩大可用范围
3. 尝试使用完整应用名称搜索

---

### 问题 3：权限申请被拒绝

**可能原因**：
1. 申请理由不充分
2. 企业安全策略限制
3. 缺少必要的合规审批

**解决方案**：
1. 重新提交申请，提供详细的使用场景说明
2. 联系企业管理员说明用途
3. 咨询飞书技术支持

---

## 最佳实践

### 1. 最小权限原则
- 只申请必需的权限
- 定期审查和清理不需要的权限

### 2. 测试环境优先
- 先在测试文档中验证功能
- 确认无问题后再应用到生产环境

### 3. 批量授权策略
- 对于企业内部文档，可以创建专门的文档模板
- 在模板中预先添加应用为协作者
- 新建文档基于模板创建

### 4. 权限监控
- 定期检查应用的文档访问日志
- 监控异常的 API 调用
- 设置告警机制

---

## 权限生命周期管理

### 权限续期
- tenant_access_token 有效期为 2 小时
- 需要定期重新获取
- 建议实现自动续期机制

### 权限撤销
- 如果不再需要访问某个文档，及时撤销应用权限
- 在文档协作者列表中移除应用
- 或通过 API 调用删除权限

### 权限审计
- 定期审查应用拥有的文档权限
- 清理不再需要的文档访问权限
- 记录权限变更历史

---

## 附录：权限配置检查清单

### 应用层配置
- [ ] 创建企业自建应用
- [ ] 添加"机器人"能力
- [ ] 申请 `docx:document:readonly` 权限
- [ ] 申请 `docx:document:write_only` 权限（可选：`docx:document:create`）
- [ ] 提交应用审核
- [ ] 应用发布成功
- [ ] 测试获取 tenant_access_token

### 文档层配置
- [ ] 打开目标文档
- [ ] 进入协作者管理
- [ ] 搜索并添加应用
- [ ] 设置权限级别为"可编辑"
- [ ] 确认添加成功
- [ ] 测试读取文档
- [ ] 测试编辑文档

### 验证测试
- [ ] API 调用返回正确响应
- [ ] 文档内容可以正常读取
- [ ] 文档内容可以正常编辑
- [ ] 错误处理机制正常工作

完成所有检查项后，权限配置就完成了！


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: suspicious | SkillSpector: suspicious (HIGH)