@yoooclaw/phone-notifications 1.4.16
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/LICENSE +674 -0
- package/README.md +344 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.js +6336 -0
- package/dist/index.js.map +1 -0
- package/openclaw.plugin.json +62 -0
- package/package.json +58 -0
- package/skills/light-rule-to-memory/SKILL.md +170 -0
- package/skills/notification-analytics/SKILL.md +196 -0
- package/skills/notification-monitor/SKILL.md +102 -0
- package/skills/notification-monitor/references/README.md +28 -0
- package/skills/notification-monitor/references/task_fetch_example.py +137 -0
- package/skills/notification-search/SKILL.md +141 -0
- package/skills/notification-to-memory/SKILL.md +273 -0
package/README.md
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# @openclaw/phone-notifications
|
|
2
|
+
|
|
3
|
+
OpenClaw 手机通知同步插件:接收手机通知并写入本地 JSON 文件系统,供 Agent 查询和消费。
|
|
4
|
+
|
|
5
|
+
## 工作方式
|
|
6
|
+
|
|
7
|
+
插件支持两种接入模式:
|
|
8
|
+
|
|
9
|
+
1. Gateway Native(默认)
|
|
10
|
+
- 手机端通过 gateway 已有连接调用 `notifications.push`
|
|
11
|
+
- 插件通过 `registerGatewayMethod` 接收 `params.items`
|
|
12
|
+
|
|
13
|
+
2. HTTP 备选模式
|
|
14
|
+
- 开启 `httpEnabled=true` 后,注册 `POST /notifications`
|
|
15
|
+
- 通过 `Authorization: Bearer <apiKey>` 鉴权
|
|
16
|
+
|
|
17
|
+
## 存储设计
|
|
18
|
+
|
|
19
|
+
通知按以下目录结构写入(JSON):
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
<workspace>/notifications/
|
|
23
|
+
├── 2026-03-02.json
|
|
24
|
+
├── 2026-03-03.json
|
|
25
|
+
└── 2026-03-04.json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
补充规则:
|
|
29
|
+
- `workspaceDir` 可用时,根目录是 `<workspace>/notifications`
|
|
30
|
+
- `workspaceDir` 不可用或不可写时,回退到 `<stateDir>/plugins/phone-notifications/notifications`
|
|
31
|
+
- 通知写入 `YYYY-MM-DD.json` 的 JSON 数组(append-only)
|
|
32
|
+
- 通知条目字段为 `appName`、`title`、`content`、`timestamp`(ISO 8601 含时区)
|
|
33
|
+
- 同一天内按 `notification-id` 去重(使用内部索引文件)
|
|
34
|
+
- `retentionDays`(默认 30)会清理过期日期文件
|
|
35
|
+
|
|
36
|
+
## 前置要求
|
|
37
|
+
|
|
38
|
+
- **Node.js >= 22.12.0**(含 npm)
|
|
39
|
+
- **curl**(用于下载安装包)
|
|
40
|
+
- **tar**
|
|
41
|
+
|
|
42
|
+
## 安装
|
|
43
|
+
|
|
44
|
+
推荐使用一键安装脚本,脚本会自动从 CDN 获取最新版本、下载、解压、注册插件并写入配置。
|
|
45
|
+
|
|
46
|
+
### 最简安装(自动获取最新版本)
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
curl -fsSL https://cdn.yoootek.com/openclaw-plugin/install.sh | bash
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 指定版本安装
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
curl -fsSL https://cdn.yoootek.com/openclaw-plugin/install.sh | bash -s -- --version 1.2.3
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 带 Token 安装
|
|
59
|
+
|
|
60
|
+
安装时同时写入灯控鉴权 Token(写入 `~/.openclaw/credentials.json`):
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
curl -fsSL https://cdn.yoootek.com/openclaw-plugin/install.sh | bash -s -- --token eyJhbGciOi...
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 使用本地包安装
|
|
67
|
+
|
|
68
|
+
如果已有 `.tgz` 文件,可跳过下载直接安装:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
bash install.sh --tgz-url ./yoooclaw-phone-notifications-1.2.3.tgz
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 全部安装选项
|
|
75
|
+
|
|
76
|
+
| 选项 | 说明 | 默认值 |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| `--version <ver>` | 指定版本号 | 自动获取最新版本 |
|
|
79
|
+
| `--tgz-url <url\|path>` | 直接指定插件包地址(跳过版本检测) | - |
|
|
80
|
+
| `--target-dir <path>` | 安装目录 | `~/.openclaw/extensions/phone-notifications` |
|
|
81
|
+
| `--token <token>` | 灯控鉴权 Token | - |
|
|
82
|
+
| `--retention-days <n>` | 通知数据保留天数 | 30 |
|
|
83
|
+
|
|
84
|
+
### 安装脚本做了什么
|
|
85
|
+
|
|
86
|
+
1. 从 CDN 下载最新版本的插件 tgz 包(或使用你指定的版本/地址)
|
|
87
|
+
2. 解压并验证包完整性(检查 `package.json`、入口文件可加载)
|
|
88
|
+
3. 备份旧版本(如有),原子替换到 `~/.openclaw/extensions/phone-notifications`
|
|
89
|
+
4. 写入 `~/.openclaw/openclaw.json` 配置:
|
|
90
|
+
- `plugins.allow` — 将插件加入白名单
|
|
91
|
+
- `plugins.entries` — 启用插件,合并用户配置
|
|
92
|
+
- `plugins.installs` — 记录安装来源和版本
|
|
93
|
+
- 清理该插件旧的 `plugins.load.paths` / 旧安装记录,避免继续命中之前通过 `openclaw plugins install` 或 `--link` 保留的副本
|
|
94
|
+
5. 如传入 `--token`,写入 `~/.openclaw/credentials.json`
|
|
95
|
+
6. 安装失败时自动回滚到旧版本
|
|
96
|
+
|
|
97
|
+
### 升级
|
|
98
|
+
|
|
99
|
+
升级方式与安装相同,重新运行安装脚本即可。脚本会自动备份旧版本并替换。
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
curl -fsSL https://cdn.yoootek.com/openclaw-plugin/install.sh | bash
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 验证安装
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
openclaw ntf --help
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
openclaw ntf --version
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
如果环境里已有其他插件占用了 `ntf`,可改用不冲突的别名:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
openclaw phone-notifications --help
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
openclaw phone-notifications -v
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## 配置
|
|
126
|
+
|
|
127
|
+
安装脚本会自动写入必要的插件注册配置。如需手动调整:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# 可选:数据保留天数(默认 30)
|
|
131
|
+
openclaw config set plugins.entries.phone-notifications.config.retentionDays 30
|
|
132
|
+
|
|
133
|
+
# 可选:忽略特定 app
|
|
134
|
+
openclaw config set plugins.entries.phone-notifications.config.ignoredApps '["com.android.systemui"]'
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
配置项说明:
|
|
138
|
+
- `retentionDays?: number`(默认 30)
|
|
139
|
+
- `ignoredApps?: string[]`
|
|
140
|
+
|
|
141
|
+
## 数据协议
|
|
142
|
+
|
|
143
|
+
### Gateway Native:`notifications.push`
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"type": "req",
|
|
148
|
+
"id": "n_abc",
|
|
149
|
+
"method": "notifications.push",
|
|
150
|
+
"params": {
|
|
151
|
+
"items": [
|
|
152
|
+
{
|
|
153
|
+
"id": "n_001",
|
|
154
|
+
"app": "WeChat",
|
|
155
|
+
"title": "张三",
|
|
156
|
+
"body": "在吗?",
|
|
157
|
+
"timestamp": "2026-03-02T08:30:00+08:00",
|
|
158
|
+
"category": "message",
|
|
159
|
+
"metadata": { "chatId": "c1" }
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
说明:
|
|
167
|
+
- `id` 用于同一天内去重(写入 `.ids` 索引),不会作为通知正文字段落盘。
|
|
168
|
+
- `app` 是手机端上报字段;插件落盘时会标准化为 `appName`。
|
|
169
|
+
|
|
170
|
+
### HTTP 备选:`POST /notifications`
|
|
171
|
+
|
|
172
|
+
```http
|
|
173
|
+
POST /notifications
|
|
174
|
+
Authorization: Bearer ntf-xxxxxxxxxxxx
|
|
175
|
+
Content-Type: application/json
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"notifications": [
|
|
181
|
+
{
|
|
182
|
+
"id": "n_001",
|
|
183
|
+
"app": "SMS",
|
|
184
|
+
"title": "京东快递",
|
|
185
|
+
"body": "包裹已发出",
|
|
186
|
+
"timestamp": "2026-03-02T08:30:00+08:00"
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
响应示例:
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
{ "ok": true, "ingested": 1 }
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## CLI 命令
|
|
199
|
+
|
|
200
|
+
插件注册了 `openclaw ntf` 命令组,并提供 `openclaw phone-notifications` 作为无冲突别名,供 Agent 直接消费。所有命令输出 JSON。
|
|
201
|
+
|
|
202
|
+
### 认证管理
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
# 设置用户 Token(灯效下发等接口需要)
|
|
206
|
+
openclaw ntf auth set-token "eyJhbGciOi..."
|
|
207
|
+
|
|
208
|
+
# 查看当前认证状态
|
|
209
|
+
openclaw ntf auth show
|
|
210
|
+
|
|
211
|
+
# 清除认证信息
|
|
212
|
+
openclaw ntf auth clear
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### 通知查询
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# 查询最近 7 天通知
|
|
219
|
+
openclaw ntf search
|
|
220
|
+
|
|
221
|
+
# 查询指定应用的通知
|
|
222
|
+
openclaw ntf search --app wechat --from 2026-03-01 --to 2026-03-09
|
|
223
|
+
|
|
224
|
+
# 按关键词搜索
|
|
225
|
+
openclaw ntf search --keyword "开会" --limit 20
|
|
226
|
+
|
|
227
|
+
# 按发送人过滤
|
|
228
|
+
openclaw ntf search --sender "张三" --from 2026-03-01
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### 通知统计
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
# 全维度统计
|
|
235
|
+
openclaw ntf stats
|
|
236
|
+
|
|
237
|
+
# 按应用维度统计
|
|
238
|
+
openclaw ntf stats --dim app --from 2026-03-01
|
|
239
|
+
|
|
240
|
+
# 按时段维度统计
|
|
241
|
+
openclaw ntf stats --dim hour --from 2026-03-01 --to 2026-03-09
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### 通知同步(记忆系统)
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
# 扫描未同步通知
|
|
248
|
+
openclaw ntf sync scan
|
|
249
|
+
|
|
250
|
+
# 获取指定日期未处理通知
|
|
251
|
+
openclaw ntf sync fetch --date 2026-03-09
|
|
252
|
+
|
|
253
|
+
# 标记同步完成
|
|
254
|
+
openclaw ntf sync commit --date 2026-03-09
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### 通知监控任务
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
# 创建监控任务
|
|
261
|
+
openclaw ntf monitor create boss-alert \
|
|
262
|
+
--description "监控老板微信消息" \
|
|
263
|
+
--match-rules '{"appName":"wechat","senderKeywords":["张总"]}' \
|
|
264
|
+
--schedule "*/30 * * * *"
|
|
265
|
+
|
|
266
|
+
# 列出监控任务
|
|
267
|
+
openclaw ntf monitor list
|
|
268
|
+
|
|
269
|
+
# 查看监控任务详情
|
|
270
|
+
openclaw ntf monitor show boss-alert
|
|
271
|
+
|
|
272
|
+
# 启用/暂停监控任务
|
|
273
|
+
openclaw ntf monitor enable boss-alert
|
|
274
|
+
openclaw ntf monitor disable boss-alert
|
|
275
|
+
|
|
276
|
+
# 删除监控任务
|
|
277
|
+
openclaw ntf monitor delete boss-alert --yes
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### 灯效控制
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
# 直接发送灯效指令到硬件设备(需要先 set-token)
|
|
284
|
+
openclaw ntf light send \
|
|
285
|
+
--segments '[{"mode":"wave","duration_s":4,"brightness":192,"color":{"r":255,"g":0,"b":0}}]'
|
|
286
|
+
|
|
287
|
+
# 呼吸灯效
|
|
288
|
+
openclaw ntf light send \
|
|
289
|
+
--segments '[{"mode":"breath","duration_s":6,"brightness":128,"color":{"r":0,"g":255,"b":0}}]'
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### 灯效规则管理
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
# 添加灯效规则
|
|
296
|
+
openclaw ntf light rules add "老板消息提醒" \
|
|
297
|
+
--trigger "收到老板的微信消息" \
|
|
298
|
+
--segments '[{"mode":"wave","duration_s":4,"brightness":192,"color":{"r":255,"g":0,"b":0}}]'
|
|
299
|
+
|
|
300
|
+
# 列出灯效规则
|
|
301
|
+
openclaw ntf light rules list
|
|
302
|
+
|
|
303
|
+
# 查看灯效规则详情
|
|
304
|
+
openclaw ntf light rules show "老板消息提醒"
|
|
305
|
+
|
|
306
|
+
# 校验灯效参数(不写入)
|
|
307
|
+
openclaw ntf light rules validate \
|
|
308
|
+
--segments '[{"mode":"breath","duration_s":6,"brightness":128,"color":{"r":0,"g":255,"b":0}}]'
|
|
309
|
+
|
|
310
|
+
# 移除灯效规则
|
|
311
|
+
openclaw ntf light rules remove "老板消息提醒" --yes
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## 开发
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
pnpm install
|
|
318
|
+
pnpm run build # tsc 编译
|
|
319
|
+
pnpm test # vitest 测试
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## 目录结构
|
|
323
|
+
|
|
324
|
+
```text
|
|
325
|
+
src/
|
|
326
|
+
├── types.ts # 类型定义
|
|
327
|
+
├── index.ts # 插件入口:service + gateway method + http route + tool + cli
|
|
328
|
+
├── storage.ts # 文件系统 JSON 存储引擎
|
|
329
|
+
├── light-protocol.ts # 灯效 ANCS 协议编码
|
|
330
|
+
└── cli/
|
|
331
|
+
├── index.ts # CLI 注册汇总入口
|
|
332
|
+
├── helpers.ts # 共享工具(路径解析、日期处理、JSON 输出)
|
|
333
|
+
├── auth.ts # openclaw ntf auth
|
|
334
|
+
├── ntf-search.ts # openclaw ntf search
|
|
335
|
+
├── ntf-stats.ts # openclaw ntf stats
|
|
336
|
+
├── ntf-sync.ts # openclaw ntf sync
|
|
337
|
+
├── ntf-monitor.ts # openclaw ntf monitor
|
|
338
|
+
├── light-rules.ts # openclaw ntf light rules
|
|
339
|
+
└── light-send.ts # openclaw ntf light send
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
## License
|
|
343
|
+
|
|
344
|
+
GPL-3.0
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
|
|
3
|
+
interface PluginApi {
|
|
4
|
+
logger: {
|
|
5
|
+
info: (msg: string) => void;
|
|
6
|
+
warn: (msg: string) => void;
|
|
7
|
+
error: (msg: string) => void;
|
|
8
|
+
};
|
|
9
|
+
pluginConfig?: Record<string, unknown>;
|
|
10
|
+
runtime: {
|
|
11
|
+
state: {
|
|
12
|
+
resolveStateDir: () => string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
registerService: (service: {
|
|
16
|
+
id: string;
|
|
17
|
+
start: (ctx: {
|
|
18
|
+
stateDir: string;
|
|
19
|
+
workspaceDir?: string;
|
|
20
|
+
}) => void | Promise<void>;
|
|
21
|
+
stop?: () => void | Promise<void>;
|
|
22
|
+
}) => void;
|
|
23
|
+
registerGatewayMethod: (method: string, handler: (opts: {
|
|
24
|
+
params: Record<string, unknown>;
|
|
25
|
+
/** 发起本次请求的 WSS 客户端(operator 节点为 null) */
|
|
26
|
+
client: {
|
|
27
|
+
connId?: string;
|
|
28
|
+
} | null;
|
|
29
|
+
context: {
|
|
30
|
+
/** 向所有已连接的 operator 客户端广播 event 帧 */
|
|
31
|
+
broadcast: (event: string, payload: unknown) => void;
|
|
32
|
+
/** 向指定 connId 集合广播 event 帧 */
|
|
33
|
+
broadcastToConnIds: (event: string, payload: unknown, connIds: ReadonlySet<string>) => void;
|
|
34
|
+
};
|
|
35
|
+
respond: (ok: boolean, payload?: unknown, error?: {
|
|
36
|
+
code: string;
|
|
37
|
+
message: string;
|
|
38
|
+
}) => void;
|
|
39
|
+
}) => void | Promise<void>) => void;
|
|
40
|
+
/** 注册供 AI Agent 调用的 tool,声明即实现 */
|
|
41
|
+
registerTool: (tool: {
|
|
42
|
+
name: string;
|
|
43
|
+
description: string;
|
|
44
|
+
parameters: Record<string, unknown>;
|
|
45
|
+
execute: (toolCallId: string, params: unknown) => unknown | Promise<unknown>;
|
|
46
|
+
}) => void;
|
|
47
|
+
registerHttpRoute: (params: {
|
|
48
|
+
path: string;
|
|
49
|
+
handler: (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;
|
|
50
|
+
auth?: "gateway" | "plugin";
|
|
51
|
+
}) => void;
|
|
52
|
+
registerCli: (registrar: (ctx: {
|
|
53
|
+
program: any;
|
|
54
|
+
stateDir?: string;
|
|
55
|
+
workspaceDir?: string;
|
|
56
|
+
logger: PluginApi["logger"];
|
|
57
|
+
}) => void | Promise<void>, opts?: {
|
|
58
|
+
commands?: string[];
|
|
59
|
+
}) => void;
|
|
60
|
+
}
|
|
61
|
+
declare const _default: {
|
|
62
|
+
id: string;
|
|
63
|
+
name: string;
|
|
64
|
+
register(api: PluginApi): void;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export { _default as default };
|