如何用JS为Discord特定角色用户设置操作次数限制?
实现Discord Bot按角色限制每日交互次数的方案
核心逻辑
- 给不同角色配置对应的每日交互限额
- 记录每个用户的交互次数和周期重置时间
- 每次用户触发交互时,先匹配角色对应的限额,再判断当前周期内的次数是否超限
- 超限则发送提示,未超限则处理交互并更新计数
步骤实现
1. 角色限额配置
先定义一个映射对象,关联角色名与对应的每日点击次数:
// 角色-每日限额映射,可按需修改 const ROLE_LIMITS = { "user": 10, "user2": 20 };
2. 存储用户交互数据
用内存Map存储用户的交互记录(重启Bot后数据会丢失,如需持久化可改用SQLite或JSON文件):
// key: 用户ID,value: { clickCount: 当前次数, lastReset: 上次周期重置时间戳 } const userClickRecords = new Map();
3. 处理按钮交互(基于discord.js v14)
在interactionCreate事件中处理按钮点击,完成角色匹配、周期检查与限额判断:
const { Client, GatewayIntentBits, ButtonBuilder, ButtonStyle, ActionRowBuilder } = require('discord.js'); const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers] }); client.on('interactionCreate', async interaction => { if (!interaction.isButton()) return; // 仅处理目标按钮(替换为你的按钮自定义ID) if (interaction.customId !== 'target-action-button') return; // 获取用户的最高可用限额(多角色时取最大值) let dailyLimit = 0; for (const [roleName, limit] of Object.entries(ROLE_LIMITS)) { const role = interaction.guild.roles.cache.find(r => r.name === roleName); if (role && interaction.member.roles.cache.has(role.id) && limit > dailyLimit) { dailyLimit = limit; } } // 用户无匹配角色时直接拒绝 if (dailyLimit === 0) { await interaction.reply({ content: '你没有权限使用此功能', ephemeral: true }); return; } const userId = interaction.user.id; let userRecord = userClickRecords.get(userId); const now = Date.now(); const dayMs = 24 * 60 * 60 * 1000; // 24小时的毫秒数 // 初始化记录或重置周期(超过24小时则清零计数) if (!userRecord || (now - userRecord.lastReset) > dayMs) { userRecord = { clickCount: 0, lastReset: now }; userClickRecords.set(userId, userRecord); } // 检查是否超限 if (userRecord.clickCount >= dailyLimit) { await interaction.reply({ content: `今日交互次数已达上限(每日${dailyLimit}次),请明天再试!`, ephemeral: true }); return; } // 未超限,执行按钮核心功能(替换为你的业务逻辑) await interaction.reply({ content: '操作成功!', ephemeral: true }); // 更新交互计数 userRecord.clickCount++; userClickRecords.set(userId, userRecord); }); client.login('你的Bot Token');
4. 持久化优化(可选)
如果需要Bot重启后保留数据,可以:
- JSON文件方案:用
fs模块定期将userClickRecords写入文件,启动时读取文件加载数据 - SQLite方案:使用
better-sqlite3库,创建表存储用户ID、点击次数、重置时间,每次操作读写数据库
注意事项
- 建议用角色ID替代角色名进行匹配,避免角色名称修改导致逻辑失效
ephemeral: true设置为仅用户可见,避免公共频道刷屏- 若需调整周期(如每周),只需修改
dayMs的数值为对应毫秒数即可
内容的提问来源于stack exchange,提问作者SlideGAW
相关产品推荐
相关产品推荐

