Description
Add a Feishu/Lark adapter to the Custom Gateway, enabling OpenAB to receive and reply to messages from Feishu (China) and Lark (international).
The adapter supports two connection modes:
- WebSocket long-connection (default) — gateway connects outbound to Feishu, no public URL required
- HTTP Webhook (fallback) — for environments where outbound WebSocket is blocked
This is the first gateway adapter that uses an outbound long-connection rather than inbound webhooks.
External Internal
Telegram --POST--> ┌─────────────────┐
LINE --POST--> │ OpenAB Gateway │ <--WS-- OAB Pod
Teams --POST--> │ :8080 │
│ ┌───────────┐ │
Feishu <--WS---- │ │ Feishu WS │ │
(default) │ │ Client │ │
│ └───────────┘ │
Feishu --POST--> │ (fallback) │
└─────────────────┘
Use Case
- Chinese enterprise teams — Feishu is where most Chinese tech teams collaborate daily. Without Feishu support, OpenAB cannot serve this market.
- Private deployment without public IP — WebSocket mode lets operators run behind NAT/firewall without HTTPS endpoints or Cloudflare Tunnel.
- Multi-platform agent — Teams using both Discord and Feishu can run the same OAB agent on both platforms with per-platform @mention gating.
- Lark international — Same adapter supports Lark by setting
FEISHU_DOMAIN=lark.
Proposed Solution
Add gateway/src/adapters/feishu.rs following the existing adapter pattern:
Feishu Cloud <--WS--> Gateway (feishu.rs) <--WS--> OAB Core --> Agent
Key components:
- WebSocket: POST /callback/ws/endpoint (AppID+AppSecret auth), protobuf frame decoding (prost), JSON event extraction
- Webhook fallback: URL challenge, verification token, encrypt key (AES-256-CBC), signature verification, rate limiting
- Token management: tenant_access_token with auto-refresh
- Reactions: Map OAB emoji to Feishu reaction API on original messages
- Mention gating: Gateway-side filtering (FEISHU_REQUIRE_MENTION) + OAB-side (bot_username = bot open_id)
- Deduplication: event_id + message_id TTL cache
Inbound:
Feishu WS push (protobuf binary frame)
--> prost decode --> JSON payload
--> parse_message_event (filter bot/empty/non-text)
--> dedupe (event_id + message_id)
--> GatewayEvent broadcast --> OAB
Outbound:
OAB GatewayReply
--> handle_reply (skip reactions cmds / send text)
--> tenant_access_token (cached, auto-refresh)
--> POST /open-apis/im/v1/messages
--> Feishu user sees reply
New dependencies: prost 0.13, aes 0.8, cbc 0.1 (all pinned).
Prior Art
| Project |
Approach |
Key Takeaway |
| OpenClaw |
Built-in channel, WS default |
WS long-connection is the standard path |
| Hermes Agent |
Python adapter, WS + webhook |
Full webhook security is essential |
| larksuite/openclaw-lark |
Official plugin (TypeScript) |
Gateway = message channel only |
Related Issues
- ADR: Custom Gateway (
docs/adr/custom-gateway.md) — this adapter follows the ADR adapter interface
- LINE adapter (
gateway/src/adapters/line.rs) — pattern reference
- Teams adapter (
gateway/src/adapters/teams.rs) — aggregated state pattern reference
Description
Add a Feishu/Lark adapter to the Custom Gateway, enabling OpenAB to receive and reply to messages from Feishu (China) and Lark (international).
The adapter supports two connection modes:
This is the first gateway adapter that uses an outbound long-connection rather than inbound webhooks.
Use Case
FEISHU_DOMAIN=lark.Proposed Solution
Add
gateway/src/adapters/feishu.rsfollowing the existing adapter pattern:Key components:
New dependencies:
prost 0.13,aes 0.8,cbc 0.1(all pinned).Prior Art
Related Issues
docs/adr/custom-gateway.md) — this adapter follows the ADR adapter interfacegateway/src/adapters/line.rs) — pattern referencegateway/src/adapters/teams.rs) — aggregated state pattern reference