Install
openclaw skills install feishu-wiki-query飞书知识库文档查询技能。当用户询问需要查询飞书知识库中的文档时使用此技能,包括:查询动物信息、查看排期、读取文档内容、处理文档中的图片、画板和电子表格等。触发场景包括:用户说"查一下xx动物"、"看看排期"、"查询知识库"、"食堂菜谱"等。
openclaw skills install feishu-wiki-query本技能用于查询飞书知识库中的文档内容,支持读取文本、图片、画板、电子表格等多种类型的文档内容。
本技能支持用户自定义知识库配置,安装后可随时添加/移除知识库。
配置存储在:~/.openclaw/workspace/skills/feishu-wiki-query/config.json
首次使用前需要先进行配置。
用户首次使用时,提示:
🎀 欢迎使用飞书知识库查询技能! 请先配置你的知识库地址~
方式:发送
添加知识库 [知识库名称] [知识库URL]例如:添加知识库 我的知识库 https://my.feishu.cn/wiki/XEMRwElx2iMzHhkkVdCcpj0tnDg知识库 URL 就是你在浏览器打开知识库时地址栏的地址~
添加知识库 [名称] [知识库URL]
示例:
添加知识库 海洋动物专区 https://my.feishu.cn/wiki/XEMRwElx2iMzHhkkVdCcpj0tnDg
添加知识库 技术文档 https://my.feishu.cn/wiki/abcdefg1234567
自动解析: 从 URL 中提取 node_token,并通过 API 获取 space_id,全程无需用户手动提供。
移除知识库 [名称]
查看知识库
重置知识库配置
⚠️ 此操作会清空所有已配置的知识库,请谨慎使用!
当用户输入 添加知识库 [名称] [URL] 时:
解析 URL 获取 node_token
https://my.feishu.cn/wiki/{node_token}node_token = URL 路径最后一段获取 space_id
feishu_wiki {
action: "get",
token: "解析出的node_token"
}
从返回中获取 space_id
保存配置
将以下内容写入 config.json:
{
"version": 1,
"updated_at": "当前时间",
"knowledge_bases": [
{
"name": "用户提供的名称",
"space_id": "获取到的space_id",
"root_node_token": "解析出的node_token"
}
]
}
首先获取首页目录(使用配置中的 space_id 和首页 node_token):
如果只有一个知识库,直接使用:
feishu_wiki {
action: "nodes",
space_id: "配置中的space_id",
parent_node_token: "配置中的首页node_token"
}
如果有多个知识库,先询问用户要查询哪个:
你想查询哪个知识库?
- 海洋动物专区
- 技术文档 ...
用户选择后,使用对应的 space_id 和 node_token。
必须加 parent_node_token 参数才能读到子目录!
feishu_wiki {
action: "nodes",
space_id: "space_id",
parent_node_token: "当前目录的node_token"
}
重复步骤2,直到找到目标文档。
feishu_doc {
action: "read",
doc_token: "obj_token"
}
如果用户提供了知识库的 wiki URL(如 https://my.feishu.cn/wiki/XEMRwElx2iMzHhkkVdCcpj0tnDg),可以尝试自动获取 space_id:
# URL 中的 node_token
node_token = "XEMRwElx2iMzHhkkVdCcpj0tnDg"
# 尝试获取节点信息(可能包含 space_id)
feishu_wiki {
action: "get",
token: node_token
}
注意:部分节点可能无法直接获取 space_id,此时请让用户提供正确的 space_id。
常用 block_type 对照表:
| block_type | 含义 |
|---|---|
| 1 | Page(页面) |
| 2 | Text(文本段落) |
| 4 | Heading2(二级标题) |
| 27 | Image(图片) |
| 43 | Whiteboard(画板) |
当文档包含图片时,feishu_doc { action: "read" } 会返回提示:
"This document contains Image which are NOT included in the plain text above."
列出所有 Blocks
feishu_doc {
action: "list_blocks",
doc_token: "文档token"
}
找到图片 Block
block_type 是 27block.image.token 字段下载图片
curl "https://open.feishu.cn/open-apis/drive/v1/medias/{image_token}/download" \
-H "Authorization: Bearer {token}"
当文档包含画板时(block_type=43):
获取画板的 whiteboard_id
list_blocks 列出所有 blocksblock_type=43 的 block,其 block_id 即为 whiteboard_id获取画板内容
curl "https://open.feishu.cn/open-apis/board/v1/whiteboards/{whiteboard_id}/nodes" \
-H "Authorization: Bearer {token}"
board:whiteboard:node:read当需要将知识库中的图片发送给用户时,使用以下Python脚本:
import requests
import json
# 1. 获取 tenant_access_token
token_resp = requests.post(
"https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
json={
"app_id": "cli_a938e5e808b8dbca",
"app_secret": "0ejwDP7CVN11Mm3PPhtYtfnMQONSJjDo"
}
)
token = token_resp.json()["tenant_access_token"]
# 2. 上传图片
with open('/tmp/图片.png', 'rb') as f:
img_resp = requests.post(
"https://open.feishu.cn/open-apis/im/v1/images",
headers={"Authorization": f"Bearer {token}"},
files={"image": ("图片.png", f.read(), "image/png")},
data={"image_type": "message"}
)
image_key = img_resp.json()["data"]["image_key"]
# 3. 发送图片消息(需提供接收者的 open_id)
msg_resp = requests.post(
"https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id",
headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
json={
"receive_id": "用户open_id",
"msg_type": "image",
"content": json.dumps({"image_key": image_key})
}
)
当知识库中的文档类型是 sheet(电子表格)时,需要使用 Sheets API 处理。
必须开通 sheets:spreadsheet 权限(不是 readonly)!否则会返回 404。
# API 路径:/sheets/v3/spreadsheets/{spreadsheetToken}/sheets/query
curl "https://open.feishu.cn/open-apis/sheets/v3/spreadsheets/{sheet_token}/sheets/query" \
-H "Authorization: Bearer {token}"
返回示例:
{
"data": {
"sheets": [{
"sheet_id": "b56f8e",
"title": "Sheet1",
"resource_type": "sheet"
}]
}
}
使用 v2 API 读取数据:
# API 路径:/sheets/v2/spreadsheets/{spreadsheetToken}/values/{sheetId}!A1:Z100
curl "https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{sheet_token}/values/b56f8e!A1:Z100" \
-H "Authorization: Bearer {token}"
返回示例:
{
"data": {
"valueRange": {
"range": "b56f8e!A1:Z100",
"values": [
["", "周一", "周二", "周三", "周四", "周五", "周六", "周日"],
["早饭", "油条", "油条", "油条", "油条", "包子", "包子", "包子"],
["午饭", "鱼香茄子", "鱼香茄子", "鱼香茄子", "鱼香茄子", "鱼香茄子", "鱼香茄子", "鱼香茄子"],
["晚饭", "红烧肉", "红烧肉", "红烧肉", "红烧肉", "红烧肉", "红烧肉", "红烧肉"]
]
}
}
}
import requests
import json
# 获取 token
token_resp = requests.post(
"https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
json={
"app_id": "cli_a938e5e808b8dbca",
"app_secret": "0ejwDP7CVN11Mm3PPhtYtfnMQONSJjDo"
}
)
token = token_resp.json()["tenant_access_token"]
sheet_token = "电子表格的obj_token"
# 1. 获取工作表 ID
sheets_resp = requests.get(
f"https://open.feishu.cn/open-apis/sheets/v3/spreadsheets/{sheet_token}/sheets/query",
headers={"Authorization": f"Bearer {token}"}
)
sheet_id = sheets_resp.json()["data"]["sheets"][0]["sheet_id"]
# 2. 读取表格数据(使用 v2 API)
values_resp = requests.get(
f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{sheet_token}/values/{sheet_id}!A1:Z100",
headers={"Authorization": f"Bearer {token}"}
)
values = values_resp.json()["data"]["valueRange"]["values"]
# 3. 格式化输出(过滤空值)
for row in values:
if any(cell is not None for cell in row):
print(row)
sheets:spreadsheet 权限 - 否则返回 404A1:Z100| 问题 | 原因 | 解决方案 |
|---|---|---|
Search is not available | 知识库搜索未开放 | 改用 nodes 遍历 |
Missing access token | token 过期 | 重新获取 tenant_access_token |
receive_id_type is required | 发送消息缺参数 | URL 加 ?receive_id_type=open_id |
WrongBaseToken | token 格式错误 | 确认使用的是正确的 token 类型 |
NOTEXIST | 文档不存在或无权访问 | 检查 token 是否正确 |
404 page not found (sheets) | 缺少 sheets:spreadsheet 权限 | 在飞书后台开通该权限 |
| 读取表格返回空数据 | 使用的 API 版本不对 | 确认用 v2 API 读取值 |
| 未配置知识库 | 首次使用未配置 | 按上方"首次配置"步骤进行配置 |
查询完成后,必须标注信息来源: