Skip to content

Commit 09ec2c8

Browse files
committed
主动消息推送,支持Rss订阅
1 parent 9380b4b commit 09ec2c8

File tree

6 files changed

+70
-4
lines changed

6 files changed

+70
-4
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
node_modules
22
WechatEveryDay.memory-card.json
3-
.env
3+
src/.env
44
test.js
55
package-lock.json
66
yarn.lock

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"p-timeout": "^6.0.0",
3939
"qrcode-terminal": "^0.12.0",
4040
"remark": "^14.0.2",
41+
"rss-parser": "^3.13.0",
4142
"strip-markdown": "^5.0.0",
4243
"wechaty": "^1.20.2",
4344
"wechaty-puppet-wechat4u": "^1.14.14",

src/Rss/index.js

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import Parser from 'rss-parser'
2+
import dotenv from 'dotenv'
3+
import { broadcastMessage } from '../wechaty/sendMessage.js'
4+
5+
export function getRssMsg() {}
6+
7+
const env = dotenv.config().parsed // 环境参数
8+
const rssList = env.RSS_URLS ? env.RSS_URLS.split(',') : [] //
9+
const lastUpdate = new Map() //
10+
const latestcontent = new Map()
11+
/**
12+
* 监听rss更新
13+
*/
14+
export async function startRssWatch(bot) {
15+
const parser = new Parser() // 初始化 RSS 解析器
16+
17+
// 每60秒检查一次更新
18+
setInterval(async () => {
19+
for (const url of rssList) {
20+
try {
21+
const feed = await parser.parseURL(url) // 解析RSS源
22+
const latestItem = feed.items[0] // 获取最新的文章
23+
24+
if (!lastUpdate.has(url) || new Date(latestItem.pubDate) > lastUpdate.get(url)) {
25+
// 如果是第一次检查,或者发现有更新
26+
lastUpdate.set(url, new Date(latestItem.pubDate)) // 更新lastUpdate
27+
latestcontent.set(url, latestItem.content) // 保存最新的文章标题
28+
console.log(`New update found in ${url}: ${latestItem.content}`)
29+
await broadcastMessage(bot, 'Rss', `${latestItem.content}`)
30+
}
31+
} catch (error) {
32+
console.error(`Failed to fetch RSS feed from ${url}:`, error)
33+
}
34+
}
35+
}, 60000) // 60000ms = 60秒
36+
}

src/index.js

+13-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import fs from 'fs'
88
import path, { dirname } from 'path'
99
import { fileURLToPath } from 'url'
1010
import { defaultMessage } from './wechaty/sendMessage.js'
11+
import { startRssWatch } from './Rss/index.js'
1112

1213
const __filename = fileURLToPath(import.meta.url)
1314
const __dirname = dirname(__filename)
@@ -50,7 +51,7 @@ async function onFriendShip(friendship) {
5051
}
5152

5253
/**
53-
* 消息发送
54+
* 回复
5455
* @param msg
5556
* @param isSharding
5657
* @returns {Promise<void>}
@@ -102,7 +103,10 @@ bot.on('error', (e) => {
102103
function botStart() {
103104
bot
104105
.start()
105-
.then(() => console.log('Start to log in wechat...'))
106+
.then(() => {
107+
console.log('Start to log in wechat...')
108+
startRssWatch(bot) //启动Rss模块
109+
})
106110
.catch((e) => console.error('❌ botStart error: ', e))
107111
}
108112

@@ -154,6 +158,12 @@ function handleStart(type) {
154158
}
155159
console.log('❌ 请先配置.env文件中的 DIFY_API_KEY')
156160
break
161+
case 'Rss':
162+
if (env.RSS_URLS) {
163+
return botStart()
164+
}
165+
console.log('❌ 请先配置.env文件中的 RSS_URLS')
166+
break
157167
default:
158168
console.log('❌ 服务类型错误, 目前支持: ChatGPT | Kimi | Xunfei')
159169
}
@@ -166,6 +176,7 @@ export const serveList = [
166176
{ name: 'deepseek-free', value: 'deepseek-free' },
167177
{ name: '302AI', value: '302AI' },
168178
{ name: 'dify', value: 'dify' },
179+
{ name: 'Rss', value: 'Rss' },
169180
// ... 欢迎大家接入更多的服务
170181
]
171182
const questions = [

src/wechaty/sendMessage.js

+15
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,21 @@ export async function defaultMessage(msg, bot, ServiceType = 'GPT') {
6262
}
6363
}
6464

65+
/**
66+
* 消息广播
67+
*/
68+
export async function broadcastMessage(bot, ServiceType = 'Rss', msg) {
69+
for (let roomName of roomWhiteList) {
70+
const room = await bot.Room.find({ topic: roomName })
71+
if (room) {
72+
// 检查 room 是否找到
73+
await room.say(msg)
74+
} else {
75+
console.error(`Room not found: ${roomName}`) // 记录未找到的房间
76+
}
77+
}
78+
}
79+
6580
/**
6681
* 分片消息发送
6782
* @param message

src/wechaty/serve.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import { getXunfeiReply } from '../xunfei/index.js'
44
import { getDeepSeekFreeReply } from '../deepseek-free/index.js'
55
import { get302AiReply } from '../302ai/index.js'
66
import { getDifyReply } from '../dify/index.js'
7+
import { getRssMsg } from '../Rss/index.js'
78

89
/**
910
* 获取ai服务
1011
* @param serviceType 服务类型 'GPT' | 'Kimi'
11-
* @returns {Promise<void>}
12+
* @returns {string}
1213
*/
1314
export function getServe(serviceType) {
1415
switch (serviceType) {
@@ -24,6 +25,8 @@ export function getServe(serviceType) {
2425
return get302AiReply
2526
case 'dify':
2627
return getDifyReply
28+
case 'Rss':
29+
return getRssMsg()
2730
default:
2831
return getGptReply
2932
}

0 commit comments

Comments
 (0)