Overview
FeishuChannelExtension bridges inbound messages from a Feishu (Lark) bot into the VeADK Runner.
This page treats Feishu as an inbound message channel: messages from Feishu users trigger the agent. To let the agent call Feishu capabilities, see Feishu tools.
Runner’s user identity, and the thread the message belongs to becomes the session identity; when there is no thread, it falls back to the current group or direct chat as the session. In 1.0.5 it extracts text from plain messages, interactive cards, and merged-forward messages and supports the synchronous Channel SDK lifecycle.
When an incoming message belongs to a Feishu thread or is a reply, the extension automatically fetches the thread history or the quoted parent message and prepends that context to the user message before forwarding it to the agent. See Thread history and quoted messages.
Environment & prerequisites
Installation:TOOL_FEISHU_CHANNEL_APP_IDTOOL_FEISHU_CHANNEL_APP_SECRETTOOL_FEISHU_CHANNEL_TRANSPORT: defaults towsTOOL_FEISHU_CHANNEL_STREAMING: whether to enable streaming output, defaults tofalseTOOL_FEISHU_CHANNEL_REACTIONS: whether to reply with a “received” reaction on incoming messages, defaults tofalseTOOL_FEISHU_CHANNEL_RECONNECT_INTERVAL: seconds to wait before reconnecting after the WebSocket disconnects, defaults to3TOOL_FEISHU_CHANNEL_DRAIN_TIMEOUT: maximum seconds to wait for already-received messages to finish during a graceful shutdown, defaults to300
config.yaml:
config.yaml
Usage
examples/channel/feishu_bot.py
Graceful shutdown
FeishuChannelExtension exposes dedicated lifecycle methods to manage the WebSocket connection from ASGI application (FastAPI, Starlette) startup and shutdown hooks, so that rolling updates or process exits do not drop in-flight Feishu messages.
Shutdown runs in two steps: first the WebSocket is closed so no new messages are accepted (Feishu re-routes new events to another instance that still holds a connection), then already-received messages are allowed to finish replying. Replies are sent over the Feishu OpenAPI HTTP client, which does not depend on the WebSocket, so messages received before shutdown still reply normally.
Long-connection scripts that only call
connect() directly do not need start() / shutdown(); this is fine for simple scripts where draining messages on exit is unnecessary. Use start() and shutdown() only when hosting the channel inside an ASGI service that needs graceful shutdown.Usage example
Callstart() and shutdown() from the ASGI app’s startup and shutdown hooks:
examples/channel/feishu_asgi.py
Methods
Environment variables
Parameters
Thread history and quoted messages
When an incoming message comes from a Feishu thread or is a reply, the extension fetches the relevant context and prepends it to the user message before forwarding it to the agent:- Thread history: when the message belongs to a thread, the extension fetches the thread’s history ordered oldest-first (up to
thread_history_limitmessages, excluding the current message) and prepends it as thread context. - Quoted message: when the message is a reply but does not belong to a thread, the extension fetches the quoted parent message; if the parent cannot be fetched, it falls back to the root message of the reply chain and prepends it as quoted context.
Fetching thread history and quoted messages requires calling Feishu OpenAPI message endpoints, so
app_id and app_secret must be configured (constructor parameters, or the TOOL_FEISHU_CHANNEL_APP_ID / TOOL_FEISHU_CHANNEL_APP_SECRET environment variables, falling back to TOOL_LARK_ENDPOINT / TOOL_LARK_API_KEY). When credentials are not configured the capability is skipped silently without raising an error.Usage example
Save and configure thefeishu_bot.py example above, then create the following file in the same directory:
examples/channel/feishu_bot_thread.py
examples/channel/feishu_bot_plain.py
Notes
- The Feishu WebSocket long-connection mode is used by default, so as long as the bot has subscribed to message events, you can start the connection directly.
- Replies are sent as replies to the original message by default, keeping VeADK output attached to the current Feishu message thread.
- Override the default identity mapping via
session_id_factoryanduser_id_factory. connect()anddisconnect()support both async clients and synchronous Channel SDK clients exposingstart()/stop().- When streaming output is enabled, reply content is concatenated directly from delta chunks and is no longer corrupted or truncated by the dedup heuristic.