Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt

Use this file to discover all available pages before exploring further.

Feishu/Lark is an all-in-one collaboration platform where teams chat, share documents, manage calendars, and get work done together. Status: production-ready for bot DMs + group chats. WebSocket is the default mode; webhook mode is optional.

Quick start

Requires OpenClaw 2026.4.25 or above. Run openclaw --version to check. Upgrade with openclaw update.
1

Run the channel setup wizard

openclaw channels login --channel feishu
Choose manual setup to paste an App ID and App Secret from Feishu Open Platform, or choose QR setup to create a bot automatically. If the domestic Feishu mobile app does not react to the QR code, rerun setup and choose manual setup.
2

After setup completes, restart the gateway to apply the changes

openclaw gateway restart

Access control

Direct messages

Configure dmPolicy to control who can DM the bot:
  • "pairing" - unknown users receive a pairing code; approve via CLI
  • "allowlist" - only users listed in allowFrom can chat (default: bot owner only)
  • "open" - allow public DMs only when allowFrom includes "*"; with restrictive entries, only matching users can chat
  • "disabled" - disable all DMs
Approve a pairing request:
openclaw pairing list feishu
openclaw pairing approve feishu <CODE>

Group chats

Group policy (channels.feishu.groupPolicy):
ValueBehavior
"open"Respond to all messages in groups
"allowlist"Only respond to groups in groupAllowFrom or explicitly configured under groups.<chat_id>
"disabled"Disable all group messages; explicit groups.<chat_id> entries do not override this
Default: allowlist Mention requirement (channels.feishu.requireMention):
  • true - require @mention (default)
  • false - respond without @mention
  • Per-group override: channels.feishu.groups.<chat_id>.requireMention
  • Broadcast-only @all and @_all are not treated as bot mentions. A message that mentions both @all and the bot directly still counts as a bot mention.

Group configuration examples

Allow all groups, no @mention required

{
  channels: {
    feishu: {
      groupPolicy: "open",
    },
  },
}

Allow all groups, still require @mention

{
  channels: {
    feishu: {
      groupPolicy: "open",
      requireMention: true,
    },
  },
}

Allow specific groups only

{
  channels: {
    feishu: {
      groupPolicy: "allowlist",
      // Group IDs look like: oc_xxx
      groupAllowFrom: ["oc_xxx", "oc_yyy"],
    },
  },
}
In allowlist mode, you can also admit a group by adding an explicit groups.<chat_id> entry. Explicit entries do not override groupPolicy: "disabled". Wildcard defaults under groups.* configure matching groups, but they do not admit groups by themselves.
{
  channels: {
    feishu: {
      groupPolicy: "allowlist",
      groups: {
        oc_xxx: {
          requireMention: false,
        },
      },
    },
  },
}

Restrict senders within a group

{
  channels: {
    feishu: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["oc_xxx"],
      groups: {
        oc_xxx: {
          // User open_ids look like: ou_xxx
          allowFrom: ["ou_user1", "ou_user2"],
        },
      },
    },
  },
}

Get group/user IDs

Group IDs (chat_id, format: oc_xxx)

Open the group in Feishu/Lark, click the menu icon in the top-right corner, and go to Settings. The group ID (chat_id) is listed on the settings page. Get Group ID

User IDs (open_id, format: ou_xxx)

Start the gateway, send a DM to the bot, then check the logs:
openclaw logs --follow
Look for open_id in the log output. You can also check pending pairing requests:
openclaw pairing list feishu

Common commands

CommandDescription
/statusShow bot status
/resetReset the current session
/modelShow or switch the AI model
Feishu/Lark does not support native slash-command menus, so send these as plain text messages.

Troubleshooting

Bot does not respond in group chats

  1. Ensure the bot is added to the group
  2. Ensure you @mention the bot (required by default)
  3. Verify groupPolicy is not "disabled"
  4. Check logs: openclaw logs --follow

Bot does not receive messages

  1. Ensure the bot is published and approved in Feishu Open Platform / Lark Developer
  2. Ensure event subscription includes im.message.receive_v1
  3. Ensure persistent connection (WebSocket) is selected
  4. Ensure all required permission scopes are granted
  5. Ensure the gateway is running: openclaw gateway status
  6. Check logs: openclaw logs --follow

QR setup does not react in the Feishu mobile app

  1. Rerun setup: openclaw channels login --channel feishu
  2. Choose manual setup
  3. In Feishu Open Platform, create a self-built app and copy its App ID and App Secret
  4. Paste those credentials into the setup wizard

App Secret leaked

  1. Reset the App Secret in Feishu Open Platform / Lark Developer
  2. Update the value in your config
  3. Restart the gateway: openclaw gateway restart

Advanced configuration

Multiple accounts

{
  channels: {
    feishu: {
      defaultAccount: "main",
      accounts: {
        main: {
          appId: "cli_xxx",
          appSecret: "xxx",
          name: "Primary bot",
          tts: {
            providers: {
              openai: { voice: "shimmer" },
            },
          },
        },
        backup: {
          appId: "cli_yyy",
          appSecret: "yyy",
          name: "Backup bot",
          enabled: false,
        },
      },
    },
  },
}
defaultAccount controls which account is used when outbound APIs do not specify an accountId. accounts.<id>.tts uses the same shape as messages.tts and deep-merges over global TTS config, so multi-bot Feishu setups can keep shared provider credentials globally while overriding only voice, model, persona, or auto mode per account.

Message limits

  • textChunkLimit - outbound text chunk size (default: 2000 chars)
  • mediaMaxMb - media upload/download limit (default: 30 MB)

Streaming

Feishu/Lark supports streaming replies via interactive cards. When enabled, the bot updates the card in real time as it generates text.
{
  channels: {
    feishu: {
      streaming: true, // enable streaming card output (default: true)
      blockStreaming: true, // opt into completed-block streaming
    },
  },
}
Set streaming: false to send the complete reply in one message. blockStreaming is off by default; enable it only when you want completed assistant blocks flushed before the final reply.

Quota optimization

Reduce the number of Feishu/Lark API calls with two optional flags:
  • typingIndicator (default true): set false to skip typing reaction calls
  • resolveSenderNames (default true): set false to skip sender profile lookups
{
  channels: {
    feishu: {
      typingIndicator: false,
      resolveSenderNames: false,
    },
  },
}

ACP sessions

Feishu/Lark supports ACP for DMs and group thread messages. Feishu/Lark ACP is text-command driven - there are no native slash-command menus, so use /acp ... messages directly in the conversation.

Persistent ACP binding

{
  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" },
    },
  ],
}

Spawn ACP from chat

In a Feishu/Lark DM or thread:
/acp spawn codex --thread here
--thread here works for DMs and Feishu/Lark thread messages. Follow-up messages in the bound conversation route directly to that ACP session.

Multi-agent routing

Use bindings to route Feishu/Lark DMs or groups to different agents.
{
  agents: {
    list: [
      { id: "main" },
      { id: "agent-a", workspace: "/home/user/agent-a" },
      { id: "agent-b", workspace: "/home/user/agent-b" },
    ],
  },
  bindings: [
    {
      agentId: "agent-a",
      match: {
        channel: "feishu",
        peer: { kind: "direct", id: "ou_xxx" },
      },
    },
    {
      agentId: "agent-b",
      match: {
        channel: "feishu",
        peer: { kind: "group", id: "oc_zzz" },
      },
    },
  ],
}
Routing fields:
  • match.channel: "feishu"
  • match.peer.kind: "direct" (DM) or "group" (group chat)
  • match.peer.id: user Open ID (ou_xxx) or group ID (oc_xxx)
See Get group/user IDs for lookup tips.

Configuration reference

Full configuration: Gateway configuration
SettingDescriptionDefault
channels.feishu.enabledEnable/disable the channeltrue
channels.feishu.domainAPI domain (feishu or lark)feishu
channels.feishu.connectionModeEvent transport (websocket or webhook)websocket
channels.feishu.defaultAccountDefault account 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 domain overridefeishu
channels.feishu.accounts.<id>.ttsPer-account TTS overridemessages.tts
channels.feishu.dmPolicyDM policyallowlist
channels.feishu.allowFromDM allowlist (open_id list)[BotOwnerId]
channels.feishu.groupPolicyGroup policyallowlist
channels.feishu.groupAllowFromGroup allowlist-
channels.feishu.requireMentionRequire @mention in groupstrue
channels.feishu.groups.<chat_id>.requireMentionPer-group @mention override; explicit IDs also admit the group in allowlist modeinherited
channels.feishu.groups.<chat_id>.enabledEnable/disable a specific grouptrue
channels.feishu.textChunkLimitMessage chunk size2000
channels.feishu.mediaMaxMbMedia size limit30
channels.feishu.streamingStreaming card outputtrue
channels.feishu.blockStreamingCompleted-block reply streamingfalse
channels.feishu.typingIndicatorSend typing reactionstrue
channels.feishu.resolveSenderNamesResolve sender display namestrue

Supported message types

Receive

  • ✅ Text
  • ✅ Rich text (post)
  • ✅ Images
  • ✅ Files
  • ✅ Audio
  • ✅ Video/media
  • ✅ Stickers
Inbound Feishu/Lark audio messages are normalized as media placeholders instead of raw file_key JSON. When tools.media.audio is configured, OpenClaw downloads the voice-note resource and runs shared audio transcription before the agent turn, so the agent receives the spoken transcript. If Feishu includes transcript text directly in the audio payload, that text is used without another ASR call. Without an audio transcription provider, the agent still receives a <media:audio> placeholder plus the saved attachment, not the raw Feishu resource payload.

Send

  • ✅ Text
  • ✅ Images
  • ✅ Files
  • ✅ Audio
  • ✅ Video/media
  • ✅ Interactive cards (including streaming updates)
  • ⚠️ Rich text (post-style formatting; doesn’t support full Feishu/Lark authoring capabilities)
Native Feishu/Lark audio bubbles use the Feishu audio message type and require Ogg/Opus upload media (file_type: "opus"). Existing .opus and .ogg media is sent directly as native audio. MP3/WAV/M4A and other likely audio formats are transcoded to 48kHz Ogg/Opus with ffmpeg only when the reply requests voice delivery (audioAsVoice / message tool asVoice, including TTS voice-note replies). Ordinary MP3 attachments stay regular files. If ffmpeg is missing or conversion fails, OpenClaw falls back to a file attachment and logs the reason.

Threads and replies

  • ✅ Inline replies
  • ✅ Thread replies
  • ✅ Media replies stay thread-aware when replying to a thread message
For groupSessionScope: "group_topic" and "group_topic_sender", native Feishu/Lark topic groups use the event thread_id (omt_*) as the canonical topic session key. If a native topic starter event omits thread_id, OpenClaw hydrates it from Feishu before routing the turn. Normal group replies that OpenClaw turns into threads keep using the reply root message ID (om_*) so the first turn and follow-up turn stay in the same session.