Discord.js+Commando:如何阻止带参数命令在指定频道执行
解决特定频道静默阻止命令执行的问题
看起来你遇到的问题是:直接在run方法开头返回的方式只对无参数命令有效,但带参数的命令还是会产生反馈——这其实是命令框架(比如discord.js-commando这类)的执行流程导致的。
问题根源
当用户触发带参数的命令时,框架在调用run方法之前,已经完成了参数的解析和验证步骤。如果参数不符合命令要求,框架会自动发送错误提示消息,而你的return语句是在run里,这时候错误消息已经发出去了,所以看起来“无效”。
正确的解决方案:使用命令拦截器(Inhibitor)
要实现完全静默阻止(包括不触发参数错误提示),你需要在命令处理的最早期阶段拦截请求,也就是在框架开始解析参数之前。以discord.js-commando为例,可以通过添加全局拦截器来实现:
// 在客户端初始化完成后添加拦截器 client.dispatcher.addInhibitor((message: CommandMessage) => { const blockedChannelId = process.env.NUMBER_CHANNEL_ID; // 检查当前频道是否是需要阻止的频道 if (message.channel.id === blockedChannelId) { // 返回silent: true,表示静默阻止,不发送任何提示 return { reason: 'blocked-channel', silent: true }; } // 返回false表示允许命令继续执行 return false; });
如果你只需要阻止特定命令在目标频道执行,而不是全局命令,可以给单个命令添加前置检查:
// 在你的命令类里重写preRun方法 public async preRun(message: CommandMessage, args: any, fromPattern: boolean): Promise<void> { if (message.channel.id === process.env.NUMBER_CHANNEL_ID) { // 抛出一个自定义错误,同时在客户端的error事件里忽略这个错误 throw new Error('SilentBlock'); } } // 然后在客户端的error事件里处理这个静默错误 client.on('error', (err) => { if (err.message === 'SilentBlock') { // 忽略这个错误,不做任何处理 return; } // 处理其他错误 console.error(err); });
为什么这个方法有效?
全局拦截器是在命令被识别后、参数解析前执行的,所以不管命令有没有参数,都会被直接拦截,不会触发任何后续的处理逻辑(包括参数验证错误提示)。而单个命令的preRun方法会在run和参数解析之后,但在任何反馈发送之前执行,配合错误忽略可以实现静默阻止。
内容的提问来源于stack exchange,提问作者Loud Software
相关产品推荐
相关产品推荐

