@openduo/channel-feishu
v0.2.11
Published
Feishu / Lark channel adapter for [duoduo](https://www.npmjs.com/package/@openduo/duoduo).
Readme
@openduo/channel-feishu
Feishu / Lark channel adapter for duoduo.
Connects duoduo to Feishu via the Feishu Open Platform WebSocket long-poll API. Requires no public URL — the gateway initiates the connection outbound.
The Feishu messaging layer in this package was written by duoduo itself, referencing openclaw as prior art (with respect). The implementation was designed from scratch to fit duoduo's channel protocol — session routing, media bridging, delivery cursors, and gateway command handling are native to this runtime.
How It Works
The Feishu gateway is an independent process that sits between the Feishu Open Platform and the duoduo daemon. It translates Feishu events into the duoduo standard protocol and vice versa.
Inbound: Feishu messages arrive via WebSocket event subscription. The gateway handles deduplication, access policy, media download, @mention normalization, and dispatch to the daemon.
Outbound: The gateway maintains a pull subscription per active chat. When the daemon produces output, the gateway renders it (plain text or interactive card), handles file upload, and sends it back to Feishu.
Media bridging: Images, files, audio, and video are downloaded from Feishu and uploaded to the daemon's file store before ingress. On egress, daemon-produced files are downloaded and re-uploaded to Feishu.
Typing indicators: Feishu has no native typing API. The gateway uses emoji reactions as staged presence signals (received → thinking → working → typing), cleaned up after each response.
Access control: Configurable DM policy (open, allowlist) and group policy (open, allowlist, disabled). Groups can require a bot @mention before the message is forwarded to the daemon.
Commands: Gateway control commands (/status, /cancel, /cd, /clear, /stats) are handled directly without routing through the agent session.
Requirements
- Node.js 20+
- A running duoduo daemon (
@openduo/duoduo) - A Feishu app with WebSocket long-poll enabled
Installation
Via duoduo CLI (recommended)
duoduo channel install @openduo/channel-feishuManual
npm install -g @openduo/channel-feishuFeishu App Setup
In the Feishu Developer Console:
- Create an app (or use an existing one).
- Enable WebSocket long-poll under Events & Callbacks → Connection mode.
- Subscribe to the
im.message.receive_v1event. - Grant the following permissions:
| Permission | Purpose |
| ---------------------------------- | --------------------------------------- |
| im:message | Send and receive messages |
| im:message.p2p_msg:readonly | Receive direct messages |
| im:message.group_at_msg:readonly | Receive @bot messages in groups |
| im:message:send_as_bot | Send messages as bot |
| im:resource | Upload and download media |
| contact:user.base:readonly | Resolve sender display names (optional) |
Configuration
All configuration is via environment variables:
| Variable | Default | Description |
| ------------------------ | ------------------------ | ------------------------------------------------ |
| FEISHU_APP_ID | — | Required. Feishu app ID |
| FEISHU_APP_SECRET | — | Required. Feishu app secret |
| FEISHU_DOMAIN | feishu | feishu, lark, or custom domain URL |
| ALADUO_DAEMON_URL | http://127.0.0.1:20233 | duoduo daemon address |
| FEISHU_DM_POLICY | open | DM access: open or allowlist |
| FEISHU_GROUP_POLICY | allowlist | Group access: open, allowlist, or disabled |
| FEISHU_REQUIRE_MENTION | true | Require @bot mention in groups |
| FEISHU_ALLOW_FROM | — | Comma-separated open_id allowlist |
| FEISHU_ALLOW_GROUPS | — | Comma-separated chat_id allowlist |
| FEISHU_RENDER_MODE | auto | Output rendering: auto, raw, or card |
| FEISHU_BOT_OPEN_ID | — | Bot's own open_id (for mention detection) |
| FEISHU_LOG_LEVEL | info | Log level |
For FEISHU_GROUP_POLICY=allowlist, FEISHU_ALLOW_FROM and FEISHU_ALLOW_GROUPS are peer entity allowlists:
- A listed
open_idmay talk to the bot in any group. - A listed
chat_idallows any member of that group to talk to the bot. - If neither list matches, the group message is denied.
Render modes:
auto— plain text by default; switches to interactive card when output contains code blocks or tables.raw— always plain text.card— always interactive card.
Usage
Via duoduo CLI
# Start (managed by duoduo)
duoduo channel feishu start
# Check status
duoduo channel feishu status
# View logs
duoduo channel feishu logs
# Stop
duoduo channel feishu stopIn host mode, duoduo channel feishu start auto-loads ~/.config/duoduo/.env before launching
the managed channel process. Put FEISHU_APP_ID, FEISHU_APP_SECRET, and optional
ALADUO_DAEMON_URL there if you want daemon and channel startup to behave consistently.
Standalone
FEISHU_APP_ID=cli_xxx \
FEISHU_APP_SECRET=xxx \
ALADUO_DAEMON_URL=http://127.0.0.1:20233 \
duoduo-feishuWhen you launch duoduo-feishu directly in host mode, the process logs a warning that
~/.config/duoduo/.env is not auto-loaded. That warning is intentional: direct standalone
launch expects you to export the environment yourself.
License
MIT
