@zhin.js/plugin-rss 0.0.0-1

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 凉菜
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # @zhin.js/plugin-rss
2
+
3
+ RSS/Atom 订阅推送插件 —— 订阅 feed 源,自动轮询并推送新内容到群聊或私聊。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npm install @zhin.js/plugin-rss
9
+ ```
10
+
11
+ ## 配置
12
+
13
+ 在 `zhin.config.yml` 中添加:
14
+
15
+ ```yaml
16
+ plugins:
17
+ - "@zhin.js/plugin-rss"
18
+ rss:
19
+ pollCron: "*/5 * * * *" # 轮询频率,Cron 表达式(默认每 5 分钟)
20
+ maxPerGroup: 30 # 每个会话最大订阅数(默认 30)
21
+ maxItems: 5 # 单次推送最多展示条数(默认 5)
22
+ timeout: 15000 # 拉取 feed 的超时时间 ms(默认 15s)
23
+ ```
24
+
25
+ ## 命令
26
+
27
+ | 命令 | 说明 | 示例 |
28
+ |------|------|------|
29
+ | `rss-add <url>` | 订阅 RSS/Atom 源 | `rss-add https://sspai.com/feed` |
30
+ | `rss-remove <url>` | 取消订阅 | `rss-remove https://sspai.com/feed` |
31
+ | `rss-list` | 查看当前会话的订阅列表 | `rss-list` |
32
+ | `rss-check [url]` | 手动检查更新 | `rss-check` |
33
+ | `rss-preview <url>` | 预览 feed 最新内容(不订阅) | `rss-preview https://rsshub.app/bilibili/hot-search` |
34
+
35
+ ## 工作原理
36
+
37
+ 1. `rss-add` 时验证 feed 可达性,记录订阅关系和当前会话(适配器、Bot、群/私聊)
38
+ 2. 订阅成功后标记所有已有条目为"已读",避免立即推送历史内容
39
+ 3. Cron 定时任务按配置的频率轮询所有已订阅的 feed
40
+ 4. 通过 `item.guid` 去重,只推送新增条目
41
+ 5. 同一 feed 被多个会话订阅时,只拉取一次,分别推送
42
+ 6. 每日凌晨 4 点清理 7 天前的已读记录,防止数据膨胀
43
+
44
+ ## 推荐 RSS 源
45
+
46
+ 搭配 [RSSHub](https://docs.rsshub.app/) 可订阅几乎任何网站的更新:
47
+
48
+ | 源 | URL |
49
+ |----|-----|
50
+ | 少数派 | `https://sspai.com/feed` |
51
+ | GitHub Trending | `https://rsshub.app/github/trending/daily` |
52
+ | Bilibili 热搜 | `https://rsshub.app/bilibili/hot-search` |
53
+ | 微博热搜 | `https://rsshub.app/weibo/search/hot` |
54
+ | Hacker News | `https://hnrss.org/frontpage` |
55
+
56
+ ## AI 工具
57
+
58
+ | 工具名 | 说明 |
59
+ |--------|------|
60
+ | `rss_list_subscriptions` | 查询所有 RSS 订阅概览 |
61
+ | `rss_preview_feed` | 预览指定 URL 的 feed 内容 |
62
+
63
+ ## 数据库
64
+
65
+ 依赖 Zhin 数据库服务,自动创建两张表:
66
+
67
+ **rss_subscriptions** — 订阅关系
68
+
69
+ | 字段 | 类型 | 说明 |
70
+ |------|------|------|
71
+ | url | text | Feed 地址 |
72
+ | feed_title | text | Feed 标题(自动获取) |
73
+ | adapter_name | text | 适配器名称 |
74
+ | bot_id | text | Bot ID |
75
+ | channel_type | text | 会话类型 (group/private) |
76
+ | channel_id | text | 会话 ID |
77
+
78
+ **rss_seen_items** — 已推送条目(去重用)
79
+
80
+ | 字段 | 类型 | 说明 |
81
+ |------|------|------|
82
+ | feed_url | text | Feed 地址 |
83
+ | item_guid | text | 条目唯一标识 |
84
+
85
+ ## 依赖
86
+
87
+ - [rss-parser](https://github.com/rbren/rss-parser) — RSS/Atom 解析
88
+ - Zhin 内置 `cron` 服务 — 定时轮询
89
+ - Zhin 内置 `database` 服务 — 数据持久化
90
+
91
+ ## 许可
92
+
93
+ MIT
package/lib/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/lib/index.js ADDED
@@ -0,0 +1,496 @@
1
+ /**
2
+ * @zhin.js/plugin-rss
3
+ *
4
+ * RSS/Atom 订阅推送插件
5
+ *
6
+ * 功能:
7
+ * - 订阅任意 RSS/Atom feed
8
+ * - 基于 Cron 的定时轮询(默认每 5 分钟)
9
+ * - 新条目自动推送到订阅的群聊/私聊
10
+ * - 支持多群订阅同一 feed(去重共享)
11
+ * - 订阅管理(增删查)
12
+ * - 手动检查更新
13
+ * - 数据库持久化
14
+ * - AI 工具集成
15
+ *
16
+ * 命令:
17
+ * rss-add <url> 订阅 RSS 源
18
+ * rss-remove <url> 取消订阅
19
+ * rss-list 查看当前订阅列表
20
+ * rss-check [url] 手动检查更新
21
+ * rss-preview <url> 预览 feed 最新内容(不订阅)
22
+ *
23
+ * 配置(zhin.config.yml):
24
+ * ```yaml
25
+ * plugins:
26
+ * - "@zhin.js/plugin-rss"
27
+ * rss:
28
+ * pollCron: "0/5 * * * *"
29
+ * maxPerGroup: 30
30
+ * maxItems: 5
31
+ * timeout: 15000
32
+ * ```
33
+ */
34
+ import { usePlugin, Cron, ZhinTool, MessageCommand, Schema } from "zhin.js";
35
+ import Parser from "rss-parser";
36
+ const plugin = usePlugin();
37
+ const { logger, root, addCommand, addCron, useContext, onDispose, declareSkill, declareConfig } = plugin;
38
+ // ─── 配置 ─────────────────────────────────────────────────────────────────────
39
+ const config = declareConfig("rss", Schema.object({
40
+ pollCron: Schema.string().default("*/5 * * * *").description("轮询频率 (Cron 表达式)"),
41
+ maxPerGroup: Schema.number().default(30).min(1).max(200).description("每会话最大订阅数"),
42
+ maxItems: Schema.number().default(5).min(1).max(20).description("单次推送最多条数"),
43
+ timeout: Schema.number().default(15_000).min(1000).max(60000).description("拉取超时 (ms)"),
44
+ }));
45
+ // ─── Feed 解析器 ──────────────────────────────────────────────────────────────
46
+ const parser = new Parser({
47
+ timeout: config.timeout,
48
+ headers: {
49
+ "User-Agent": "ZhinBot-RSS/1.0",
50
+ Accept: "application/rss+xml, application/atom+xml, application/xml, text/xml",
51
+ },
52
+ });
53
+ async function fetchFeed(url) {
54
+ const feed = await parser.parseURL(url);
55
+ const items = (feed.items || []).slice(0, 20).map((item) => ({
56
+ title: (item.title || "").trim(),
57
+ link: (item.link || "").trim(),
58
+ date: item.isoDate || item.pubDate || "",
59
+ summary: stripHtml(item.contentSnippet || item.content || "").slice(0, 200),
60
+ guid: item.guid || item.link || item.title || "",
61
+ }));
62
+ return { title: (feed.title || url).trim(), items };
63
+ }
64
+ function stripHtml(html) {
65
+ return html.replace(/<[^>]*>/g, "").replace(/&nbsp;/g, " ").replace(/\s+/g, " ").trim();
66
+ }
67
+ // ─── 数据库 ───────────────────────────────────────────────────────────────────
68
+ let _db = null;
69
+ function getSubs() {
70
+ if (!_db) {
71
+ const database = root.inject("database");
72
+ if (database)
73
+ _db = database;
74
+ }
75
+ return _db?.models?.get("rss_subscriptions") ?? null;
76
+ }
77
+ function getSeen() {
78
+ return _db?.models?.get("rss_seen_items") ?? null;
79
+ }
80
+ useContext("database", (db) => {
81
+ _db = db;
82
+ db.define("rss_subscriptions", {
83
+ url: { type: "text", nullable: false },
84
+ feed_title: { type: "text", default: "" },
85
+ adapter_name: { type: "text", default: "" },
86
+ bot_id: { type: "text", default: "" },
87
+ channel_type: { type: "text", default: "group" },
88
+ channel_id: { type: "text", default: "" },
89
+ creator_id: { type: "text", default: "" },
90
+ creator_name: { type: "text", default: "" },
91
+ created_at: { type: "text", default: "" },
92
+ });
93
+ db.define("rss_seen_items", {
94
+ feed_url: { type: "text", nullable: false },
95
+ item_guid: { type: "text", nullable: false },
96
+ item_title: { type: "text", default: "" },
97
+ seen_at: { type: "text", default: "" },
98
+ });
99
+ logger.info("RSS 数据模型已注册");
100
+ });
101
+ function ts() {
102
+ return new Date().toISOString();
103
+ }
104
+ // ─── 辅助:消息上下文提取 ─────────────────────────────────────────────────────
105
+ function extractChannelInfo(message) {
106
+ const channelType = message.$channel?.type || (message.type === "group" ? "group" : "private");
107
+ const channelId = String(message.$channel?.id || message.$group?.id || message.$target?.id || message.$sender?.id || "");
108
+ return {
109
+ adapterName: String(message.$adapter || ""),
110
+ botId: String(message.$bot || ""),
111
+ channelType,
112
+ channelId,
113
+ };
114
+ }
115
+ // ─── 推送引擎 ─────────────────────────────────────────────────────────────────
116
+ async function pushToChannel(adapterName, botId, channelType, channelId, content) {
117
+ try {
118
+ const adapter = root.inject(adapterName);
119
+ if (!adapter)
120
+ return false;
121
+ await adapter.sendMessage({
122
+ context: adapterName,
123
+ bot: botId,
124
+ type: channelType,
125
+ id: channelId,
126
+ content,
127
+ });
128
+ return true;
129
+ }
130
+ catch (e) {
131
+ logger.warn(`推送失败 [${adapterName}:${botId} → ${channelType}:${channelId}]: ${e.message}`);
132
+ return false;
133
+ }
134
+ }
135
+ function formatItems(feedTitle, items) {
136
+ const lines = [`${feedTitle} 有 ${items.length} 条新内容:`];
137
+ for (const item of items.slice(0, config.maxItems)) {
138
+ lines.push("");
139
+ lines.push(`${item.title}`);
140
+ if (item.summary)
141
+ lines.push(item.summary);
142
+ if (item.link)
143
+ lines.push(item.link);
144
+ }
145
+ if (items.length > config.maxItems) {
146
+ lines.push(`\n...还有 ${items.length - config.maxItems} 条,请查看源站`);
147
+ }
148
+ return lines.join("\n");
149
+ }
150
+ // ─── 轮询逻辑 ─────────────────────────────────────────────────────────────────
151
+ let polling = false;
152
+ async function pollAllFeeds() {
153
+ const Subs = getSubs();
154
+ const Seen = getSeen();
155
+ if (!Subs || !Seen)
156
+ return;
157
+ if (polling)
158
+ return;
159
+ polling = true;
160
+ try {
161
+ const allSubs = await Subs.select();
162
+ if (allSubs.length === 0)
163
+ return;
164
+ const urlSet = new Set(allSubs.map((s) => s.url));
165
+ for (const url of urlSet) {
166
+ try {
167
+ const { title, items } = await fetchFeed(url);
168
+ if (items.length === 0)
169
+ continue;
170
+ const seenRows = await Seen.select().where({ feed_url: url });
171
+ const seenGuids = new Set(seenRows.map((r) => r.item_guid));
172
+ const newItems = items.filter((item) => !seenGuids.has(item.guid));
173
+ if (newItems.length === 0)
174
+ continue;
175
+ for (const item of newItems) {
176
+ await Seen.insert({
177
+ feed_url: url,
178
+ item_guid: item.guid,
179
+ item_title: item.title,
180
+ seen_at: ts(),
181
+ });
182
+ }
183
+ const message = formatItems(title, newItems);
184
+ const subscribers = allSubs.filter((s) => s.url === url);
185
+ for (const sub of subscribers) {
186
+ await pushToChannel(sub.adapter_name, sub.bot_id, sub.channel_type, sub.channel_id, message);
187
+ }
188
+ // 更新 feed 标题
189
+ if (title) {
190
+ for (const sub of subscribers) {
191
+ if (sub.feed_title !== title) {
192
+ await Subs.update({ feed_title: title }).where({ id: sub.id });
193
+ }
194
+ }
195
+ }
196
+ }
197
+ catch (e) {
198
+ logger.debug(`轮询 ${url} 失败: ${e.message}`);
199
+ }
200
+ }
201
+ }
202
+ catch (e) {
203
+ logger.warn(`轮询异常: ${e.message}`);
204
+ }
205
+ finally {
206
+ polling = false;
207
+ }
208
+ }
209
+ // 定期清理过老的 seen 记录(保留最近 7 天)
210
+ async function cleanOldSeen() {
211
+ const Seen = getSeen();
212
+ if (!Seen)
213
+ return;
214
+ try {
215
+ const cutoff = new Date();
216
+ cutoff.setDate(cutoff.getDate() - 7);
217
+ const cutoffStr = cutoff.toISOString();
218
+ const all = await Seen.select();
219
+ const expired = all.filter((r) => r.seen_at && r.seen_at < cutoffStr);
220
+ for (const row of expired) {
221
+ await Seen.delete().where({ id: row.id });
222
+ }
223
+ }
224
+ catch {
225
+ // 清理失败不影响主流程
226
+ }
227
+ }
228
+ // ─── Cron 定时任务 ────────────────────────────────────────────────────────────
229
+ addCron(new Cron(config.pollCron, pollAllFeeds));
230
+ addCron(new Cron("0 4 * * *", cleanOldSeen));
231
+ // ─── 命令:rss-add ───────────────────────────────────────────────────────────
232
+ addCommand(new MessageCommand("rss-add <url:text>")
233
+ .desc("订阅 RSS", "订阅一个 RSS/Atom 源,新内容将自动推送到当前会话")
234
+ .usage("rss-add <Feed URL>")
235
+ .examples("rss-add https://sspai.com/feed", "rss-add https://rsshub.app/bilibili/user/dynamic/1")
236
+ .action(async (message, result) => {
237
+ const Subs = getSubs();
238
+ if (!Subs)
239
+ return "RSS 数据库尚未就绪,请稍后重试";
240
+ const url = result.params.url?.trim();
241
+ if (!url)
242
+ return "请提供 RSS 源地址,格式:rss-add <URL>";
243
+ if (!/^https?:\/\//i.test(url))
244
+ return "请提供有效的 HTTP/HTTPS 地址";
245
+ const { adapterName, botId, channelType, channelId } = extractChannelInfo(message);
246
+ if (!channelId)
247
+ return "无法确定当前会话,请在群聊或私聊中使用";
248
+ // 检查是否已订阅
249
+ const existing = await Subs.select().where({
250
+ url,
251
+ adapter_name: adapterName,
252
+ channel_type: channelType,
253
+ channel_id: channelId,
254
+ });
255
+ if (existing.length > 0)
256
+ return "当前会话已订阅该源,无需重复添加";
257
+ // 检查数量限制
258
+ const currentSubs = await Subs.select().where({
259
+ adapter_name: adapterName,
260
+ channel_type: channelType,
261
+ channel_id: channelId,
262
+ });
263
+ if (currentSubs.length >= config.maxPerGroup) {
264
+ return `当前会话订阅数已达上限 (${config.maxPerGroup}),请先取消一些`;
265
+ }
266
+ // 验证 feed 可达
267
+ let feedTitle = "";
268
+ try {
269
+ const { title } = await fetchFeed(url);
270
+ feedTitle = title;
271
+ }
272
+ catch (e) {
273
+ return `无法解析该地址: ${e.message}\n请确认是有效的 RSS/Atom 源`;
274
+ }
275
+ await Subs.insert({
276
+ url,
277
+ feed_title: feedTitle,
278
+ adapter_name: adapterName,
279
+ bot_id: botId,
280
+ channel_type: channelType,
281
+ channel_id: channelId,
282
+ creator_id: String(message.$sender?.id || ""),
283
+ creator_name: String(message.$sender?.name || ""),
284
+ created_at: ts(),
285
+ });
286
+ // 标记现有条目为已读,避免订阅后立即推送历史
287
+ try {
288
+ const Seen = getSeen();
289
+ if (Seen) {
290
+ const { items } = await fetchFeed(url);
291
+ for (const item of items) {
292
+ const dup = await Seen.select().where({ feed_url: url, item_guid: item.guid });
293
+ if (dup.length === 0) {
294
+ await Seen.insert({ feed_url: url, item_guid: item.guid, item_title: item.title, seen_at: ts() });
295
+ }
296
+ }
297
+ }
298
+ }
299
+ catch {
300
+ // 标记失败不影响订阅
301
+ }
302
+ return `订阅成功!\n源: ${feedTitle || url}\n新内容将自动推送到当前会话`;
303
+ }));
304
+ // ─── 命令:rss-remove ────────────────────────────────────────────────────────
305
+ addCommand(new MessageCommand("rss-remove <url:text>")
306
+ .desc("取消订阅", "取消一个 RSS 订阅")
307
+ .usage("rss-remove <Feed URL>")
308
+ .examples("rss-remove https://sspai.com/feed")
309
+ .action(async (message, result) => {
310
+ const Subs = getSubs();
311
+ if (!Subs)
312
+ return "RSS 数据库尚未就绪";
313
+ const url = result.params.url?.trim();
314
+ if (!url)
315
+ return "请提供要取消的 RSS 源地址";
316
+ const { adapterName, channelType, channelId } = extractChannelInfo(message);
317
+ const rows = await Subs.select().where({
318
+ url,
319
+ adapter_name: adapterName,
320
+ channel_type: channelType,
321
+ channel_id: channelId,
322
+ });
323
+ if (rows.length === 0)
324
+ return "未找到该订阅";
325
+ await Subs.delete().where({ id: rows[0].id });
326
+ return `已取消订阅: ${rows[0].feed_title || url}`;
327
+ }));
328
+ // ─── 命令:rss-list ──────────────────────────────────────────────────────────
329
+ addCommand(new MessageCommand("rss-list")
330
+ .desc("订阅列表", "查看当前会话的所有 RSS 订阅")
331
+ .action(async (message) => {
332
+ const Subs = getSubs();
333
+ if (!Subs)
334
+ return "RSS 数据库尚未就绪";
335
+ const { adapterName, channelType, channelId } = extractChannelInfo(message);
336
+ const rows = await Subs.select().where({
337
+ adapter_name: adapterName,
338
+ channel_type: channelType,
339
+ channel_id: channelId,
340
+ });
341
+ if (rows.length === 0)
342
+ return "当前会话没有订阅任何 RSS 源\n使用 rss-add <URL> 添加订阅";
343
+ const lines = rows.map((r, i) => {
344
+ const title = r.feed_title || "(未知标题)";
345
+ return `${i + 1}. ${title}\n ${r.url}`;
346
+ });
347
+ return `当前订阅 (${rows.length}/${config.maxPerGroup}):\n${lines.join("\n")}`;
348
+ }));
349
+ // ─── 命令:rss-check ─────────────────────────────────────────────────────────
350
+ addCommand(new MessageCommand("rss-check [url:text]")
351
+ .desc("检查更新", "手动触发检查 RSS 更新,可指定某个源")
352
+ .usage("rss-check [URL]")
353
+ .action(async (message, result) => {
354
+ const Subs = getSubs();
355
+ const Seen = getSeen();
356
+ if (!Subs || !Seen)
357
+ return "RSS 数据库尚未就绪";
358
+ const targetUrl = result.params.url?.trim();
359
+ const { adapterName, channelType, channelId } = extractChannelInfo(message);
360
+ let subs;
361
+ if (targetUrl) {
362
+ subs = await Subs.select().where({
363
+ url: targetUrl,
364
+ adapter_name: adapterName,
365
+ channel_type: channelType,
366
+ channel_id: channelId,
367
+ });
368
+ if (subs.length === 0)
369
+ return "当前会话未订阅该源";
370
+ }
371
+ else {
372
+ subs = await Subs.select().where({
373
+ adapter_name: adapterName,
374
+ channel_type: channelType,
375
+ channel_id: channelId,
376
+ });
377
+ if (subs.length === 0)
378
+ return "当前会话没有任何订阅";
379
+ }
380
+ const urlSet = new Set(subs.map((s) => s.url));
381
+ let totalNew = 0;
382
+ for (const url of urlSet) {
383
+ try {
384
+ const { title, items } = await fetchFeed(url);
385
+ const seenRows = await Seen.select().where({ feed_url: url });
386
+ const seenGuids = new Set(seenRows.map((r) => r.item_guid));
387
+ const newItems = items.filter((item) => !seenGuids.has(item.guid));
388
+ if (newItems.length > 0) {
389
+ for (const item of newItems) {
390
+ await Seen.insert({ feed_url: url, item_guid: item.guid, item_title: item.title, seen_at: ts() });
391
+ }
392
+ totalNew += newItems.length;
393
+ const msg = formatItems(title, newItems);
394
+ await pushToChannel(adapterName, subs[0].bot_id, channelType, channelId, msg);
395
+ }
396
+ }
397
+ catch (e) {
398
+ await message.$reply(`检查 ${url} 失败: ${e.message}`);
399
+ }
400
+ }
401
+ if (totalNew === 0)
402
+ return `已检查 ${urlSet.size} 个源,没有新内容`;
403
+ return "";
404
+ }));
405
+ // ─── 命令:rss-preview ───────────────────────────────────────────────────────
406
+ addCommand(new MessageCommand("rss-preview <url:text>")
407
+ .desc("预览 RSS", "预览一个 RSS 源的最新内容(不订阅)")
408
+ .usage("rss-preview <URL>")
409
+ .examples("rss-preview https://sspai.com/feed")
410
+ .action(async (_message, result) => {
411
+ const url = result.params.url?.trim();
412
+ if (!url)
413
+ return "请提供 RSS 源地址";
414
+ if (!/^https?:\/\//i.test(url))
415
+ return "请提供有效的 HTTP/HTTPS 地址";
416
+ try {
417
+ const { title, items } = await fetchFeed(url);
418
+ if (items.length === 0)
419
+ return `${title}: 暂无内容`;
420
+ const lines = [`${title} (共 ${items.length} 条)`];
421
+ for (const item of items.slice(0, 5)) {
422
+ lines.push("");
423
+ lines.push(`${item.title}`);
424
+ if (item.date)
425
+ lines.push(` ${new Date(item.date).toLocaleString("zh-CN")}`);
426
+ if (item.link)
427
+ lines.push(` ${item.link}`);
428
+ }
429
+ if (items.length > 5)
430
+ lines.push(`\n...还有 ${items.length - 5} 条`);
431
+ return lines.join("\n");
432
+ }
433
+ catch (e) {
434
+ return `解析失败: ${e.message}\n请确认是有效的 RSS/Atom 地址`;
435
+ }
436
+ }));
437
+ // ─── AI 工具 ─────────────────────────────────────────────────────────────────
438
+ plugin.addTool(new ZhinTool("rss_list_subscriptions")
439
+ .desc("查询当前所有 RSS 订阅")
440
+ .execute(async () => {
441
+ const Subs = getSubs();
442
+ if (!Subs)
443
+ return "RSS 数据库尚未就绪";
444
+ const all = await Subs.select();
445
+ if (all.length === 0)
446
+ return "暂无任何 RSS 订阅";
447
+ const grouped = new Map();
448
+ for (const sub of all) {
449
+ const key = `${sub.channel_type}:${sub.channel_id}`;
450
+ const list = grouped.get(key) || [];
451
+ list.push(sub);
452
+ grouped.set(key, list);
453
+ }
454
+ const lines = [];
455
+ for (const [channel, subs] of grouped) {
456
+ lines.push(`[${channel}]`);
457
+ for (const s of subs) {
458
+ lines.push(` - ${s.feed_title || s.url}`);
459
+ }
460
+ }
461
+ return `RSS 订阅总览 (${all.length} 条):\n${lines.join("\n")}`;
462
+ })
463
+ .toTool());
464
+ plugin.addTool(new ZhinTool("rss_preview_feed")
465
+ .desc("预览一个 RSS 源的最新内容")
466
+ .param("url", { type: "string", description: "RSS/Atom 源地址" })
467
+ .execute(async (args) => {
468
+ const url = args.url;
469
+ if (!url)
470
+ return "请提供 RSS 源 URL";
471
+ try {
472
+ const { title, items } = await fetchFeed(url);
473
+ if (items.length === 0)
474
+ return `${title}: 无内容`;
475
+ return items
476
+ .slice(0, 5)
477
+ .map((item, i) => `${i + 1}. ${item.title}\n ${item.link}`)
478
+ .join("\n");
479
+ }
480
+ catch (e) {
481
+ return `解析失败: ${e.message}`;
482
+ }
483
+ })
484
+ .toTool());
485
+ // ─── Skill 声明 ──────────────────────────────────────────────────────────────
486
+ declareSkill({
487
+ description: "RSS/Atom 订阅推送系统:订阅 RSS 源并自动推送新内容到群聊或私聊。支持订阅管理、手动检查、预览。可用 AI 工具查询订阅和预览 feed。",
488
+ keywords: [
489
+ "rss", "atom", "feed", "订阅", "推送",
490
+ "rss-add", "rss-remove", "rss-list", "rss-check", "rss-preview",
491
+ "subscribe", "unsubscribe",
492
+ ],
493
+ tags: ["rss", "feed", "subscription", "push"],
494
+ });
495
+ logger.info(`插件已加载 (轮询=${config.pollCron}, 上限=${config.maxPerGroup}/会话)`);
496
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@zhin.js/plugin-rss",
3
+ "version": "0.0.0-1",
4
+ "description": "RSS/Atom feed subscription & push plugin for Zhin.js — subscribe feeds, auto-poll, push new items to groups",
5
+ "type": "module",
6
+ "main": "./lib/index.js",
7
+ "types": "./lib/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./lib/index.d.ts",
11
+ "development": "./src/index.ts",
12
+ "import": "./lib/index.js"
13
+ },
14
+ "./package.json": "./package.json"
15
+ },
16
+ "files": [
17
+ "lib",
18
+ "README.md"
19
+ ],
20
+ "keywords": [
21
+ "zhin",
22
+ "bot",
23
+ "plugin",
24
+ "rss",
25
+ "atom",
26
+ "feed",
27
+ "subscription",
28
+ "push",
29
+ "notify",
30
+ "chatbot",
31
+ "im"
32
+ ],
33
+ "author": {
34
+ "name": "lc-cn",
35
+ "email": "admin@liucl.cn",
36
+ "url": "https://github.com/lc-cn"
37
+ },
38
+ "license": "MIT",
39
+ "dependencies": {
40
+ "rss-parser": "^3.13.0"
41
+ },
42
+ "devDependencies": {
43
+ "typescript": "^5.3.3",
44
+ "zhin.js": "1.0.43"
45
+ },
46
+ "peerDependencies": {
47
+ "zhin.js": ">=1.0.43"
48
+ },
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://github.com/zhinjs/zhin.git",
52
+ "directory": "plugins/utils/rss"
53
+ },
54
+ "publishConfig": {
55
+ "access": "public",
56
+ "registry": "https://registry.npmjs.org"
57
+ },
58
+ "scripts": {
59
+ "build": "tsc --build",
60
+ "clean": "rimraf lib"
61
+ }
62
+ }