Skip to content

Commit

Permalink
fix mix group and private error
Browse files Browse the repository at this point in the history
  • Loading branch information
snowtafir committed Aug 16, 2024
1 parent 182fa90 commit bf003e6
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 85 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# 1.0.3
* 修复群组与好友动态推送混淆问题
* 更新获取B站up信息api
* 优化动态字体样式
* 优化文字动态内容排版
* 修复转发动态内容缺失

# 1.0.2
* 新增支持获取完整文章动态内容
* 修复宫格样式
Expand Down
96 changes: 55 additions & 41 deletions models/bilibili/bilibili.task.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import QRCode from 'qrcode';
//import { Bot, Redis, Segment, EventType } from 'yunzai';
import { MainProps } from "../../components/dynamic/MainPage";
import Config from '../../utils/config';
import Image from '../../utils/image';
Expand All @@ -14,11 +13,13 @@ declare const logger: any;

export class BiliTask {
taskName: string;
key: string;
groupKey: string;
privateKey: string;
e?: any;
constructor(e?: any) {
this.taskName = "biliTask";
this.key = "Yz:yuki:bili:upPush:";
this.groupKey = "Yz:yuki:bili:upPush:group:";
this.privateKey = "Yz:yuki:bili:upPush:private:";
}

async hendleEventDynamicData(uid: string | number, count: number = 0): Promise<any> {
Expand Down Expand Up @@ -47,7 +48,7 @@ export class BiliTask {
let biliPushData = await Config.getUserConfig("bilibili", "push");
let interval: number = biliConfigData.interval || 7200;
let lastLiveStatus = JSON.parse(await redis.get("yuki:bililive:lastlivestatus")) || {};
const uidMap = new Map(); // 存放 uid 与推送信息的映射
const uidMap: Map<any, Map<string, any>> = new Map(); // 存放group 和 private 对应所属 uid 与推送信息的映射
const dynamicList = {}; // 存放获取的所有动态,键为 uid,值为动态数组

await this.processBiliData(biliPushData, uidMap, dynamicList, lastLiveStatus);
Expand All @@ -63,8 +64,12 @@ export class BiliTask {
* @param dynamicList 动态列表
* @param lastLiveStatus 最后直播状态
*/
async processBiliData(biliPushData: any, uidMap: Map<any, any>, dynamicList: any, lastLiveStatus: any) {
async processBiliData(biliPushData: any, uidMap: Map<any, Map<string, any>>, dynamicList: any, lastLiveStatus: any) {
for (let chatType in biliPushData) { // 遍历 group 和 private

if (!uidMap.has(chatType)) { uidMap.set(chatType, new Map()); }
const chatTypeMap = uidMap.get(chatType); // 建立当前 chatType (group 或 private) 的 uid 映射

for (let chatId in biliPushData[chatType]) {
const subUpsOfChat: { uid: string; bot_id: string[]; name: string; type: string[] }[] = biliPushData[chatType][chatId] || [];
for (let subInfoOfup of subUpsOfChat) {
Expand All @@ -90,10 +95,10 @@ export class BiliTask {
return;
}

const chatIds: any[] = Array.from(new Set([...Object((uidMap.get(subInfoOfup.uid) && uidMap.get(subInfoOfup.uid).chatIds) || []), chatId]));
const chatIds: any[] = Array.from(new Set([...Object((chatTypeMap.get(subInfoOfup.uid) && chatTypeMap.get(subInfoOfup.uid).chatIds) || []), chatId]));
const bot_id: string[] | number[] = subInfoOfup.bot_id || [];
const { name, type } = subInfoOfup;
uidMap.set(subInfoOfup.uid, { chatIds, bot_id, upName: name, type, chatType });
chatTypeMap.set(subInfoOfup.uid, { chatIds, bot_id, upName: name, type });
await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * (8000 - 2000 + 1) + 2000))); // 随机延时2-8秒
}
}
Expand All @@ -108,39 +113,41 @@ export class BiliTask {
* @param interval 推送间隔时间
* @param biliConfigData Bilibili配置数据
*/
async pushDynamicMessages(uidMap: Map<any, any>, dynamicList: any, now: number, interval: number, biliConfigData: any) {
for (let [key, value] of uidMap) {
const tempDynamicList = dynamicList[key] || [];
const willPushDynamicList = [];

const printedList = new Set(); // 已打印的动态列表
for (let dynamicItem of tempDynamicList) {
let author = dynamicItem?.modules?.module_author || {};
if (!printedList.has(author?.mid)) {
logger.info(`正在检测B站动态 [ ${author?.name} : ${author?.mid} ]`);
printedList.add(author?.mid);
async pushDynamicMessages(uidMap: Map<any, Map<string, any>>, dynamicList: any, now: number, interval: number, biliConfigData: any) {
for (let [chatType, chatTypeMap] of uidMap) {
for (let [key, value] of chatTypeMap) {
const tempDynamicList = dynamicList[key] || [];
const willPushDynamicList = [];

const printedList = new Set(); // 已打印的动态列表
for (let dynamicItem of tempDynamicList) {
let author = dynamicItem?.modules?.module_author || {};
if (!printedList.has(author?.mid)) {
logger.info(`正在检测B站动态 [ ${author?.name} : ${author?.mid} ]`);
printedList.add(author?.mid);
}
if (!author?.pub_ts) continue; // 如果动态没有发布时间,跳过当前循环
if (Number(now - author.pub_ts) > interval) {
logger.debug(`超过间隔,跳过 [ ${author?.name} : ${author?.mid} ] ${author?.pub_time} 的动态`);
continue;
} // 如果超过推送时间间隔,跳过当前循环
if (dynamicItem.type === "DYNAMIC_TYPE_FORWARD" && !biliConfigData.pushTransmit) continue; // 如果关闭了转发动态的推送,跳过当前循环
willPushDynamicList.push(dynamicItem);
}
if (!author?.pub_ts) continue; // 如果动态没有发布时间,跳过当前循环
if (Number(now - author.pub_ts) > interval) {
logger.debug(`超过间隔,跳过 [ ${author?.name} : ${author?.mid} ] ${author?.pub_time} 的动态`);
continue;
} // 如果超过推送时间间隔,跳过当前循环
if (dynamicItem.type === "DYNAMIC_TYPE_FORWARD" && !biliConfigData.pushTransmit) continue; // 如果关闭了转发动态的推送,跳过当前循环
willPushDynamicList.push(dynamicItem);
}
printedList.clear();
printedList.clear();

const pushMapInfo = value || {}; // 获取当前 uid 对应的推送信息
const pushMapInfo = value || {}; // 获取当前 uid 对应的推送信息

const { chatIds, bot_id, upName, type, chatType } = pushMapInfo;
const { chatIds, bot_id, upName, type } = pushMapInfo;

// 遍历待推送的动态数组,发送动态消息
for (let pushDynamicData of willPushDynamicList) {
if (chatIds && chatIds.length) {
for (let chatId of chatIds) {
if (type && type.length && !type.includes(pushDynamicData.type)) continue; // 如果禁用了某类型的动态推送,跳过当前循环
await this.sendDynamic(chatId, bot_id, upName, pushDynamicData, biliConfigData, chatType); // 发送动态消息
await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * (6500 - 2000 + 1) + 2000))); // 随机延时2-6.5秒
// 遍历待推送的动态数组,发送动态消息
for (let pushDynamicData of willPushDynamicList) {
if (chatIds && chatIds.length) {
for (let chatId of chatIds) {
if (type && type.length && !type.includes(pushDynamicData.type)) continue; // 如果禁用了某类型的动态推送,跳过当前循环
await this.sendDynamic(chatId, bot_id, upName, pushDynamicData, biliConfigData, chatType); // 发送动态消息
await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * (6500 - 2000 + 1) + 2000))); // 随机延时2-6.5秒
}
}
}
}
Expand All @@ -151,7 +158,14 @@ export class BiliTask {
async sendDynamic(chatId: string | number, bot_id: string | number, upName: string, pushDynamicData: any, biliConfigData: any, chatType: string) {
const id_str = pushDynamicData.id_str;

let sended: string | null = await redis.get(`${this.key}${chatId}:${id_str}`);
let sended: string | null, markKey: string;
if (chatType === "group") {
markKey = this.groupKey;
sended = await redis.get(`${markKey}${chatId}:${id_str}`);
} else if (chatType === "private") {
markKey = this.privateKey;
sended = await redis.get(`${markKey}${chatId}:${id_str}`);
}
if (sended) return; // 如果已经发送过,则直接返回

if (!!biliConfigData.pushMsgMode) {
Expand Down Expand Up @@ -186,7 +200,7 @@ export class BiliTask {
let imgs: Buffer[] | null = await this.renderDynamicCard(uid, renderData, ScreenshotOptionsData);
if (!imgs) return;

redis.set(`${this.key}${chatId}:${id_str}`, "1", { EX: 3600 * 10 }); // 设置已发送标记
redis.set(`${markKey}${chatId}:${id_str}`, "1", { EX: 3600 * 10 }); // 设置已发送标记

(logger ?? Bot.logger)?.mark("优纪插件:B站动态执行推送");

Expand All @@ -201,7 +215,7 @@ export class BiliTask {
} else {
const dynamicMsg = await BiliQuery.formatTextDynamicData(upName, pushDynamicData, false, biliConfigData); // 构建图文动态消息

redis.set(`${this.key}${chatId}:${id_str}`, "1", { EX: 3600 * 10 }); // 设置已发送标记
redis.set(`${markKey}${chatId}:${id_str}`, "1", { EX: 3600 * 10 }); // 设置已发送标记

if (dynamicMsg == "continue") {
return "return"; // 如果动态消息构建失败,则直接返回
Expand Down Expand Up @@ -309,10 +323,10 @@ export class BiliTask {
(logger ?? Bot.logger)?.error(`群组[${chatId}]推送失败:${JSON.stringify(error)}`);
});
} else if (chatType === "private") {
await (Bot[bot_id] ?? Bot)?.pickUser(String(chatId)).sendMsg(message)
await (Bot[bot_id] ?? Bot)?.pickFriend(String(chatId)).sendMsg(message)
.catch((error: any) => {
(logger ?? Bot.logger)?.error(`用户[${chatId}]推送失败:${JSON.stringify(error)}`);
}); // 发送私聊
}); // 发送好友私聊
}
}

Expand Down
104 changes: 60 additions & 44 deletions models/weibo/weibo.task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,20 @@ declare const logger: any;

export class WeiboTask {
taskName: string;
key: string;
groupKey: string;
privateKey: string;
e?: any;
constructor(e?) {
this.taskName = "weiboTask";
this.key = "Yz:yuki:weibo:upPush:";
this.groupKey = "Yz:yuki:weibo:upPush:group:";
this.privateKey = "Yz:yuki:weibo:upPush:private:";
}

async runTask() {
let weiboConfigData = await Config.getUserConfig("weibo", "config");
let weiboPushData = await Config.getUserConfig("weibo", "push");
let interval: number = weiboConfigData.interval || 7200; // 推送间隔时间,单位为秒,默认2小时
const uidMap: Map<any, any> = new Map(); // 存放 uid 与推送信息的映射
const uidMap: Map<any, Map<string, any>> = new Map(); // 存放group 和 private 对应所属 uid 与推送信息的映射
const dynamicList = {}; // 存放获取的所有动态,键为 uid,值为动态数组

await this.processWeiboData(weiboPushData, uidMap, dynamicList);
Expand All @@ -38,8 +40,12 @@ export class WeiboTask {
* @param uidMap uid 映射
* @param dynamicList 动态列表
*/
async processWeiboData(weiboPushData: any, uidMap: Map<any, any>, dynamicList: any) {
async processWeiboData(weiboPushData: any, uidMap: Map<any, Map<string, any>>, dynamicList: any) {
for (let chatType in weiboPushData) { // 遍历 group 和 private

if (!uidMap.has(chatType)) { uidMap.set(chatType, new Map()); }
const chatTypeMap = uidMap.get(chatType); // 建立当前 chatType (group 或 private) 的 uid 映射

for (let chatId in weiboPushData[chatType]) {
const subUpsOfChat: { uid: string; bot_id: string[]; name: string; type: string[] }[] = weiboPushData[chatType][chatId] || [];
for (let subInfoOfup of subUpsOfChat) {
Expand All @@ -49,10 +55,10 @@ export class WeiboTask {
dynamicList[subInfoOfup.uid] = dynamicData;
}

const chatIds: string[] = Array.from(new Set([...Object((uidMap.get(subInfoOfup.uid) && uidMap.get(subInfoOfup.uid).chatIds) || []), chatId]));
const bot_id: string[] = subInfoOfup.bot_id || [];
const chatIds: any[] = Array.from(new Set([...Object((chatTypeMap.get(subInfoOfup.uid) && chatTypeMap.get(subInfoOfup.uid).chatIds) || []), chatId]));
const bot_id: string[] | number[] = subInfoOfup.bot_id || [];
const { name, type } = subInfoOfup;
uidMap.set(subInfoOfup.uid, { chatIds, bot_id, upName: name, type, chatType });
chatTypeMap.set(subInfoOfup.uid, { chatIds, bot_id, upName: name, type });
await this.randomDelay(1000, 4000); // 随机延时1-4秒
}
}
Expand All @@ -67,39 +73,41 @@ export class WeiboTask {
* @param interval 推送间隔时间
* @param weiboConfigData 微博配置数据
*/
async pushDynamicMessages(uidMap: Map<any, any>, dynamicList: any, now: number, interval: number, weiboConfigData: any) {
for (let [key, value] of uidMap) {
const tempDynamicList = dynamicList[key] || [];
const willPushDynamicList = [];

const printedList = new Set(); // 已打印的动态列表
for (let dynamicItem of tempDynamicList) {
let raw_post = dynamicItem || {};
let user = raw_post?.mblog?.user || {};
if (!printedList.has(user?.id)) {
logger.info(`正在检测微博动态 [ ${user?.screen_name} : ${user?.id} ]`);
printedList.add(user?.id);
async pushDynamicMessages(uidMap: Map<any, Map<string, any>>, dynamicList: any, now: number, interval: number, weiboConfigData: any) {
for (let [chatType, chatTypeMap] of uidMap) {
for (let [key, value] of chatTypeMap) {
const tempDynamicList = dynamicList[key] || [];
const willPushDynamicList = [];

const printedList = new Set(); // 已打印的动态列表
for (let dynamicItem of tempDynamicList) {
let raw_post = dynamicItem || {};
let user = raw_post?.mblog?.user || {};
if (!printedList.has(user?.id)) {
logger.info(`正在检测微博动态 [ ${user?.screen_name} : ${user?.id} ]`);
printedList.add(user?.id);
}
if (!raw_post?.mblog?.created_at) continue;
if (Number(now - (WeiboQuery.getDynamicCreatetDate(raw_post) / 1000)) > interval) {
logger.debug(`超过间隔,跳过 [ ${user?.screen_name} : ${user?.id} ] ${raw_post?.mblog?.created_at} 的动态`);
continue;
} // 如果超过推送时间间隔,跳过当前循环
if (dynamicItem.type === "DYNAMIC_TYPE_FORWARD" && !weiboConfigData.pushTransmit) continue; // 如果关闭了转发动态的推送,跳过当前循环
willPushDynamicList.push(dynamicItem);
}
if (!raw_post?.mblog?.created_at) continue;
if (Number(now - (WeiboQuery.getDynamicCreatetDate(raw_post) / 1000)) > interval) {
logger.debug(`超过间隔,跳过 [ ${user?.screen_name} : ${user?.id} ] ${raw_post?.mblog?.created_at} 的动态`);
continue;
} // 如果超过推送时间间隔,跳过当前循环
if (dynamicItem.type === "DYNAMIC_TYPE_FORWARD" && !weiboConfigData.pushTransmit) continue; // 如果关闭了转发动态的推送,跳过当前循环
willPushDynamicList.push(dynamicItem);
}
printedList.clear();

const pushMapInfo = value || {}; // 获取当前 uid 对应的推送信息
const { chatIds, bot_id, upName, type, chatType } = pushMapInfo;

// 遍历待推送的动态数组,发送动态消息
for (let pushDynamicData of willPushDynamicList) {
if (chatIds && chatIds.length) {
for (let chatId of chatIds) {
if (type && type.length && !type.includes(pushDynamicData.type)) continue; // 如果禁用了某类型的动态推送,跳过当前循环
await this.sendDynamic(chatId, bot_id, upName, pushDynamicData, weiboConfigData, chatType); // 发送动态消息
await this.randomDelay(2000, 10500); // 随机延时2-10.5秒
printedList.clear();

const pushMapInfo = value || {}; // 获取当前 uid 对应的推送信息
const { chatIds, bot_id, upName, type } = pushMapInfo;

// 遍历待推送的动态数组,发送动态消息
for (let pushDynamicData of willPushDynamicList) {
if (chatIds && chatIds.length) {
for (let chatId of chatIds) {
if (type && type.length && !type.includes(pushDynamicData.type)) continue; // 如果禁用了某类型的动态推送,跳过当前循环
await this.sendDynamic(chatId, bot_id, upName, pushDynamicData, weiboConfigData, chatType); // 发送动态消息
await this.randomDelay(2000, 10500); // 随机延时2-10.5秒
}
}
}
}
Expand All @@ -117,7 +125,15 @@ export class WeiboTask {
*/
async sendDynamic(chatId: string | number, bot_id: string | number, upName: string, pushDynamicData: any, weiboConfigData: any, chatType: string) {
const id_str: string = WeiboQuery.getDynamicId(pushDynamicData); // 获取动态 ID
let sended: string | null = await redis.get(`${this.key}${chatId}:${id_str}`);

let sended: string | null, markKey: string;
if (chatType === "group") {
markKey = this.groupKey;
sended = await redis.get(`${markKey}${chatId}:${id_str}`);
} else if (chatType === "private") {
markKey = this.privateKey;
sended = await redis.get(`${markKey}${chatId}:${id_str}`);
}
if (sended) return; // 如果已经发送过,则直接返回

if (!!weiboConfigData.pushMsgMode) {
Expand Down Expand Up @@ -152,7 +168,7 @@ export class WeiboTask {
let imgs: Buffer[] | null = await this.renderDynamicCard(uid, renderData, ScreenshotOptionsData);
if (!imgs) return;

redis.set(`${this.key}${chatId}:${id_str}`, "1", { EX: 3600 * 10 }); // 设置已发送标记
redis.set(`${markKey}${chatId}:${id_str}`, "1", { EX: 3600 * 10 }); // 设置已发送标记

(logger ?? Bot.logger)?.mark("优纪插件:B站动态执行推送");

Expand All @@ -165,7 +181,7 @@ export class WeiboTask {
} else {
const dynamicMsg: string[] | "continue" | false = await WeiboQuery.formatTextDynamicData(upName, pushDynamicData, false, weiboConfigData); //构建文字动态消息

redis.set(`${this.key}${chatId}:${id_str}`, "1", { EX: 3600 * 10 }); // 设置已发送标记
redis.set(`${markKey}${chatId}:${id_str}`, "1", { EX: 3600 * 10 }); // 设置已发送标记

if (dynamicMsg == "continue" || dynamicMsg == false) {
return "return"; // 如果动态消息构建失败或内部资源获取失败,则直接返回
Expand Down Expand Up @@ -273,10 +289,10 @@ export class WeiboTask {
(logger ?? Bot.logger)?.error(`群组[${chatId}]推送失败:${JSON.stringify(error)}`);
});
} else if (chatType === "private") {
await (Bot[bot_id] ?? Bot)?.pickUser(String(chatId)).sendMsg(message)
await (Bot[bot_id] ?? Bot)?.pickFriend(String(chatId)).sendMsg(message)
.catch((error) => {
(logger ?? Bot.logger)?.error(`用户[${chatId}]推送失败:${JSON.stringify(error)}`);
}); // 发送私聊
}); // 发送好友私聊
}
}

Expand Down

0 comments on commit bf003e6

Please sign in to comment.