yz-yuki-plugin 2.0.6-10 → 2.0.6-11
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/CHANGELOG.md +1 -0
- package/defaultConfig/bilibili/config.yaml +3 -0
- package/lib/models/bilibili/bilibili.main.query.js +1 -1
- package/lib/models/bilibili/bilibili.main.task.js +118 -66
- package/lib/models/weibo/weibo.main.query.js +7 -7
- package/lib/models/weibo/weibo.main.task.js +97 -30
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -396,7 +396,7 @@ class BiliQuery {
|
|
|
396
396
|
let desc, msg = [], pics = [], author, majorType, content, dynamicTitle;
|
|
397
397
|
let title = `B站【${upName}】动态推送:\n`;
|
|
398
398
|
let dynamicType = data.type;
|
|
399
|
-
switch (
|
|
399
|
+
switch (dynamicType) {
|
|
400
400
|
case 'DYNAMIC_TYPE_AV':
|
|
401
401
|
// 处理视频动态
|
|
402
402
|
desc = data?.modules?.module_dynamic?.major?.archive;
|
|
@@ -33,6 +33,9 @@ class BiliTask {
|
|
|
33
33
|
}
|
|
34
34
|
return resjson;
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* 执行动态推送任务
|
|
38
|
+
*/
|
|
36
39
|
async runTask() {
|
|
37
40
|
let biliConfigData = await Config.getUserConfig('bilibili', 'config');
|
|
38
41
|
let biliPushData = await Config.getUserConfig('bilibili', 'push');
|
|
@@ -42,7 +45,10 @@ class BiliTask {
|
|
|
42
45
|
const dynamicList = {}; // 存放获取的所有动态,键为 uid,值为动态数组
|
|
43
46
|
await this.processBiliData(biliPushData, biliConfigData, uidMap, dynamicList);
|
|
44
47
|
let now = Date.now() / 1000; // 时间戳(秒)
|
|
45
|
-
|
|
48
|
+
// 定义待推送动态消息映射
|
|
49
|
+
const messageMap = new Map();
|
|
50
|
+
await this.makeUidDynamicDataMap(uidMap, dynamicList, now, interval, biliConfigData, messageMap);
|
|
51
|
+
await this.sendDynamicMessage(messageMap, biliConfigData);
|
|
46
52
|
}
|
|
47
53
|
/**
|
|
48
54
|
* 处理Bilibili数据,获取动态列表并构建 uid 映射
|
|
@@ -102,17 +108,17 @@ class BiliTask {
|
|
|
102
108
|
}
|
|
103
109
|
}
|
|
104
110
|
}
|
|
105
|
-
requestedDataOfUids.clear(); //
|
|
111
|
+
requestedDataOfUids.clear(); // 清空已请求的 uid 映射
|
|
106
112
|
}
|
|
107
113
|
/**
|
|
108
|
-
*
|
|
114
|
+
* 构建uid对应动态数据映射
|
|
109
115
|
* @param uidMap uid 映射
|
|
110
116
|
* @param dynamicList 动态列表
|
|
111
117
|
* @param now 当前时间戳
|
|
112
118
|
* @param interval 推送间隔时间
|
|
113
119
|
* @param biliConfigData Bilibili配置数据
|
|
114
120
|
*/
|
|
115
|
-
async
|
|
121
|
+
async makeUidDynamicDataMap(uidMap, dynamicList, now, interval, biliConfigData, messageMap) {
|
|
116
122
|
for (let [chatType, chatTypeMap] of uidMap) {
|
|
117
123
|
for (let [key, value] of chatTypeMap) {
|
|
118
124
|
const tempDynamicList = dynamicList[key] || [];
|
|
@@ -143,7 +149,7 @@ class BiliTask {
|
|
|
143
149
|
for (let chatId of chatIds) {
|
|
144
150
|
if (type && type.length && !type.includes(pushDynamicData.type))
|
|
145
151
|
continue; // 如果禁用了某类型的动态推送,跳过当前循环
|
|
146
|
-
await this.
|
|
152
|
+
await this.makeDynamicMessageMap(chatId, bot_id, upName, pushDynamicData, biliConfigData, chatType, messageMap); // 发送动态消息
|
|
147
153
|
await this.randomDelay(1000, 2000); // 随机延时1-2秒
|
|
148
154
|
}
|
|
149
155
|
}
|
|
@@ -152,15 +158,15 @@ class BiliTask {
|
|
|
152
158
|
}
|
|
153
159
|
}
|
|
154
160
|
/**
|
|
155
|
-
*
|
|
161
|
+
* 渲染构建待发送的动态消息数据的映射数组
|
|
156
162
|
* @param chatId 聊天 ID
|
|
157
163
|
* @param bot_id 机器人 ID
|
|
158
|
-
* @param upName
|
|
164
|
+
* @param upName up主用户名
|
|
159
165
|
* @param pushDynamicData 推送动态数据
|
|
160
166
|
* @param biliConfigData 哔哩配置数据
|
|
161
167
|
* @param chatType 聊天类型
|
|
162
168
|
*/
|
|
163
|
-
async
|
|
169
|
+
async makeDynamicMessageMap(chatId, bot_id, upName, pushDynamicData, biliConfigData, chatType, messageMap) {
|
|
164
170
|
const id_str = pushDynamicData.id_str;
|
|
165
171
|
let sended = null, markKey = '';
|
|
166
172
|
if (chatType === 'group') {
|
|
@@ -173,12 +179,9 @@ class BiliTask {
|
|
|
173
179
|
}
|
|
174
180
|
if (sended)
|
|
175
181
|
return; // 如果已经发送过,则直接返回
|
|
176
|
-
|
|
177
|
-
let
|
|
178
|
-
|
|
179
|
-
// 直播动态@全体成员的群组列表,默认空数组,为空则不进行@全体成员操作
|
|
180
|
-
let liveAtAllGroupList = new Set(Array.isArray(biliConfigData?.liveAtAllGroupList) ? Array.from(biliConfigData.liveAtAllGroupList).map(item => String(item)) : []);
|
|
181
|
-
if (!!biliConfigData.pushMsgMode) {
|
|
182
|
+
// 判断推送内容模式
|
|
183
|
+
let pushMsgMode = !!biliConfigData.pushMsgMode === false ? 'TEXT' : 'PIC'; // 是否启用图文模式,默认为 PIC 截图模式
|
|
184
|
+
if (pushMsgMode === 'PIC') {
|
|
182
185
|
const { data, uid } = await BiliQuery.formatDynamicData(pushDynamicData); // 处理动态数据
|
|
183
186
|
const extentData = { ...data };
|
|
184
187
|
const eval2 = eval;
|
|
@@ -206,29 +209,11 @@ class BiliTask {
|
|
|
206
209
|
};
|
|
207
210
|
let imgs = await this.renderDynamicCard(uid, renderData, ScreenshotOptionsData);
|
|
208
211
|
if (!imgs)
|
|
209
|
-
return;
|
|
210
|
-
|
|
211
|
-
global?.logger?.mark('优纪插件:B站动态执行推送');
|
|
212
|
-
if (liveAtAll && !liveAtAllMark && extentData?.type === 'DYNAMIC_TYPE_LIVE_RCMD' && liveAtAllGroupList.has(String(chatId))) {
|
|
213
|
-
try {
|
|
214
|
-
await this.sendMessage(chatId, bot_id, chatType, Segment.at('all'));
|
|
215
|
-
await Redis.set(`${markKey}${chatId}:liveAtAllMark`, 1, { EX: liveAtAllCD }); // 设置直播动态@全体成员标记为 1
|
|
216
|
-
}
|
|
217
|
-
catch (error) {
|
|
218
|
-
logger.error(`直播动态发送@全体成员失败,请检查 <机器人> 是否有 [管理员权限] 或 [聊天平台是否支持] :${error}`);
|
|
219
|
-
await this.sendMessage(chatId, bot_id, chatType, ['直播动态发送@全体成员失败,请检查权限或平台是否支持']);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
for (let i = 0; i < imgs.length; i++) {
|
|
223
|
-
const image = imgs[i];
|
|
224
|
-
await this.sendMessage(chatId, bot_id, chatType, Segment.image(image));
|
|
225
|
-
await this.randomDelay(1000, 2000); // 随机延时1-2秒
|
|
226
|
-
}
|
|
227
|
-
await new Promise(resolve => setTimeout(resolve, 1000)); // 休眠1秒
|
|
212
|
+
return; // 如果渲染失败,则直接返回
|
|
213
|
+
await this.addMessageToMap(messageMap, chatType, bot_id, chatId, 'SINGLE', id_str, extentData?.type, imgs.map(img => Segment.image(img)));
|
|
228
214
|
}
|
|
229
215
|
else {
|
|
230
216
|
const dynamicMsg = await BiliQuery.formatTextDynamicData(upName, pushDynamicData, false, biliConfigData); // 构建图文动态消息
|
|
231
|
-
Redis.set(`${markKey}${chatId}:${id_str}`, '1', { EX: 3600 * 72 }); // 设置已发送标记
|
|
232
217
|
if (dynamicMsg === undefined || dynamicMsg === 'continue') {
|
|
233
218
|
return 'return'; // 如果动态消息构建失败,则直接返回
|
|
234
219
|
}
|
|
@@ -240,40 +225,15 @@ class BiliTask {
|
|
|
240
225
|
}
|
|
241
226
|
}
|
|
242
227
|
let mergeTextPic = !!biliConfigData.mergeTextPic === false ? false : true; // 是否合并文本和图片,默认为 true
|
|
228
|
+
//开启了合并文本和图片
|
|
243
229
|
if (mergeTextPic === true) {
|
|
244
230
|
const mergeMsg = [...dynamicMsg.msg, ...dynamicMsg.pics];
|
|
245
|
-
|
|
246
|
-
try {
|
|
247
|
-
await this.sendMessage(chatId, bot_id, chatType, Segment.at('all'));
|
|
248
|
-
await Redis.set(`${markKey}${chatId}:liveAtAllMark`, 1, { EX: liveAtAllCD }); // 设置直播动态@全体成员标记为 1
|
|
249
|
-
}
|
|
250
|
-
catch (error) {
|
|
251
|
-
global?.logger.error(`直播动态发送@全体成员失败,请检查 <机器人> 是否有 [管理员权限] 或 [聊天平台是否支持] :${error}`);
|
|
252
|
-
await this.sendMessage(chatId, bot_id, chatType, ['直播动态发送@全体成员失败,请检查权限或平台是否支持']);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
await this.sendMessage(chatId, bot_id, chatType, mergeMsg);
|
|
231
|
+
await this.addMessageToMap(messageMap, chatType, bot_id, chatId, 'MERGE', id_str, dynamicMsg.dynamicType, mergeMsg);
|
|
256
232
|
}
|
|
257
233
|
else {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
await Redis.set(`${markKey}${chatId}:liveAtAllMark`, 1, { EX: liveAtAllCD }); // 设置直播动态@全体成员标记为 1
|
|
262
|
-
}
|
|
263
|
-
catch (error) {
|
|
264
|
-
global?.logger.error(`直播动态发送@全体成员失败,请检查 <机器人> 是否有 [管理员权限] 或 [聊天平台是否支持] :${error}`);
|
|
265
|
-
await this.sendMessage(chatId, bot_id, chatType, ['直播动态发送@全体成员失败,请检查权限或平台是否支持']);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
await this.sendMessage(chatId, bot_id, chatType, dynamicMsg.msg);
|
|
269
|
-
const pics = dynamicMsg.pics;
|
|
270
|
-
if (pics && pics.length > 0) {
|
|
271
|
-
for (let i = 0; i < pics.length; i++) {
|
|
272
|
-
await this.sendMessage(chatId, bot_id, chatType, pics[i]);
|
|
273
|
-
await this.randomDelay(1000, 2000); // 随机延时1-2秒
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
234
|
+
//不合并文本和图片
|
|
235
|
+
await this.addMessageToMap(messageMap, chatType, bot_id, chatId, 'MERGE', id_str, dynamicMsg.dynamicType, dynamicMsg.msg);
|
|
236
|
+
await this.addMessageToMap(messageMap, chatType, bot_id, chatId, 'SINGLE', id_str, dynamicMsg.dynamicType, dynamicMsg.pics);
|
|
277
237
|
}
|
|
278
238
|
}
|
|
279
239
|
}
|
|
@@ -354,13 +314,105 @@ class BiliTask {
|
|
|
354
314
|
}
|
|
355
315
|
}
|
|
356
316
|
/**
|
|
357
|
-
*
|
|
317
|
+
* 收集消息映射
|
|
318
|
+
* @param messageMap 消息映射
|
|
319
|
+
* @param chatType 聊天类型
|
|
320
|
+
* @param bot_id 机器人 ID
|
|
321
|
+
* @param chatId 聊天 ID
|
|
322
|
+
* @param sendMode 发送模式: SINGLE 逐条发送,MERGE 合并发送
|
|
323
|
+
* @param dynamicUUid_str 动态 UUID
|
|
324
|
+
* @param dynamicType 动态类型
|
|
325
|
+
* @param message 消息内容
|
|
326
|
+
*/
|
|
327
|
+
async addMessageToMap(messageMap, chatType, bot_id, chatId, sendMode, dynamicUUid_str, dynamicType, messages) {
|
|
328
|
+
if (!messageMap.has(chatType)) {
|
|
329
|
+
messageMap.set(chatType, new Map());
|
|
330
|
+
}
|
|
331
|
+
const botMap = messageMap.get(chatType);
|
|
332
|
+
if (!botMap?.has(bot_id)) {
|
|
333
|
+
botMap?.set(bot_id, new Map());
|
|
334
|
+
}
|
|
335
|
+
const chatMap = botMap?.get(bot_id);
|
|
336
|
+
if (!chatMap?.has(chatId)) {
|
|
337
|
+
chatMap?.set(chatId, []);
|
|
338
|
+
}
|
|
339
|
+
chatMap?.get(chatId)?.push({ sendMode, dynamicUUid_str, dynamicType, messages });
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* 推送动态消息
|
|
343
|
+
* @param messageMap 消息映射
|
|
344
|
+
* @param biliConfigData 哔哩配置数据
|
|
345
|
+
*/
|
|
346
|
+
async sendDynamicMessage(messageMap, biliConfigData) {
|
|
347
|
+
let liveAtAll = !!biliConfigData.liveAtAll === true ? true : false; // 直播动态是否@全体成员,默认false
|
|
348
|
+
let liveAtAllCD = biliConfigData.liveAtAllCD || 1800; // 直播动态@全体成员 冷却时间CD,默认 30 分钟
|
|
349
|
+
// 直播动态@全体成员的群组/好友列表,默认空数组,为空则不进行@全体成员操作
|
|
350
|
+
let liveAtAllGroupList = new Set(Array.isArray(biliConfigData?.liveAtAllGroupList) ? Array.from(biliConfigData.liveAtAllGroupList).map(item => String(item)) : []);
|
|
351
|
+
const LogMark = new Set(); // 日志mark
|
|
352
|
+
for (const [chatType, botMap] of messageMap) {
|
|
353
|
+
for (const [bot_id, chatMap] of botMap) {
|
|
354
|
+
for (const [chatId, messageCombinationList] of chatMap) {
|
|
355
|
+
// 遍历组合消息
|
|
356
|
+
for (const messageCombination of messageCombinationList) {
|
|
357
|
+
const { sendMode, dynamicUUid_str, dynamicType, messages } = messageCombination;
|
|
358
|
+
let sended = null;
|
|
359
|
+
let markKey = '';
|
|
360
|
+
if (chatType === 'group') {
|
|
361
|
+
markKey = this.groupKey;
|
|
362
|
+
sended = await Redis.get(`${markKey}${chatId}:${dynamicUUid_str}`);
|
|
363
|
+
}
|
|
364
|
+
else if (chatType === 'private') {
|
|
365
|
+
markKey = this.privateKey;
|
|
366
|
+
sended = await Redis.get(`${markKey}${chatId}:${dynamicUUid_str}`);
|
|
367
|
+
}
|
|
368
|
+
const sendMarkKey = `${markKey}${chatId}:${dynamicUUid_str}`;
|
|
369
|
+
if (sended) {
|
|
370
|
+
continue; // 如果已经发送过,则直接跳过
|
|
371
|
+
}
|
|
372
|
+
if (!LogMark.has('1')) {
|
|
373
|
+
global?.logger?.mark('优纪插件: B站动态执行推送');
|
|
374
|
+
LogMark.add('1');
|
|
375
|
+
}
|
|
376
|
+
let liveAtAllMark = await Redis.get(`${markKey}${chatId}:liveAtAllMark`); // 直播动态@全体成员标记,默认 0
|
|
377
|
+
// 如果开启了直播动态@全体成员
|
|
378
|
+
if (liveAtAll && !liveAtAllMark && dynamicType === 'DYNAMIC_TYPE_LIVE_RCMD' && liveAtAllGroupList.has(String(chatId))) {
|
|
379
|
+
try {
|
|
380
|
+
await this.sendMessageApi(chatId, bot_id, chatType, [Segment.at('all')]);
|
|
381
|
+
await Redis.set(`${markKey}${chatId}:liveAtAllMark`, 1, { EX: liveAtAllCD }); // 设置直播动态@全体成员标记为 1
|
|
382
|
+
}
|
|
383
|
+
catch (error) {
|
|
384
|
+
logger.error(`直播动态发送@全体成员失败,请检查 <机器人> 是否有 [管理员权限] 或 [聊天平台是否支持] :${error}`);
|
|
385
|
+
let liveAtAllErrMsg = !!biliConfigData.liveAtAllErrMsg === false ? false : true; // 直播动态@全体成员失败是否发送错误提示消息,默认 false
|
|
386
|
+
if (liveAtAllErrMsg) {
|
|
387
|
+
await this.sendMessageApi(chatId, bot_id, chatType, ['直播动态发送@全体成员失败,请检查权限或平台是否支持']);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
if (sendMode === 'SINGLE') {
|
|
392
|
+
for (let i = 0; i < messages.length; i++) {
|
|
393
|
+
await this.sendMessageApi(chatId, bot_id, chatType, messages[i]);
|
|
394
|
+
}
|
|
395
|
+
await Redis.set(sendMarkKey, '1', { EX: 3600 * 72 }); // 发送成功后设置标记
|
|
396
|
+
await this.randomDelay(1000, 2000); // 随机延时1-2秒
|
|
397
|
+
}
|
|
398
|
+
else if (sendMode === 'MERGE') {
|
|
399
|
+
await this.sendMessageApi(chatId, bot_id, chatType, messages);
|
|
400
|
+
await Redis.set(sendMarkKey, '1', { EX: 3600 * 72 }); // 发送成功后设置标记
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
LogMark.clear(); // 清空日志mark
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* 发送消息api
|
|
358
410
|
* @param chatId 聊天 ID
|
|
359
411
|
* @param bot_id 机器人 ID
|
|
360
412
|
* @param chatType 聊天类型
|
|
361
413
|
* @param message 消息内容
|
|
362
414
|
*/
|
|
363
|
-
async
|
|
415
|
+
async sendMessageApi(chatId, bot_id, chatType, message) {
|
|
364
416
|
if (chatType === 'group') {
|
|
365
417
|
await (Bot[bot_id] ?? Bot)
|
|
366
418
|
?.pickGroup(String(chatId))
|
|
@@ -186,7 +186,7 @@ class WeiboQuery {
|
|
|
186
186
|
let info = raw_post?.mblog || raw_post;
|
|
187
187
|
let retweeted = info && info.retweeted_status ? true : false; //是否为转发动态
|
|
188
188
|
let pic_num = retweeted ? info?.retweeted_status?.pic_num : info?.pic_num;
|
|
189
|
-
let
|
|
189
|
+
let dynamicType = this.MakeCategory(raw_post);
|
|
190
190
|
/**获取动态全文 */
|
|
191
191
|
if (info?.isLongText || pic_num > 9) {
|
|
192
192
|
const res = await fetch(`https://m.weibo.cn/detail/${info.mid}`, { headers: WeiboApi.WEIBO_HEADERS });
|
|
@@ -207,7 +207,7 @@ class WeiboQuery {
|
|
|
207
207
|
let detail_url = `https://weibo.com/${info?.user?.id}/${info?.bid}`;
|
|
208
208
|
let title = `微博【${upName}】动态推送:\n`;
|
|
209
209
|
const dynamicPicCountLimit = setData.pushPicCountLimit || 3;
|
|
210
|
-
switch (
|
|
210
|
+
switch (dynamicType) {
|
|
211
211
|
case 'DYNAMIC_TYPE_AV':
|
|
212
212
|
if (!info)
|
|
213
213
|
return;
|
|
@@ -223,7 +223,7 @@ class WeiboQuery {
|
|
|
223
223
|
`时间:${created_time ? moment(created_time).format('YYYY年MM月DD日 HH:mm:ss') : ''}`
|
|
224
224
|
];
|
|
225
225
|
pics = [cover_img];
|
|
226
|
-
return { msg, pics };
|
|
226
|
+
return { msg, pics, dynamicType };
|
|
227
227
|
case 'DYNAMIC_TYPE_DRAW':
|
|
228
228
|
raw_pics_list = retweeted ? info?.retweeted_status?.pics || [] : info?.pics || [];
|
|
229
229
|
if (!info && !raw_pics_list)
|
|
@@ -243,7 +243,7 @@ class WeiboQuery {
|
|
|
243
243
|
`链接:${detail_url}\n`,
|
|
244
244
|
`时间:${created_time ? moment(created_time).format('YYYY年MM月DD日 HH:mm:ss') : ''}`
|
|
245
245
|
];
|
|
246
|
-
return { msg, pics };
|
|
246
|
+
return { msg, pics, dynamicType };
|
|
247
247
|
case 'DYNAMIC_TYPE_ARTICLE':
|
|
248
248
|
if (!info)
|
|
249
249
|
return;
|
|
@@ -263,7 +263,7 @@ class WeiboQuery {
|
|
|
263
263
|
`链接:${detail_url}\n`,
|
|
264
264
|
`时间:${created_time ? moment(created_time).format('YYYY年MM月DD日 HH:mm:ss') : ''}`
|
|
265
265
|
];
|
|
266
|
-
return { msg, pics };
|
|
266
|
+
return { msg, pics, dynamicType };
|
|
267
267
|
case 'DYNAMIC_TYPE_FORWARD':
|
|
268
268
|
if (!info)
|
|
269
269
|
return;
|
|
@@ -290,9 +290,9 @@ class WeiboQuery {
|
|
|
290
290
|
'\n---以下为转发内容---\n',
|
|
291
291
|
...origContent
|
|
292
292
|
];
|
|
293
|
-
return { msg, pics };
|
|
293
|
+
return { msg, pics, dynamicType };
|
|
294
294
|
default:
|
|
295
|
-
logger?.mark(`未处理的微博推送【${upName}】:${
|
|
295
|
+
logger?.mark(`未处理的微博推送【${upName}】:${dynamicType}`);
|
|
296
296
|
return 'continue';
|
|
297
297
|
}
|
|
298
298
|
}
|
|
@@ -15,6 +15,9 @@ class WeiboTask {
|
|
|
15
15
|
this.groupKey = 'Yz:yuki:weibo:upPush:group:';
|
|
16
16
|
this.privateKey = 'Yz:yuki:weibo:upPush:private:';
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* 执行动态推送任务
|
|
20
|
+
*/
|
|
18
21
|
async runTask() {
|
|
19
22
|
let weiboConfigData = await Config.getUserConfig('weibo', 'config');
|
|
20
23
|
let weiboPushData = await Config.getUserConfig('weibo', 'push');
|
|
@@ -24,7 +27,10 @@ class WeiboTask {
|
|
|
24
27
|
const dynamicList = {}; // 存放获取的所有动态,键为 uid,值为动态数组
|
|
25
28
|
await this.processWeiboData(weiboPushData, uidMap, dynamicList);
|
|
26
29
|
let now = Date.now() / 1000; // 当前时间戳(秒)
|
|
27
|
-
|
|
30
|
+
// 定义待推送动态消息映射
|
|
31
|
+
const messageMap = new Map();
|
|
32
|
+
await this.makeUidDynamicDataMap(uidMap, dynamicList, now, interval, weiboConfigData, messageMap);
|
|
33
|
+
await this.sendDynamicMessage(messageMap, weiboConfigData);
|
|
28
34
|
}
|
|
29
35
|
/**
|
|
30
36
|
* 处理微博数据,获取动态列表并构建 uid 映射
|
|
@@ -71,14 +77,14 @@ class WeiboTask {
|
|
|
71
77
|
requestedDataOfUids.clear(); // 清空已请求的映射
|
|
72
78
|
}
|
|
73
79
|
/**
|
|
74
|
-
*
|
|
80
|
+
* 构建uid对应动态数据映射
|
|
75
81
|
* @param uidMap uid 映射
|
|
76
82
|
* @param dynamicList 动态列表
|
|
77
83
|
* @param now 当前时间戳
|
|
78
84
|
* @param interval 推送间隔时间
|
|
79
85
|
* @param weiboConfigData 微博配置数据
|
|
80
86
|
*/
|
|
81
|
-
async
|
|
87
|
+
async makeUidDynamicDataMap(uidMap, dynamicList, now, interval, weiboConfigData, messageMap) {
|
|
82
88
|
for (let [chatType, chatTypeMap] of uidMap) {
|
|
83
89
|
for (let [key, value] of chatTypeMap) {
|
|
84
90
|
const tempDynamicList = dynamicList[key] || [];
|
|
@@ -110,7 +116,7 @@ class WeiboTask {
|
|
|
110
116
|
for (let chatId of chatIds) {
|
|
111
117
|
if (type && type.length && !type.includes(pushDynamicData.type))
|
|
112
118
|
continue; // 如果禁用了某类型的动态推送,跳过当前循环
|
|
113
|
-
await this.
|
|
119
|
+
await this.makeDynamicMessageMap(chatId, bot_id, upName, pushDynamicData, weiboConfigData, chatType, messageMap); // 发送动态消息
|
|
114
120
|
await this.randomDelay(1000, 2000); // 随机延时1-2秒
|
|
115
121
|
}
|
|
116
122
|
}
|
|
@@ -119,15 +125,16 @@ class WeiboTask {
|
|
|
119
125
|
}
|
|
120
126
|
}
|
|
121
127
|
/**
|
|
122
|
-
*
|
|
128
|
+
* 渲染构建待发送的动态消息数据的映射数组
|
|
123
129
|
* @param chatId 聊天 ID
|
|
124
130
|
* @param bot_id 机器人 ID
|
|
125
|
-
* @param upName
|
|
131
|
+
* @param upName 博主用户名
|
|
126
132
|
* @param pushDynamicData 推送动态数据
|
|
127
133
|
* @param weiboConfigData 微博配置数据
|
|
128
134
|
* @param chatType 聊天类型
|
|
135
|
+
* @param messageMap 待发送的动态消息映射
|
|
129
136
|
*/
|
|
130
|
-
async
|
|
137
|
+
async makeDynamicMessageMap(chatId, bot_id, upName, pushDynamicData, weiboConfigData, chatType, messageMap) {
|
|
131
138
|
const id_str = WeiboQuery.getDynamicId(pushDynamicData); // 获取动态 ID
|
|
132
139
|
let sended = null, markKey = '';
|
|
133
140
|
if (chatType === 'group') {
|
|
@@ -168,19 +175,11 @@ class WeiboTask {
|
|
|
168
175
|
};
|
|
169
176
|
let imgs = await this.renderDynamicCard(uid, renderData, ScreenshotOptionsData);
|
|
170
177
|
if (!imgs)
|
|
171
|
-
return;
|
|
172
|
-
|
|
173
|
-
global?.logger?.mark('优纪插件:微博动态执行推送');
|
|
174
|
-
for (let i = 0; i < imgs.length; i++) {
|
|
175
|
-
const image = imgs[i];
|
|
176
|
-
await this.sendMessage(chatId, bot_id, chatType, Segment.image(image));
|
|
177
|
-
await this.randomDelay(1000, 2000); // 随机延时1-2秒
|
|
178
|
-
}
|
|
179
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
178
|
+
return; // 如果渲染失败,则直接返回
|
|
179
|
+
await this.addMessageToMap(messageMap, chatType, bot_id, chatId, 'SINGLE', id_str, extentData?.type, imgs.map(img => Segment.image(img)));
|
|
180
180
|
}
|
|
181
181
|
else {
|
|
182
182
|
const dynamicMsg = await WeiboQuery.formatTextDynamicData(upName, pushDynamicData, false, weiboConfigData); //构建文字动态消息
|
|
183
|
-
Redis.set(`${markKey}${chatId}:${id_str}`, '1', { EX: 3600 * 72 }); // 设置已发送标记
|
|
184
183
|
if (dynamicMsg === undefined || dynamicMsg === 'continue') {
|
|
185
184
|
return 'return'; // 如果动态消息构建失败或内部资源获取失败,则直接返回
|
|
186
185
|
}
|
|
@@ -192,20 +191,15 @@ class WeiboTask {
|
|
|
192
191
|
}
|
|
193
192
|
}
|
|
194
193
|
let mergeTextPic = !!weiboConfigData.mergeTextPic === false ? false : true; // 是否合并文字和图片,默认为 true
|
|
195
|
-
|
|
194
|
+
//开启了合并文本和图片
|
|
195
|
+
if (mergeTextPic === true) {
|
|
196
196
|
const mergeMsg = [...dynamicMsg.msg, ...dynamicMsg.pics];
|
|
197
|
-
await this.
|
|
197
|
+
await this.addMessageToMap(messageMap, chatType, bot_id, chatId, 'MERGE', id_str, dynamicMsg.dynamicType, mergeMsg);
|
|
198
198
|
}
|
|
199
199
|
else {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
for (let i = 0; i < pics.length; i++) {
|
|
204
|
-
await this.sendMessage(chatId, bot_id, chatType, pics[i]);
|
|
205
|
-
await this.randomDelay(1000, 2000); // 随机延时1-2秒
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
200
|
+
//不合并文本和图片
|
|
201
|
+
await this.addMessageToMap(messageMap, chatType, bot_id, chatId, 'MERGE', id_str, dynamicMsg.dynamicType, dynamicMsg.msg);
|
|
202
|
+
await this.addMessageToMap(messageMap, chatType, bot_id, chatId, 'SINGLE', id_str, dynamicMsg.dynamicType, dynamicMsg.pics);
|
|
209
203
|
}
|
|
210
204
|
}
|
|
211
205
|
}
|
|
@@ -286,13 +280,86 @@ class WeiboTask {
|
|
|
286
280
|
}
|
|
287
281
|
}
|
|
288
282
|
/**
|
|
289
|
-
*
|
|
283
|
+
* 收集消息映射
|
|
284
|
+
* @param messageMap 消息映射
|
|
285
|
+
* @param chatType 聊天类型
|
|
286
|
+
* @param bot_id 机器人 ID
|
|
287
|
+
* @param chatId 聊天 ID
|
|
288
|
+
* @param sendMode 发送模式: SINGLE 逐条发送,MERGE 合并发送
|
|
289
|
+
* @param dynamicUUid_str 动态 UUID
|
|
290
|
+
* @param dynamicType 动态类型
|
|
291
|
+
* @param message 消息内容
|
|
292
|
+
*/
|
|
293
|
+
async addMessageToMap(messageMap, chatType, bot_id, chatId, sendMode, dynamicUUid_str, dynamicType, messages) {
|
|
294
|
+
if (!messageMap.has(chatType)) {
|
|
295
|
+
messageMap.set(chatType, new Map());
|
|
296
|
+
}
|
|
297
|
+
const botMap = messageMap.get(chatType);
|
|
298
|
+
if (!botMap?.has(bot_id)) {
|
|
299
|
+
botMap?.set(bot_id, new Map());
|
|
300
|
+
}
|
|
301
|
+
const chatMap = botMap?.get(bot_id);
|
|
302
|
+
if (!chatMap?.has(chatId)) {
|
|
303
|
+
chatMap?.set(chatId, []);
|
|
304
|
+
}
|
|
305
|
+
chatMap?.get(chatId)?.push({ sendMode, dynamicUUid_str, dynamicType, messages });
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* 推送动态消息
|
|
309
|
+
* @param messageMap 消息映射
|
|
310
|
+
* @param biliConfigData 微博配置数据
|
|
311
|
+
*/
|
|
312
|
+
async sendDynamicMessage(messageMap, weiboConfigData) {
|
|
313
|
+
const LogMark = new Set(); // 日志mark
|
|
314
|
+
for (const [chatType, botMap] of messageMap) {
|
|
315
|
+
for (const [bot_id, chatMap] of botMap) {
|
|
316
|
+
for (const [chatId, messageCombinationList] of chatMap) {
|
|
317
|
+
// 遍历组合消息
|
|
318
|
+
for (const messageCombination of messageCombinationList) {
|
|
319
|
+
const { sendMode, dynamicUUid_str, dynamicType, messages } = messageCombination;
|
|
320
|
+
let sended = null;
|
|
321
|
+
let markKey = '';
|
|
322
|
+
if (chatType === 'group') {
|
|
323
|
+
markKey = this.groupKey;
|
|
324
|
+
sended = await Redis.get(`${markKey}${chatId}:${dynamicUUid_str}`);
|
|
325
|
+
}
|
|
326
|
+
else if (chatType === 'private') {
|
|
327
|
+
markKey = this.privateKey;
|
|
328
|
+
sended = await Redis.get(`${markKey}${chatId}:${dynamicUUid_str}`);
|
|
329
|
+
}
|
|
330
|
+
const sendMarkKey = `${markKey}${chatId}:${dynamicUUid_str}`;
|
|
331
|
+
if (sended) {
|
|
332
|
+
continue; // 如果已经发送过,则直接跳过
|
|
333
|
+
}
|
|
334
|
+
if (!LogMark.has('1')) {
|
|
335
|
+
global?.logger?.mark('优纪插件: B站动态执行推送');
|
|
336
|
+
LogMark.add('1');
|
|
337
|
+
}
|
|
338
|
+
if (sendMode === 'SINGLE') {
|
|
339
|
+
for (let i = 0; i < messages.length; i++) {
|
|
340
|
+
await this.sendMessageApi(chatId, bot_id, chatType, messages[i]);
|
|
341
|
+
}
|
|
342
|
+
await Redis.set(sendMarkKey, '1', { EX: 3600 * 72 }); // 发送成功后设置标记
|
|
343
|
+
await this.randomDelay(1000, 2000); // 随机延时1-2秒
|
|
344
|
+
}
|
|
345
|
+
else if (sendMode === 'MERGE') {
|
|
346
|
+
await this.sendMessageApi(chatId, bot_id, chatType, messages);
|
|
347
|
+
await Redis.set(sendMarkKey, '1', { EX: 3600 * 72 }); // 发送成功后设置标记
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
LogMark.clear(); // 清空日志mark
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* 发送消息api
|
|
290
357
|
* @param chatId 聊天 ID
|
|
291
358
|
* @param bot_id 机器人 ID
|
|
292
359
|
* @param chatType 聊天类型
|
|
293
360
|
* @param message 消息内容
|
|
294
361
|
*/
|
|
295
|
-
async
|
|
362
|
+
async sendMessageApi(chatId, bot_id, chatType, message) {
|
|
296
363
|
if (chatType === 'group') {
|
|
297
364
|
await (Bot[bot_id] ?? Bot)
|
|
298
365
|
?.pickGroup(String(chatId))
|