本技能参考了社区中的 feishu-drive 技能,但在实现过程中发现原技能存在以下问题:
GET /open-apis/drive/v1/files/:token/children 应改为 drive/explorer/v2 版本)因此基于飞书官方文档重新开发了此技能,修复了所有已知问题,并新增了权限管理功能。
你是飞书云盘管理专家,负责通过飞书官方 API 实现文件列表查询、上传、下载和文件夹管理。
设置环境变量:
bash
export FEISHU_APP_ID="your_app_id"
export FEISHU_APP_SECRET="your_app_secret"
export FEISHU_ROOT_FOLDER_TOKEN="your_folder_token" # 可选:指定默认根目录
在使用技能之前,先指定一个根目录,后续所有操作都以此目录为基准:
python
from feishu_drive_client import create_client, FeishuDriveClient
import os
# 方式1:使用便捷函数(推荐)
# 自动从环境变量 FEISHU_APP_ID, FEISHU_APP_SECRET, FEISHU_ROOT_FOLDER_TOKEN 读取
client = create_client()
# 方式2:手动创建客户端,从环境变量读取
client = FeishuDriveClient(
app_id=os.getenv("FEISHU_APP_ID"),
app_secret=os.getenv("FEISHU_APP_SECRET"),
root_folder_token=os.getenv("FEISHU_ROOT_FOLDER_TOKEN") # 可选
)
# 方式3:手动指定所有参数
client = FeishuDriveClient(
app_id="your_app_id",
app_secret="your_app_secret",
root_folder_token="your_folder_token" # 可选
)
# 方式4:后续动态设置根目录
client = FeishuDriveClient(app_id, app_secret)
client.set_root_folder("your_folder_token")
设置根目录后,所有操作默认在根目录下进行:
python
# 在根目录下创建子文件夹(无需传入 folder_token)
result = client.create_folder("新文件夹")
# 在根目录下上传文件
result = client.upload_file("/path/to/file.jpg")
# 列出根目录内容
result = client.list_folder()
# 如需操作其他目录,可临时指定 folder_token
result = client.create_folder("其他位置的文件夹", parent_folder_token="其他token")
优先级规则: 传入的 folder_token > 设置的 root_folder_token > 空字符串(根目录)
项目值Base URLhttps://open.feishu.cn/open-apis/drive/v1认证方式Authorization: Bearer {tenant_access_token}Content-Typeapplication/json (文件上传用 multipart/form-data)
接口说明: 获取用户"我的空间"根文件夹的元数据
text
GET /open-apis/drive/explorer/v2/root_folder/meta
响应示例:
json
{
"code": 0,
"data": {
"token": "nodcnXXXXXX",
"id": "7110173013420512356",
"user_id": "7103496998321312356"
},
"msg": "success"
}
注意事项:
drive:drive 或 drive:drive.metadata:readonly接口说明: 在指定父文件夹下创建新文件夹
text
POST /open-apis/drive/v1/files/create_folder
请求参数:
json
{
"name": "文件夹名称",
"folder_token": "父文件夹token"
}
响应示例:
json
{
"code": 0,
"data": {
"token": "fldcnXXXXXX",
"url": "https://xxx.feishu.cn/drive/folder/fldcnXXXXXX",
"name": "文件夹名称"
}
}
注意事项:
folder_token 为父文件夹 token,可以通过 URL 获取或通过 API 查询接口说明: 获取指定文件夹下的文件和子文件夹列表
推荐方法 (Explorer v2):
text
GET /open-apis/drive/explorer/v2/folder/:folder_token/children
响应示例:
json
{
"code": 0,
"data": {
"children": {
"file_token1": {
"token": "file_token1",
"name": "文件名",
"type": "file"
},
"folder_token1": {
"token": "folder_token1",
"name": "文件夹名",
"type": "folder"
}
},
"parentToken": "folder_token"
},
"msg": "success"
}
注意事项:
type 为 folder 表示文件夹,为 file 表示文件children 是字典格式,不是数组接口说明: 上传文件到指定文件夹
text
POST /open-apis/drive/v1/files/upload_all
Content-Type: multipart/form-data
请求参数:
参数类型必填说明filebinary是文件二进制内容file_namestring是文件名parent_typestring是父节点类型, explorer = 云空间parent_nodestring是父节点 token(文件夹 token)sizenumber是文件大小(字节)
响应示例:
json
{
"code": 0,
"data": {
"file_token": "file_token"
}
}
注意事项:
parent_type 使用 explorer 表示云空间文件夹size 参数必填,建议在上传前计算文件大小接口说明: 根据文件 token 下载文件
text
GET /open-apis/drive/v1/files/:file_token/download
请求参数:
参数类型必填说明file_tokenstring是文件 token
响应:
注意事项:
Authorization: Bearer {tenant_access_token}接口说明: 通过邮箱或手机号获取用户的 open_id
text
POST /open-apis/contact/v3/users/batch_get_id
请求参数:
json
{
"emails": ["user@example.com"],
"mobiles": ["13800138000"],
"include_resigned": false
}
响应示例:
json
{
"code": 0,
"data": {
"user_list": [
{
"user_id": "ou_xxxxxxxxx",
"email": "user@example.com",
"status": {
"is_activated": true,
"is_resigned": false
}
}
]
}
}
注意事项:
contact:user.id:readonly 权限user_id 就是 open_id接口说明: 为文件夹添加用户权限
text
POST /open-apis/drive/v1/permissions/:token/members?type=folder
请求参数:
json
{
"member_type": "openid",
"member_id": "ou_xxxxxxxxx",
"perm": "full_access",
"perm_type": "container",
"type": "user"
}
权限类型:
perm说明view可阅读edit可编辑full_access可管理(完全访问)
注意事项:
member_id 必须是 open_id,不能是 user_id接口说明: 获取文件的详细信息
text
GET /open-apis/drive/v1/files/:file_token
请求参数:
参数类型必填说明file_tokenstring是文件或文件夹 token
响应示例:
json
{
"code": 0,
"data": {
"token": "token",
"name": "名称",
"type": "file/folder",
"size": 1024,
"created_time": 1234567890,
"owner": {
"open_id": "xxx"
}
}
}
接口说明: 删除指定文件夹(删除后进入回收站)
text
DELETE /open-apis/drive/v1/files/:folder_token?type=folder
请求参数:
参数类型必填说明folder_tokenstring是文件夹 tokentypestring是固定值 folder
响应示例:
json
{
"code": 0,
"msg": "success"
}
注意事项:
Python 示例:
python
# 删除文件夹(带确认提示)
def delete_folder_with_confirm(client, folder_token, folder_name, confirmed=False):
# 1. 显示文件夹信息
print(f"即将删除文件夹: {folder_name}")
print(f"Token: {folder_token}")
# 2. 请求用户确认(在自主运行环境中,通过参数传递确认状态)
if not confirmed:
print("请设置 confirmed=True 确认删除")
return
# 3. 执行删除
result = client.delete_folder(folder_token)
if result.get("code") == 0:
print("删除成功!文件夹已进入回收站")
else:
print(f"删除失败: {result.get('msg')}")
# 使用示例 - 必须显式确认
delete_folder_with_confirm(client, "folder_token", "测试文件夹", confirmed=True)
接口说明: 删除指定文件(删除后进入回收站)
text
DELETE /open-apis/drive/v1/files/:file_token?type=file
请求参数:
参数类型必填说明file_tokenstring是文件 tokentypestring是固定值 file
注意事项:
接口说明: 将文件或文件夹移动到指定文件夹
text
POST /open-apis/drive/v1/files/:file_token/move
请求参数:
json
{
"type": "file",
"destination_folder_token": "目标文件夹token"
}
类型说明:
type 值说明file普通文件folder文件夹doc文档sheet电子表格bitable多维表格docx新版文档
接口说明: 复制文件到指定文件夹(异步操作)
text
POST /open-apis/drive/v1/files/:file_token/copy
请求参数:
json
{
"type": "file",
"destination_folder_token": "目标文件夹token",
"name": "复制后的新名称(可选)"
}
响应示例:
json
{
"code": 0,
"data": {
"ticket": "task_ticket_xxx"
},
"msg": "success"
}
注意事项:
check_task_status(ticket) 查询复制进度接口说明: 批量获取多个文件的元数据信息
text
POST /open-apis/drive/v1/metas/batch_query
请求参数:
json
{
"file_tokens": ["token1", "token2", "token3"]
}
限制: 最多 100 个文件 token
接口说明: 获取文件的阅读、点赞、评论等统计信息
text
POST /open-apis/drive/v1/files/:file_token/statistics
响应示例:
json
{
"code": 0,
"data": {
"uv": 100,
"pv": 200,
"like_count": 10,
"comment_count": 5
}
}
接口说明: 获取谁访问了该文件的记录
text
POST /open-apis/drive/v1/files/:file_token/view_records
请求参数:
json
{
"page_size": 50,
"page_token": "可选的分页token"
}
接口说明: 在指定文件夹创建文件的快捷方式
text
POST /open-apis/drive/v1/files/create_shortcut
请求参数:
json
{
"file_token": "源文件token",
"folder_token": "目标文件夹token",
"type": "file"
}
接口说明: 在云空间中搜索文件
text
POST /open-apis/suite/docs-api/search/object
请求参数:
json
{
"search_key": "title",
"search_value": "搜索关键词",
"page_size": 50
}
search_key 说明:
值说明title按标题搜索content按内容搜索
注意事项:
user_access_token,不支持 tenant_access_token接口说明: 查询复制、移动等异步操作的任务状态
text
GET /open-apis/drive/v1/files/task_check?ticket=xxx
请求参数:
参数类型必填说明ticketstring是异步任务 ticket
响应示例:
json
{
"code": 0,
"data": {
"status": "success",
"file_token": "新文件token"
}
}
status 说明:
值说明pending等待中processing处理中success成功failed失败
错误码含义解决方案0成功—99991663token 过期重新获取 tenant_access_token1061002无权限检查应用权限和文件夹授权1061001文件/文件夹不存在检查 token 是否正确1061045文件大小超限使用分片上传或减小文件大小404文件不存在常见原因:使用了字典 key 而非 item['token'],参见下方常见错误
在获取文件夹内容后尝试下载文件时,出现 404 错误。
混淆了飞书 API 返回数据结构中的两种"token":
json
{
"children": {
"nodcn5OkQG6q8Y4SuSncukJmCtc": { // ← 错误:这是字典的 key,不是下载用 token
"token": "KdLTbke3BoN85RxQg5qcswFYnah", // ← 正确:这才是下载用的 token
"name": "Screenshot_20260323-115306.png",
"type": "file"
}
}
}
python
result = client.list_folder(folder_token)
children = result["data"]["children"]
for token, item in children.items(): # ← token 实际是 dict_key (nodcn...)
file_token = token # ← 错误!这会导致 404
client.download_file(file_token, "/path/to/file")
python
result = client.list_folder(folder_token)
children = result["data"]["children"]
for dict_key, item in children.items(): # dict_key 是 nodcn...
file_token = item["token"] # ← 正确!从 item 中获取 token
client.download_file(file_token, "/path/to/file")
# 或者直接使用 list_all() 方法,它已经处理了这个问题
files = client.list_all(folder_token)
for file in files:
client.download_file(file["token"], f"/path/to/{file['name']}")
位置值用途字典 keynodcn5OkQG6q8Y4SuSncukJmCtc仅用于迭代,通常不使用item['token']``KdLTbke3BoN85RxQg5qcswFYnah下载、删除、复制、移动等所有操作
确保应用已获取以下权限:
drive:file:read - 读取文件drive:file:write - 写入文件drive:folder:read - 读取文件夹drive:folder:write - 创建文件夹contact:user.id:readonly - 获取用户 ID(用于权限管理)get_file_info 测试 token 是否可用