@xwang152/claw-lark 0.1.1 → 0.1.2
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.
- package/README.md +69 -223
- package/README_zh.md +78 -214
- package/eslint.config.js +34 -0
- package/index.ts +3 -3
- package/openclaw.plugin.json +35 -14
- package/package.json +2 -2
- package/src/__tests__/sample.test.ts +1 -1
package/README.md
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
|
-
# Lark Plugin
|
|
1
|
+
# OpenClaw Feishu/Lark Plugin
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
A channel plugin that enables OpenClaw to communicate via Lark (Larksuite) messaging platform.
|
|
3
|
+
A channel plugin for OpenClaw that enables communication through the Feishu or Lark platform.
|
|
6
4
|
|
|
7
5
|
## Features
|
|
8
6
|
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
- A Lark app with Bot capability enabled
|
|
7
|
+
- **Dual Platform Support**: Full compatibility with Feishu (China) and Lark (International).
|
|
8
|
+
- **WebSocket (Long Connection)**: Recommended for custom apps, low latency, no public IP required.
|
|
9
|
+
- **Webhook Mode**: For traditional deployments, supports event verification and encryption.
|
|
10
|
+
- **Multi-Mode Rendering**: Supports `auto` / `raw` / `card`, with Interactive Cards for Markdown, tables, and highlighting.
|
|
11
|
+
- **Media Support**:
|
|
12
|
+
- **Inbound**: AI can receive images and files (PDF, Excel, Word, etc.).
|
|
13
|
+
- **Outbound**: Support for sending images and files.
|
|
14
|
+
- **Advanced Interaction**:
|
|
15
|
+
- **Typing Indicator**: Simulated via message reactions.
|
|
16
|
+
- **@ Forwarding**: Automatic handling of @mentions in group chats.
|
|
17
|
+
- **Contextual Replies**: Support for message threading and replies.
|
|
18
|
+
- **Auto-Recovery**: Automatic reconnection for WebSocket and server restarts for Webhooks.
|
|
22
19
|
|
|
23
20
|
## Installation
|
|
24
21
|
|
|
@@ -30,25 +27,9 @@ Install directly via the OpenClaw CLI:
|
|
|
30
27
|
openclaw plugins install @xwang152/claw-lark
|
|
31
28
|
```
|
|
32
29
|
|
|
33
|
-
### 2.
|
|
30
|
+
### 2. Restart Gateway
|
|
34
31
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
# Clone the repository
|
|
39
|
-
git clone https://github.com/xwang152-jack/claw-lark.git
|
|
40
|
-
cd claw-lark
|
|
41
|
-
|
|
42
|
-
# Install dependencies
|
|
43
|
-
npm install
|
|
44
|
-
|
|
45
|
-
# Install plugin in link mode
|
|
46
|
-
openclaw plugins install --link .
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### 3. Restart Gateway
|
|
50
|
-
|
|
51
|
-
After installation, restart the Gateway to load the plugin:
|
|
32
|
+
Restart the Gateway to load the plugin:
|
|
52
33
|
|
|
53
34
|
```bash
|
|
54
35
|
openclaw gateway restart
|
|
@@ -60,202 +41,67 @@ Verify installation:
|
|
|
60
41
|
openclaw plugins list
|
|
61
42
|
```
|
|
62
43
|
|
|
63
|
-
You should see `
|
|
64
|
-
|
|
65
|
-
## Lark App Setup
|
|
66
|
-
|
|
67
|
-
1. Go to [Lark Developer Console](https://open.larksuite.com/app)
|
|
68
|
-
|
|
69
|
-
2. Create a new app or use an existing one
|
|
70
|
-
|
|
71
|
-
3. Enable **Bot** capability under App Features
|
|
72
|
-
|
|
73
|
-
4. Add the following permissions under Permissions & Scopes:
|
|
74
|
-
|
|
75
|
-
| Permission | Scope | Description |
|
|
76
|
-
| :--- | :--- | :--- |
|
|
77
|
-
| `im:message` | Message | Send and receive messages |
|
|
78
|
-
| `im:message.p2p_msg:readonly` | P2P Message | Read direct messages sent to the bot |
|
|
79
|
-
| `im:message.group_at_msg:readonly` | Group Message | Receive messages where the bot is @mentioned in groups |
|
|
80
|
-
| `im:message:send_as_bot` | Send | Send messages as the bot |
|
|
81
|
-
| `im:resource` | Resource | Upload/download images and files |
|
|
82
|
-
|
|
83
|
-
**Optional Permissions (add as needed):**
|
|
84
|
-
|
|
85
|
-
| Permission | Scope | Description |
|
|
86
|
-
| :--- | :--- | :--- |
|
|
87
|
-
| `im:message.group_msg` | Group | Read all group messages (Sensitive permission) |
|
|
88
|
-
| `im:message:readonly` | Read | Get historical messages |
|
|
89
|
-
| `im:message:update` | Edit | Update/edit sent messages |
|
|
90
|
-
| `im:message:recall` | Recall | Recall sent messages |
|
|
91
|
-
| `im:message.reactions:read` | Reaction | View message emoji reactions |
|
|
92
|
-
|
|
93
|
-
5. Note your **App ID** and **App Secret** from Credentials & Basic Info (you'll need these for configuration)
|
|
94
|
-
|
|
95
|
-
6. Publish your app under Version Management
|
|
44
|
+
You should see the `feishu` plugin with a `loaded` status.
|
|
96
45
|
|
|
97
46
|
## Configuration
|
|
98
47
|
|
|
99
|
-
###
|
|
100
|
-
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
#
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
#
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|--------|------|---------|-------------|
|
|
136
|
-
| `appId` | string | - | Lark App ID (required) |
|
|
137
|
-
| `appSecret` | string | - | Lark App Secret (required) |
|
|
138
|
-
| `connectionMode` | string | `websocket` | `webhook` or `websocket` |
|
|
139
|
-
| `webhookPort` | number | `3000` | Port for webhook server |
|
|
140
|
-
| `domain` | string | `feishu` | `feishu` (China) or `lark` (international) |
|
|
141
|
-
| `encryptKey` | string | - | Encrypt key for decrypting event payloads (from Events & Callbacks > Encryption Strategy) |
|
|
142
|
-
| `verificationToken` | string | - | Token for verifying request authenticity (from Events & Callbacks > Encryption Strategy) |
|
|
143
|
-
| `dmPolicy` | string | `pairing` | `open`, `pairing`, or `allowlist` |
|
|
144
|
-
| `groupPolicy` | string | `open` | `open`, `allowlist`, or `disabled` |
|
|
145
|
-
| `groupMentionGated` | boolean | `true` | Require @mention in groups |
|
|
146
|
-
|
|
147
|
-
## Webhook Mode Setup
|
|
148
|
-
|
|
149
|
-
Choose the setup method based on your deployment environment.
|
|
150
|
-
|
|
151
|
-
### 1. Development (Using ngrok)
|
|
152
|
-
|
|
153
|
-
Recommended for local development and testing.
|
|
154
|
-
|
|
155
|
-
> **Security & Privacy Notice**: ngrok exposes your local server to the internet. Keep the following in mind:
|
|
156
|
-
> - Never share your ngrok URL publicly — anyone with the URL can send requests to your local machine
|
|
157
|
-
> - Use a paid ngrok plan with authentication or IP restrictions for production use
|
|
158
|
-
> - Stop ngrok when not in use to close the tunnel
|
|
159
|
-
> - Consider using Lark's `encryptKey` and `verificationToken` for additional request validation
|
|
160
|
-
|
|
161
|
-
1. Start ngrok to expose your local webhook server:
|
|
162
|
-
|
|
163
|
-
```bash
|
|
164
|
-
ngrok http 3000
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
2. Copy the HTTPS URL from ngrok (e.g., `https://abc123.ngrok.io`)
|
|
168
|
-
|
|
169
|
-
3. Configure Events & Callbacks in Lark Developer Console:
|
|
170
|
-
- Add event subscription: `im.message.receive_v1`
|
|
171
|
-
- Set Request URL to your ngrok HTTPS URL (e.g., `https://abc123.ngrok.io`)
|
|
172
|
-
|
|
173
|
-
### 2. Production (Server Deployment)
|
|
174
|
-
|
|
175
|
-
When deploying on a server, ngrok is **not** required.
|
|
176
|
-
|
|
177
|
-
1. **Open Port**: Ensure your server's firewall (Security Group) allows traffic on the port used by the plugin (default is `3000`).
|
|
178
|
-
2. **Configure URL**: In Lark Developer Console, configure "Events & Callbacks":
|
|
179
|
-
- Set the "Request URL" to your server's public address: `http://your-server-ip:3000`.
|
|
180
|
-
3. **(Recommended) Reverse Proxy**: Use Nginx or Caddy to set up a reverse proxy with SSL (HTTPS) and forward traffic to port `3000`.
|
|
181
|
-
|
|
182
|
-
### 3. Start the Plugin
|
|
183
|
-
|
|
184
|
-
1. Start OpenClaw:
|
|
185
|
-
|
|
186
|
-
```bash
|
|
187
|
-
openclaw start
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
2. The webhook server will start automatically and handle URL verification.
|
|
191
|
-
|
|
192
|
-
## WebSocket Mode
|
|
193
|
-
|
|
194
|
-
WebSocket mode is available for enterprise Lark accounts (Custom Apps) that support long connections. Set `connectionMode` to `websocket`:
|
|
195
|
-
|
|
196
|
-
```bash
|
|
197
|
-
openclaw config set channels.lark.accounts.default.connectionMode 'websocket'
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
**Advantages:**
|
|
201
|
-
- **No Public IP Needed**: No need for ngrok or reverse proxy, suitable for local or intranet environments.
|
|
202
|
-
- **Easy Setup**: Simply enable the "Receive events through persistent connection" toggle in the Lark Developer Console.
|
|
203
|
-
- **High Stability**: The plugin supports automatic reconnection.
|
|
204
|
-
|
|
205
|
-
**Configuration Steps:**
|
|
206
|
-
1. Go to **Events & Callbacks** in the Lark Developer Console.
|
|
207
|
-
2. Select **Receive events through persistent connection** under "Subscription Mode".
|
|
208
|
-
3. Ensure the `im.message.receive_v1` event is added.
|
|
209
|
-
|
|
210
|
-
## Multiple Accounts
|
|
211
|
-
|
|
212
|
-
You can configure multiple Lark accounts:
|
|
213
|
-
|
|
214
|
-
```bash
|
|
215
|
-
openclaw config set channels.lark.accounts.work.appId 'cli_work_app'
|
|
216
|
-
openclaw config set channels.lark.accounts.work.appSecret 'work-secret'
|
|
217
|
-
openclaw config set channels.lark.accounts.personal.appId 'cli_personal_app'
|
|
218
|
-
openclaw config set channels.lark.accounts.personal.appSecret 'personal-secret'
|
|
48
|
+
### Example Configuration (`openclaw.yaml`)
|
|
49
|
+
|
|
50
|
+
```yaml
|
|
51
|
+
channels:
|
|
52
|
+
feishu:
|
|
53
|
+
accounts:
|
|
54
|
+
default:
|
|
55
|
+
enabled: true
|
|
56
|
+
appId: "cli_a9f722ad2cb9dccb"
|
|
57
|
+
appSecret: "********"
|
|
58
|
+
# Domain: "feishu" (China) or "lark" (International)
|
|
59
|
+
domain: "feishu"
|
|
60
|
+
# Mode: "websocket" (recommended) or "webhook"
|
|
61
|
+
connectionMode: "websocket"
|
|
62
|
+
# Webhook settings (required only for webhook mode)
|
|
63
|
+
# verificationToken: "********"
|
|
64
|
+
# encryptKey: "********"
|
|
65
|
+
# webhookPort: 3000
|
|
66
|
+
# DM Policy: "pairing" | "open" | "allowlist"
|
|
67
|
+
dmPolicy: "pairing"
|
|
68
|
+
# DM allowlist (only when dmPolicy=allowlist, OpenID)
|
|
69
|
+
# dmAllowlist:
|
|
70
|
+
# - "ou_xxx"
|
|
71
|
+
# Group Policy: "open" | "allowlist" | "disabled"
|
|
72
|
+
groupPolicy: "allowlist"
|
|
73
|
+
# Group allowlist (only when groupPolicy=allowlist, ChatID)
|
|
74
|
+
# groupAllowlist:
|
|
75
|
+
# - "oc_xxx"
|
|
76
|
+
# Require @mention in groups
|
|
77
|
+
requireMention: true
|
|
78
|
+
# Max media size (MB, default 30)
|
|
79
|
+
mediaMaxMb: 30
|
|
80
|
+
# Rendering mode: "auto" | "raw" | "card"
|
|
81
|
+
renderMode: "auto"
|
|
82
|
+
# History limit (default 10)
|
|
83
|
+
# historyLimit: 10
|
|
219
84
|
```
|
|
220
85
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
### Bot not receiving messages
|
|
86
|
+
### Rendering Modes
|
|
224
87
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
88
|
+
| Mode | Description |
|
|
89
|
+
| :--- | :--- |
|
|
90
|
+
| **auto** | (Default) Automatic detection: Use cards for code blocks, lists, or tables, otherwise use plain text. |
|
|
91
|
+
| **raw** | Always use plain text. Tables are converted to ASCII text. |
|
|
92
|
+
| **card** | Always use Feishu Interactive Cards with Markdown syntax highlighting. |
|
|
229
93
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
Add the `im:resource` permission in Lark Developer Console and republish your app.
|
|
233
|
-
|
|
234
|
-
### Webhook server not starting
|
|
235
|
-
|
|
236
|
-
Check if port 3000 is already in use. Change the port:
|
|
94
|
+
## Development
|
|
237
95
|
|
|
238
96
|
```bash
|
|
239
|
-
|
|
97
|
+
git clone https://github.com/xwang152-jack/claw-lark.git
|
|
98
|
+
cd claw-lark
|
|
99
|
+
npm install
|
|
100
|
+
npm run typecheck
|
|
101
|
+
openclaw plugins install --link .
|
|
240
102
|
```
|
|
241
103
|
|
|
242
|
-
###
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
## Contributing
|
|
247
|
-
|
|
248
|
-
Issues and pull requests are welcome! If you encounter bugs or have feature requests, please open an issue at https://github.com/xwang152-jack/claw-lark/issues.
|
|
249
|
-
|
|
250
|
-
## Automated Publishing (CI/CD)
|
|
251
|
-
|
|
252
|
-
The project is configured with GitHub Actions. When you push code to the `main` branch, if the version in `package.json` has changed, it will be automatically published to npm.
|
|
253
|
-
|
|
254
|
-
**Setup Steps:**
|
|
255
|
-
1. Create an **Automation Token** on the npm website.
|
|
256
|
-
2. In your GitHub repository, go to **Settings > Secrets and variables > Actions**.
|
|
257
|
-
3. Add a new Repository secret named `NPM_TOKEN` with your npm token as the value.
|
|
258
|
-
|
|
259
|
-
## License
|
|
260
|
-
|
|
261
|
-
MIT
|
|
104
|
+
### Commands
|
|
105
|
+
- `npm run lint`: Lint code
|
|
106
|
+
- `npm run format`: Format code
|
|
107
|
+
- `npm test`: Run tests
|
package/README_zh.md
CHANGED
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
# OpenClaw 飞书/Lark 插件
|
|
2
2
|
|
|
3
|
-
这是一个为 OpenClaw 开发的频道插件,使 OpenClaw 能够通过飞书 (
|
|
3
|
+
这是一个为 OpenClaw 开发的频道插件,使 OpenClaw 能够通过飞书 (Feishu) 或 Lark 平台进行通信。
|
|
4
4
|
|
|
5
5
|
## 功能特性
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
- 已启用机器人能力的飞书应用
|
|
7
|
+
- **双平台支持**:全面兼容飞书 (国内) 和 Lark (国际)
|
|
8
|
+
- **长连接 (WebSocket)**:企业自建应用推荐使用,低延迟,无需公网 IP
|
|
9
|
+
- **Webhook 模式**:适用于传统部署,支持事件验证和加密
|
|
10
|
+
- **多模式渲染**:支持 `auto` / `raw` / `card` 三种模式,卡片模式支持 Markdown 语法高亮和表格
|
|
11
|
+
- **多媒体支持**:
|
|
12
|
+
- **进站**:AI 可以接收图片、文件 (PDF, Excel, Word 等)
|
|
13
|
+
- **出站**:支持发送图片和文件
|
|
14
|
+
- **高级交互**:
|
|
15
|
+
- **输入指示器**:通过消息表情回复模拟 "正在输入" 状态
|
|
16
|
+
- **@ 转发**:自动处理群聊中的 @ 提及
|
|
17
|
+
- **上下文引用**:支持消息引用和回复上下文
|
|
18
|
+
- **自动恢复**:连接中断后自动重连,服务崩溃自动重启
|
|
20
19
|
|
|
21
20
|
## 安装步骤
|
|
22
21
|
|
|
@@ -28,23 +27,7 @@
|
|
|
28
27
|
openclaw plugins install @xwang152/claw-lark
|
|
29
28
|
```
|
|
30
29
|
|
|
31
|
-
### 2.
|
|
32
|
-
|
|
33
|
-
如果你想进行二次开发或修改代码:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
# 克隆仓库
|
|
37
|
-
git clone https://github.com/xwang152-jack/claw-lark.git
|
|
38
|
-
cd claw-lark
|
|
39
|
-
|
|
40
|
-
# 安装依赖
|
|
41
|
-
npm install
|
|
42
|
-
|
|
43
|
-
# 以链接模式安装插件
|
|
44
|
-
openclaw plugins install --link .
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### 3. 重启 Gateway
|
|
30
|
+
### 2. 重启 Gateway
|
|
48
31
|
|
|
49
32
|
安装完成后,重启 Gateway 以加载插件:
|
|
50
33
|
|
|
@@ -58,202 +41,83 @@ openclaw gateway restart
|
|
|
58
41
|
openclaw plugins list
|
|
59
42
|
```
|
|
60
43
|
|
|
61
|
-
您应该能看到 `
|
|
44
|
+
您应该能看到 `feishu` 插件且状态为 `loaded`。
|
|
62
45
|
|
|
63
46
|
## 飞书应用设置
|
|
64
47
|
|
|
65
48
|
1. 前往 [飞书开放平台](https://open.feishu.cn/app) (国内) 或 [Lark Developer Console](https://open.larksuite.com/app) (国际)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
| `im:message.p2p_msg:readonly` | 私聊 | 读取发给机器人的私聊消息 |
|
|
77
|
-
| `im:message.group_at_msg:readonly` | 群聊 | 接收群内 @机器人 的消息 |
|
|
78
|
-
| `im:message:send_as_bot` | 发送 | 以机器人身份发送消息 |
|
|
79
|
-
| `im:resource` | 媒体 | 上传和下载图片/文件 |
|
|
80
|
-
|
|
81
|
-
**可选权限(根据需求添加):**
|
|
82
|
-
|
|
83
|
-
| 权限 | 范围 | 说明 |
|
|
84
|
-
| :--- | :--- | :--- |
|
|
85
|
-
| `im:message.group_msg` | 群聊 | 读取所有群消息(敏感权限,慎用) |
|
|
86
|
-
| `im:message:readonly` | 读取 | 获取历史消息 |
|
|
87
|
-
| `im:message:update` | 编辑 | 更新/编辑已发送消息 |
|
|
88
|
-
| `im:message:recall` | 撤回 | 撤回已发送消息 |
|
|
89
|
-
| `im:message.reactions:read` | 表情 | 查看消息表情回复 |
|
|
90
|
-
|
|
91
|
-
5. 从“凭证与基础信息”中获取 **App ID** 和 **App Secret**(配置时需要用到)
|
|
92
|
-
|
|
93
|
-
6. 在“版本管理与发布”中发布您的应用
|
|
49
|
+
2. 创建新应用,在“应用能力”中启用 **机器人** 能力
|
|
50
|
+
3. 在“权限管理”中添加以下权限:
|
|
51
|
+
- `im:message` (消息)
|
|
52
|
+
- `im:message.p2p_msg:readonly` (读取私聊)
|
|
53
|
+
- `im:message.group_at_msg:readonly` (读取群聊 @ 提及)
|
|
54
|
+
- `im:message:send_as_bot` (以机器人身份发送消息)
|
|
55
|
+
- `im:resource` (媒体文件权限)
|
|
56
|
+
- `im:chat` (群组管理,用于获取群列表)
|
|
57
|
+
- `contact:user.employee:readonly` (通讯录读取,可选)
|
|
58
|
+
4. 在“版本管理与发布”中发布应用。
|
|
94
59
|
|
|
95
60
|
## 配置说明
|
|
96
61
|
|
|
97
|
-
###
|
|
98
|
-
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
#
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
#
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|--------|------|---------|-------------|
|
|
134
|
-
| `appId` | string | - | 飞书 App ID (必填) |
|
|
135
|
-
| `appSecret` | string | - | 飞书 App Secret (必填) |
|
|
136
|
-
| `connectionMode` | string | `websocket` | `webhook` 或 `websocket` |
|
|
137
|
-
| `webhookPort` | number | `3000` | Webhook 服务器端口 |
|
|
138
|
-
| `domain` | string | `feishu` | `feishu` (国内版) 或 `lark` (国际版) |
|
|
139
|
-
| `encryptKey` | string | - | 加密密钥(从事件订阅 > 加密策略获取) |
|
|
140
|
-
| `verificationToken` | string | - | 验证令牌(从事件订阅 > 加密策略获取) |
|
|
141
|
-
| `dmPolicy` | string | `pairing` | 私聊策略:`open`, `pairing`, 或 `allowlist` |
|
|
142
|
-
| `groupPolicy` | string | `open` | 群聊策略:`open`, `allowlist`, 或 `disabled` |
|
|
143
|
-
| `groupMentionGated` | boolean | `true` | 是否要求在群聊中 @机器人 |
|
|
144
|
-
|
|
145
|
-
## Webhook 模式设置
|
|
146
|
-
|
|
147
|
-
根据您的部署环境,选择相应的配置方式。
|
|
148
|
-
|
|
149
|
-
### 1. 开发环境(使用 ngrok)
|
|
150
|
-
|
|
151
|
-
推荐在本地开发调试时使用。
|
|
152
|
-
|
|
153
|
-
> **安全与隐私提示**:ngrok 会将您的本地服务器暴露到公网。请注意:
|
|
154
|
-
> - 不要公开分享您的 ngrok URL
|
|
155
|
-
> - 生产环境建议使用付费版 ngrok 或自建反向代理
|
|
156
|
-
> - 不使用时请关闭 ngrok 隧道
|
|
157
|
-
> - 建议配置飞书的 `encryptKey` 和 `verificationToken` 以增强安全性
|
|
158
|
-
|
|
159
|
-
1. 启动 ngrok 暴露本地 Webhook 端口:
|
|
160
|
-
|
|
161
|
-
```bash
|
|
162
|
-
ngrok http 3000
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
2. 从 ngrok 复制 HTTPS URL(例如:`https://abc123.ngrok.io`)
|
|
166
|
-
|
|
167
|
-
3. 在飞书开发者后台配置“事件订阅”:
|
|
168
|
-
- 添加事件:`im.message.receive_v1` (接收消息 v1.0)
|
|
169
|
-
- 将“请求地址”设置为您的 ngrok HTTPS URL(例如:`https://abc123.ngrok.io`)
|
|
170
|
-
|
|
171
|
-
### 2. 生产环境(服务器部署)
|
|
172
|
-
|
|
173
|
-
在服务器上部署时,**不需要**使用 ngrok。
|
|
174
|
-
|
|
175
|
-
1. **开放端口**:确保您的服务器防火墙(安全组)已开放插件使用的端口(默认是 `3000`)。
|
|
176
|
-
2. **配置地址**:在飞书开发者后台配置“事件订阅”:
|
|
177
|
-
- 将“请求地址”设置为您的服务器公网地址:`http://您的服务器IP:3000`。
|
|
178
|
-
3. **(推荐)反向代理**:建议使用 Nginx 或 Caddy 配置反向代理和 SSL 证书(HTTPS),然后将流量转发到 `3000` 端口。
|
|
179
|
-
|
|
180
|
-
### 3. 启动插件
|
|
181
|
-
|
|
182
|
-
1. 启动 OpenClaw:
|
|
183
|
-
|
|
184
|
-
```bash
|
|
185
|
-
openclaw start
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
2. Webhook 服务器会自动启动并处理 URL 验证。
|
|
189
|
-
|
|
190
|
-
## WebSocket 模式
|
|
191
|
-
|
|
192
|
-
WebSocket 模式适用于支持长连接的企业级飞书账号(自建应用)。将 `connectionMode` 设置为 `websocket`:
|
|
193
|
-
|
|
194
|
-
```bash
|
|
195
|
-
openclaw config set channels.lark.accounts.default.connectionMode 'websocket'
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
**优势:**
|
|
199
|
-
- **无需公网 IP**:不需要配置 ngrok 或反向代理,适合本地或内网环境。
|
|
200
|
-
- **配置简单**:只需在飞书后台开启“使用长连接接收事件”开关即可。
|
|
201
|
-
- **稳定性高**:插件支持自动重连。
|
|
202
|
-
|
|
203
|
-
**配置步骤:**
|
|
204
|
-
1. 在飞书开发者后台 -> **事件订阅**。
|
|
205
|
-
2. 在“订阅方式”中选择 **使用长连接接收事件**。
|
|
206
|
-
3. 确保已添加 `im.message.receive_v1` 事件。
|
|
207
|
-
|
|
208
|
-
## 多账号配置
|
|
209
|
-
|
|
210
|
-
您可以配置多个飞书账号:
|
|
211
|
-
|
|
212
|
-
```bash
|
|
213
|
-
openclaw config set channels.lark.accounts.work.appId 'cli_work_app'
|
|
214
|
-
openclaw config set channels.lark.accounts.work.appSecret 'work-secret'
|
|
215
|
-
openclaw config set channels.lark.accounts.personal.appId 'cli_personal_app'
|
|
216
|
-
openclaw config set channels.lark.accounts.personal.appSecret 'personal-secret'
|
|
62
|
+
### 配置文件示例 (`openclaw.yaml`)
|
|
63
|
+
|
|
64
|
+
```yaml
|
|
65
|
+
channels:
|
|
66
|
+
feishu:
|
|
67
|
+
accounts:
|
|
68
|
+
default:
|
|
69
|
+
enabled: true
|
|
70
|
+
appId: "cli_a9f722ad2cb9dccb"
|
|
71
|
+
appSecret: "********"
|
|
72
|
+
# 域名: "feishu" (国内) 或 "lark" (国际)
|
|
73
|
+
domain: "feishu"
|
|
74
|
+
# 连接模式: "websocket" (推荐) 或 "webhook"
|
|
75
|
+
connectionMode: "websocket"
|
|
76
|
+
# Webhook 相关 (仅在 webhook 模式需要)
|
|
77
|
+
# verificationToken: "********"
|
|
78
|
+
# encryptKey: "********"
|
|
79
|
+
# webhookPort: 3000
|
|
80
|
+
# 私聊策略: "pairing" | "open" | "allowlist"
|
|
81
|
+
dmPolicy: "pairing"
|
|
82
|
+
# 私聊白名单 (仅 dmPolicy=allowlist 时生效,填写 OpenID)
|
|
83
|
+
# dmAllowlist:
|
|
84
|
+
# - "ou_xxx"
|
|
85
|
+
# 群聊策略: "open" | "allowlist" | "disabled"
|
|
86
|
+
groupPolicy: "allowlist"
|
|
87
|
+
# 群聊白名单 (仅 groupPolicy=allowlist 时生效,填写 ChatID)
|
|
88
|
+
# groupAllowlist:
|
|
89
|
+
# - "oc_xxx"
|
|
90
|
+
# 群聊是否需要 @机器人
|
|
91
|
+
requireMention: true
|
|
92
|
+
# 媒体文件最大大小 (MB, 默认 30)
|
|
93
|
+
mediaMaxMb: 30
|
|
94
|
+
# 回复渲染模式: "auto" | "raw" | "card"
|
|
95
|
+
renderMode: "auto"
|
|
96
|
+
# 历史消息读取条数 (默认 10)
|
|
97
|
+
# historyLimit: 10
|
|
217
98
|
```
|
|
218
99
|
|
|
219
|
-
|
|
100
|
+
### 渲染模式说明
|
|
220
101
|
|
|
221
|
-
|
|
102
|
+
| 模式 | 说明 |
|
|
103
|
+
| :--- | :--- |
|
|
104
|
+
| **auto** | (默认) 自动检测:检测到代码块、列表或表格时使用卡片渲染,否则使用纯文本 |
|
|
105
|
+
| **raw** | 始终使用纯文本渲染,表格会被转换为 ASCII 文本 |
|
|
106
|
+
| **card** | 始终使用飞书交互式卡片渲染,支持 Markdown 语法高亮和高级布局 |
|
|
222
107
|
|
|
223
|
-
|
|
224
|
-
2. 检查回调 URL 是否配置正确且公网可访问
|
|
225
|
-
3. 检查权限是否已开启
|
|
226
|
-
4. 确保应用已发布(不仅是保存草稿)
|
|
108
|
+
## 开发者相关
|
|
227
109
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
在飞书开发者后台添加 `im:resource` 权限并重新发布应用。
|
|
231
|
-
|
|
232
|
-
### Webhook 服务器启动失败
|
|
233
|
-
|
|
234
|
-
检查端口 3000 是否被占用。可以修改端口:
|
|
110
|
+
如果您想参与开发:
|
|
235
111
|
|
|
236
112
|
```bash
|
|
237
|
-
|
|
113
|
+
git clone https://github.com/xwang152-jack/claw-lark.git
|
|
114
|
+
cd claw-lark
|
|
115
|
+
npm install
|
|
116
|
+
npm run typecheck
|
|
117
|
+
openclaw plugins install --link .
|
|
238
118
|
```
|
|
239
119
|
|
|
240
|
-
###
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
## 贡献
|
|
245
|
-
|
|
246
|
-
欢迎提交 Issue 和 Pull Request!如果您发现 Bug 或有功能建议,请在 https://github.com/xwang152-jack/claw-lark/issues 提交。
|
|
247
|
-
|
|
248
|
-
## 自动化发布 (CI/CD)
|
|
249
|
-
|
|
250
|
-
项目已配置 GitHub Actions。当你将代码推送到 `main` 分支时,如果 `package.json` 中的版本号发生了变化,系统会自动将其发布到 npm。
|
|
251
|
-
|
|
252
|
-
**配置步骤:**
|
|
253
|
-
1. 在 npm 官网创建一个 **Automation Token**。
|
|
254
|
-
2. 在 GitHub 仓库设置中,进入 **Settings > Secrets and variables > Actions**。
|
|
255
|
-
3. 添加一个新的 Repository secret,名称为 `NPM_TOKEN`,值为你的 npm token。
|
|
256
|
-
|
|
257
|
-
## 开源协议
|
|
258
|
-
|
|
259
|
-
MIT
|
|
120
|
+
### 常用命令
|
|
121
|
+
- `npm run lint`: 代码风格检查
|
|
122
|
+
- `npm run format`: 自动格式化代码
|
|
123
|
+
- `npm test`: 运行自动化测试
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import tseslint from "@typescript-eslint/eslint-plugin";
|
|
2
|
+
import tsParser from "@typescript-eslint/parser";
|
|
3
|
+
import prettierConfig from "eslint-config-prettier";
|
|
4
|
+
import prettierPlugin from "eslint-plugin-prettier";
|
|
5
|
+
|
|
6
|
+
export default [
|
|
7
|
+
prettierConfig,
|
|
8
|
+
{
|
|
9
|
+
files: ["**/*.ts"],
|
|
10
|
+
ignores: [
|
|
11
|
+
"**/*.test.ts",
|
|
12
|
+
"**/*.spec.ts",
|
|
13
|
+
"src/__tests__/**",
|
|
14
|
+
],
|
|
15
|
+
languageOptions: {
|
|
16
|
+
parser: tsParser,
|
|
17
|
+
parserOptions: {
|
|
18
|
+
ecmaVersion: 2022,
|
|
19
|
+
sourceType: "module",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
plugins: {
|
|
23
|
+
"@typescript-eslint": tseslint,
|
|
24
|
+
prettier: prettierPlugin,
|
|
25
|
+
},
|
|
26
|
+
rules: {
|
|
27
|
+
...tseslint.configs.recommended.rules,
|
|
28
|
+
"no-undef": "off",
|
|
29
|
+
"prettier/prettier": "error",
|
|
30
|
+
"@typescript-eslint/no-explicit-any": "warn",
|
|
31
|
+
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
];
|
package/index.ts
CHANGED
|
@@ -29,9 +29,9 @@ export type {
|
|
|
29
29
|
} from "./src/types.js";
|
|
30
30
|
|
|
31
31
|
const plugin = {
|
|
32
|
-
id: "
|
|
33
|
-
name: "
|
|
34
|
-
description: "Lark
|
|
32
|
+
id: "feishu",
|
|
33
|
+
name: "Feishu",
|
|
34
|
+
description: "Feishu / Lark channel plugin for OpenClaw",
|
|
35
35
|
configSchema: emptyPluginConfigSchema(),
|
|
36
36
|
register(api: OpenClawPluginApi) {
|
|
37
37
|
setLarkRuntime(api);
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"id": "
|
|
3
|
-
"channels": ["
|
|
2
|
+
"id": "feishu",
|
|
3
|
+
"channels": ["feishu"],
|
|
4
4
|
"configSchema": {
|
|
5
5
|
"type": "object",
|
|
6
6
|
"properties": {
|
|
@@ -12,57 +12,78 @@
|
|
|
12
12
|
"enabled": {
|
|
13
13
|
"type": "boolean",
|
|
14
14
|
"default": true,
|
|
15
|
-
"description": "
|
|
15
|
+
"description": "是否启用此账号"
|
|
16
16
|
},
|
|
17
17
|
"appId": {
|
|
18
18
|
"type": "string",
|
|
19
|
-
"description": "
|
|
19
|
+
"description": "飞书应用 App ID (cli_xxx)"
|
|
20
20
|
},
|
|
21
21
|
"appSecret": {
|
|
22
22
|
"type": "string",
|
|
23
|
-
"description": "
|
|
23
|
+
"description": "飞书应用 App Secret"
|
|
24
24
|
},
|
|
25
25
|
"encryptKey": {
|
|
26
26
|
"type": "string",
|
|
27
|
-
"description": "
|
|
27
|
+
"description": "事件解密密钥 (可选)"
|
|
28
28
|
},
|
|
29
29
|
"domain": {
|
|
30
30
|
"type": "string",
|
|
31
31
|
"enum": ["lark", "feishu"],
|
|
32
32
|
"default": "feishu",
|
|
33
|
-
"description": "API
|
|
33
|
+
"description": "API 域名: feishu (国内) 或 lark (国际)"
|
|
34
34
|
},
|
|
35
35
|
"connectionMode": {
|
|
36
36
|
"type": "string",
|
|
37
37
|
"enum": ["websocket", "webhook"],
|
|
38
38
|
"default": "websocket",
|
|
39
|
-
"description": "
|
|
39
|
+
"description": "连接模式: websocket (企业自建应用推荐) 或 webhook"
|
|
40
40
|
},
|
|
41
41
|
"verificationToken": {
|
|
42
42
|
"type": "string",
|
|
43
|
-
"description": "
|
|
43
|
+
"description": "事件校验令牌 (用于 Webhook 模式)"
|
|
44
44
|
},
|
|
45
45
|
"webhookPort": {
|
|
46
46
|
"type": "number",
|
|
47
47
|
"default": 3000,
|
|
48
|
-
"description": "
|
|
48
|
+
"description": "Webhook 服务端口"
|
|
49
49
|
},
|
|
50
50
|
"dmPolicy": {
|
|
51
51
|
"type": "string",
|
|
52
52
|
"enum": ["open", "pairing", "allowlist"],
|
|
53
53
|
"default": "pairing",
|
|
54
|
-
"description": "
|
|
54
|
+
"description": "私聊策略"
|
|
55
|
+
},
|
|
56
|
+
"dmAllowlist": {
|
|
57
|
+
"type": "array",
|
|
58
|
+
"items": { "type": "string" },
|
|
59
|
+
"description": "私聊白名单 (OpenID)"
|
|
55
60
|
},
|
|
56
61
|
"groupPolicy": {
|
|
57
62
|
"type": "string",
|
|
58
63
|
"enum": ["open", "allowlist", "disabled"],
|
|
59
64
|
"default": "open",
|
|
60
|
-
"description": "
|
|
65
|
+
"description": "群聊策略"
|
|
66
|
+
},
|
|
67
|
+
"groupAllowlist": {
|
|
68
|
+
"type": "array",
|
|
69
|
+
"items": { "type": "string" },
|
|
70
|
+
"description": "群聊白名单 (ChatID)"
|
|
61
71
|
},
|
|
62
|
-
"
|
|
72
|
+
"requireMention": {
|
|
63
73
|
"type": "boolean",
|
|
64
74
|
"default": true,
|
|
65
|
-
"description": "
|
|
75
|
+
"description": "群聊是否需要 @ 机器人"
|
|
76
|
+
},
|
|
77
|
+
"mediaMaxMb": {
|
|
78
|
+
"type": "number",
|
|
79
|
+
"default": 30,
|
|
80
|
+
"description": "媒体文件最大大小 (MB)"
|
|
81
|
+
},
|
|
82
|
+
"renderMode": {
|
|
83
|
+
"type": "string",
|
|
84
|
+
"enum": ["auto", "raw", "card"],
|
|
85
|
+
"default": "auto",
|
|
86
|
+
"description": "回复渲染模式"
|
|
66
87
|
}
|
|
67
88
|
}
|
|
68
89
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xwang152/claw-lark",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Lark/Feishu channel plugin for OpenClaw with WebSocket and Webhook support",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"scripts": {
|
|
29
29
|
"typecheck": "tsc -p tsconfig.json",
|
|
30
|
-
"lint": "eslint src/**/*.ts index.ts",
|
|
30
|
+
"lint": "eslint src/**/*.ts index.ts --no-warn-ignored",
|
|
31
31
|
"format": "prettier --write src/**/*.ts index.ts",
|
|
32
32
|
"test": "vitest run",
|
|
33
33
|
"test:watch": "vitest",
|