Feishu Wiki Query

Other

飞书知识库文档查询技能。当用户询问需要查询飞书知识库中的文档时使用此技能,包括:查询动物信息、查看排期、读取文档内容、处理文档中的图片、画板和电子表格等。触发场景包括:用户说"查一下xx动物"、"看看排期"、"查询知识库"、"食堂菜谱"等。

Install

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] 时:

  1. 解析 URL 获取 node_token

    • URL 格式:https://my.feishu.cn/wiki/{node_token}
    • 提取 node_token = URL 路径最后一段
  2. 获取 space_id

    feishu_wiki {
      action: "get",
      token: "解析出的node_token"
    }
    

    从返回中获取 space_id

  3. 保存配置 将以下内容写入 config.json

    {
      "version": 1,
      "updated_at": "当前时间",
      "knowledge_bases": [
        {
          "name": "用户提供的名称",
          "space_id": "获取到的space_id",
          "root_node_token": "解析出的node_token"
        }
      ]
    }
    

查询流程

步骤1:浏览知识库目录

首先获取首页目录(使用配置中的 space_id 和首页 node_token):

如果只有一个知识库,直接使用:

feishu_wiki {
  action: "nodes",
  space_id: "配置中的space_id",
  parent_node_token: "配置中的首页node_token"
}

如果有多个知识库,先询问用户要查询哪个:

你想查询哪个知识库?

  1. 海洋动物专区
  2. 技术文档 ...

用户选择后,使用对应的 space_id 和 node_token。

步骤2:进入子目录

必须加 parent_node_token 参数才能读到子目录!

feishu_wiki {
  action: "nodes",
  space_id: "space_id",
  parent_node_token: "当前目录的node_token"
}

步骤3:递归深入找到目标文档

重复步骤2,直到找到目标文档。

步骤4:读取文档内容

feishu_doc {
  action: "read",
  doc_token: "obj_token"
}

通过 URL 解析获取 space_id

如果用户提供了知识库的 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。

文档Blocks类型

常用 block_type 对照表:

block_type含义
1Page(页面)
2Text(文本段落)
4Heading2(二级标题)
27Image(图片)
43Whiteboard(画板)

处理图片内容

当文档包含图片时,feishu_doc { action: "read" } 会返回提示:

"This document contains Image which are NOT included in the plain text above."

处理步骤:

  1. 列出所有 Blocks

    feishu_doc {
      action: "list_blocks",
      doc_token: "文档token"
    }
    
  2. 找到图片 Block

    • 图片的 block_type27
    • 图片 token 在 block.image.token 字段
  3. 下载图片

    curl "https://open.feishu.cn/open-apis/drive/v1/medias/{image_token}/download" \
      -H "Authorization: Bearer {token}"
    

处理画板(Whiteboard)内容

当文档包含画板时(block_type=43):

  1. 获取画板的 whiteboard_id

    • list_blocks 列出所有 blocks
    • 找到 block_type=43 的 block,其 block_id 即为 whiteboard_id
  2. 获取画板内容

    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)

当知识库中的文档类型是 sheet(电子表格)时,需要使用 Sheets API 处理。

重要前提

必须开通 sheets:spreadsheet 权限(不是 readonly)!否则会返回 404。

读取电子表格步骤

步骤1:获取工作表列表

# 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"
    }]
  }
}

步骤2:读取表格数据

使用 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)

注意事项

  1. 获取工作表用 v3,读取数据用 v2 - 这是飞书 API 的现状
  2. 必须开通 sheets:spreadsheet 权限 - 否则返回 404
  3. 表格数据可能很大 - 建议只读取需要的范围,如 A1:Z100

常见问题

问题原因解决方案
Search is not available知识库搜索未开放改用 nodes 遍历
Missing access tokentoken 过期重新获取 tenant_access_token
receive_id_type is required发送消息缺参数URL 加 ?receive_id_type=open_id
WrongBaseTokentoken 格式错误确认使用的是正确的 token 类型
NOTEXIST文档不存在或无权访问检查 token 是否正确
404 page not found (sheets)缺少 sheets:spreadsheet 权限在飞书后台开通该权限
读取表格返回空数据使用的 API 版本不对确认用 v2 API 读取值
未配置知识库首次使用未配置按上方"首次配置"步骤进行配置

输出格式

查询完成后,必须标注信息来源:

  • "📋 来源:飞书知识库 - [知识库名称]"
  • "📋 来源:飞书知识库 - 动物园排班表"