@openduo/channel-feishu 0.2.3 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +117 -0
  2. package/dist/plugin.js +35 -34
  3. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,117 @@
1
+ # @openduo/channel-feishu
2
+
3
+ Feishu / Lark channel adapter for [duoduo](https://www.npmjs.com/package/@openduo/duoduo).
4
+
5
+ Connects duoduo to Feishu via the Feishu Open Platform WebSocket long-poll API. Requires no public URL — the gateway initiates the connection outbound.
6
+
7
+ > The Feishu messaging layer in this package was written by duoduo itself, referencing [openclaw](https://github.com/openclaw/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.
8
+
9
+ ## How It Works
10
+
11
+ 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.
12
+
13
+ **Inbound**: Feishu messages arrive via WebSocket event subscription. The gateway handles deduplication, access policy, media download, @mention normalization, and dispatch to the daemon.
14
+
15
+ **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.
16
+
17
+ **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.
18
+
19
+ **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.
20
+
21
+ **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.
22
+
23
+ **Commands**: Gateway control commands (`/status`, `/cancel`, `/cd`, `/clear`, `/stats`) are handled directly without routing through the agent session.
24
+
25
+ ## Requirements
26
+
27
+ - Node.js 20+
28
+ - A running duoduo daemon (`@openduo/duoduo`)
29
+ - A Feishu app with WebSocket long-poll enabled
30
+
31
+ ## Installation
32
+
33
+ ### Via duoduo CLI (recommended)
34
+
35
+ ```bash
36
+ duoduo channel install @openduo/channel-feishu
37
+ ```
38
+
39
+ ### Manual
40
+
41
+ ```bash
42
+ npm install -g @openduo/channel-feishu
43
+ ```
44
+
45
+ ## Feishu App Setup
46
+
47
+ In the Feishu Developer Console:
48
+
49
+ 1. Create an app (or use an existing one).
50
+ 2. Enable **WebSocket long-poll** under Events & Callbacks → Connection mode.
51
+ 3. Subscribe to the `im.message.receive_v1` event.
52
+ 4. Grant the following permissions:
53
+
54
+ | Permission | Purpose |
55
+ | ---------------------------------- | --------------------------------------- |
56
+ | `im:message` | Send and receive messages |
57
+ | `im:message.p2p_msg:readonly` | Receive direct messages |
58
+ | `im:message.group_at_msg:readonly` | Receive @bot messages in groups |
59
+ | `im:message:send_as_bot` | Send messages as bot |
60
+ | `im:resource` | Upload and download media |
61
+ | `contact:user.base:readonly` | Resolve sender display names (optional) |
62
+
63
+ ## Configuration
64
+
65
+ All configuration is via environment variables:
66
+
67
+ | Variable | Default | Description |
68
+ | ------------------------ | ------------------------ | ------------------------------------------------ |
69
+ | `FEISHU_APP_ID` | — | **Required.** Feishu app ID |
70
+ | `FEISHU_APP_SECRET` | — | **Required.** Feishu app secret |
71
+ | `FEISHU_DOMAIN` | `feishu` | `feishu`, `lark`, or custom domain URL |
72
+ | `ALADUO_DAEMON_URL` | `http://127.0.0.1:20233` | duoduo daemon address |
73
+ | `FEISHU_DM_POLICY` | `open` | DM access: `open` or `allowlist` |
74
+ | `FEISHU_GROUP_POLICY` | `allowlist` | Group access: `open`, `allowlist`, or `disabled` |
75
+ | `FEISHU_REQUIRE_MENTION` | `true` | Require @bot mention in groups |
76
+ | `FEISHU_ALLOW_FROM` | — | Comma-separated open_id allowlist |
77
+ | `FEISHU_ALLOW_GROUPS` | — | Comma-separated chat_id allowlist |
78
+ | `FEISHU_RENDER_MODE` | `auto` | Output rendering: `auto`, `raw`, or `card` |
79
+ | `FEISHU_BOT_OPEN_ID` | — | Bot's own open_id (for mention detection) |
80
+ | `FEISHU_LOG_LEVEL` | `info` | Log level |
81
+
82
+ **Render modes:**
83
+
84
+ - `auto` — plain text by default; switches to interactive card when output contains code blocks or tables.
85
+ - `raw` — always plain text.
86
+ - `card` — always interactive card.
87
+
88
+ ## Usage
89
+
90
+ ### Via duoduo CLI
91
+
92
+ ```bash
93
+ # Start (managed by duoduo)
94
+ duoduo channel feishu start
95
+
96
+ # Check status
97
+ duoduo channel feishu status
98
+
99
+ # View logs
100
+ duoduo channel feishu logs
101
+
102
+ # Stop
103
+ duoduo channel feishu stop
104
+ ```
105
+
106
+ ### Standalone
107
+
108
+ ```bash
109
+ FEISHU_APP_ID=cli_xxx \
110
+ FEISHU_APP_SECRET=xxx \
111
+ ALADUO_DAEMON_URL=http://127.0.0.1:20233 \
112
+ duoduo-feishu
113
+ ```
114
+
115
+ ## License
116
+
117
+ MIT