yz-yuki-plugin 2.0.7-18 → 2.0.7-19
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
CHANGED
|
@@ -380,51 +380,103 @@ class BiliTask {
|
|
|
380
380
|
async sendDynamicMessage(messageMap, biliConfigData) {
|
|
381
381
|
let liveAtAll = !!biliConfigData.liveAtAll === true ? true : false; // 直播动态是否@全体成员,默认false
|
|
382
382
|
let liveAtAllCD = biliConfigData.liveAtAllCD || 1800; // 直播动态@全体成员 冷却时间CD,默认 30 分钟
|
|
383
|
+
let forwardSendDynamic = biliConfigData.forwardSendDynamic === 0 || biliConfigData.forwardSendDynamic === false ? false : true; // 转发动态是否合并发送,默认 true
|
|
383
384
|
// 直播动态@全体成员的群组/好友列表,默认空数组,为空则不进行@全体成员操作
|
|
384
385
|
let liveAtAllGroupList = new Set(Array.isArray(biliConfigData?.liveAtAllGroupList) ? Array.from(biliConfigData.liveAtAllGroupList).map(item => String(item)) : []);
|
|
385
386
|
const LogMark = new Set(); // 日志mark
|
|
386
387
|
for (const [chatType, botMap] of messageMap) {
|
|
387
388
|
for (const [bot_id, chatMap] of botMap) {
|
|
388
389
|
for (const [chatId, messageCombinationList] of chatMap) {
|
|
389
|
-
//
|
|
390
|
+
// 区分群聊和私聊
|
|
391
|
+
let markKey = chatType === 'group' ? this.groupKey : this.privateKey;
|
|
392
|
+
if (!LogMark.has('1')) {
|
|
393
|
+
global?.logger?.mark('优纪插件: B站动态执行推送');
|
|
394
|
+
LogMark.add('1');
|
|
395
|
+
}
|
|
396
|
+
let liveAtAllMark = await Redis.get(`${markKey}${chatId}:liveAtAllMark`); // 直播动态@全体成员标记,默认 0
|
|
397
|
+
const hasLiveDynamic = messageCombinationList.some(m => m.dynamicType === 'DYNAMIC_TYPE_LIVE_RCMD');
|
|
398
|
+
// 如果开启了直播动态@全体成员
|
|
399
|
+
if (liveAtAll && !liveAtAllMark && hasLiveDynamic && liveAtAllGroupList.has(String(chatId))) {
|
|
400
|
+
try {
|
|
401
|
+
await this.sendMsgApi(chatId, bot_id, chatType, [Segment.at('all')]);
|
|
402
|
+
await Redis.set(`${markKey}${chatId}:liveAtAllMark`, 1, { EX: liveAtAllCD }); // 设置直播动态@全体成员标记为 1
|
|
403
|
+
}
|
|
404
|
+
catch (error) {
|
|
405
|
+
logger.error(`直播动态发送@全体成员失败,请检查 <机器人> 是否有 [管理员权限] 或 [聊天平台是否支持] :${error}`);
|
|
406
|
+
let liveAtAllErrMsg = !!biliConfigData.liveAtAllErrMsg === false ? false : true; // 直播动态@全体成员失败是否发送错误提示消息,默认 false
|
|
407
|
+
if (liveAtAllErrMsg) {
|
|
408
|
+
await this.sendMsgApi(chatId, bot_id, chatType, ['直播动态发送@全体成员失败,请检查权限或平台是否支持']);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
// 统计图片数量和文字长度
|
|
413
|
+
let imageCount = 0;
|
|
414
|
+
let textLength = 0;
|
|
390
415
|
for (const messageCombination of messageCombinationList) {
|
|
391
|
-
const {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
416
|
+
const { messages } = messageCombination;
|
|
417
|
+
for (const msg of messages) {
|
|
418
|
+
if (typeof msg === 'object' && msg.type === 'image') {
|
|
419
|
+
imageCount++;
|
|
420
|
+
}
|
|
421
|
+
else if (typeof msg === 'string') {
|
|
422
|
+
textLength += msg.length;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
// 满足条件才使用合并转发
|
|
427
|
+
const useForward = imageCount > 2 || textLength > 300;
|
|
428
|
+
if (forwardSendDynamic && useForward) {
|
|
429
|
+
const forwardNodes = [];
|
|
430
|
+
// 合并所有消息
|
|
431
|
+
const forwardSendMardKeyList = [];
|
|
432
|
+
forwardNodes.push({
|
|
433
|
+
name: '优纪酱通知',
|
|
434
|
+
uin: String(80000000),
|
|
435
|
+
message: ['有新的B站动态了~'],
|
|
436
|
+
time: Date.now()
|
|
437
|
+
});
|
|
438
|
+
for (const messageCombination of messageCombinationList) {
|
|
439
|
+
const { sendMode, dynamicUUid_str, dynamicType, messages } = messageCombination;
|
|
440
|
+
const sendMarkKey = `${markKey}${chatId}:${dynamicUUid_str}`;
|
|
441
|
+
// 原子性设置标记,防止并发重复
|
|
442
|
+
const setResult = await Redis.set(sendMarkKey, '1', { NX: true, EX: 3600 * 72 });
|
|
443
|
+
if (!setResult) {
|
|
444
|
+
continue; // 已有标记,跳过
|
|
445
|
+
}
|
|
446
|
+
forwardSendMardKeyList.push(sendMarkKey); // 收集合并转发的标记键
|
|
447
|
+
// 每条动态一个 node
|
|
448
|
+
forwardNodes.push({
|
|
449
|
+
name: '匿名消息',
|
|
450
|
+
uin: String(80000000),
|
|
451
|
+
message: messages,
|
|
452
|
+
time: Date.now()
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
// 尝试合并转发动态
|
|
456
|
+
if ((await this.sendMsgApi(chatId, bot_id, chatType, '优纪酱B站动态通知~')) &&
|
|
457
|
+
(await this.sendForwardMsgApi(chatId, bot_id, chatType, forwardNodes))) {
|
|
458
|
+
await this.randomDelay(1000, 2000);
|
|
459
|
+
continue; // 合并转发成功,跳过后续单条发送逻辑
|
|
395
460
|
}
|
|
396
|
-
else
|
|
397
|
-
|
|
461
|
+
else {
|
|
462
|
+
for (const sendMarkKey of forwardSendMardKeyList) {
|
|
463
|
+
await Redis.del(sendMarkKey); // 发送消息失败,删除合并转发成功标记
|
|
464
|
+
}
|
|
398
465
|
}
|
|
466
|
+
}
|
|
467
|
+
// 合并转发失败,回退为原有方式
|
|
468
|
+
for (const messageCombination of messageCombinationList) {
|
|
469
|
+
const { sendMode, dynamicUUid_str, dynamicType, messages } = messageCombination;
|
|
399
470
|
const sendMarkKey = `${markKey}${chatId}:${dynamicUUid_str}`;
|
|
400
471
|
// 原子性设置标记,防止并发重复
|
|
401
472
|
const setResult = await Redis.set(sendMarkKey, '1', { NX: true, EX: 3600 * 72 });
|
|
402
473
|
if (!setResult) {
|
|
403
474
|
continue; // 已有标记,跳过
|
|
404
475
|
}
|
|
405
|
-
if (!LogMark.has('1')) {
|
|
406
|
-
global?.logger?.mark('优纪插件: B站动态执行推送');
|
|
407
|
-
LogMark.add('1');
|
|
408
|
-
}
|
|
409
|
-
let liveAtAllMark = await Redis.get(`${markKey}${chatId}:liveAtAllMark`); // 直播动态@全体成员标记,默认 0
|
|
410
|
-
// 如果开启了直播动态@全体成员
|
|
411
|
-
if (liveAtAll && !liveAtAllMark && dynamicType === 'DYNAMIC_TYPE_LIVE_RCMD' && liveAtAllGroupList.has(String(chatId))) {
|
|
412
|
-
try {
|
|
413
|
-
await this.sendMessageApi(chatId, bot_id, chatType, [Segment.at('all')]);
|
|
414
|
-
await Redis.set(`${markKey}${chatId}:liveAtAllMark`, 1, { EX: liveAtAllCD }); // 设置直播动态@全体成员标记为 1
|
|
415
|
-
}
|
|
416
|
-
catch (error) {
|
|
417
|
-
logger.error(`直播动态发送@全体成员失败,请检查 <机器人> 是否有 [管理员权限] 或 [聊天平台是否支持] :${error}`);
|
|
418
|
-
let liveAtAllErrMsg = !!biliConfigData.liveAtAllErrMsg === false ? false : true; // 直播动态@全体成员失败是否发送错误提示消息,默认 false
|
|
419
|
-
if (liveAtAllErrMsg) {
|
|
420
|
-
await this.sendMessageApi(chatId, bot_id, chatType, ['直播动态发送@全体成员失败,请检查权限或平台是否支持']);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
476
|
let sendSuccess = true;
|
|
425
477
|
if (sendMode === 'SINGLE') {
|
|
426
478
|
for (let i = 0; i < messages.length; i++) {
|
|
427
|
-
if (!(await this.
|
|
479
|
+
if (!(await this.sendMsgApi(chatId, bot_id, chatType, messages[i]))) {
|
|
428
480
|
sendSuccess = false;
|
|
429
481
|
break;
|
|
430
482
|
}
|
|
@@ -437,7 +489,7 @@ class BiliTask {
|
|
|
437
489
|
}
|
|
438
490
|
}
|
|
439
491
|
else if (sendMode === 'MERGE') {
|
|
440
|
-
if (!(await this.
|
|
492
|
+
if (!(await this.sendMsgApi(chatId, bot_id, chatType, messages))) {
|
|
441
493
|
await Redis.del(sendMarkKey); // 失败删除标记
|
|
442
494
|
}
|
|
443
495
|
await this.randomDelay(1000, 2000);
|
|
@@ -455,7 +507,7 @@ class BiliTask {
|
|
|
455
507
|
* @param chatType 聊天类型
|
|
456
508
|
* @param message 消息内容
|
|
457
509
|
*/
|
|
458
|
-
async
|
|
510
|
+
async sendMsgApi(chatId, bot_id, chatType, message) {
|
|
459
511
|
try {
|
|
460
512
|
if (chatType === 'group') {
|
|
461
513
|
await (Bot[bot_id] ?? Bot)?.pickGroup(String(chatId)).sendMsg(message); // 发送群聊
|
|
@@ -470,6 +522,30 @@ class BiliTask {
|
|
|
470
522
|
return false; // 发送失败
|
|
471
523
|
}
|
|
472
524
|
}
|
|
525
|
+
/**
|
|
526
|
+
* 发送合并转发消息
|
|
527
|
+
* @param chatId 聊天 ID
|
|
528
|
+
* @param bot_id 机器人 ID
|
|
529
|
+
* @param chatType 聊天类型
|
|
530
|
+
* @param message 消息内容
|
|
531
|
+
* @returns 是否发送成功
|
|
532
|
+
*/
|
|
533
|
+
async sendForwardMsgApi(chatId, bot_id, chatType, forwardNodes) {
|
|
534
|
+
const forwardMsg = await Bot.makeForwardMsg(forwardNodes);
|
|
535
|
+
try {
|
|
536
|
+
if (chatType === 'group') {
|
|
537
|
+
await (Bot[bot_id] ?? Bot)?.pickGroup(String(chatId)).sendMsg(forwardMsg); // 发送群聊合并转发
|
|
538
|
+
}
|
|
539
|
+
else if (chatType === 'private') {
|
|
540
|
+
await (Bot[bot_id] ?? Bot)?.pickFriend(String(chatId)).sendMsg(forwardMsg); // 发送好友私聊合并转发
|
|
541
|
+
}
|
|
542
|
+
return true; // 发送成功
|
|
543
|
+
}
|
|
544
|
+
catch (error) {
|
|
545
|
+
global?.logger?.error(`${chatType === 'group' ? '群聊' : '私聊'} ${chatId} 合并转发消息发送失败:${JSON.stringify(error)}`);
|
|
546
|
+
return false; // 发送失败
|
|
547
|
+
}
|
|
548
|
+
}
|
|
473
549
|
/**
|
|
474
550
|
* 随机延时
|
|
475
551
|
* @param min 最小延时时间
|
|
@@ -344,34 +344,85 @@ class WeiboTask {
|
|
|
344
344
|
* @param biliConfigData 微博配置数据
|
|
345
345
|
*/
|
|
346
346
|
async sendDynamicMessage(messageMap, weiboConfigData) {
|
|
347
|
+
let forwardSendDynamic = weiboConfigData.forwardSendDynamic === 0 || weiboConfigData.forwardSendDynamic === false ? false : true; // 转发动态是否合并发送,默认 true
|
|
347
348
|
const LogMark = new Set(); // 日志mark
|
|
348
349
|
for (const [chatType, botMap] of messageMap) {
|
|
349
350
|
for (const [bot_id, chatMap] of botMap) {
|
|
350
351
|
for (const [chatId, messageCombinationList] of chatMap) {
|
|
351
|
-
//
|
|
352
|
+
// 区分群聊和私聊
|
|
353
|
+
let markKey = chatType === 'group' ? this.groupKey : this.privateKey;
|
|
354
|
+
if (!LogMark.has('1')) {
|
|
355
|
+
global?.logger?.mark('优纪插件: B站动态执行推送');
|
|
356
|
+
LogMark.add('1');
|
|
357
|
+
}
|
|
358
|
+
// 统计图片数量和文字长度
|
|
359
|
+
let imageCount = 0;
|
|
360
|
+
let textLength = 0;
|
|
352
361
|
for (const messageCombination of messageCombinationList) {
|
|
353
|
-
const {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
362
|
+
const { messages } = messageCombination;
|
|
363
|
+
for (const msg of messages) {
|
|
364
|
+
if (typeof msg === 'object' && msg.type === 'image') {
|
|
365
|
+
imageCount++;
|
|
366
|
+
}
|
|
367
|
+
else if (typeof msg === 'string') {
|
|
368
|
+
textLength += msg.length;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
// 满足条件才使用合并转发
|
|
373
|
+
const useForward = imageCount > 2 || textLength > 300;
|
|
374
|
+
if (forwardSendDynamic && useForward) {
|
|
375
|
+
const forwardNodes = [];
|
|
376
|
+
// 合并所有消息
|
|
377
|
+
const forwardSendMardKeyList = [];
|
|
378
|
+
forwardNodes.push({
|
|
379
|
+
name: '优纪酱通知',
|
|
380
|
+
uin: String(80000000),
|
|
381
|
+
message: ['有新的微博动态了~'],
|
|
382
|
+
time: Date.now()
|
|
383
|
+
});
|
|
384
|
+
for (const messageCombination of messageCombinationList) {
|
|
385
|
+
const { sendMode, dynamicUUid_str, dynamicType, messages } = messageCombination;
|
|
386
|
+
const sendMarkKey = `${markKey}${chatId}:${dynamicUUid_str}`;
|
|
387
|
+
// 原子性设置标记,防止并发重复
|
|
388
|
+
const setResult = await Redis.set(sendMarkKey, '1', { NX: true, EX: 3600 * 72 });
|
|
389
|
+
if (!setResult) {
|
|
390
|
+
continue; // 已有标记,跳过
|
|
391
|
+
}
|
|
392
|
+
forwardSendMardKeyList.push(sendMarkKey); // 收集合并转发的标记键
|
|
393
|
+
// 每条动态一个 node
|
|
394
|
+
forwardNodes.push({
|
|
395
|
+
name: '匿名消息',
|
|
396
|
+
uin: String(80000000),
|
|
397
|
+
message: messages,
|
|
398
|
+
time: Date.now()
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
// 尝试合并转发动态
|
|
402
|
+
if ((await this.sendMsgApi(chatId, bot_id, chatType, '优纪酱微博动态通知~')) &&
|
|
403
|
+
(await this.sendForwardMsgApi(chatId, bot_id, chatType, forwardNodes))) {
|
|
404
|
+
await this.randomDelay(1000, 2000);
|
|
405
|
+
continue; // 合并转发成功,跳过后续单条发送逻辑
|
|
357
406
|
}
|
|
358
|
-
else
|
|
359
|
-
|
|
407
|
+
else {
|
|
408
|
+
for (const sendMarkKey of forwardSendMardKeyList) {
|
|
409
|
+
await Redis.del(sendMarkKey); // 发送消息失败,删除合并转发成功标记
|
|
410
|
+
}
|
|
360
411
|
}
|
|
412
|
+
}
|
|
413
|
+
// 合并转发失败,回退为原有方式
|
|
414
|
+
for (const messageCombination of messageCombinationList) {
|
|
415
|
+
const { sendMode, dynamicUUid_str, dynamicType, messages } = messageCombination;
|
|
361
416
|
const sendMarkKey = `${markKey}${chatId}:${dynamicUUid_str}`;
|
|
362
417
|
// 原子性设置标记,防止并发重复
|
|
363
418
|
const setResult = await Redis.set(sendMarkKey, '1', { NX: true, EX: 3600 * 72 });
|
|
364
419
|
if (!setResult) {
|
|
365
420
|
continue; // 已有标记,跳过
|
|
366
421
|
}
|
|
367
|
-
if (!LogMark.has('1')) {
|
|
368
|
-
global?.logger?.mark('优纪插件: B站动态执行推送');
|
|
369
|
-
LogMark.add('1');
|
|
370
|
-
}
|
|
371
422
|
let sendSuccess = true;
|
|
372
423
|
if (sendMode === 'SINGLE') {
|
|
373
424
|
for (let i = 0; i < messages.length; i++) {
|
|
374
|
-
if (!(await this.
|
|
425
|
+
if (!(await this.sendMsgApi(chatId, bot_id, chatType, messages[i]))) {
|
|
375
426
|
sendSuccess = false;
|
|
376
427
|
break;
|
|
377
428
|
}
|
|
@@ -384,7 +435,7 @@ class WeiboTask {
|
|
|
384
435
|
}
|
|
385
436
|
}
|
|
386
437
|
else if (sendMode === 'MERGE') {
|
|
387
|
-
if (!(await this.
|
|
438
|
+
if (!(await this.sendMsgApi(chatId, bot_id, chatType, messages))) {
|
|
388
439
|
await Redis.del(sendMarkKey); // 失败删除标记
|
|
389
440
|
}
|
|
390
441
|
await this.randomDelay(1000, 2000);
|
|
@@ -402,7 +453,7 @@ class WeiboTask {
|
|
|
402
453
|
* @param chatType 聊天类型
|
|
403
454
|
* @param message 消息内容
|
|
404
455
|
*/
|
|
405
|
-
async
|
|
456
|
+
async sendMsgApi(chatId, bot_id, chatType, message) {
|
|
406
457
|
try {
|
|
407
458
|
if (chatType === 'group') {
|
|
408
459
|
await (Bot[bot_id] ?? Bot)?.pickGroup(String(chatId)).sendMsg(message); // 发送群聊
|
|
@@ -417,6 +468,30 @@ class WeiboTask {
|
|
|
417
468
|
return false; // 发送失败
|
|
418
469
|
}
|
|
419
470
|
}
|
|
471
|
+
/**
|
|
472
|
+
* 发送合并转发消息
|
|
473
|
+
* @param chatId 聊天 ID
|
|
474
|
+
* @param bot_id 机器人 ID
|
|
475
|
+
* @param chatType 聊天类型
|
|
476
|
+
* @param message 消息内容
|
|
477
|
+
* @returns 是否发送成功
|
|
478
|
+
*/
|
|
479
|
+
async sendForwardMsgApi(chatId, bot_id, chatType, forwardNodes) {
|
|
480
|
+
const forwardMsg = await Bot.makeForwardMsg(forwardNodes);
|
|
481
|
+
try {
|
|
482
|
+
if (chatType === 'group') {
|
|
483
|
+
await (Bot[bot_id] ?? Bot)?.pickGroup(String(chatId)).sendMsg(forwardMsg); // 发送群聊合并转发
|
|
484
|
+
}
|
|
485
|
+
else if (chatType === 'private') {
|
|
486
|
+
await (Bot[bot_id] ?? Bot)?.pickFriend(String(chatId)).sendMsg(forwardMsg); // 发送好友私聊合并转发
|
|
487
|
+
}
|
|
488
|
+
return true; // 发送成功
|
|
489
|
+
}
|
|
490
|
+
catch (error) {
|
|
491
|
+
global?.logger?.error(`${chatType === 'group' ? '群聊' : '私聊'} ${chatId} 合并转发消息发送失败:${JSON.stringify(error)}`);
|
|
492
|
+
return false; // 发送失败
|
|
493
|
+
}
|
|
494
|
+
}
|
|
420
495
|
/**
|
|
421
496
|
* 随机延时
|
|
422
497
|
* @param min 最小延时时间
|