feishu-doc
feishu-doc — a Claude Code skill from m1heng/clawdbot-feishu
Features
- ✓WebSocket and Webhook connection modes
- ✓Direct messages and group chats
- ✓Message replies and quoted message context
- ✓**Inbound media support**: AI can see images, read files (PDF, Excel, etc.), and process rich text with embedded images
- ✓Image and file uploads (outbound)
- ✓Typing indicator (via emoji reactions)
- ✓Pairing flow for DM approval
- ✓User and group directory lookup
- ✓**Card render mode**: Optional markdown rendering with syntax highlighting
- ✓**Document tools**: Read, create, and write Feishu documents with markdown, including atomic `create_and_write` / `import_document` flows for reliable create+content write
- ✓**Wiki tools**: Navigate knowledge bases, list spaces, get node details, search, create/move/rename nodes
- ✓**Drive tools**: List folders, get file info, create folders, move/delete files
- ✓**Bitable tools**: Manage bitable (多维表格) fields and records (read/create/update/delete), supports both `/base/` and `/wiki/` URLs
- ✓**Task tools**: Create, get details, update, and delete tasks via Feishu Task v2 API
- ✓**Chat tools**: Read and write group announcements, create group chats, add members, check bot membership, delete chats (`feishu_chat`)
- ✓**Urgent notification tools**: Send buzz/urgent notifications (app, SMS, voice call) via `feishu_urgent`
- ✓**Message tools**: Read single messages or list recent chat history with time range and pagination (`feishu_message`)
- ✓**Reaction tools**: Add, remove, and list emoji reactions on messages (`feishu_reaction`)
- ✓**@mention forwarding**: When you @mention someone in your message, the bot's reply will automatically @mention them too
- ✓**Permission error notification**: When the bot encounters a Feishu API permission error, it automatically notifies the user with the permission grant URL
- ✓**Dynamic agent creation**: Each DM user can have their own isolated agent instance with dedicated workspace (optional)
- ✓**In DM**: `@张三 say hello` → Bot replies with `@张三 Hello!`
- ✓**In Group**: `@bot @张三 say hello` → Bot replies with `@张三 Hello!`
Installation Guide
openclaw plugins install @m1heng-clawd/feishu[!IMPORTANT]
Windows Troubleshooting (spawn npm ENOENT)>
If openclaw plugins install fails, install manually with the latest tarball:>
>
> # Option A (recommended): download latest package tarball
> npm pack @m1heng-clawd/feishu
> openclaw plugins install ./m1heng-clawd-feishu-<version>.tgz
>>
>
> # Option B (keep curl flow): resolve latest tarball URL, then download/install
> TARBALL_URL="$(npm view @m1heng-clawd/feishu dist.tarball)"
> curl -L -o feishu-latest.tgz "$TARBALL_URL"
> openclaw plugins install ./feishu-latest.tgz
>>
>
> # Windows PowerShell (Option B)
> $tarball = npm view @m1heng-clawd/feishu dist.tarball
> curl.exe -L $tarball -o feishu-latest.tgz
> openclaw plugins install .\feishu-latest.tgz
>>
>
> # Option C (no npm command): use URL template with latest version from npm Versions tab
> # https://www.npmjs.com/package/@m1heng-clawd/feishu?activeTab=versions
> curl -L -o feishu-latest.tgz https://registry.npmjs.org/@m1heng-clawd/feishu/-/feishu-<version>.tgz
> openclaw plugins install ./feishu-latest.tgz
>Upgrade
openclaw plugins update feishuCheck installed version:
openclaw plugins list | rg -i feishuConfiguration
#### Required Permissions
| Permission | Scope | Description |
|------------|-------|-------------|
| im:message | Messaging | Send and receive messages |
| im:message.p2p_msg:readonly | DM | Read direct messages to bot |
| im:message.group_at_msg:readonly | Group | Receive @mention messages in groups |
| im:message:send_as_bot | Send | Send messages as the bot |
| im:resource | Media | Upload and download images/files |
#### Optional Permissions
| Permission | Scope | Description |
|------------|-------|-------------|
| contact:user.base:readonly | User info | Get basic user info (required to resolve sender display names for speaker attribution) |
| im:message.group_msg | Group | Read all group messages (sensitive). Required when you want requireMention: false to work for non-@ group messages |
| im:message:readonly | Read | Get message history |
| im:message:update | Edit | Update/edit sent messages |
| im:message:recall | Recall | Recall sent messages |
| im:message.reactions:read | Reactions | View message reactions |
#### Tool Permissions
Read-only (minimum required):
| Permission | Tool | Description |
|------------|------|-------------|
| docx:document:readonly | feishu_doc | Read documents |
| drive:drive:readonly | feishu_drive | List folders, get file info |
| wiki:wiki:readonly | feishu_wiki | List spaces, list nodes, get node info, search |
| bitable:app:readonly | feishu_bitable | Read bitable records and fields |
| task:task:read | feishu_task_get | Get task details |
| task:tasklist:read | feishu_tasklist_get, feishu_tasklist_list | Get/list tasklists |
| task:comment:read | feishu_task_comment_list, feishu_task_comment_get | List/get task comments |
| task:attachment:read | feishu_task_attachment_list, feishu_task_attachment_get | List/get task attachments |
| im:chat.announcement:read | feishu_chat | Read group announcement |
| im:chat:readonly | feishu_chat | Get chat info, check bot membership |
| im:message or im:message:readonly | feishu_message | Read single/DM messages |
| im:message.group_at_msg:readonly | feishu_message | Read all messages in group chats |
| im:message.reactions:read | feishu_reaction | List reactions on messages |
Read-write (optional, for create/edit/delete operations):
| Permission | Tool | Description |
|------------|------|-------------|
| docx:document | feishu_doc | Create/edit documents |
| docx:document.block:convert | feishu_doc | Markdown to blocks conversion (required for write/append/create_and_write; also used by feishu_drive.import_document) |
| drive:drive | feishu_doc, feishu_drive | Upload images to documents, create folders, move/delete files |
| wiki:wiki | feishu_wiki | Create/move/rename wiki nodes |
| bitable:app | feishu_bitable | Create/update/delete bitable records and manage fields |
| task:task:write | feishu_task_create, feishu_task_subtask_create, feishu_task_update, feishu_task_delete | Create/update/delete tasks |
| task:tasklist:write | feishu_tasklist_create, feishu_tasklist_update, feishu_tasklist_delete, feishu_tasklist_add_members, feishu_tasklist_remove_members, feishu_task_add_tasklist, feishu_task_remove_tasklist | Create/update/delete tasklists and manage membership |
| task:comment:write | feishu_task_comment_create, feishu_task_comment_update, feishu_task_comment_delete | Create/update/delete task comments |
| task:attachment:write | feishu_task_attachment_upload, feishu_task_attachment_delete | Upload/delete task attachments |
| im:message.urgent | feishu_urgent | Send urgent (buzz) notifications via app (in-app). Use sms and phone variants (im:message.urgent:sms, im:message.urgent:phone) for SMS and voice call. |
| im:chat.announcement | feishu_chat | Write/update group announcement |
| im:chat | feishu_chat | Create and delete group chats |
| im:chat.members | feishu_chat | Add members to group chats |
| im:message.reactions:write_only | feishu_reaction | Add and remove reactions |
Task scope names may vary slightly in Feishu console UI. If needed, search for Task / Tasklist / Comment / Attachment-related permissions and grant read/write accordingly.
#### Task Comment Scopes ⚠️
Task comments require dedicated scopes:
task:comment:read.task:comment:write.If these scopes are missing, comment APIs will return permission-denied errors.
#### Task Attachment Upload ⚠️
Task attachments support upload/get/list/delete. Upload sources:
file_path)file_url, public or presigned)For file_url, OpenClaw runtime media loader is used with safety checks and size limit (mediaMaxMb), then the downloaded file is uploaded via a temporary local file.
#### Tasklist Ownership ⚠️
Important: Keep tasklist owner as the bot. Add users as members instead.
Tasklist access is granted based on owner + member roles. If you change the owner to a user and the bot is not a member, the bot may lose permission to read/edit/manage that tasklist (and subsequent operations will fail).
#### Task Visibility & Subtasks ⚠️
Important: A user can only view a task when they are included as an assignee.
>
Limitation: The bot can currently only create subtasks for tasks created by itself.
To avoid “task created but not visible” issues:
#### Drive Access ⚠️
Important: Bots don't have their own "My Space" (root folder). Bots can only access files/folders that have been shared with them.
To let the bot manage files:
Without this step, feishu_drive operations like create_folder will fail because the bot has no root folder to create in.
#### Wiki Space Access ⚠️
Important: API permissions alone are not enough for wiki access. You must also add the bot to each wiki space.
Without this step, feishu_wiki will return empty results even with correct API permissions.
Reference: Wiki FAQ - How to add app to wiki
#### Bitable Access ⚠️
Important: Like other resources, the bot can only access bitables that have been shared with it.
To let the bot access a bitable:
The feishu_bitable tools support both URL formats:
/base/XXX?table=YYY - Standard bitable URL/wiki/XXX?table=YYY - Bitable embedded in wiki (auto-converts to app_token)#### Event Subscriptions ⚠️
This is the most commonly missed configuration! If the bot can send messages but cannot receive them, check this section.
In the Feishu Open Platform console, go to Events & Callbacks:
connectionMode:- Long connection — for
connectionMode: "websocket" (recommended, no public URL needed)- Request URL — for
connectionMode: "webhook" (requires a publicly accessible URL)| Event | Description |
|-------|-------------|
| im.message.receive_v1 | Receive messages (required) |
| im.message.message_read_v1 | Message read receipts |
| im.chat.member.bot.added_v1 | Bot added to group |
| im.chat.member.bot.deleted_v1 | Bot removed from group |
openclaw config set channels.feishu.appId "cli_xxxxx"
openclaw config set channels.feishu.appSecret "your_app_secret"
openclaw config set channels.feishu.enabled trueConfiguration Options
channels:
feishu:
enabled: true
appId: "cli_xxxxx"
appSecret: "secret"
# Domain: "feishu" (China), "lark" (International), or custom URL
domain: "feishu" # or "https://open.xxx.cn" for private deployment
# Connection mode: "websocket" (recommended) or "webhook"
connectionMode: "websocket"
# DM policy: "pairing" | "open" | "allowlist"
dmPolicy: "pairing"
# DM allowlist (open_id/user_id). Include "*" when dmPolicy="open"
allowFrom: []
# Group policy: "open" | "allowlist" | "disabled"
groupPolicy: "allowlist"
# Require @mention in groups
requireMention: true
# Safety default for mention-free mode (`requireMention: false`):
# only allow non-@ messages in groups with <= 1 bot.
# Set true to also allow mention-free messages in multi-bot groups.
allowMentionlessInMultiBotGroup: false
# Group command mention bypass: "never" | "single_bot" | "always"
# Default "single_bot": allow authorized command-only messages without @
# only when the group has a single bot.
groupCommandMentionBypass: "single_bot"
# Max media size in MB (default: 30)
mediaMaxMb: 30
# Render mode for bot replies: "auto" | "raw" | "card"
renderMode: "auto"#### DM Policy & Access Control
dmPolicy controls who can interact with the bot in direct messages (DM).
In multi-account mode, this is resolved per account (channels.feishu.accounts.<accountId>).
| dmPolicy | Who can send DM | How to grant access to a user |
|------------|------------------|--------------------------------|
| pairing | Users in allowFrom, or users approved through pairing | User sends a DM and gets a pairing code; bot owner runs openclaw pairing approve feishu <code>. |
| open | Everyone | Set allowFrom: ["*"] so all users are treated as allowed. |
| allowlist | Only users in allowFrom | Add the user's open_id/user_id to allowFrom, then reload config. |
Notes:
allowFrom accepts Feishu user IDs (open_id recommended, user_id also supported).dmPolicy: "open", use allowFrom: ["*"]. This is required by top-level schema validation and keeps access behavior explicit.pairing and allowlist can both pre-authorize users with allowFrom.Pairing flow (owner approval):
H9ZEHY8R).openclaw pairing approve feishu H9ZEHY8RExample: open to everyone
channels:
feishu:
dmPolicy: "open"
allowFrom: ["*"]Example: controlled rollout (pairing + pre-approved users)
channels:
feishu:
dmPolicy: "pairing"
allowFrom:
- "ou_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"Example: strict allowlist
channels:
feishu:
dmPolicy: "allowlist"
allowFrom:
- "ou_alice"
- "ou_bob"Example: account-level isolation
channels:
feishu:
accounts:
lobster-1:
dmPolicy: "open"
allowFrom: ["*"]
lobster-5:
dmPolicy: "pairing"Top-level channels.feishu.dmPolicy / channels.feishu.allowFrom are fallback defaults for accounts that do not override them.
dmPolicy only controls who can trigger the bot. To actually read/write docs or files, you still need: (1) correct Feishu app scopes, and (2) sharing the target resources (Drive/Wiki/Bitable) with the bot.
#### Group Command Mention Bypass
When requireMention: true, Feishu can still allow authorized control commands (such as /new) without @bot.
| groupCommandMentionBypass | Behavior |
|----------------------------|----------|
| never | Never bypass @ requirement for group commands. |
| single_bot | Bypass only when the group contains at most one bot (default). |
| always | Always allow authorized control commands to bypass mention gating. |
Notes:
@-mentioned in the same message, bypass is disabled.#### Group Mention-Free Behavior (requireMention: false)
When requireMention: false, non-@ group messages are handled with a safety default:
| allowMentionlessInMultiBotGroup | Behavior for non-@ group messages |
|-----------------------------------|-----------------------------------|
| false (default) | Only accepted when the group has at most one bot. In multi-bot groups, explicit @bot is still required. |
| true | Accepted even in multi-bot groups (use only if you accept duplicate-trigger risk). |
Important:
im:message.group_msg is required for receiving non-@ group messages and this is a sensitive permission in Feishu.@bot group messages (im:message.group_at_msg:readonly).#### Connection Mode
Two connection modes are available for receiving events from Feishu:
| Mode | Description |
|------|-------------|
| websocket | (Default, recommended) Long-polling WebSocket connection. No public URL required, works behind NAT/firewall. Best for local development and most deployments. |
| webhook | HTTP server that receives event callbacks. Requires a publicly accessible URL. Suitable for server deployments behind a reverse proxy (e.g. Nginx). |
WebSocket mode (default, no extra config needed):
channels:
feishu:
connectionMode: "websocket" # or just omit this lineIn Feishu console: Events & Callbacks → select Long connection.
Webhook mode:
channels:
feishu:
connectionMode: "webhook"
webhookPort: 3000 # HTTP server port (default: 3000)
webhookPath: "/feishu/events" # Event callback path (default: "/feishu/events")
encryptKey: "your_encrypt_key" # From Feishu console → Events & Callbacks → Encrypt Key
verificationToken: "your_verify_token" # From Feishu console → Events & Callbacks → Verification TokenIn Feishu console: Events & Callbacks → select Request URL → set the URL to:
https://your-domain.com/feishu/eventsvar(--color-accent)]/40 pl-3 my-2 text-[var(--text-tertiary)]">Note: The Request URL must be HTTPS and publicly accessible. For local development, you can use tools like [ngrok to create a tunnel: ngrok http 3000, then use the generated URL.#### Render Mode
| Mode | Description |
|------|-------------|
| auto | (Default) Automatically detect: use card for messages with code blocks or tables, plain text otherwise. |
| raw | Always send replies as plain text. Markdown tables are converted to ASCII. |
| card | Always send replies as interactive cards with full markdown rendering (syntax highlighting, tables, clickable links). |
#### Dynamic Agent Creation (Multi-User Workspace Isolation)
When enabled, each DM user automatically gets their own isolated agent instance with a dedicated workspace. This provides complete isolation including separate conversation history, memory (MEMORY.md), and workspace files.
#### Chat Management Limitations ⚠️
Important: delete_chat requires the bot to be the group owner. If the bot was added to an existing chat as a member (not the owner), it cannot disband it.>
If you need to disband a chat that the bot does not own:
1. The group owner transfers ownership to the bot first, or
2. The group owner disbands the group directly in the Feishu app.
channels:
feishu:
dmPolicy: "open"
allowFrom: ["*"]
dynamicAgentCreation:
enabled: true
# Template for workspace directory ({userId} = OpenID, {agentId} = generated agent ID)
workspaceTemplate: "~/workspaces/feishu-{agentId}"
# Template for agent config directory
agentDirTemplate: "~/.openclaw/agents/{agentId}/agent"
# Optional: limit total number of dynamic agents
maxAgents: 100
session:
# Also set dmScope for session isolation (conversation history)
dmScope: "per-peer"| Option | Description |
|--------|-------------|
| enabled | Enable dynamic agent creation for DM users |
| workspaceTemplate | Template for workspace path. Supports {userId} (OpenID) and {agentId} (= feishu-{openId}) |
| agentDirTemplate | Template for agent directory path |
| maxAgents | Optional limit on number of dynamic agents |
How it works:
openclaw.jsonDifference from dmScope: "per-peer":
dmScope: "per-peer" only isolates conversation historydynamicAgentCreation provides full isolation (workspace, memory, identity, tools)Features
create_and_write / import_document flows for reliable create+content write/base/ and /wiki/ URLsfeishu_chat)feishu_urgentfeishu_message)feishu_reaction)#### @Mention Forwarding
When you want the bot to @mention someone in its reply, simply @mention them in your message:
@张三 say hello → Bot replies with @张三 Hello!@bot @张三 say hello → Bot replies with @张三 Hello!The bot automatically detects @mentions in your message and includes them in its reply. No extra permissions required beyond the standard messaging permissions.
FAQ
#### Bot cannot receive messages
Check the following:
connectionMode?-
websocket → Long connection in Feishu console-
webhook → Request URL in Feishu console (URL must be reachable)im.message.receive_v1 event?#### requireMention: false but group still needs @
Check the following:
im:message.group_msg approved? (sensitive permission, required for non-@ group messages)allowMentionlessInMultiBotGroup: true?requireMention: false configured on the effective account/group?#### 403 error when sending messages
Ensure im:message:send_as_bot permission is approved.
#### How to clear history / start new conversation
Send /new command in the chat.
#### Why is the output not streaming
Feishu API has rate limits. Streaming updates can easily trigger throttling. We use complete-then-send approach for stability.
#### Cannot find the bot in Feishu
---