Install
openclaw skills install @kooui/feishu-doc-pipelineComplete pipeline for reading Feishu wiki docs and downloading embedded attachments. Covers auth, node routing, and Windows path workaround. / 飞书知识库文档读取与附件下载完整流水线,涵盖分步授权、节点类型路由和 Windows 路径处理。
openclaw skills install @kooui/feishu-doc-pipelineEnd-to-end pipeline: wiki URL/token -> resolve node -> read document -> extract embedded tokens -> download files to local disk.
lark-cli installed and on PATH (typically ~/.qoderworkcn/bin/lark-cli or lark-cli.cmd on Windows)The pipeline needs up to 4 independent scopes, depending on what the wiki contains:
| Scope | When Needed | Command |
|---|---|---|
wiki:node:read | Always (resolving wiki tokens) | lark-cli auth login --scope "wiki:node:read" --no-wait --json |
docx:document:readonly | When wiki contains docx documents | lark-cli auth login --scope "docx:document:readonly" --no-wait --json |
docs:document.media:download | When downloading embedded images/files from docx | lark-cli auth login --scope "docs:document.media:download" --no-wait --json |
drive:file:download | When wiki nodes are uploaded files (obj_type: file) | lark-cli auth login --scope "drive:file:download" --no-wait --json |
Important: Each scope requires a separate authorization flow. Run --no-wait --json to get the device verification URL, have the user open it in browser, then complete with lark-cli auth login --device-code "<code>".
Given a wiki URL (https://xxx.feishu.cn/wiki/<wiki_token>) or raw token:
lark-cli wiki spaces get_node --params '{"token":"<wiki_token>"}' --as user --format json
Response gives you:
node.obj_token - the actual document/file tokennode.obj_type - determines the download path (critical!)node.space_id - for listing child nodesnode.title - human-readable nameTo list all child nodes under this node:
lark-cli wiki +node-list --space-id "<space_id>" --parent-node-token "<wiki_token>" --as user --format json
Or list all root-level nodes in a space:
lark-cli wiki +node-list --space-id "<space_id>" --as user --format json
This is the critical branching point. Different obj_type values require completely different download approaches.
Read the document content:
lark-cli docs +fetch --api-version v2 --doc "<obj_token>" --as user
The output is XML (default) or Markdown. Embedded files appear as tagged elements:
<image token="TOKEN"> - embedded images<file token="TOKEN" name="filename.ext"> - embedded attachments<sheet token="TOKEN" sheet-id="ID"> - embedded spreadsheets<bitable token="TOKEN" table-id="ID"> - embedded bitablesExtract the token attribute from <image> and <file> tags for downloading.
The node IS the file itself (e.g., an uploaded .xlsx, .txt, .pdf). Download directly:
cd "<target_directory>" && lark-cli drive +download --file-token "<obj_token>" --output "<filename>" --as user --overwrite
Do NOT use docs +media-download for file-type nodes - it will return 403.
Hand off to lark-sheets or lark-base skill respectively.
cd "<target_directory>" && lark-cli docs +media-download --token "<file_token>" --output "<filename>" --as user --overwrite
cd "<target_directory>" && lark-cli drive +download --file-token "<obj_token>" --output "<filename>" --as user --overwrite
After download, read and parse the files:
.txt / .md - read directly with Read tool.xlsx - use Python (openpyxl or pandas) or the xlsx skill.pdf - use the pdf skillThis is a common pitfall on Windows. When using --output with an absolute path containing backslashes (e.g., "C:\Users\...\file.xlsx"), the quotes may be embedded into the path string, causing the file to be written to an unexpected location (typically the QoderWork installation directory).
Always cd to the target directory first, then use a relative filename for --output:
# CORRECT
cd "C:\Users\zhong\.qoderworkcn\workspace\xxx" && lark-cli docs +media-download --token "abc123" --output myfile.xlsx --as user --overwrite
# WRONG - file may end up in QoderWork install dir
lark-cli docs +media-download --token "abc123" --output "C:\Users\zhong\.qoderworkcn\workspace\xxx\myfile.xlsx" --as user --overwrite
Check C:\Users\<username>\AppData\Local\Programs\QoderWork CN\ for misplaced files, then move them:
mv "/c/Users/zhong/AppData/Local/Programs/QoderWork CN/filename" "/c/Users/zhong/.qoderworkcn/workspace/xxx/"
The token belongs to a wiki file node (obj_type: file), not an embedded media element. Switch to drive +download --file-token <token>.
The drive:file:download scope has not been authorized. Run:
lark-cli auth login --scope "drive:file:download" --no-wait --json
Then complete the device verification flow.
This happens when the pipeline encounters a new operation that needs a scope not yet authorized. To minimize back-and-forth, pre-authorize all 4 scopes upfront before starting the pipeline:
lark-cli auth login --scope "wiki:node:read" --no-wait --json
# complete auth, then:
lark-cli auth login --scope "docx:document:readonly" --no-wait --json
# complete auth, then:
lark-cli auth login --scope "docs:document.media:download" --no-wait --json
# complete auth, then:
lark-cli auth login --scope "drive:file:download" --no-wait --json
Scopes are cumulative - once authorized, they persist across sessions.
The node may have no children, or you may be querying the wrong space_id. Use wiki spaces get_node to confirm the correct space_id for the node.
User provides wiki URL/token
|
v
wiki spaces get_node --> obj_token, obj_type, space_id
|
+--> obj_type: docx
| |
| +--> docs +fetch (read content)
| +--> Extract <image>/<file> tokens from XML
| +--> docs +media-download (per token)
|
+--> obj_type: file
| |
| +--> drive +download (direct)
|
+--> obj_type: sheet/bitable
|
+--> Hand off to lark-sheets / lark-base