@ulthon/ul-opencode-event 0.1.27 → 0.1.30
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 +147 -431
- package/dist/cli.js +158 -2
- package/dist/config.d.ts +1 -3
- package/dist/config.js +14 -13
- package/dist/feishu.d.ts +50 -0
- package/dist/feishu.js +209 -0
- package/dist/formatters.d.ts +2 -1
- package/dist/formatters.js +7 -2
- package/dist/handler.js +13 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +61 -1
- package/dist/types.d.ts +3 -2
- package/dist/updater.d.ts +1 -0
- package/dist/updater.js +5 -5
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,431 +1,147 @@
|
|
|
1
|
-
# @ulthon/ul-opencode-event
|
|
2
|
-
|
|
3
|
-
**Never miss an OpenCode notification, even when you're away from your desk.**
|
|
4
|
-
|
|
5
|
-
OpenCode multi-channel notification plugin that keeps you informed wherever you are.
|
|
6
|
-
|
|
7
|
-
## Why ul-opencode-event?
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
## Roadmap
|
|
15
|
-
|
|
16
|
-
| Channel | Status | Description |
|
|
17
|
-
|---------|--------|-------------|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
npm install @ulthon/ul-opencode-event
|
|
32
|
-
|
|
33
|
-
#
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
{
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
###
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
|
93
|
-
|
|
|
94
|
-
|
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
| `host` | string | Yes | SMTP server hostname or IPv4/IPv6 address |
|
|
149
|
-
| `port` | number | Yes | SMTP port (465 for SSL, 587 for STARTTLS) |
|
|
150
|
-
| `secure` | boolean | No | Use SSL (default: true for port 465) |
|
|
151
|
-
| `localAddress` | string | No | Local interface to bind for IPv4/IPv6 control |
|
|
152
|
-
| `auth.user` | string | Yes | SMTP username (usually your email) |
|
|
153
|
-
| `auth.pass` | string | Yes | SMTP password or authorization code |
|
|
154
|
-
|
|
155
|
-
### DingTalk 机器人配置
|
|
156
|
-
|
|
157
|
-
通过钉钉群自定义机器人接收 OpenCode 通知消息,支持 Markdown 格式和 @人功能。
|
|
158
|
-
|
|
159
|
-
#### 获取 Webhook 和 Secret
|
|
160
|
-
|
|
161
|
-
1. 打开钉钉群,点击右上角 **群设置** > **智能群助手** > **添加机器人**
|
|
162
|
-
2. 选择 **自定义** 机器人,输入机器人名称和头像
|
|
163
|
-
3. **安全设置** 选择 **加签** 模式(推荐),复制生成的 **Secret**
|
|
164
|
-
4. 完成后复制 **Webhook 地址**(格式: `https://oapi.dingtalk.com/robot/send?access_token=xxx`)
|
|
165
|
-
|
|
166
|
-
> **建议**: 始终开启加签模式,避免 Webhook 被恶意调用。
|
|
167
|
-
|
|
168
|
-
#### 最小配置
|
|
169
|
-
|
|
170
|
-
```json
|
|
171
|
-
{
|
|
172
|
-
"channels": [
|
|
173
|
-
{
|
|
174
|
-
"type": "dingtalk",
|
|
175
|
-
"enabled": true,
|
|
176
|
-
"name": "钉钉通知",
|
|
177
|
-
"config": {
|
|
178
|
-
"webhook": "https://oapi.dingtalk.com/robot/send?access_token=YOUR_ACCESS_TOKEN"
|
|
179
|
-
},
|
|
180
|
-
"events": {
|
|
181
|
-
"idle": true,
|
|
182
|
-
"error": true
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
]
|
|
186
|
-
}
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
#### 完整配置示例
|
|
190
|
-
|
|
191
|
-
```json
|
|
192
|
-
{
|
|
193
|
-
"channels": [
|
|
194
|
-
{
|
|
195
|
-
"type": "dingtalk",
|
|
196
|
-
"enabled": true,
|
|
197
|
-
"name": "钉钉通知",
|
|
198
|
-
"config": {
|
|
199
|
-
"webhook": "https://oapi.dingtalk.com/robot/send?access_token=YOUR_ACCESS_TOKEN",
|
|
200
|
-
"secret": "SEC-your-secret-key-here",
|
|
201
|
-
"at": {
|
|
202
|
-
"atMobiles": ["13800138000"],
|
|
203
|
-
"atAll": false
|
|
204
|
-
}
|
|
205
|
-
},
|
|
206
|
-
"events": {
|
|
207
|
-
"created": false,
|
|
208
|
-
"idle": true,
|
|
209
|
-
"error": true
|
|
210
|
-
},
|
|
211
|
-
"templates": {
|
|
212
|
-
"idle": {
|
|
213
|
-
"body": "### [{{projectName}}] 任务完成\n\n**耗时**: {{duration}}\n**消息**: {{message}}\n\n> {{timestamp}}"
|
|
214
|
-
},
|
|
215
|
-
"error": {
|
|
216
|
-
"body": "### [{{projectName}}] 任务错误\n\n**错误**: {{error}}\n\n> {{timestamp}}"
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
]
|
|
221
|
-
}
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
#### DingTalk 配置字段说明
|
|
225
|
-
|
|
226
|
-
| Field | Type | Required | Default | Description |
|
|
227
|
-
|-------|------|----------|---------|-------------|
|
|
228
|
-
| `webhook` | string | Yes | - | 钉钉机器人 Webhook 地址 |
|
|
229
|
-
| `secret` | string | No | - | 加签密钥(安全设置选"加签"时提供) |
|
|
230
|
-
| `at.atMobiles` | string[] | No | - | 要 @的成员手机号列表 |
|
|
231
|
-
| `at.atAll` | boolean | No | false | 是否 @所有人 |
|
|
232
|
-
|
|
233
|
-
> **注意**: 钉钉通道不需要 `recipients` 字段,消息发送到机器人所在的钉钉群。
|
|
234
|
-
|
|
235
|
-
#### @人功能
|
|
236
|
-
|
|
237
|
-
钉钉支持在消息中 @指定群成员:
|
|
238
|
-
|
|
239
|
-
- **@指定成员**: 在 `at.atMobiles` 中填写手机号数组,如 `["13800138000", "13900139000"]`
|
|
240
|
-
- **@所有人**: 设置 `at.atAll` 为 `true`
|
|
241
|
-
- **不@任何人**: 不配置 `at` 字段,或设为空对象 `{}`
|
|
242
|
-
|
|
243
|
-
默认行为是不 @任何人。如果同时设置了 `atMobiles` 和 `atAll=true`,将以 `atAll` 为准。
|
|
244
|
-
|
|
245
|
-
#### 钉钉常见问题
|
|
246
|
-
|
|
247
|
-
**Q: 签名失败 (signature mismatch) 怎么办?**
|
|
248
|
-
|
|
249
|
-
A: 检查以下几点:
|
|
250
|
-
1. 确认 `secret` 值与钉钉后台显示的完全一致(注意前后空格)
|
|
251
|
-
2. 确认服务器时间与标准时间偏差不超过 1 小时
|
|
252
|
-
3. 如果使用代理/TUN 环境,确认网络能正常访问 `oapi.dingtalk.com`
|
|
253
|
-
|
|
254
|
-
**Q: 消息发送频率有限制吗?**
|
|
255
|
-
|
|
256
|
-
A: 有。每个机器人每条消息不超过 20 条/分钟。如果短时间内产生大量事件通知(如批量文件编辑),部分消息可能被限流丢弃。
|
|
257
|
-
|
|
258
|
-
**Q: 钉钉 Markdown 支持哪些格式?**
|
|
259
|
-
|
|
260
|
-
A: 钉钉 Markdown 支持有限的语法子集:
|
|
261
|
-
- 标题: `#` `##` `###`
|
|
262
|
-
- 加粗: `**text**`
|
|
263
|
-
- 引用: `>`
|
|
264
|
-
- 有序/无序列表
|
|
265
|
-
- 链接: `[text](url)`
|
|
266
|
-
- 图片: ``
|
|
267
|
-
|
|
268
|
-
不支持表格、代码块高亮、HTML 标签等。编写自定义模板时请使用支持的语法。
|
|
269
|
-
|
|
270
|
-
**Q: 消息丢失或收不到怎么办?**
|
|
271
|
-
|
|
272
|
-
A: 排查步骤:
|
|
273
|
-
1. 运行 `npx @ulthon/ul-opencode-event test --channel "钉钉通知"` 测试连接
|
|
274
|
-
2. 设置环境变量 `UL_OPENCODE_EVENT_DEBUG=1` 查看详细日志
|
|
275
|
-
3. 检查钉钉群中机器人是否已被移除或禁用
|
|
276
|
-
4. 确认 Webhook 地址中的 `access_token` 未过期(通常不会过期)
|
|
277
|
-
|
|
278
|
-
### IPv4/IPv6 Configuration
|
|
279
|
-
|
|
280
|
-
By default, the plugin automatically supports both IPv4 and IPv6. Nodemailer will:
|
|
281
|
-
- Resolve DNS to both IPv4 (A) and IPv6 (AAAA) records
|
|
282
|
-
- Try both address families in parallel
|
|
283
|
-
- Use whichever connects successfully
|
|
284
|
-
|
|
285
|
-
#### Force IPv4
|
|
286
|
-
If you want to force IPv4 connection (e.g., IPv6 is unavailable or unstable):
|
|
287
|
-
```json
|
|
288
|
-
{
|
|
289
|
-
"config": {
|
|
290
|
-
"host": "smtp.qq.com",
|
|
291
|
-
"port": 465,
|
|
292
|
-
"secure": true,
|
|
293
|
-
"localAddress": "0.0.0.0",
|
|
294
|
-
"auth": {
|
|
295
|
-
"user": "your@qq.com",
|
|
296
|
-
"pass": "authorization-code"
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
#### Force IPv6
|
|
303
|
-
If you want to force IPv6 connection:
|
|
304
|
-
```json
|
|
305
|
-
{
|
|
306
|
-
"config": {
|
|
307
|
-
"host": "smtp.example.com",
|
|
308
|
-
"port": 465,
|
|
309
|
-
"secure": true,
|
|
310
|
-
"localAddress": "::",
|
|
311
|
-
"auth": {
|
|
312
|
-
"user": "your@example.com",
|
|
313
|
-
"pass": "your-password"
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
#### Use IPv6 Address as Host
|
|
320
|
-
You can also use an IPv6 address directly as the host:
|
|
321
|
-
```json
|
|
322
|
-
{
|
|
323
|
-
"config": {
|
|
324
|
-
"host": "2001:db8::1",
|
|
325
|
-
"port": 465,
|
|
326
|
-
"secure": true,
|
|
327
|
-
"auth": {
|
|
328
|
-
"user": "your@example.com",
|
|
329
|
-
"pass": "your-password"
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
### Events Configuration
|
|
336
|
-
| Event | Default | Description |
|
|
337
|
-
|-------|---------|-------------|
|
|
338
|
-
| `created` | false | When a new session starts |
|
|
339
|
-
| `idle` | true | When a session completes (AI finishes responding) |
|
|
340
|
-
| `error` | true | When a session encounters an error |
|
|
341
|
-
### Template Variables
|
|
342
|
-
| Variable | Description | Available Events |
|
|
343
|
-
|----------|-------------|------------------|
|
|
344
|
-
| `{{eventType}}` | Event type (created, idle, error) | All |
|
|
345
|
-
| `{{timestamp}}` | ISO 8601 timestamp | All |
|
|
346
|
-
| `{{projectName}}` | Project short name (directory basename or config value) | All |
|
|
347
|
-
| `{{projectPath}}` | Project full path (e.g. `/home/user/my-project`) | All |
|
|
348
|
-
| `{{sessionId}}` | Session ID | All |
|
|
349
|
-
| `{{message}}` | Completion message | idle |
|
|
350
|
-
| `{{duration}}` | Task duration | idle |
|
|
351
|
-
| `{{error}}` | Error message | error |
|
|
352
|
-
## CLI Tool
|
|
353
|
-
This package includes a CLI tool to test your notification channel configuration.
|
|
354
|
-
### Test Command
|
|
355
|
-
```bash
|
|
356
|
-
# Test all channels (validates config, tests connection, sends test email)
|
|
357
|
-
npx @ulthon/ul-opencode-event test
|
|
358
|
-
|
|
359
|
-
# Test a specific channel by name
|
|
360
|
-
npx @ulthon/ul-opencode-event test --channel "My Email"
|
|
361
|
-
|
|
362
|
-
# Only verify connection without sending email
|
|
363
|
-
npx @ulthon/ul-opencode-event test --no-send
|
|
364
|
-
```
|
|
365
|
-
### Test Output Example
|
|
366
|
-
```
|
|
367
|
-
[ul-opencode-event-cli] Starting channel test...
|
|
368
|
-
[ul-opencode-event-cli] Loaded project config: ./ul-opencode-event.json
|
|
369
|
-
[ul-opencode-event-cli] Found 1 channel(s) to test
|
|
370
|
-
|
|
371
|
-
[ul-opencode-event-cli] Testing channel: "My Email"
|
|
372
|
-
Type: smtp
|
|
373
|
-
Recipients: user@example.com
|
|
374
|
-
|
|
375
|
-
[1/3] Validating configuration...
|
|
376
|
-
[OK] Configuration is valid
|
|
377
|
-
|
|
378
|
-
[2/3] Testing SMTP connection to smtp.example.com:465...
|
|
379
|
-
[OK] Connection successful
|
|
380
|
-
|
|
381
|
-
[3/3] Sending test email...
|
|
382
|
-
[OK] Test email sent successfully
|
|
383
|
-
Message ID: <xxx>
|
|
384
|
-
|
|
385
|
-
[SUCCESS] Channel "My Email" passed all tests
|
|
386
|
-
|
|
387
|
-
[ul-opencode-event-cli] Test Summary:
|
|
388
|
-
Passed: 1
|
|
389
|
-
Failed: 0
|
|
390
|
-
```
|
|
391
|
-
## Troubleshooting
|
|
392
|
-
### SMTP connection failed
|
|
393
|
-
**Q: Does this plugin support IPv4? IPv6?**
|
|
394
|
-
**A: Yes, both are supported.** The plugin uses nodemailer which automatically:
|
|
395
|
-
- Resolves DNS to both IPv4 (A) and IPv6 (AAAA) records
|
|
396
|
-
- Tries both address families in parallel
|
|
397
|
-
- Falls back if one fails
|
|
398
|
-
**Common issues:**
|
|
399
|
-
1. **Wrong password**: Use authorization code for QQ/163, App Password for Gmail
|
|
400
|
-
2. **Wrong port**: Use 465 for SSL, 587 for STARTTLS
|
|
401
|
-
3. **Firewall**: Ensure outbound connections to SMTP port are allowed
|
|
402
|
-
4. **IPv6 issues**: If your network has incomplete IPv6, connections may timeout
|
|
403
|
-
- Check your network's IPv6 configuration
|
|
404
|
-
- Contact your network administrator if needed
|
|
405
|
-
### Debug mode
|
|
406
|
-
```bash
|
|
407
|
-
# Enable debug logging
|
|
408
|
-
UL_OPENCODE_EVENT_DEBUG=1 npx @ulthon/ul-opencode-event test
|
|
409
|
-
```
|
|
410
|
-
### No notifications sent
|
|
411
|
-
1. Check if `enabled: true` is set
|
|
412
|
-
2. Check if the event type is enabled in `events`
|
|
413
|
-
3. Check SMTP credentials are correct
|
|
414
|
-
4. Ensure config file exists at correct location
|
|
415
|
-
## Local Development
|
|
416
|
-
```bash
|
|
417
|
-
# Build
|
|
418
|
-
npm run build
|
|
419
|
-
|
|
420
|
-
# Test locally without publishing
|
|
421
|
-
node dist/cli.js test
|
|
422
|
-
|
|
423
|
-
# Or use npm link
|
|
424
|
-
npm link
|
|
425
|
-
npx @ulthon/ul-opencode-event test
|
|
426
|
-
|
|
427
|
-
# Unlink when done
|
|
428
|
-
npm unlink -g @ulthon/ul-opencode-event
|
|
429
|
-
```
|
|
430
|
-
## License
|
|
431
|
-
MIT
|
|
1
|
+
# @ulthon/ul-opencode-event
|
|
2
|
+
|
|
3
|
+
**Never miss an OpenCode notification, even when you're away from your desk.**
|
|
4
|
+
|
|
5
|
+
OpenCode multi-channel notification plugin that keeps you informed wherever you are. Get notified when tasks complete or errors occur via email, DingTalk, or Feishu.
|
|
6
|
+
|
|
7
|
+
## Why ul-opencode-event?
|
|
8
|
+
|
|
9
|
+
- **Remote Development Friendly** - Get notified when your AI coding agent finishes a task
|
|
10
|
+
- **Multi-Channel Support** - SMTP email, DingTalk robot, Feishu robot, with more planned
|
|
11
|
+
- **Real-time Alerts** - Immediate notifications on session `idle` or `error` events
|
|
12
|
+
- **Easy Configuration** - Simple JSON config with template variables
|
|
13
|
+
|
|
14
|
+
## Roadmap
|
|
15
|
+
|
|
16
|
+
| Channel | Status | Description |
|
|
17
|
+
|---------|--------|-------------|
|
|
18
|
+
| SMTP (Email) | Available | Email notifications via any SMTP server |
|
|
19
|
+
| DingTalk | Available | DingTalk robot notifications |
|
|
20
|
+
| Feishu | Available | Feishu robot notifications |
|
|
21
|
+
| Webhook | Planned | HTTP webhook for custom integrations |
|
|
22
|
+
| Telegram | Planned | Telegram bot notifications |
|
|
23
|
+
| Slack | Planned | Slack incoming webhooks |
|
|
24
|
+
| WeChat Work | Planned | Enterprise WeChat |
|
|
25
|
+
|
|
26
|
+
**Have a channel request?** Open an issue on our [Gitee repo](https://gitee.com/augushong/ul-opencode-event)!
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install @ulthon/ul-opencode-event
|
|
32
|
+
cp node_modules/@ulthon/ul-opencode-event/examples/ul-opencode-event.json ./
|
|
33
|
+
# Edit config with your SMTP credentials
|
|
34
|
+
npx @ulthon/ul-opencode-event test
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Add to `~/.config/opencode/opencode.json`:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{ "plugin": ["@ulthon/ul-opencode-event"] }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Configuration
|
|
44
|
+
|
|
45
|
+
### File Locations
|
|
46
|
+
|
|
47
|
+
1. **Project-level**: `.opencode/ul-opencode-event.json` or `./ul-opencode-event.json`
|
|
48
|
+
2. **Global**: `~/.config/opencode/ul-opencode-event.json`
|
|
49
|
+
|
|
50
|
+
Project-level config overrides global (channels merged by name).
|
|
51
|
+
|
|
52
|
+
### Minimal SMTP Example
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"channels": [{
|
|
57
|
+
"type": "smtp",
|
|
58
|
+
"enabled": true,
|
|
59
|
+
"name": "My Email",
|
|
60
|
+
"config": {
|
|
61
|
+
"host": "smtp.qq.com",
|
|
62
|
+
"port": 465,
|
|
63
|
+
"secure": true,
|
|
64
|
+
"auth": { "user": "your-email@example.com", "pass": "your-app-password" }
|
|
65
|
+
},
|
|
66
|
+
"recipients": ["receiver@example.com"],
|
|
67
|
+
"events": { "idle": true, "error": true }
|
|
68
|
+
}]
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Common SMTP Servers
|
|
73
|
+
|
|
74
|
+
| Provider | Host | Port | Auth |
|
|
75
|
+
|----------|------|------|------|
|
|
76
|
+
| QQ Mail | smtp.qq.com | 465 | Authorization code |
|
|
77
|
+
| 163 Mail | smtp.163.com | 465 | Authorization code |
|
|
78
|
+
| Gmail | smtp.gmail.com | 587 | App Password |
|
|
79
|
+
| Outlook | smtp.office365.com | 587 | Password |
|
|
80
|
+
|
|
81
|
+
> For QQ/163 use the authorization code, not login password. For Gmail use an App Password with 2FA.
|
|
82
|
+
|
|
83
|
+
### Other Channels
|
|
84
|
+
|
|
85
|
+
- **DingTalk**: See [docs/dingtalk-channel.md](docs/dingtalk-channel.md) for robot setup, @mentions, and FAQ.
|
|
86
|
+
- **Feishu**: See [docs/feishu-channel.md](docs/feishu-channel.md) for robot setup, card format, and FAQ.
|
|
87
|
+
|
|
88
|
+
### Events
|
|
89
|
+
|
|
90
|
+
| Event | Default | Description |
|
|
91
|
+
|-------|---------|-------------|
|
|
92
|
+
| `created` | false | When a new session starts |
|
|
93
|
+
| `idle` | true | When a session completes |
|
|
94
|
+
| `error` | true | When a session encounters an error |
|
|
95
|
+
|
|
96
|
+
### Template Variables
|
|
97
|
+
|
|
98
|
+
| Variable | Description | Events |
|
|
99
|
+
|----------|-------------|--------|
|
|
100
|
+
| `{{eventType}}` | Event type (created, idle, error) | All |
|
|
101
|
+
| `{{timestamp}}` | ISO 8601 timestamp | All |
|
|
102
|
+
| `{{projectName}}` | Project short name | All |
|
|
103
|
+
| `{{projectPath}}` | Project full path | All |
|
|
104
|
+
| `{{sessionId}}` | Session ID | All |
|
|
105
|
+
| `{{message}}` | Completion message | idle |
|
|
106
|
+
| `{{duration}}` | Task duration | idle |
|
|
107
|
+
| `{{error}}` | Error message | error |
|
|
108
|
+
|
|
109
|
+
See [docs/template-configuration.md](docs/template-configuration.md) for customization details.
|
|
110
|
+
|
|
111
|
+
## CLI Tool
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npx @ulthon/ul-opencode-event test # Test all channels
|
|
115
|
+
npx @ulthon/ul-opencode-event test --channel "My Email" # Test specific channel
|
|
116
|
+
npx @ulthon/ul-opencode-event test --no-send # Verify connection only
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Documentation
|
|
120
|
+
|
|
121
|
+
| Document | Description |
|
|
122
|
+
|----------|-------------|
|
|
123
|
+
| [Configuration](docs/configuration.md) | Config file locations, merge rules, events |
|
|
124
|
+
| [SMTP Channel](docs/smtp-channel.md) | Email configuration, IPv4/IPv6, FAQ |
|
|
125
|
+
| [DingTalk Channel](docs/dingtalk-channel.md) | Configuration, @mentions, FAQ |
|
|
126
|
+
| [Feishu Channel](docs/feishu-channel.md) | Configuration, card format, FAQ |
|
|
127
|
+
| [Template Configuration](docs/template-configuration.md) | Template variables and customization |
|
|
128
|
+
| [Channel Development](docs/channel-development.md) | Developing new notification channels |
|
|
129
|
+
|
|
130
|
+
## Troubleshooting
|
|
131
|
+
|
|
132
|
+
- **Wrong password**: Use authorization code for QQ/163, App Password for Gmail
|
|
133
|
+
- **Wrong port**: Use 465 for SSL, 587 for STARTTLS
|
|
134
|
+
- **No notifications**: Check `enabled: true`, event types, and config file location
|
|
135
|
+
- **IPv4/IPv6**: Both supported; if IPv6 unstable, set `localAddress` to `"0.0.0.0"`
|
|
136
|
+
- **Debug mode**: `UL_OPENCODE_EVENT_DEBUG=1 npx @ulthon/ul-opencode-event test`
|
|
137
|
+
|
|
138
|
+
## Local Development
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
npm run build && node dist/cli.js test
|
|
142
|
+
# Or: npm link && npx @ulthon/ul-opencode-event test
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## License
|
|
146
|
+
|
|
147
|
+
MIT
|