Skip to content

Connecting OpenClaw to Feishu via WebSocket

Feishu comes bundled with current OpenClaw releases, so you don’t need to worry about a separate plugin installation.

If you happen to be using an older build or a custom setup that doesn’t include it, you can install it manually:

Terminal window
openclaw plugins install @openclaw/feishu

You have two ways to get your Feishu channel up and running:

If you just finished installing OpenClaw, run the onboarding wizard:

Terminal window
openclaw onboard

The wizard will walk you through:

  1. Creating a Feishu app and grabbing your credentials
  2. Setting up those credentials in OpenClaw
  3. Starting the gateway

✅ After configuration, you can check the gateway status:

Terminal window
- `openclaw gateway status`
- `openclaw logs --follow`

If you’ve already done the initial install, you can add the channel directly via the CLI:

Terminal window
openclaw channels add

Choose Feishu, then type in your App ID and App Secret.

✅ After configuration, you can manage the gateway with these:

Terminal window
- `openclaw gateway status`
- `openclaw gateway restart`
- `openclaw logs --follow`

Head over to the Feishu Open Platform and sign in.

If you are using Lark (the global version), use https://open.larksuite.com/app instead and remember to set domain: "lark" in your Feishu config later.

  1. Click Create enterprise app
  2. Give your app a name and description
  3. Pick an icon for your bot

Create enterprise app

Go to Credentials & Basic Info and copy these:

  • App ID (it looks like cli_xxx)
  • App Secret

❗ Important: keep your App Secret private.

Get credentials

In the Permissions section, click Batch import and paste this JSON:

{
"scopes": {
"tenant": [
"aily:file:read",
"aily:file:write",
"application:application.app_message_stats.overview:readonly",
"application:application:self_manage",
"application:bot.menu:write",
"cardkit:card:read",
"cardkit:card:write",
"contact:user.employee_id:readonly",
"corehr:file:download",
"event:ip_list",
"im:chat.access_event.bot_p2p_chat:read",
"im:chat.members:bot_access",
"im:message",
"im:message.group_at_msg:readonly",
"im:message.p2p_msg:readonly",
"im:message:readonly",
"im:message:send_as_bot",
"im:resource"
],
"user": ["aily:file:read", "aily:file:write", "im:chat.access_event.bot_p2p_chat:read"]
}
}

Configure permissions

Go to App Capability > Bot:

  1. Turn on the bot capability
  2. Give your bot a name

Enable bot capability

⚠️ Important: before you set this up, make sure:

  1. You already ran openclaw channels add for Feishu
  2. Your gateway is actually running (openclaw gateway status)

In Event Subscription:

  1. Select Use long connection to receive events (this uses WebSocket)
  2. Add the event: im.message.receive_v1
  3. (Optional) If you want Drive comment workflows, add: drive.notice.comment_add_v1

⚠️ If your gateway isn’t running, Feishu might fail to save the long-connection setup.

Configure event subscription

  1. Create a new version in Version Management & Release
  2. Submit it for review and publish it
  3. Wait for admin approval (enterprise apps are often auto-approved)
Terminal window
openclaw channels add

Pick Feishu and paste your App ID and App Secret.

You can also edit ~/.openclaw/openclaw.json directly:

{
channels: {
feishu: {
enabled: true,
dmPolicy: "pairing",
accounts: {
main: {
appId: "cli_xxx",
appSecret: "xxx",
name: "My AI assistant",
},
},
},
},
}

If you decide to use connectionMode: "webhook", you need to set both verificationToken and encryptKey. The Feishu webhook server binds to 127.0.0.1 by default; only change webhookHost if you really need a different address.

Verification Token and Encrypt Key (webhook mode)

Section titled “Verification Token and Encrypt Key (webhook mode)”

When you use webhook mode, you’ll need to add channels.feishu.verificationToken and channels.feishu.encryptKey to your config. Here is how to find them:

  1. Open your app in the Feishu Open Platform
  2. Go to Development → Events & Callbacks (开发配置 → 事件与回调)
  3. Open the Encryption tab (加密策略)
  4. Copy the Verification Token and Encrypt Key

The image below shows where the Verification Token lives. You’ll find the Encrypt Key in that same section.

Verification Token location

You can also use environment variables if you prefer:

Terminal window
export FEISHU_APP_ID="cli_xxx"
export FEISHU_APP_SECRET="xxx"

If your team is on Lark, set the domain to lark. You can do this globally at channels.feishu.domain or specifically for one account:

{
channels: {
feishu: {
domain: "lark",
accounts: {
main: {
appId: "cli_xxx",
appSecret: "xxx",
},
},
},
},
}

If you want to save on Feishu API usage, you can use these two optional flags:

  • typingIndicator (defaults to true): set to false to stop sending typing status.
  • resolveSenderNames (defaults to true): set to false to skip looking up user profiles.

You can set these at the top level or per account:

{
channels: {
feishu: {
typingIndicator: false,
resolveSenderNames: false,
accounts: {
main: {
appId: "cli_xxx",
appSecret: "xxx",
typingIndicator: true,
resolveSenderNames: false,
},
},
},
},
}

You’ve finished the configuration, so let’s get everything running and verify that it works.

Run this command to bring the gateway online:

Terminal window
openclaw gateway

Open Feishu, find your bot, and send it a message to wake it up.

By default, the bot will reply with a pairing code for security. You need to approve it manually:

Terminal window
openclaw pairing approve feishu <CODE>

After you approve the code, you can chat with the bot normally.


Here is how the Feishu integration handles your data and connections:

  • Feishu bot channel: The gateway manages the Feishu bot directly.
  • Deterministic routing: Your replies always return to the correct Feishu conversation.
  • Session isolation: Direct messages share a main session, while group chats are kept isolated from each other.
  • WebSocket connection: The system uses a long connection via the Feishu SDK, so you don’t need to set up a public URL or handle incoming webhooks.

You can manage exactly who is allowed to interact with your bot.

  • Default: The system uses dmPolicy: "pairing", meaning unknown users will receive a pairing code.

  • Approve pairing: Use these commands to see pending requests and allow them:

    Terminal window
    openclaw pairing list feishu
    openclaw pairing approve feishu <CODE>
  • Allowlist mode: If you want to bypass pairing for specific people, set channels.feishu.allowFrom with their Open IDs.

1. Group policy (channels.feishu.groupPolicy):

  • "open": This allows everyone in a group to use the bot.
  • "allowlist": The bot only responds to groups listed in groupAllowFrom.
  • "disabled": This turns off group message processing entirely.

The default setting is allowlist.

2. Mention requirement (channels.feishu.requireMention):

You can control this globally or override it per group using channels.feishu.groups.<chat_id>.requireMention:

  • true: The bot only responds when someone @mentions it.
  • false: The bot listens and responds to all messages in the group.
  • When unset and groupPolicy is "open": It defaults to false.
  • When unset and groupPolicy is anything else: It defaults to true.

Here are a few ways you can set up your group chat logic.

Allow all groups, no @mention required (default for open groups)

Section titled “Allow all groups, no @mention required (default for open groups)”
{
channels: {
feishu: {
groupPolicy: "open",
},
},
}

Allow all groups, but still require @mention

Section titled “Allow all groups, but still require @mention”
{
channels: {
feishu: {
groupPolicy: "open",
requireMention: true,
},
},
}
{
channels: {
feishu: {
groupPolicy: "allowlist",
// Feishu group IDs (chat_id) look like: oc_xxx
groupAllowFrom: ["oc_xxx", "oc_yyy"],
},
},
}

Restrict which senders can message in a group (sender allowlist)

Section titled “Restrict which senders can message in a group (sender allowlist)”

You can gate messages at the sender level. Even if a group is allowed, only users listed in groups.<chat_id>.allowFrom will have their messages processed. The bot will ignore everyone else.

{
channels: {
feishu: {
groupPolicy: "allowlist",
groupAllowFrom: ["oc_xxx"],
groups: {
oc_xxx: {
// Feishu user IDs (open_id) look like: ou_xxx
allowFrom: ["ou_user1", "ou_user2"],
},
},
},
},
}

AI Setup Assistant

To route messages correctly, you need to identify where they are coming from. You will mainly deal with two types of IDs.

Group IDs identify specific group chats and typically start with oc_xxx.

Method 1 (recommended)

This is the most straightforward approach. Start your gateway and @mention the bot inside the group. Then, run this command to find the chat_id in your terminal:

openclaw logs --follow

Method 2

You can also use the Feishu API debugger to list your group chats and find the IDs there.

User IDs identify individual users and look like ou_xxx.

Method 1 (recommended)

Start the gateway and send a direct message to the bot. Run the logs command to see your open_id:

openclaw logs --follow

Method 2

You can check pairing requests to find user Open IDs by running:

Terminal window
openclaw pairing list feishu

Once your bot is live, you can interact with it using these standard commands:

CommandDescription
/statusShow bot status
/resetReset the session
/modelShow/switch model

Feishu does not support native command menus yet, so you need to send these commands as regular text messages.

Managing your gateway shouldn’t be a chore. You can handle the service lifecycle and check on its health using these specific commands.

CommandDescription
openclaw gateway statusShow gateway status
openclaw gateway installInstall/start gateway service
openclaw gateway stopStop gateway service
openclaw gateway restartRestart gateway service
openclaw logs --followTail gateway logs

If things aren’t working as expected, it’s usually a quick fix. Here are the most common scenarios you might run into and how to solve them.

If your bot is silent in a group, check these four things:

  1. Make sure you’ve actually added the bot to the group.
  2. Remember to @mention the bot, as that’s the default way it listens.
  3. Double-check that groupPolicy isn’t set to "disabled".
  4. Run openclaw logs --follow to see what’s happening behind the scenes.

When messages aren’t reaching your bot, go through this checklist:

  1. Confirm your app is published and has been approved.
  2. Verify your event subscriptions include im.message.receive_v1.
  3. Make sure you have long connection turned on.
  4. Check that all required app permissions are granted.
  5. Use openclaw gateway status to see if the gateway is actually running.
  6. Look at the logs with openclaw logs --follow.

If your secret is compromised, you need to act fast:

  1. Reset the App Secret in Feishu Open Platform.
  2. Update the App Secret in your config.
  3. Restart the gateway.

If the bot can’t send messages out, check these points:

  1. Ensure the app has im:message:send_as_bot permission.
  2. Ensure the app is published.
  3. Check logs for detailed errors.

If you need to go beyond a basic setup, you can customize how your Feishu integration behaves. This includes managing multiple bots, setting message size limits, and handling how text streams to your users.

You can run multiple Feishu bots within a single instance. This is great if you need a primary bot and a backup, or different bots for different environments.

{
channels: {
feishu: {
defaultAccount: "main",
accounts: {
main: {
appId: "cli_xxx",
appSecret: "xxx",
name: "Primary bot",
},
backup: {
appId: "cli_yyy",
appSecret: "yyy",
name: "Backup bot",
enabled: false,
},
},
},
},
}

The defaultAccount setting determines which account handles outbound API calls if you don’t specify an accountId in your code.

You can control the size of the data your bot sends and receives using these two settings:

  • textChunkLimit: This sets the size for outbound text chunks. It defaults to 2000 characters.
  • mediaMaxMb: This limits media uploads and downloads. The default is 30MB.

Feishu supports streaming replies through interactive cards. When you turn this on, your bot updates the message card in real-time as it generates text, which makes the experience feel much faster.

{
channels: {
feishu: {
streaming: true, // enable streaming card output (default true)
blockStreaming: true, // enable block-level streaming (default true)
},
},
}

If you prefer to wait for the entire response before sending it, just set streaming: false.

Feishu supports ACP for direct messages and group topic conversations.

Because Feishu doesn’t have native slash-command menus, ACP here is entirely text-command driven. You can interact with it by typing /acp ... commands directly into your chat.

You can pin a specific Feishu DM or a topic conversation to a persistent ACP session. This ensures that the conversation always stays connected to the right agent and workspace.

{
agents: {
list: [
{
id: "codex",
runtime: {
type: "acp",
acp: {
agent: "codex",
backend: "acpx",
mode: "persistent",
cwd: "/workspace/openclaw",
},
},
},
],
},
bindings: [
{
type: "acp",
agentId: "codex",
match: {
channel: "feishu",
accountId: "default",
peer: { kind: "direct", id: "ou_1234567890" },
},
},
{
type: "acp",
agentId: "codex",
match: {
channel: "feishu",
accountId: "default",
peer: { kind: "group", id: "oc_group_chat:topic:om_topic_root" },
},
acp: { label: "codex-feishu-topic" },
},
],
}

If you are already in a DM or a topic conversation, you can spawn and bind an ACP session on the spot with a simple command:

/acp spawn codex --thread here

A few things to keep in mind:

  • The --thread here flag is designed for DMs and Feishu topics.
  • Once bound, any follow-up messages in that DM or topic go straight to that ACP session.
  • Note that v1 does not support generic non-topic group chats for this feature.

You can use bindings to direct different Feishu DMs or groups to specific agents. This is useful if you want one bot for your dev team and another for your support team.

{
agents: {
list: [
{ id: "main" },
{
id: "clawd-fan",
workspace: "/home/user/clawd-fan",
agentDir: "/home/user/.openclaw/agents/clawd-fan/agent",
},
{
id: "clawd-xi",
workspace: "/home/user/clawd-xi",
agentDir: "/home/user/.openclaw/agents/clawd-xi/agent",
},
],
},
bindings: [
{
agentId: "main",
match: {
channel: "feishu",
peer: { kind: "direct", id: "ou_xxx" },
},
},
{
agentId: "clawd-fan",
match: {
channel: "feishu",
peer: { kind: "direct", id: "ou_yyy" },
},
},
{
agentId: "clawd-xi",
match: {
channel: "feishu",
peer: { kind: "group", id: "oc_zzz" },
},
},
],
}

When setting up routing, you’ll use these fields:

  • match.channel: Set this to "feishu".
  • match.peer.kind: Use "direct" for users or "group" for chats.
  • match.peer.id: This is the user’s Open ID (ou_xxx) or the group ID (oc_xxx).

If you need help finding these IDs, check out the Get group/user IDs section.

For a look at every available option, you can check the Gateway configuration page. Here are the key settings for Feishu:

SettingDescriptionDefault
channels.feishu.enabledEnable/disable channeltrue
channels.feishu.domainAPI domain (feishu or lark)feishu
channels.feishu.connectionModeEvent transport modewebsocket
channels.feishu.defaultAccountDefault account ID for outbound routingdefault
channels.feishu.verificationTokenRequired for webhook mode-
channels.feishu.encryptKeyRequired for webhook mode-
channels.feishu.webhookPathWebhook route path/feishu/events
channels.feishu.webhookHostWebhook bind host127.0.0.1
channels.feishu.webhookPortWebhook bind port3000
channels.feishu.accounts.<id>.appIdApp ID-
channels.feishu.accounts.<id>.appSecretApp Secret-
channels.feishu.accounts.<id>.domainPer-account API domain overridefeishu
channels.feishu.dmPolicyDM policypairing
channels.feishu.allowFromDM allowlist (open_id list)-
channels.feishu.groupPolicyGroup policyallowlist
channels.feishu.groupAllowFromGroup allowlist-
channels.feishu.requireMentionDefault require @mentionconditional
channels.feishu.groups.<chat_id>.requireMentionPer-group require @mention overrideinherited
channels.feishu.groups.<chat_id>.enabledEnable grouptrue
channels.feishu.textChunkLimitMessage chunk size2000
channels.feishu.mediaMaxMbMedia size limit30
channels.feishu.streamingEnable streaming card outputtrue
channels.feishu.blockStreamingEnable block streamingtrue

When you’re setting up how your bot handles direct messages, you need to pick a dmPolicy. This setting controls who can actually talk to your bot and how they get access.

ValueBehavior
"pairing"Default. Unknown users get a pairing code; must be approved
"allowlist"Only users in allowFrom can chat
"open"Allow all users (requires "*" in allowFrom)
"disabled"Disable DMs

I recommend sticking with "pairing" if you want a balance of security and accessibility. It’s the default for a reason—it ensures you don’t get spammed while still letting new users connect after a quick approval. If you need a private bot for a specific team, "allowlist" is your best bet.

Knowing what data your bot can handle helps you build better interactions. Here is the breakdown of what is currently supported for receiving and sending.

Your bot can pick up almost anything a user throws at it:

  • ✅ Text
  • ✅ Rich text (post)
  • ✅ Images
  • ✅ Files
  • ✅ Audio
  • ✅ Video/media
  • ✅ Stickers

When your bot talks back, you have plenty of options, though there are some limits on complex formatting:

  • ✅ Text
  • ✅ Images
  • ✅ Files
  • ✅ Audio
  • ✅ Video/media
  • ✅ Interactive cards
  • ⚠️ Rich text (post-style formatting and cards, not arbitrary Feishu authoring features)

Keeping conversations organized is easy with these features:

  • ✅ Inline replies
  • ✅ Topic-thread replies where Feishu exposes reply_in_thread
  • ✅ Media replies stay thread-aware when replying to a thread/topic message

Feishu can trigger your agent whenever someone adds a comment on a Feishu Drive document, like Docs or Sheets. Your agent receives the comment text and document context, along with the sender info and the comment thread. This allows it to respond directly in the thread or make document edits.

To get started, you need to follow these requirements:

  • Subscribe to drive.notice.comment_add_v1 in your Feishu app event subscription settings. Keep your existing im.message.receive_v1 subscription active as well.
  • The Drive tool is enabled by default. If you need to turn it off, use channels.feishu.tools.drive: false.

The feishu_drive tool exposes these comment actions:

ActionDescription
list_commentsList comments on a document
list_comment_repliesList replies in a comment thread
add_commentAdd a new top-level comment
reply_commentReply to an existing comment thread

When your agent handles a Drive comment event, it receives:

  • The comment text and the sender
  • Document metadata (including title, type, URL, and context)
  • The comment thread context for in-thread replies
  • Document edit permissions

After making document edits, I recommend guiding the agent to use feishu_drive.reply_comment to notify the commenter. You should then output NO_REPLY to avoid sending duplicate messages.

Feishu currently exposes these runtime actions for your agent:

  • send
  • read
  • edit
  • thread-reply
  • pin
  • list-pins
  • unpin
  • member-info
  • channel-info
  • channel-list
  • react and reactions when reactions are enabled in config
  • feishu_drive comment actions: list_comments, list_comment_replies, add_comment, reply_comment

AI Setup Assistant

OpenClaw

OpenClaw Expert

Still stuck?

If this page didn't answer your case, ask OpenClaw Expert for step-by-step guidance.