如何在discord.js v12中为Discord机器人实现禁言、临时禁言及解除禁言命令
实现方案
discord.js v12 版本的禁言逻辑核心是给目标用户添加预设了频道权限的Muted角色,以下是完整的修改步骤:
第一步:在现有的message事件中添加三个命令的处理逻辑
找到你代码里$kick命令的代码块结束位置,插入以下代码:
// 通用方法:获取或创建Muted角色 async function getMuteRole(guild) { let muteRole = guild.roles.cache.find(r => r.name === 'Muted'); if (!muteRole) { try { muteRole = await guild.roles.create({ data: { name: 'Muted', color: '#808080', permissions: [] }, reason: '创建禁言角色' }); // 给所有频道设置Muted角色的权限 guild.channels.cache.forEach(async (channel) => { await channel.updateOverwrite(muteRole, { SEND_MESSAGES: false, ADD_REACTIONS: false, SPEAK: false, CONNECT: true // 允许进语音但不能说话 }); }); } catch (err) { console.error(err); return null; } } return muteRole; } // $mute 永久禁言命令 if (message.content.startsWith('$mute')) { if (!message.member.hasPermission("MANAGE_ROLES")) { return message.channel.send('你没有管理角色的权限,无法使用禁言命令'); } const targetUser = message.mentions.users.first(); if (!targetUser) { return message.channel.send('你需要@要禁言的用户,格式:$mute @用户'); } const targetMember = message.guild.members.resolve(targetUser); if (!targetMember) { return message.channel.send('该用户不在当前服务器'); } // 不能禁言权限比自己高的用户 if (targetMember.roles.highest.position >= message.member.roles.highest.position && message.guild.ownerID !== message.author.id) { return message.channel.send('你无法禁言权限高于或等于你的用户'); } // 不能禁言机器人自己 if (targetMember.id === client.user.id) { return message.channel.send('我不能禁言我自己'); } const muteRole = await getMuteRole(message.guild); if (!muteRole) { return message.channel.send('创建禁言角色失败,请检查我是否有管理角色和管理频道的权限'); } if (targetMember.roles.cache.has(muteRole.id)) { return message.channel.send('该用户已经处于禁言状态'); } try { await targetMember.roles.add(muteRole); message.channel.send(`成功禁言 ${targetUser.tag}`); } catch (err) { console.error(err); message.channel.send('禁言失败,请检查我的角色权限是否高于Muted角色'); } } // $unmute 解除禁言命令 if (message.content.startsWith('$unmute')) { if (!message.member.hasPermission("MANAGE_ROLES")) { return message.channel.send('你没有管理角色的权限,无法使用解除禁言命令'); } const targetUser = message.mentions.users.first(); if (!targetUser) { return message.channel.send('你需要@要解除禁言的用户,格式:$unmute @用户'); } const targetMember = message.guild.members.resolve(targetUser); if (!targetMember) { return message.channel.send('该用户不在当前服务器'); } const muteRole = await getMuteRole(message.guild); if (!muteRole) { return message.channel.send('未找到禁言角色'); } if (!targetMember.roles.cache.has(muteRole.id)) { return message.channel.send('该用户没有处于禁言状态'); } try { await targetMember.roles.remove(muteRole); message.channel.send(`成功解除禁言 ${targetUser.tag}`); } catch (err) { console.error(err); message.channel.send('解除禁言失败,请检查我的权限'); } } // $tempmute 临时禁言命令 格式:$tempmute @用户 10m 支持s(秒)/m(分钟)/h(小时)/d(天) if (message.content.startsWith('$tempmute')) { if (!message.member.hasPermission("MANAGE_ROLES")) { return message.channel.send('你没有管理角色的权限,无法使用临时禁言命令'); } const args = message.content.split(' '); const targetUser = message.mentions.users.first(); if (!targetUser || args.length < 3) { return message.channel.send('格式错误,正确格式:$tempmute @用户 时长 例如 $tempmute @用户 10m'); } const targetMember = message.guild.members.resolve(targetUser); if (!targetMember) { return message.channel.send('该用户不在当前服务器'); } if (targetMember.roles.highest.position >= message.member.roles.highest.position && message.guild.ownerID !== message.author.id) { return message.channel.send('你无法禁言权限高于或等于你的用户'); } const timeStr = args[2]; const timeUnit = timeStr.slice(-1); const timeValue = parseInt(timeStr.slice(0, -1)); if (isNaN(timeValue) || !['s','m','h','d'].includes(timeUnit)) { return message.channel.send('时长格式错误,支持的单位:s(秒)、m(分钟)、h(小时)、d(天),例如 10m'); } // 转换为毫秒 let timeMs; switch(timeUnit) { case 's': timeMs = timeValue * 1000; break; case 'm': timeMs = timeValue * 60 * 1000; break; case 'h': timeMs = timeValue * 60 * 60 * 1000; break; case 'd': timeMs = timeValue * 24 * 60 * 60 * 1000; break; } const muteRole = await getMuteRole(message.guild); if (!muteRole) { return message.channel.send('创建禁言角色失败,请检查我是否有管理角色和管理频道的权限'); } if (targetMember.roles.cache.has(muteRole.id)) { return message.channel.send('该用户已经处于禁言状态'); } try { await targetMember.roles.add(muteRole); message.channel.send(`成功临时禁言 ${targetUser.tag},时长 ${timeStr}`); // 定时解除禁言 setTimeout(async () => { if (targetMember.roles.cache.has(muteRole.id)) { await targetMember.roles.remove(muteRole); message.channel.send(`临时禁言到期,已解除 ${targetUser.tag} 的禁言`); } }, timeMs); } catch (err) { console.error(err); message.channel.send('禁言失败,请检查我的角色权限是否高于Muted角色'); } }
第二步:更新帮助菜单
找到你代码里的help embed的addFields部分,添加三个新命令的说明:
.addFields( // 原有字段保留,新增以下三个字段即可 { name: '$mute @user', value: '永久禁言指定用户', inline: true }, { name: '$unmute @user', value: '解除指定用户的禁言', inline: true }, { name: '$tempmute @user 时长', value: '临时禁言用户,支持s/m/h/d单位,例如$tempmute @user 10m', inline: true }, )
注意事项
- 确保你的机器人拥有
管理角色、管理频道权限 - 机器人的角色排序要高于
Muted角色,否则无法给用户添加/移除该角色 - 后续新创建的频道会自动继承Muted角色的权限设置,无需手动调整
内容的提问来源于stack exchange,提问作者CaptainBeast123
相关产品推荐
相关产品推荐

