en un clic
feishu
// 飞书/Lark 消息渠道工具集。通过 message 工具调用飞书 API,支持表情回应、消息操作、 群聊查询、文档/表格创建与编辑(含图片插入)、多维表格、话题帖子、云空间搜索与上传。
// 飞书/Lark 消息渠道工具集。通过 message 工具调用飞书 API,支持表情回应、消息操作、 群聊查询、文档/表格创建与编辑(含图片插入)、多维表格、话题帖子、云空间搜索与上传。
| name | feishu |
| description | 飞书/Lark 消息渠道工具集。通过 message 工具调用飞书 API,支持表情回应、消息操作、 群聊查询、文档/表格创建与编辑(含图片插入)、多维表格、话题帖子、云空间搜索与上传。 |
| metadata | {"openclaw":{"emoji":"📎"}} |
本文档可独立使用。 即使不安装 better-feishu 插件,也可以参考这里的 action 格式和工作流。 如需安装完整插件,请看 README.md。
所有飞书操作都通过 message 工具调用,核心参数是 action。
正确调用方式: 将下面示例中的 JSON 对象作为 message 工具的参数直接传入,参数需要展开到顶层。
// 正确 ✓ - 参数展开到顶层
message(action="react", messageId="om_xxx", emoji="SMILE")
// 错误 ✗ - 不要把参数嵌套成字符串
message(path='{"action": "react", "messageId": "om_xxx", ...}')
to vs chatId这是最常犯的错误,必须记住:
to(格式 chat:oc_xxx) — 只用于框架原生 action:send、reply、react、sendAttachmentchatId(格式 oc_xxx,不带 chat: 前缀) — 用于所有其他飞书自定义 actionto 参数,否则框架报错群消息正文开头有 [chatId=oc_xxx sender=xxx],从这里取 oc_xxx:
chat:oc_xxx 传给 tooc_xxx 给 chatId飞书渠道用户看不到 agent 本地文件! 分享时必须选择以下方式:
sendAttachment action,把本地文件路径传给 pathcreateDocument / createSpreadsheet 创建appendDocument / writeSpreadsheet 写入内容manageDocPermission 给用户开权限禁止: 只发本地文件路径 / 创建文档后不开权限 / 只发文档 ID 不生成链接
{ "action": "react", "to": "chat:oc_xxx", "messageId": "om_xxx", "emoji": "THUMBSUP" }
取消表情:加 "reactionId": "xxx" 和 "remove": true
emoji_type 清单(大小写敏感):
| 场景 | emoji_type |
|---|---|
| 加油 | MUSCLE, SaluteFace, STRIVE, GoGoGo |
| 尴尬 | FACEPALM, LOL, NOSEPICK, DULL, GLANCE, INNOCENTSMILE, ENOUGH, SWEAT, SLIGHT |
| 心有灵犀 | SMIRK, FullMoonFace |
| 聪明 | WITTY, SMART |
| 反应不过来 | SCOWL, FROWN, WHAT |
| 深深赞同 | FINGERHEART, APPLAUSE, SMOOCH, DROOL, HIGHFIVE, JIAYI, THUMBSUP |
| 被夸 | PROUD, WINK, CRY, COMFORT |
| 惊讶 | SHOCKED, PETRIFIED, TERROR |
| 疲惫 | YAWN, SICK, Sigh |
| 工作中 | Typing, OneSecond, OnIt |
| 吃饭 | EatingFood |
| 搞定 | DONE |
| 不同意 | No, CrossMark, MinusOne, POOP, ClownFace |
在消息文本中 @ 用户,使用以下格式:
<at user_id="ou_xxx">用户名</at>
示例:
{
"action": "send",
"to": "chat:oc_xxx",
"text": "<at user_id=\"ou_abc123\">张三</at> 请查看这个文档"
}
获取 user_id:
sender 字段就是发送者的 ou_xxxgetChatMembers 可以获取群成员列表及其 user_id注意:
user_id 格式为 ou_xxx(open_id)<at> 标签即可// 列消息
{ "action": "listMessages", "chatId": "oc_xxx", "pageSize": 20 }
// Pin
{ "action": "pinMessage", "messageId": "om_xxx" }
// 取消Pin
{ "action": "unpinMessage", "messageId": "om_xxx" }
// 撤回
{ "action": "recallMessage", "messageId": "om_xxx" }
// 编辑
{ "action": "updateMessage", "messageId": "om_xxx", "content": "修改后的内容" }
// 发文件/图片(框架原生 action,用 to)
{ "action": "sendAttachment", "to": "chat:oc_xxx", "path": "/tmp/file.png" }
在飞书中以话题形式回复消息,会创建一个独立的讨论串。
// 话题形式回复(会创建话题或在已有话题中回复)
{ "action": "replyInThread", "messageId": "om_xxx", "content": "这是话题回复内容" }
// 指定消息类型(可选,默认 text)
{ "action": "replyInThread", "messageId": "om_xxx", "content": "回复内容", "msgType": "text" }
// 获取话题内的所有消息(threadId 从 replyInThread 响应或 listMessages 返回的消息中获取)
{ "action": "listThreadMessages", "threadId": "omt_xxx", "pageSize": 20 }
返回值:
replyInThread 返回 { ok: true, messageId: "om_xxx", threadId: "omt_xxx" }listThreadMessages 返回话题内所有消息列表使用场景:
限制:话题内不能发送附件(图片/文件)。 如需发送附件,请直接发到群聊主界面。
在话题群(chat_mode 为 thread 的群聊)中发起新的话题帖子。
// 发起话题帖子(支持 post 富文本格式)
{ "action": "createTopicPost", "chatId": "oc_xxx", "content": "# 标题\n帖子正文内容" }
// 纯文本话题帖子
{ "action": "createTopicPost", "chatId": "oc_xxx", "content": "帖子内容", "msgType": "text" }
返回值: { ok: true, messageId: "om_xxx", threadId: "omt_xxx" }
与 replyInThread 的区别:
createTopicPost — 在话题群中发起新话题(相当于论坛里发新帖)replyInThread — 在已有消息下创建/回复讨论串注意: createTopicPost 只适用于话题群(chat_mode = "thread"),普通群请用 send。
// 查群成员
{ "action": "getChatMembers", "chatId": "oc_xxx" }
// 查群详情
{ "action": "getChatInfo", "chatId": "oc_xxx" }
⚠️ 从飞书链接提取 token 的方法:
https://xxx.feishu.cn/docx/ABC123def → documentId = ABC123defhttps://xxx.feishu.cn/sheets/ABC123def → spreadsheetToken = ABC123defhttps://xxx.feishu.cn/sheets/ABC123def?sheet=0ab1c2 → spreadsheetToken = ABC123def, sheetId = 0ab1c2https://xxx.feishu.cn/wiki/ABC123def → documentId = ABC123def(URL 里有 /wiki/ 但它就是普通文档,直接用 readDocument)doxcn/shtcn 开头,直接从 URL 提取即可?sheet= 参数时,sheetId 可以省略或传 "Sheet1"⚠️ 重要:创建文档后必须开权限,否则用户打不开!
appendDocument 支持图片插入: 在 markdown 内容中使用  语法即可插入图片。支持本地路径和 HTTP(S) URL,图片会自动上传到飞书。上传失败时会 fallback 为文字链接。
完整工作流(创建 → 分批写入 → 开权限 → 发链接):
// 第1步:创建文档(返回 documentId)
{ "action": "createDocument", "title": "标题" }
// 返回: { "documentId": "doxcnXXX", "url": "https://xxx.feishu.cn/docx/doxcnXXX" }
// 第2步:分批写入内容(每次 appendDocument 有字数限制,约 5000 字)
{ "action": "appendDocument", "documentId": "doxcnXXX", "content": "# 第一部分\n内容..." }
{ "action": "appendDocument", "documentId": "doxcnXXX", "content": "# 第二部分\n更多内容..." }
// 长文档必须分多次 append,每次控制在 5000 字以内
// 第3步:给用户开权限(用消息中的 sender 作为 memberId)
{ "action": "manageDocPermission", "docToken": "doxcnXXX", "action": "add", "memberId": "ou_xxx", "perm": "view" }
// perm 可选: "view"(只读), "edit"(可编辑)
// 第4步:把链接发给用户
// 直接发送 url: https://xxx.feishu.cn/docx/doxcnXXX
单独的 action:
// 读取文档
{ "action": "readDocument", "documentId": "doxcnXXX" }
// 查看当前权限
{ "action": "manageDocPermission", "docToken": "doxcnXXX", "action": "list" }
常见错误: 创建文档后直接发链接给用户,用户点开提示「无权限」→ 忘了第3步开权限!
// 创建
{ "action": "createSpreadsheet", "title": "表格名" }
// 读取(sheetId 是工作表名或 ID,range 如 "A1:C10")
{ "action": "readSpreadsheet", "spreadsheetToken": "shtcnXXX", "sheetId": "Sheet1", "range": "A1:C10" }
// 写入(values 是二维数组)
{ "action": "writeSpreadsheet", "spreadsheetToken": "shtcnXXX", "sheetId": "Sheet1", "range": "A1", "values": [["姓名","分数"],["张三",95]] }
⚠️ 从飞书链接提取 token 的方法:
https://xxx.feishu.cn/base/ABC123def → appToken = ABC123def完整工作流(创建 → 加字段 → 写数据 → 开权限 → 发链接):
// 第1步:创建多维表格(返回 appToken,自动清理默认空记录和默认字段)
{ "action": "createBitable", "name": "表格名" }
// 可选:指定云空间文件夹
{ "action": "createBitable", "name": "表格名", "folderToken": "fldcnXXX" }
// 返回: { "appToken": "XXX", "name": "表格名", "url": "https://xxx.feishu.cn/base/XXX" }
// 第2步:查看表结构(获取 tableId 和现有字段)
{ "action": "listBitableTables", "appToken": "XXX" }
// 返回每个 table 的 tableId、name 和 fields(含 fieldId、name、type)
// 第3步:按需添加字段
{ "action": "addBitableField", "appToken": "XXX", "tableId": "tblXXX", "fieldName": "书名", "fieldType": "text" }
{ "action": "addBitableField", "appToken": "XXX", "tableId": "tblXXX", "fieldName": "评分", "fieldType": "number" }
// select/multi_select 可带选项列表
{ "action": "addBitableField", "appToken": "XXX", "tableId": "tblXXX", "fieldName": "状态", "fieldType": "select", "options": ["待读", "在读", "已读"] }
{ "action": "addBitableField", "appToken": "XXX", "tableId": "tblXXX", "fieldName": "标签", "fieldType": "multi_select", "options": ["科幻", "文学", "历史"] }
// fieldType 可选: text(1), number(2), select(3), multi_select(4), date(5), checkbox(7), person(11), url(15), attachment(17)
// options 支持字符串数组 ["A","B"] 或对象数组 [{"name":"A","color":0}],颜色 0-9
// 第4步:写入数据(fields 是字段名到值的映射)
{ "action": "createBitableRecord", "appToken": "XXX", "tableId": "tblXXX", "fields": {"书名": "三体", "评分": 9.5} }
各字段类型的值格式:
| 字段类型 | 值格式 | 示例 |
|---|---|---|
| text | 字符串 | "三体" |
| number | 数字 | 9.5 |
| select | 选项名字符串 | "在读" |
| multi_select | 选项名数组 | ["科幻", "文学"] |
| date | 毫秒时间戳 | 1735084800000 |
| checkbox | 布尔 | true |
| person | 对象数组 | [{"id": "ou_xxx"}] |
| url | 字符串 | "https://example.com" |
| attachment | token数组 | [{"file_token": "xxx"}] |
人员字段注意: 必须是 [{"id": "ou_xxx"}] 格式(数组包对象),不能直接传 "ou_xxx" 字符串。ou_xxx 从消息的 sender 或 getChatMembers 获取。
附件字段注意: 不能直接传文件路径!必须先上传拿 file_token:
// 第1步:上传文件拿 file_token
{ "action": "uploadBitableFile", "path": "/tmp/screenshot.png" }
// 返回: { "ok": true, "fileToken": "xxx", "fileName": "screenshot.png" }
// 第2步:写入记录时用 file_token
{ "action": "createBitableRecord", "appToken": "XXX", "tableId": "tblXXX", "fields": {"截图": [{"file_token": "xxx"}]} }
// 第5步:给用户开权限
{ "action": "manageDocPermission", "docToken": "XXX", "docType": "bitable", "action": "add", "memberId": "ou_xxx", "perm": "view" }
// 第6步:发送链接给用户
给已有字段追加选项(不要新建字段!):
// 先用 listBitableTables 获取 fieldId
{ "action": "listBitableTables", "appToken": "XXX" }
// 返回每个字段的 fieldId
// 给已有 select/multi_select 字段追加选项(自动合并,不会覆盖已有选项)
{ "action": "updateBitableField", "appToken": "XXX", "tableId": "tblXXX", "fieldId": "fldXXX", "addOptions": ["新选项A", "新选项B"] }
// 重命名字段
{ "action": "updateBitableField", "appToken": "XXX", "tableId": "tblXXX", "fieldId": "fldXXX", "fieldName": "新名称" }
// 删除字段(主字段不可删)
{ "action": "deleteBitableField", "appToken": "XXX", "tableId": "tblXXX", "fieldId": "fldXXX" }
重要: 当需要给单选/多选字段新增选项时,用 updateBitableField + addOptions,不要用 addBitableField 新建同名字段,否则会产生重复列。
其他操作:
// 查询记录(支持 filter 筛选)
{ "action": "listBitableRecords", "appToken": "XXX", "tableId": "tblXXX" }
{ "action": "listBitableRecords", "appToken": "XXX", "tableId": "tblXXX", "filter": "CurrentValue.[评分] > 8" }
// 更新记录
{ "action": "updateBitableRecord", "appToken": "XXX", "tableId": "tblXXX", "recordId": "recXXX", "fields": {"评分": 10} }
// 删除记录
{ "action": "deleteBitableRecord", "appToken": "XXX", "tableId": "tblXXX", "recordId": "recXXX" }
常见错误:
listBitableTables 查看现有字段名docType 要传 "bitable"// 搜索文件
{ "action": "searchDrive", "query": "周报" }
// 上传文件
{ "action": "uploadFile", "path": "/tmp/report.pdf", "parentToken": "fldcnXXX" }
查看、回复和解决飞书文档上的评论。
// 获取文档评论列表
{ "action": "listDocComments", "fileToken": "doxcnXXX" }
// 筛选未解决的评论
{ "action": "listDocComments", "fileToken": "doxcnXXX", "isSolved": false }
// 指定文件类型(默认 "docx",可选 "sheet", "bitable" 等)
{ "action": "listDocComments", "fileToken": "shtcnXXX", "fileType": "sheet" }
// 回复文档评论
{ "action": "replyDocComment", "fileToken": "doxcnXXX", "commentId": "xxx", "text": "已收到,马上处理" }
// 解决评论(标记为已解决)
{ "action": "resolveDocComment", "fileToken": "doxcnXXX", "commentId": "xxx" }
// 恢复已解决的评论(标记为未解决)
{ "action": "resolveDocComment", "fileToken": "doxcnXXX", "commentId": "xxx", "isSolved": false }
参数说明:
fileToken — 文档 token(也接受 docToken 或 token)fileType — 文件类型,默认 "docx",可选 "sheet"、"bitable" 等commentId — 评论 ID,从 listDocComments 返回的 commentId 字段获取isSolved — 布尔值,listDocComments 中用于筛选,resolveDocComment 中用于解决/恢复返回值:
listDocComments 返回 { comments: [{ commentId, quote, isSolved, replies: [{ replyId, userId, content }] }], total, hasMore }replyDocComment 返回 { commentId, replyId, content }resolveDocComment 返回 { commentId, isSolved }注意: 调用 listDocComments 或对文档执行其他操作时,文档会自动注册到评论监控列表(doc-comment-watch.json)。
用户发送图片/文件时,系统会自动下载到本地:
workspace/chatdownload/ 目录/tmp/ 目录下载后的文件路径会自动设置到 MediaPaths,agent 可直接用 read 工具查看。