UNPKG

koishi-plugin-auto-tata-group-name

Version:

个人自用,自动更新群聊名称的 Koishi 插件,根据群聊成员数量变化自动更新群名

421 lines (420 loc) 19.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Config = exports.name = void 0; exports.apply = apply; const koishi_1 = require("koishi"); exports.name = 'auto-tata-group-name'; exports.Config = koishi_1.Schema.object({ guildTemplates: koishi_1.Schema.array(koishi_1.Schema.object({ guildId: koishi_1.Schema.string() .description('群聊ID') .required(), nameTemplate: koishi_1.Schema.string() .description('该群的模板,使用{count}表示人数。如果不填写,将使用默认模板') .default('({count})🦦獭家一爱相亲相') })).description('群聊模板配置,配置了就表示监听该群').default([]), updateDelay: koishi_1.Schema.number().description('成员变动后等待平台更新的延迟时间(毫秒)').default(2000).min(500).max(10000) }); // 人数反转函数 function reverseNumber(num) { return num.toString().split('').reverse().join(''); } // 获取群的模板函数 function getGuildTemplate(guildId, config) { const guildConfig = config.guildTemplates.find(g => g.guildId === guildId); if (!guildConfig) return null; // 如果 nameTemplate 为空或未定义,使用默认模板 return guildConfig.nameTemplate || '({count})🦦獭家一爱相亲相'; } // 获取监听的群列表 function getWatchedGuilds(config) { return config.guildTemplates.map(g => g.guildId); } function apply(ctx, config) { // 规范化配置,确保每个群组都有 nameTemplate config.guildTemplates = config.guildTemplates.map(guild => ({ ...guild, nameTemplate: guild.nameTemplate || '({count})🦦獭家一爱相亲相' })); // 在插件启动时输出配置信息 ctx.on('ready', () => { ctx.logger.info('Auto-tata-group-name 插件已启动'); config.guildTemplates.forEach(guild => { const template = guild.nameTemplate || '({count})🦦獭家一爱相亲相'; ctx.logger.info(`监听群组 ${guild.guildId},使用模板: ${template}`); }); }); // 监听群成员加入事件 ctx.on('guild-member-added', async (session) => { await handleMemberChange(session, 'join'); }); // 监听群成员退出事件 ctx.on('guild-member-removed', async (session) => { await handleMemberChange(session, 'leave'); }); async function handleMemberChange(session, action) { try { const guildId = session.guildId; if (!guildId) { return; } const watchedGuilds = getWatchedGuilds(config); if (!watchedGuilds.includes(guildId)) { return; // 不在监听列表中的群聊 } // 获取当前群聊信息 let guild; try { guild = await session.bot.getGuild(guildId); } catch (error) { ctx.logger.warn(`无法获取群聊信息: ${guildId}`); return; } // 延迟一段时间后获取成员数量,确保平台已更新成员列表 ctx.logger.debug(`检测到成员${action === 'join' ? '加入' : '退出'}事件,等待平台更新成员列表...`); // 等待指定时间让平台更新成员列表 await new Promise(resolve => setTimeout(resolve, config.updateDelay)); // 尝试获取群成员数量 let memberCount = 0; let retryCount = 0; const maxRetries = 3; while (retryCount < maxRetries) { try { const members = await session.bot.getGuildMemberList(guildId); memberCount = members.data?.length || 0; if (memberCount > 0) { break; // 成功获取到成员数量 } } catch (error) { ctx.logger.warn(`第${retryCount + 1}次获取群成员列表失败: ${error instanceof Error ? error.message : String(error)}`); } retryCount++; if (retryCount < maxRetries) { // 等待1秒后重试 await new Promise(resolve => setTimeout(resolve, 1000)); } } if (memberCount === 0) { ctx.logger.error(`无法获取群 ${guildId} 的成员数量,跳过更新`); return; } ctx.logger.debug(`获取到群 ${guildId} 当前成员数量: ${memberCount}`); // 获取该群的模板并生成新的群名(使用反转的人数) const nameTemplate = getGuildTemplate(guildId, config); if (!nameTemplate) { ctx.logger.error(`群 ${guildId} 没有配置模板`); return; } const reversedCount = reverseNumber(memberCount); const newName = nameTemplate.replace('{count}', reversedCount); // 检查是否需要更新(避免重复更新) if (guild.name === newName) { ctx.logger.debug(`群名已经是目标名称,跳过更新: ${newName}`); return; } // 尝试更新群名 try { let success = false; // 尝试多种API方法来更新群名 // 方法1: 通用的 setGuildName if (!success && session.bot.internal?.setGuildName) { try { await session.bot.internal.setGuildName(guildId, newName); success = true; } catch (error) { ctx.logger.debug(`setGuildName 失败: ${error instanceof Error ? error.message : String(error)}`); } } // 方法2: 通用的 editGuild if (!success && session.bot.internal?.editGuild) { try { await session.bot.internal.editGuild(guildId, { name: newName }); success = true; } catch (error) { ctx.logger.debug(`editGuild 失败: ${error instanceof Error ? error.message : String(error)}`); } } // 方法3: QQ 平台相关API if (!success && session.bot.internal) { const methods = [ 'set_group_name', 'setGroupName', 'modify_group_info', 'modifyGroupInfo' ]; for (const method of methods) { if (session.bot.internal[method]) { try { await session.bot.internal[method](guildId, newName); success = true; break; } catch (error) { ctx.logger.debug(`${method} 失败: ${error instanceof Error ? error.message : String(error)}`); } } } } // 方法4: 尝试 OneBot API if (!success && session.bot.internal?.call) { try { await session.bot.internal.call('set_group_name', { group_id: guildId, group_name: newName }); success = true; } catch (error) { ctx.logger.debug(`OneBot API 失败: ${error instanceof Error ? error.message : String(error)}`); } } if (!success) { ctx.logger.warn(`当前平台不支持修改群名,平台: ${session.bot.platform},可用方法: ${Object.keys(session.bot.internal || {}).filter(k => typeof session.bot.internal[k] === 'function').join(', ')}`); return; } ctx.logger.info(`群聊 ${guildId} 名称已更新为: ${newName} (成员${action === 'join' ? '加入' : '退出'}, 实际人数: ${memberCount}, 显示人数: ${reversedCount})`); } catch (error) { ctx.logger.error(`更新群名失败: ${error instanceof Error ? error.message : String(error)}`); } } catch (error) { ctx.logger.error(`处理成员变动失败: ${error instanceof Error ? error.message : String(error)}`); } } // 添加手动更新群名的指令 ctx.command('update-group-name [guildId]', '手动更新群聊名称') .option('count', '-c <count:number> 指定人数') .action(async ({ session, options }, guildId) => { const targetGuildId = guildId || session?.guildId; if (!targetGuildId) { return '请指定群聊ID或在群聊中使用此命令'; } const watchedGuilds = getWatchedGuilds(config); if (!watchedGuilds.includes(targetGuildId)) { return '该群聊没有配置模板'; } if (!session) { return '无法获取会话信息'; } try { let memberCount = options?.count; if (memberCount === undefined) { // 获取实际成员数量 try { const members = await session.bot.getGuildMemberList(targetGuildId); memberCount = members.data?.length || 0; } catch (error) { return `无法获取群成员数量: ${error instanceof Error ? error.message : String(error)}`; } } const nameTemplate = getGuildTemplate(targetGuildId, config); if (!nameTemplate) { return `群 ${targetGuildId} 没有配置模板`; } const reversedCount = reverseNumber(memberCount); const newName = nameTemplate.replace('{count}', reversedCount); // 尝试更新群名 try { let success = false; // 尝试多种API方法来更新群名 // 方法1: 通用的 setGuildName if (!success && session.bot.internal?.setGuildName) { try { await session.bot.internal.setGuildName(targetGuildId, newName); success = true; } catch (error) { ctx.logger.debug(`setGuildName 失败: ${error instanceof Error ? error.message : String(error)}`); } } // 方法2: 通用的 editGuild if (!success && session.bot.internal?.editGuild) { try { await session.bot.internal.editGuild(targetGuildId, { name: newName }); success = true; } catch (error) { ctx.logger.debug(`editGuild 失败: ${error instanceof Error ? error.message : String(error)}`); } } // 方法3: QQ 平台相关API if (!success && session.bot.internal) { const methods = [ 'set_group_name', 'setGroupName', 'modify_group_info', 'modifyGroupInfo' ]; for (const method of methods) { if (session.bot.internal[method]) { try { await session.bot.internal[method](targetGuildId, newName); success = true; break; } catch (error) { ctx.logger.debug(`${method} 失败: ${error instanceof Error ? error.message : String(error)}`); } } } } // 方法4: 尝试 OneBot API if (!success && session.bot.internal?.call) { try { await session.bot.internal.call('set_group_name', { group_id: targetGuildId, group_name: newName }); success = true; } catch (error) { ctx.logger.debug(`OneBot API 失败: ${error instanceof Error ? error.message : String(error)}`); } } if (!success) { return `当前平台不支持修改群名,平台: ${session.bot.platform}`; } return `群名已更新为: ${newName} (实际人数: ${memberCount}, 显示人数: ${reversedCount})`; } catch (error) { return `更新失败: ${error instanceof Error ? error.message : String(error)}`; } } catch (error) { ctx.logger.error(`手动更新群名失败: ${error instanceof Error ? error.message : String(error)}`); return `操作失败: ${error instanceof Error ? error.message : String(error)}`; } }); // 添加配置查看指令 ctx.command('group-name-config', '查看群名自动更新配置') .action(() => { const watchedGuilds = getWatchedGuilds(config); const result = [ '群名自动更新配置:', `- 监听群聊: ${watchedGuilds.length > 0 ? watchedGuilds.join(', ') : '无'}`, `- 更新延迟: ${config.updateDelay}ms` ]; if (config.guildTemplates.length > 0) { result.push('- 群聊模板:'); config.guildTemplates.forEach(guild => { result.push(` * ${guild.guildId}: ${guild.nameTemplate}`); }); } else { result.push('- 群聊模板: 无'); } return result.join('\n'); }); // 添加设置群模板的指令 ctx.command('set-group-template <guildId> <template>', '设置群聊模板') .action(async ({ session }, guildId, template) => { if (!guildId || !template) { return '请提供群聊ID和模板内容'; } if (!template.includes('{count}')) { return '模板必须包含 {count} 占位符'; } // 查找是否已存在该群的配置 const existingIndex = config.guildTemplates.findIndex(g => g.guildId === guildId); if (existingIndex >= 0) { // 更新现有配置 config.guildTemplates[existingIndex].nameTemplate = template; return `已更新群 ${guildId} 的模板为: ${template}`; } else { // 添加新配置 config.guildTemplates.push({ guildId, nameTemplate: template }); return `已为群 ${guildId} 设置模板: ${template}`; } }); // 添加删除群模板的指令 ctx.command('remove-group-template <guildId>', '删除群聊模板,停止监听该群') .action(async ({ session }, guildId) => { if (!guildId) { return '请提供群聊ID'; } const index = config.guildTemplates.findIndex(g => g.guildId === guildId); if (index >= 0) { config.guildTemplates.splice(index, 1); return `已删除群 ${guildId} 的模板,停止监听该群`; } else { return `群 ${guildId} 没有配置模板`; } }); // 添加API测试指令 ctx.command('test-group-api [guildId]', '测试群聊API功能') .action(async ({ session }, guildId) => { const targetGuildId = guildId || session?.guildId; if (!targetGuildId) { return '请指定群聊ID或在群聊中使用此命令'; } if (!session) { return '无法获取会话信息'; } try { // 获取群聊信息 const guild = await session.bot.getGuild(targetGuildId); // 获取成员列表 const members = await session.bot.getGuildMemberList(targetGuildId); const memberCount = members.data?.length || 0; // 检查可用的API方法 const availableMethods = []; if (session.bot.internal?.setGuildName) availableMethods.push('setGuildName'); if (session.bot.internal?.editGuild) availableMethods.push('editGuild'); if (session.bot.internal?.set_group_name) availableMethods.push('set_group_name'); if (session.bot.internal?.setGroupName) availableMethods.push('setGroupName'); if (session.bot.internal?.modify_group_info) availableMethods.push('modify_group_info'); if (session.bot.internal?.modifyGroupInfo) availableMethods.push('modifyGroupInfo'); if (session.bot.internal?.call) availableMethods.push('call (OneBot)'); const templateInfo = config.guildTemplates.find(g => g.guildId === targetGuildId); const currentTemplate = templateInfo ? templateInfo.nameTemplate : '未配置'; return [ `群聊API测试结果:`, `- 群聊ID: ${targetGuildId}`, `- 当前群名: ${guild.name}`, `- 成员数量: ${memberCount}`, `- 使用模板: ${currentTemplate}`, `- 监听状态: ${templateInfo ? '已监听' : '未监听'}`, `- 平台: ${session.bot.platform}`, `- 可用API方法: ${availableMethods.length > 0 ? availableMethods.join(', ') : '无'}`, `- 所有内部方法: ${Object.keys(session.bot.internal || {}).filter(k => typeof session.bot.internal[k] === 'function').join(', ')}` ].join('\n'); } catch (error) { return `API测试失败: ${error instanceof Error ? error.message : String(error)}`; } }); // 添加平台调试指令 ctx.command('debug-platform', '显示当前平台信息') .action(async ({ session }) => { if (!session) { return '无法获取会话信息'; } const bot = session.bot; const internal = bot.internal || {}; return [ `平台调试信息:`, `- 平台: ${bot.platform}`, `- 机器人ID: ${bot.selfId}`, `- 用户ID: ${bot.userId}`, `- 内部方法数量: ${Object.keys(internal).length}`, `- 函数方法: ${Object.keys(internal).filter(k => typeof internal[k] === 'function').join(', ')}`, `- 属性: ${Object.keys(internal).filter(k => typeof internal[k] !== 'function').join(', ')}` ].join('\n'); }); }