如何实现带自动倒计时嵌入消息的连续消息反垃圾自动禁言系统?
实现连续短间隔消息禁言的反垃圾系统
嘿,这个需求很实用!核心思路就是追踪用户的消息发送时间戳,当在设定的极短时间窗口内收到第5条消息时,触发禁言并推送带动态倒计时的嵌入消息。下面我用Discord.js v14为例,给你一步步拆解实现方案:
1. 前期准备
先确保你的机器人拥有ManageRoles和ManageChannels权限,并且你创建的Muted角色权限配置正确(比如禁用发送消息、语音权限等),同时角色位置要高于普通用户的角色,不然机器人可能没法给用户添加这个角色。
2. 核心代码实现
2.1 初始化存储与阈值配置
我们用Map来保存每个用户的消息时间戳数组,方便快速判断是否触发规则:
const { Client, EmbedBuilder, GatewayIntentBits } = require('discord.js'); const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent] }); // 存储用户消息时间戳的Map const messageTimestamps = new Map(); // 规则阈值:可按需调整 const MAX_CONSECUTIVE_MESSAGES = 5; // 连续消息数 const TIME_WINDOW = 1000; // 时间窗口(毫秒,这里设为1秒,即间隔极短的标准) const MUTE_SECONDS = 60; // 禁言时长(秒)
2.2 监听消息事件并处理逻辑
在messageCreate事件里完成消息追踪、规则判断、禁言操作和动态Embed更新:
client.on('messageCreate', async (message) => { // 忽略机器人消息和私信 if (message.author.bot || !message.guild) return; const userId = message.author.id; const now = Date.now(); // 获取当前用户的消息时间戳数组,没有则初始化空数组 let timestamps = messageTimestamps.get(userId) || []; // 添加当前时间戳 timestamps.push(now); // 过滤掉超出时间窗口的旧记录,只保留符合"间隔极短"的消息 timestamps = timestamps.filter(timestamp => now - timestamp <= TIME_WINDOW); // 更新Map中的记录 messageTimestamps.set(userId, timestamps); // 触发禁言规则的判断 if (timestamps.length >= MAX_CONSECUTIVE_MESSAGES) { // 清空该用户的时间记录,避免重复触发 messageTimestamps.delete(userId); // 查找Muted角色 const mutedRole = message.guild.roles.cache.find(role => role.name === 'Muted'); if (!mutedRole) { return message.channel.send('找不到名为"Muted"的禁言角色,请检查角色名称是否正确!'); } try { // 给用户添加禁言角色 await message.member.roles.add(mutedRole); // 初始化禁言提示Embed const embed = new EmbedBuilder() .setColor('#FF4444') .setTitle('⚠️ 消息频率过高,已被禁言') .setDescription(`由于连续发送消息过于频繁,你将被禁言 **${MUTE_SECONDS}秒**`) .addFields({ name: '剩余时间', value: `${MUTE_SECONDS}秒`, inline: true }) .setTimestamp(); // 发送Embed消息 const sentEmbed = await message.channel.send({ embeds: [embed] }); // 启动倒计时更新逻辑 let remainingSeconds = MUTE_SECONDS; const countdownInterval = setInterval(async () => { remainingSeconds--; if (remainingSeconds <= 0) { // 倒计时结束:清除定时器、解除禁言、更新Embed clearInterval(countdownInterval); await message.member.roles.remove(mutedRole); embed.setDescription('✅ 禁言已结束,请遵守消息发送频率规则!'); embed.setFields({ name: '剩余时间', value: '0秒', inline: true }); await sentEmbed.edit({ embeds: [embed] }); } else { // 每秒更新剩余时间字段 embed.setFields({ name: '剩余时间', value: `${remainingSeconds}秒`, inline: true }); await sentEmbed.edit({ embeds: [embed] }); } }, 1000); } catch (error) { console.error('禁言操作失败:', error); message.channel.send('无法执行禁言操作,请检查机器人权限是否充足!'); } } }); // 登录机器人 client.login('你的机器人Token');
3. 关键细节说明
- 时间窗口过滤:每次添加新时间戳后,都会自动剔除超出设定时间窗口的旧记录,确保我们只统计真正“间隔极短”的连续消息。
- 动态Embed更新:通过
setInterval每秒更新一次Embed的剩余时间字段,倒计时结束后自动解除禁言并更新提示内容。 - 容错处理:加入了角色不存在、权限不足的报错提示,避免机器人异常崩溃。
4. 可选优化方向
- 把阈值参数(消息数、时间窗口、禁言时长)抽成配置文件,方便后续调整。
- 支持针对不同频道设置不同的规则(比如允许公告频道的消息频率更高)。
- 添加日志记录,把触发禁言的用户、时间等信息存入日志文件,方便排查问题。
内容的提问来源于stack exchange,提问作者Brandon
相关产品推荐
相关产品推荐

