diff --git a/apps/reportBots.js b/apps/reportBots.js index 254c6f0..686fdcb 100644 --- a/apps/reportBots.js +++ b/apps/reportBots.js @@ -4,13 +4,18 @@ export default class ReportBots extends plugin { constructor() { super({ name: 'crystelf Bot状态上报', - dsc: '定时上报botID和群聊列表', + dsc: '一些操作bot的功能', rule: [ { reg: '^#crystelf同步$', fnc: 'manualReport', permission: 'master', }, + { + reg: '^#crystelf广播(.+)$', + fnc: 'broadcast', + permission: 'master', + }, ], task: [ { @@ -34,4 +39,20 @@ export default class ReportBots extends plugin { e.reply('crystelf Bot同步失败:核心未连接..'); } } + + async broadcast(e) { + const msg = e?.msg?.match(/^#crystelf广播(.+)$/)?.[1]?.trim(); + if (!msg) { + return e.reply('广播内容不能为空'); + } + + e.reply(`开始广播消息到所有群(内容:${msg})..`); + + try { + await botControl.broadcastMessage(msg); + } catch (err) { + logger.error(`广播执行异常: ${err.message}`); + return e.reply('广播过程中发生错误,请检查日志..'); + } + } } diff --git a/lib/core/botControl.js b/lib/core/botControl.js index 3f0768a..bfbc148 100644 --- a/lib/core/botControl.js +++ b/lib/core/botControl.js @@ -53,7 +53,7 @@ const botControl = { } const group = bot.pickGroup(groupId); - if (!group || typeof group.getInfo !== 'function') { + if (!group) { logger.warn(`Bot ${botId}中未找到群${groupId}`); return null; } @@ -81,18 +81,57 @@ const botControl = { } const group = bot.pickGroup(groupId); - if (!group || typeof group.getInfo !== 'function') { + if (!group) { logger.warn(`Bot ${botId}中未找到群${groupId}`); return false; } try { - return !!group.send(message); + return !!(await group.send(message)); } catch (e) { logger.error(`发送群信息失败:${groupId}..`); return false; } }, + + /** + * 广播消息到所有群聊 + * @param message 消息 + * @returns {Promise} + */ + async broadcastMessage(message) { + const groupMap = new Map(); + + for (const bot of Object.values(Bot)) { + if (!bot?.uin || !bot.gl) continue; + for (const [groupId, groupInfo] of bot.gl.entries()) { + if (!groupMap.has(groupId)) { + groupMap.set(groupId, []); + } + groupMap.get(groupId).push(bot); + } + } + const tasks = []; + for (const [groupId, botList] of groupMap.entries()) { + const delay = Math.floor(30_000 + Math.random() * 60_000); //30s-90s + const bot = botList[Math.floor(Math.random() * botList.length)]; + const task = setTimeout(async () => { + try { + const group = bot.pickGroup(groupId); + if (!group) { + logger.warn(`无法发消息到群${groupId}`); + return; + } + await group.send(message); + logger.mark(`已广播消息到群 ${groupId}(Bot ${bot.uin}),延迟 ${delay / 1000}s`); + } catch (err) { + logger.error(`广播到群 ${groupId} 失败:${err}`); + } + }, delay); + tasks.push(task); + } + logger.info(`广播任务已部署,总群数:${groupMap.size}`); + }, }; export default botControl; diff --git a/models/ws/handler.js b/models/ws/handler.js index cf54551..6a206f6 100644 --- a/models/ws/handler.js +++ b/models/ws/handler.js @@ -10,6 +10,7 @@ class Handler { ['error', this.handleError.bind(this)], ['getGroupInfo', this.handleGetGroupInfo.bind(this)], ['sendMessage', this.handleSendMessage.bind(this)], + ['broadcastMessage', this.broadcastMessage.bind(this)], ]); } @@ -83,6 +84,17 @@ class Handler { const message = msg.data?.message; await botControl.sendMessage(botId, message, groupId); } + + /** + * 广播消息 + * @param client + * @param msg + * @returns {Promise} + */ + async broadcastMessage(client, msg) { + const message = msg.data?.message; + await botControl.broadcastMessage(message); + } } const handler = new Handler();