docs(feishu): document long connection mode
This commit is contained in:
parent
1f7d41183d
commit
e9eda754b4
@ -2,12 +2,12 @@
|
||||
summary: "Feishu bot support status, capabilities, and configuration"
|
||||
read_when:
|
||||
- You want to connect Clawdbot to Feishu
|
||||
- You are debugging Feishu webhook callbacks
|
||||
- You are debugging Feishu webhook callbacks or long connection events
|
||||
---
|
||||
|
||||
# Feishu (Bot API)
|
||||
|
||||
Status: experimental. HTTP callback only. Text messages only (V1).
|
||||
Status: experimental. Text messages only (V1). Supports HTTP callback and long connection.
|
||||
|
||||
## Plugin required
|
||||
|
||||
@ -26,16 +26,40 @@ Feishu ships as a plugin and is not bundled with the core install.
|
||||
- `appId`
|
||||
- `appSecret`
|
||||
3. Configure event subscription:
|
||||
- Callback URL: `https://gateway.example.com/feishu`
|
||||
- Events: subscribe to `im.message.receive_v1`
|
||||
- Set either a **verification token** or an **encrypt key**
|
||||
4. Configure Clawdbot:
|
||||
- Choose one delivery mode:
|
||||
- **Long connection** (no public URL required)
|
||||
- **HTTP callback** (public HTTPS webhook required)
|
||||
4. Configure Clawdbot (choose one):
|
||||
|
||||
### Long connection (mode: ws)
|
||||
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
feishu: {
|
||||
enabled: true,
|
||||
mode: "ws",
|
||||
appId: "cli_xxx",
|
||||
appSecret: "xxx",
|
||||
dm: { policy: "pairing" },
|
||||
groupPolicy: "allowlist",
|
||||
groups: {
|
||||
oc_xxx: { allow: true, requireMention: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### HTTP callback (mode: http)
|
||||
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
feishu: {
|
||||
enabled: true,
|
||||
mode: "http",
|
||||
appId: "cli_xxx",
|
||||
appSecret: "xxx",
|
||||
verificationToken: "xxx", // or encryptKey: "xxx"
|
||||
@ -50,10 +74,10 @@ Feishu ships as a plugin and is not bundled with the core install.
|
||||
}
|
||||
```
|
||||
|
||||
5. Start the gateway. Feishu will POST to the webhook path.
|
||||
5. Start the gateway. In HTTP callback mode, Feishu will POST to the webhook path.
|
||||
6. DM access is pairing by default; approve the pairing code on first contact.
|
||||
|
||||
## Webhook security
|
||||
## Webhook security (mode: http)
|
||||
|
||||
The plugin validates webhook requests using one of:
|
||||
|
||||
@ -98,6 +122,7 @@ Provider options:
|
||||
- `channels.feishu.enabled`: enable/disable the channel.
|
||||
- `channels.feishu.appId`: Feishu appId.
|
||||
- `channels.feishu.appSecret`: Feishu appSecret.
|
||||
- `channels.feishu.mode`: `http | ws` (default `http`).
|
||||
- `channels.feishu.verificationToken`: webhook verification token.
|
||||
- `channels.feishu.encryptKey`: webhook encrypt key (signature validation + optional decryption).
|
||||
- `channels.feishu.webhookPath`: webhook path on the gateway HTTP server (default `/feishu`).
|
||||
@ -111,6 +136,7 @@ Multi-account options:
|
||||
|
||||
- `channels.feishu.accounts.<id>.appId`
|
||||
- `channels.feishu.accounts.<id>.appSecret`
|
||||
- `channels.feishu.accounts.<id>.mode`
|
||||
- `channels.feishu.accounts.<id>.verificationToken`
|
||||
- `channels.feishu.accounts.<id>.encryptKey`
|
||||
- `channels.feishu.accounts.<id>.webhookPath`
|
||||
|
||||
@ -17,7 +17,7 @@ Text is supported everywhere; media and reactions vary by channel.
|
||||
- [Discord](/channels/discord) — Discord Bot API + Gateway; supports servers, channels, and DMs.
|
||||
- [Slack](/channels/slack) — Bolt SDK; workspace apps.
|
||||
- [Google Chat](/channels/googlechat) — Google Chat API app via HTTP webhook.
|
||||
- [Feishu](/channels/feishu) — Feishu Bot API via HTTP callback (plugin, installed separately).
|
||||
- [Feishu](/channels/feishu) — Feishu Bot API via webhook or long connection (plugin, installed separately).
|
||||
- [Mattermost](/channels/mattermost) — Bot API + WebSocket; channels, groups, DMs (plugin, installed separately).
|
||||
- [Signal](/channels/signal) — signal-cli; privacy-focused.
|
||||
- [BlueBubbles](/channels/bluebubbles) — **Recommended for iMessage**; uses the BlueBubbles macOS server REST API with full feature support (edit, unsend, effects, reactions, group management — edit currently broken on macOS 26 Tahoe).
|
||||
|
||||
@ -2,12 +2,12 @@
|
||||
summary: "Feishu bot support status, capabilities, and configuration"
|
||||
read_when:
|
||||
- You want to connect Clawdbot to Feishu
|
||||
- You are debugging Feishu webhook callbacks
|
||||
- You are debugging Feishu webhook callbacks or long connection events
|
||||
---
|
||||
|
||||
# Feishu (Bot API)
|
||||
|
||||
Status: experimental. HTTP callback only. Text messages only (V1).
|
||||
Status: experimental. Text messages only (V1). Supports HTTP callback and long connection.
|
||||
|
||||
## Plugin required
|
||||
|
||||
@ -25,16 +25,40 @@ Feishu ships as a plugin and is not bundled with the core install.
|
||||
- `appId`
|
||||
- `appSecret`
|
||||
3. Configure event subscription:
|
||||
- Callback URL: `https://gateway.example.com/feishu`
|
||||
- Events: subscribe to `im.message.receive_v1`
|
||||
- Set either a **verification token** or an **encrypt key**
|
||||
4. Configure Clawdbot:
|
||||
- Choose one delivery mode:
|
||||
- **Long connection** (no public URL required)
|
||||
- **HTTP callback** (public HTTPS webhook required)
|
||||
4. Configure Clawdbot (choose one):
|
||||
|
||||
### Long connection (mode: ws)
|
||||
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
feishu: {
|
||||
enabled: true,
|
||||
mode: "ws",
|
||||
appId: "cli_xxx",
|
||||
appSecret: "xxx",
|
||||
dm: { policy: "pairing" },
|
||||
groupPolicy: "allowlist",
|
||||
groups: {
|
||||
oc_xxx: { allow: true, requireMention: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### HTTP callback (mode: http)
|
||||
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
feishu: {
|
||||
enabled: true,
|
||||
mode: "http",
|
||||
appId: "cli_xxx",
|
||||
appSecret: "xxx",
|
||||
verificationToken: "xxx", // or encryptKey: "xxx"
|
||||
@ -49,10 +73,10 @@ Feishu ships as a plugin and is not bundled with the core install.
|
||||
}
|
||||
```
|
||||
|
||||
5. Start the gateway. Feishu will POST to the webhook path.
|
||||
5. Start the gateway. In HTTP callback mode, Feishu will POST to the webhook path.
|
||||
6. DM access is pairing by default; approve the pairing code on first contact.
|
||||
|
||||
## Webhook security
|
||||
## Webhook security (mode: http)
|
||||
|
||||
The plugin validates webhook requests using one of:
|
||||
|
||||
@ -83,6 +107,7 @@ Provider options:
|
||||
- `channels.feishu.enabled`: enable/disable the channel.
|
||||
- `channels.feishu.appId`: Feishu appId.
|
||||
- `channels.feishu.appSecret`: Feishu appSecret.
|
||||
- `channels.feishu.mode`: `http | ws` (default `http`).
|
||||
- `channels.feishu.verificationToken`: webhook verification token.
|
||||
- `channels.feishu.encryptKey`: webhook encrypt key (signature validation + optional decryption).
|
||||
- `channels.feishu.webhookPath`: webhook path on the gateway HTTP server (default `/feishu`).
|
||||
@ -96,6 +121,7 @@ Multi-account options:
|
||||
|
||||
- `channels.feishu.accounts.<id>.appId`
|
||||
- `channels.feishu.accounts.<id>.appSecret`
|
||||
- `channels.feishu.accounts.<id>.mode`
|
||||
- `channels.feishu.accounts.<id>.verificationToken`
|
||||
- `channels.feishu.accounts.<id>.encryptKey`
|
||||
- `channels.feishu.accounts.<id>.webhookPath`
|
||||
|
||||
@ -4,11 +4,11 @@
|
||||
|
||||
Implement `@clawdbot/feishu` as a channel extension that:
|
||||
|
||||
- Registers a channel plugin (`api.registerChannel`) and an HTTP webhook handler (`api.registerHttpHandler`).
|
||||
- Starts a per-account “monitor” on gateway start (via `plugin.gateway.startAccount`) that registers webhook targets and manages runtime status.
|
||||
- Registers a channel plugin (`api.registerChannel`) and an HTTP handler (`api.registerHttpHandler`).
|
||||
- Starts a per-account “monitor” on gateway start (via `plugin.gateway.startAccount`) that runs until aborted and manages runtime status.
|
||||
- Uses the existing Clawdbot reply pipeline (`runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher`) to route inbound messages to an agent and send outbound replies back to Feishu.
|
||||
|
||||
This follows the proven “webhook channel” structure in `extensions/googlechat`.
|
||||
This follows the proven “webhook channel” structure in `extensions/googlechat`, with an additional long-connection transport option.
|
||||
|
||||
## Architecture
|
||||
|
||||
@ -27,6 +27,10 @@ This follows the proven “webhook channel” structure in `extensions/googlecha
|
||||
- Parses raw body, validates signature/token, decrypts if needed.
|
||||
- Handles `url_verification`.
|
||||
- Handles `im.message.receive_v1` text messages.
|
||||
- **Long connection monitor**: `extensions/feishu/src/ws.ts`
|
||||
- Fetches long-connection endpoint config from Feishu.
|
||||
- Connects to Feishu’s event WebSocket and acknowledges events quickly.
|
||||
- **Inbound processing + routing**: `extensions/feishu/src/inbound.ts`
|
||||
- Applies DM + group policies and mention gating.
|
||||
- Builds inbound context and calls reply dispatcher.
|
||||
- Sends replies via Feishu REST API.
|
||||
|
||||
@ -7,7 +7,7 @@ Clawdbot already supports several chat surfaces (e.g. Slack, Google Chat, Telegr
|
||||
## Goals
|
||||
|
||||
- Ship a Feishu **channel plugin** under `extensions/` (installable from npm) that can:
|
||||
- Receive inbound messages (DM + group) via Feishu event subscription callback.
|
||||
- Receive inbound messages (DM + group) via Feishu event subscription (HTTP callback or long connection).
|
||||
- Respond with text replies (agent replies + `clawdbot message send`).
|
||||
- Respect Clawdbot’s DM security model (pairing/allowlist/open/disabled).
|
||||
- Support group allowlists + mention gating behavior consistent with other channels.
|
||||
@ -31,14 +31,15 @@ Single human operator running Clawdbot for personal use, inside one Feishu tenan
|
||||
|
||||
1. User installs and enables the Feishu plugin.
|
||||
2. User creates a Feishu app (self-built/internal) with Bot capability enabled.
|
||||
3. User configures event subscription callback URL (served by Clawdbot Gateway).
|
||||
3. User configures event subscription delivery (HTTP callback or long connection).
|
||||
4. User DMs the bot; unknown DMs get pairing code; after approval bot answers.
|
||||
5. User adds bot to a group; bot responds only when allowed and mention-gated.
|
||||
|
||||
## Functional requirements (high-level)
|
||||
|
||||
- Inbound:
|
||||
- HTTP handler for Feishu event subscription callback.
|
||||
- HTTP handler for Feishu event subscription callback (`mode="http"`).
|
||||
- Long connection listener for Feishu event subscription (`mode="ws"`).
|
||||
- Support `url_verification` challenge handshake.
|
||||
- Validate inbound requests (signature and/or verification token).
|
||||
- Handle `im.message.receive_v1` events.
|
||||
@ -64,7 +65,7 @@ Single human operator running Clawdbot for personal use, inside one Feishu tenan
|
||||
## Decisions (confirmed)
|
||||
|
||||
1. **Region**: Feishu only.
|
||||
2. **Inbound transport**: HTTP callback (event subscription webhook).
|
||||
2. **Inbound transport**: HTTP callback and long connection.
|
||||
3. **V1 scope**: text-only.
|
||||
|
||||
## Risks and mitigations
|
||||
@ -73,52 +74,6 @@ Single human operator running Clawdbot for personal use, inside one Feishu tenan
|
||||
- Secret leakage: never log app secrets; store secrets only in config.
|
||||
- Rate limits: cache tokens; chunk outbound messages via existing chunker helpers.
|
||||
|
||||
\*\*\* Add File: extensions/feishu/spec/design.md
|
||||
|
||||
# Tech design: Feishu (飞书) channel plugin
|
||||
|
||||
## Summary
|
||||
|
||||
Implement `@clawdbot/feishu` as a channel extension that:
|
||||
|
||||
- Registers a channel plugin (`api.registerChannel`) and an HTTP webhook handler (`api.registerHttpHandler`).
|
||||
- Starts a per-account “monitor” on gateway start (via `plugin.gateway.startAccount`) that registers webhook targets and manages runtime status.
|
||||
- Uses the existing Clawdbot reply pipeline (`runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher`) to route inbound messages to an agent and send outbound replies back to Feishu.
|
||||
|
||||
This follows the proven “webhook channel” structure in `extensions/googlechat`.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Components
|
||||
|
||||
- **Feishu plugin entrypoint**: `extensions/feishu/index.ts`
|
||||
- Stores `PluginRuntime` (like `extensions/googlechat/src/runtime.ts`).
|
||||
- Registers channel + HTTP handler.
|
||||
- **Channel plugin**: `extensions/feishu/src/channel.ts`
|
||||
- Config adapter (accounts, enabled/configured, allowFrom formatting).
|
||||
- Outbound adapter (sendText).
|
||||
- Security adapter (DM policy warnings, group policy warnings).
|
||||
- Status adapter (probe + runtime snapshot).
|
||||
- Gateway adapter (startAccount → register webhook target).
|
||||
- **Monitor / webhook handler**: `extensions/feishu/src/monitor.ts`
|
||||
- Parses raw body, validates signature/token, decrypts if needed.
|
||||
- Handles `url_verification`.
|
||||
- Handles `im.message.receive_v1` text messages.
|
||||
- Applies DM + group policies and mention gating.
|
||||
- Builds inbound context and calls reply dispatcher.
|
||||
- Sends replies via Feishu REST API.
|
||||
- **API client**: `extensions/feishu/src/api.ts`
|
||||
- Token manager: `tenant_access_token/internal` (self-built apps).
|
||||
- Send message / reply message endpoints.
|
||||
- Bot info (`/open-apis/bot/v3/info`) to detect mentions.
|
||||
|
||||
## Webhook verification and decryption
|
||||
|
||||
### URL verification
|
||||
|
||||
- Feishu sends a payload (plain or encrypted) where `type === "url_verification"` and includes `challenge`.
|
||||
- The handler responds `200` with JSON: `{"challenge":"<challenge>"}`.
|
||||
|
||||
### Decrypt algorithm
|
||||
|
||||
- If payload has `encrypt`:
|
||||
@ -154,16 +109,6 @@ Colocate tests in `extensions/feishu/src/` (Vitest).
|
||||
- Target normalization.
|
||||
- URL verification and event parsing.
|
||||
|
||||
\*\*\* Add File: extensions/feishu/spec/spec.md
|
||||
|
||||
# Spec: Feishu channel extension
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Channel plugin availability
|
||||
|
||||
The system SHALL provide a Feishu chat channel as a Clawdbot extension plugin that can be installed and enabled without modifying core channel code.
|
||||
|
||||
#### Scenario: Plugin appears in onboarding catalog
|
||||
|
||||
- **GIVEN** a user runs `clawdbot onboard` in a workspace that contains the Feishu plugin (local path) or can access it on npm
|
||||
@ -241,60 +186,3 @@ The system SHALL expose Feishu channel health via `clawdbot channels status`, in
|
||||
- **GIVEN** the plugin is enabled but credentials are invalid
|
||||
- **WHEN** the user runs `clawdbot channels status --probe`
|
||||
- **THEN** the Feishu channel shows `probe=error` with an actionable message (e.g. token fetch failed)
|
||||
|
||||
\*\*\* Add File: extensions/feishu/spec/tasks.md
|
||||
|
||||
# Tasks: Add Feishu (飞书) channel extension
|
||||
|
||||
## 1. Extension scaffold
|
||||
|
||||
- [x] Create `extensions/feishu/` workspace package (`package.json`, `clawdbot.plugin.json`, `index.ts`, `src/`).
|
||||
- [x] Add plugin catalog metadata in `extensions/feishu/package.json` (`clawdbot.channel` + `clawdbot.install`) so onboarding can install it.
|
||||
|
||||
## 2. Config + normalization
|
||||
|
||||
- [x] Define Feishu config Zod schema (extension-local) and expose it as `configSchema` via `buildChannelConfigSchema`.
|
||||
- [x] Implement target normalization (`user:<open_id>`, `chat:<chat_id>`) and allowlist formatting.
|
||||
- [x] Implement account model (start with default account; keep `accounts` extensible).
|
||||
|
||||
## 3. Token manager + API client
|
||||
|
||||
- [x] Implement tenant access token fetch + cache (`/auth/v3/tenant_access_token/internal`).
|
||||
- [x] Implement Feishu “bot info” fetch (`/bot/v3/info`) for mention gating.
|
||||
- [x] Implement send message (`/im/v1/messages`) and reply message (`/im/v1/messages/:message_id/reply`).
|
||||
|
||||
## 4. Webhook handler
|
||||
|
||||
- [x] Implement `handleFeishuWebhookRequest(req,res)` and register via `api.registerHttpHandler`.
|
||||
- [x] Support `url_verification` challenge response (plain + encrypted).
|
||||
- [x] Implement secure validation:
|
||||
- [x] Raw-body capture with size limit.
|
||||
- [x] Signature verification when `encryptKey` is configured.
|
||||
- [x] Verification token checks when `encryptKey` is not configured.
|
||||
- [x] Implement decrypt for payloads with `encrypt`.
|
||||
|
||||
## 5. Event processing + routing
|
||||
|
||||
- [x] Handle `im.message.receive_v1` (text-only V1):
|
||||
- [x] DM policy + pairing store integration (mirror GoogleChat monitor behavior).
|
||||
- [x] Group policy allowlists + mention gating integration.
|
||||
- [x] Control command gating for group chats.
|
||||
- [x] Build inbound context via `runtime.channel.reply.finalizeInboundContext` and dispatch replies via buffered dispatcher.
|
||||
|
||||
## 6. Outbound adapters
|
||||
|
||||
- [x] Implement `outbound.sendText` for `clawdbot message send` and heartbeats.
|
||||
|
||||
## 7. Status + probe
|
||||
|
||||
- [x] Implement `status` adapter snapshot + summary.
|
||||
- [x] Implement `probeAccount` to validate credentials (token + bot info).
|
||||
|
||||
## 8. Onboarding
|
||||
|
||||
- [x] Add onboarding adapter with prompts for app id/secret and webhook settings.
|
||||
|
||||
## 9. Tests
|
||||
|
||||
- [x] Add unit tests for: signature, decrypt, target normalization.
|
||||
- [ ] Add unit tests for: url_verification, event parsing.
|
||||
|
||||
@ -12,7 +12,7 @@ The system SHALL provide a Feishu chat channel as a Clawdbot extension plugin th
|
||||
- **WHEN** the user reaches the channel selection step
|
||||
- **THEN** Feishu is listed as an installable channel plugin with a docs link
|
||||
|
||||
### Requirement: Webhook endpoint and URL verification
|
||||
### Requirement: Webhook endpoint and URL verification (mode: http)
|
||||
|
||||
The system SHALL accept Feishu event subscription callbacks over HTTP and complete the platform “request URL verification” handshake.
|
||||
|
||||
@ -22,7 +22,7 @@ The system SHALL accept Feishu event subscription callbacks over HTTP and comple
|
||||
- **WHEN** Clawdbot receives the POST at the configured webhook path
|
||||
- **THEN** the response status is `200` and the response body is `{"challenge":"<value>"}` (JSON)
|
||||
|
||||
### Requirement: Request validation
|
||||
### Requirement: Request validation (mode: http)
|
||||
|
||||
The system SHALL validate inbound callback requests before processing events.
|
||||
|
||||
@ -32,7 +32,7 @@ The system SHALL validate inbound callback requests before processing events.
|
||||
- **WHEN** the request is received
|
||||
- **THEN** the request is rejected with `401` and no message processing occurs
|
||||
|
||||
### Requirement: Encrypted payload support
|
||||
### Requirement: Encrypted payload support (mode: http)
|
||||
|
||||
When configured with an encrypt key, the system SHALL decrypt payloads that use the `encrypt` envelope.
|
||||
|
||||
@ -83,3 +83,13 @@ The system SHALL expose Feishu channel health via `clawdbot channels status`, in
|
||||
- **GIVEN** the plugin is enabled but credentials are invalid
|
||||
- **WHEN** the user runs `clawdbot channels status --probe`
|
||||
- **THEN** the Feishu channel shows `probe=error` with an actionable message (e.g. token fetch failed)
|
||||
|
||||
### Requirement: Long connection mode (mode: ws)
|
||||
|
||||
The system SHALL support receiving Feishu events over long connection when `channels.feishu.mode="ws"` is configured.
|
||||
|
||||
#### Scenario: Long connection receives events without public URL
|
||||
|
||||
- **GIVEN** `channels.feishu.mode="ws"` and `channels.feishu.appId/appSecret` are configured
|
||||
- **WHEN** the gateway starts
|
||||
- **THEN** the plugin establishes a long connection to Feishu and can receive `im.message.receive_v1` events without an exposed webhook URL
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
## 2. Config + normalization
|
||||
|
||||
- [x] Define Feishu config Zod schema (extension-local) and expose it as `configSchema` via `buildChannelConfigSchema`.
|
||||
- [x] Add `mode: http | ws` to select HTTP callback vs long connection.
|
||||
- [x] Implement target normalization (`user:<open_id>`, `chat:<chat_id>`) and allowlist formatting.
|
||||
- [x] Implement account model (start with default account; keep `accounts` extensible).
|
||||
|
||||
@ -46,9 +47,15 @@
|
||||
|
||||
## 8. Onboarding
|
||||
|
||||
- [x] Add onboarding adapter with prompts for app id/secret and webhook settings.
|
||||
- [x] Add onboarding adapter with prompts for app id/secret and delivery mode.
|
||||
|
||||
## 9. Tests
|
||||
## 9. Long connection (WebSocket)
|
||||
|
||||
- [x] Implement long connection transport (`mode="ws"`) for event subscriptions.
|
||||
- [x] Acknowledge events quickly and process messages asynchronously.
|
||||
|
||||
## 10. Tests
|
||||
|
||||
- [x] Add unit tests for: signature, decrypt, target normalization.
|
||||
- [x] Add unit tests for: url_verification, event parsing.
|
||||
- [x] Add unit tests for: long connection frame codec + monitor lifecycle.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user