智能广播接口

未完工
This commit is contained in:
Jerry 2025-05-14 18:42:38 +08:00
parent d1d6440f62
commit 865f606399
3 changed files with 87 additions and 1 deletions

View File

@ -3,6 +3,7 @@ import response from '../../utils/core/response';
import BotService from './bot.service';
import tools from '../../utils/modules/tools';
import logger from '../../utils/core/logger';
import wsClientManager from '../../services/ws/wsClientManager';
class BotController {
private readonly router: express.Router;
@ -20,6 +21,7 @@ class BotController {
this.router.post(`/getBotId`, this.postBotsId);
this.router.post('/getGroupInfo', this.postGroupInfo);
this.router.post('/sendMessage', this.sendMessage);
this.router.post('/reportBots', this.reportBots);
}
/**
@ -73,6 +75,29 @@ class BotController {
}
};
/**
* 广bot连接情况
* @param req
* @param res
*/
private reportBots = async (req: express.Request, res: express.Response): Promise<void> => {
try {
const token = req.body.token;
if (tools.checkToken(token.toString())) {
const sendMessage = {
type: 'reportBots',
data: {},
};
await wsClientManager.broadcast(sendMessage);
await response.success(res, {});
} else {
await tools.tokenCheckFailed(res, token);
}
} catch (e) {
await response.error(res);
}
};
/**
*
* @param req

View File

@ -4,6 +4,7 @@ import fs from 'fs/promises';
import path from 'path';
import redisService from '../../services/redis/redis';
import wsClientManager from '../../services/ws/wsClientManager';
import tools from '../../utils/core/tool';
class BotService {
/**
@ -119,6 +120,59 @@ class BotService {
return false;
}
public async broadcastToAllGroups(message: string): Promise<void> {
const userPath = paths.get('userData');
const botsPath = path.join(userPath, '/crystelfBots');
const dirData = await fs.readdir(botsPath);
const groupMap: Map<number, { botId: number; clientId: string }[]> = new Map();
for (const fileName of dirData) {
if (!fileName.endsWith('.json')) continue;
const clientId = path.basename(fileName, '.json');
const botList = await redisService.fetch('crystelfBots', fileName);
if (!Array.isArray(botList)) continue;
for (const bot of botList) {
if (!bot.uin || !bot.groups) continue;
for (const group of bot.groups) {
if (!groupMap.has(group.group_id)) {
groupMap.set(group.group_id, []);
}
groupMap.get(group.group_id)?.push({ botId: bot.uin, clientId });
}
}
}
for (const [groupId, botEntries] of groupMap.entries()) {
const clientGroups = new Map<string, number[]>();
botEntries.forEach(({ botId, clientId }) => {
if (!clientGroups.has(clientId)) clientGroups.set(clientId, []);
clientGroups.get(clientId)!.push(botId);
});
const selectedClientId = tools.getRandomItem([...clientGroups.keys()]);
const botCandidates = clientGroups.get(selectedClientId)!;
const selectedBotId = tools.getRandomItem(botCandidates);
const delay = tools.getRandomDelay(30_000, 90_000);
setTimeout(() => {
const sendData = {
type: 'sendMessage',
data: {
botId: selectedBotId,
groupId,
clientId: selectedClientId,
message,
},
};
logger.info(
`[广播] 向群 ${groupId} 使用Bot ${selectedBotId}(客户端 ${selectedClientId})发送消息,延迟 ${delay / 1000}`
);
wsClientManager.send(selectedClientId, sendData).catch((e) => {
logger.error(`发送到群${groupId}失败:`, e);
});
}, delay);
}
}
/**
* `botId``client`
* @param botId
@ -172,7 +226,6 @@ class BotService {
logger.error(`读取${clientId}出错..`);
}
}
return undefined;
}
}

View File

@ -21,6 +21,14 @@ let tools = {
}
logger.error(lastError);
},
getRandomItem<T>(list: T[]): T {
return list[Math.floor(Math.random() * list.length)];
},
getRandomDelay(min: number, max: number): number {
return Math.floor(Math.random() * (max - min + 1)) + min;
},
};
export default tools;