Discord.js strike命令如何支持使用用户ID而非仅@提及用户
修复方案
问题根因
原代码存在两处问题导致ID输入无效:
- 参数校验顺序颠倒:先尝试获取用户,后判断
args[0]是否存在,逻辑顺序错误 - 仅读取本地缓存的成员列表,未主动拉取不在缓存中的用户数据,大量场景下输入ID会因为用户不在缓存中查询失败
- 原代码机器人校验逻辑错误,
GuildMember对象和Client对象不可能相等,该判断永远不生效
具体修改步骤
1. 替换用户获取和参数校验逻辑
将原有代码中权限校验完成后、到let type = args[1]之前的代码替换为如下内容:
// 先校验第一个参数是否存在 if (!args[0]) return message.channel.send("你必须提供被处罚用户的@提及或ID。").then(msg => msg.delete({ timeout: 8000 })).catch(console.error); let user; // 优先从@提及获取用户 if (message.mentions.users.size) { user = message.guild.member(message.mentions.users.first()); } else { // 输入ID的场景主动拉取用户,解决缓存缺失导致查询失败的问题 try { user = await message.guild.members.fetch(args[0]); } catch (err) { user = null; } } if (!user) return message.channel.send("请输入有效的用户@提及或ID以执行处罚。").then(msg => msg.delete({ timeout: 8000 })).catch(console.error); // 修复原机器人校验逻辑错误 if (user.user.bot) return message.channel.send('你无法处罚机器人').then(msg => msg.delete({ timeout: 8000 })).catch(console.error); if (!user.roles.cache.find(r => r.id === botconfig["join_roles"].role)) return message.channel.send("你无法处罚该用户,该用户未完成服务器验证。").then(msg => msg.delete({ timeout: 8000 })).catch(console.error); let type = args[1]; let callSign = args[2]; let banned = args[3] let comments = args.slice(4).join(" ");
2. 开启机器人权限配置
进入Discord开发者面板的机器人设置页,找到Privileged Gateway Intents分组,开启Server Members Intent开关,否则机器人无法拉取服务器成员列表,ID查询仍然会失败。
内容的提问来源于stack exchange,提问作者Lorelei Ramirez
相关产品推荐
相关产品推荐

