@openhermit/channel-lark
v0.1.0
Published
OpenHermit channel plugin for Lark / Feishu (飞书). WebSocket long-connection event subscription — no public URL required. Text and media in both directions; group @mention gating; supports both open.feishu.cn and open.larksuite.com tenants.
Downloads
24
Maintainers
Readme
@openhermit/channel-lark
OpenHermit channel plugin for Lark / 飞书 (Feishu).
Two event delivery modes:
- WebSocket long connection (default) — no public URL, webhook, or tunnel required; the gateway only needs outbound internet access.
- Webhook — events POST to the gateway's public webhook route. Use when you already run behind a public HTTPS URL and prefer push delivery.
Supports both platforms: 飞书 (open.feishu.cn, China) and
Lark international (open.larksuite.com) — pick via the domain config.
Features
- Text messages in both directions (long replies auto-chunked)
- Inbound images / files / audio → session attachments (vision input for images)
- Outbound agent attachments → native Lark image / file messages
- Group chats with @mention gating (the agent replies only when @mentioned)
/new(or@bot newin groups) starts a fresh conversationsession_sendreachability vialark_chat_idsession metadata
Install
hermit channel install @openhermit/channel-lark
# restart the gateway to load the pluginLark app setup (one app per agent!)
⚠️ Lark allows one live WebSocket connection per app. Two gateways (or two agents) sharing an app_id will fight over the connection ("system busy"). Create a separate app for each agent — same rule as one Telegram bot token per agent.
- Create a self-built app in the Developer Console
(or open.larksuite.com for international
tenants). Note the App ID (
cli_…) and App Secret. - Add the Bot capability (App features → Bot).
- Grant permissions (Permissions & Scopes). Minimum set:
im:message— send messagesim:message.p2p_msg— receive DMsim:message.group_at_msg— receive group @mentions (without this the bot receives nothing in groups — the most common misconfiguration)im:resource— upload/download message images & files
- Subscribe to events (Event Subscriptions), then add the event
im.message.receive_v1. Pick the delivery mode:- WebSocket (default): choose “Receive events through a persistent connection” in the Console.
- Webhook: choose “Send events to a Request URL”. The exact URL to
paste (
…/api/agents/<id>/channels/lark/webhook) is printed in the channel logs at start — it needsOPENHERMIT_GATEWAY_PUBLIC_URLset on the gateway. Copy the Console's Encrypt Key / Verification Token into theLARK_ENCRYPT_KEY/LARK_VERIFICATION_TOKENsecrets (recommended; events are then decrypted and signature-checked).
- Publish an app version and approve it — permissions and events only take effect on a released version.
- In the OpenHermit admin UI, enable the Lark / 飞书 channel on the
agent: paste the App ID, pick the platform (飞书 / Lark), and set
the App Secret secret (
LARK_APP_SECRET).
Config
Stored in the agent's channel row:
{
"app_id": "cli_a1b2c3d4…",
"app_secret": "${{LARK_APP_SECRET}}",
"domain": "feishu",
"mode": "ws",
"encrypt_key": "${{LARK_ENCRYPT_KEY}}",
"verification_token": "${{LARK_VERIFICATION_TOKEN}}"
}| Field | Values | Notes |
| --- | --- | --- |
| app_id | cli_… | Developer Console → Credentials & Basic Info |
| app_secret | secret ref | via the LARK_APP_SECRET agent secret |
| domain | feishu (default) | lark | which platform your tenant lives on |
| mode | ws (default) | webhook | event delivery; webhook needs a public gateway URL |
| encrypt_key | optional secret ref | webhook mode: decrypt + signature-check events |
| verification_token | optional secret ref | webhook mode: challenge token check |
Troubleshooting
| Symptom | Cause |
| --- | --- |
| Bot silent in groups, DMs fine | im:message.group_at_msg permission missing, or the app version wasn't republished after adding it |
| “system busy” / connection churn in logs | another process holds the app's WS connection — one app per agent |
| bot info failed at startup | wrong App ID/Secret, Bot capability not added, or app not published |
| Replies work but session_send can't reach the chat | the session predates this plugin — send one message in the chat to stamp lark_chat_id metadata |
Not yet supported
- Interactive cards / rich-post outbound (replies are plain text)
- Sender display names (needs
contact:user.base:readonly; planned) - Inbound voice STT transcription (audio arrives as a file attachment)
