Discord.js如何实现无前缀命令且兼容原有带前缀命令
问题根源
你现在遇到的goodnight命令不生效,本质是消息监听里的判断逻辑把无前缀的消息全拦在最外层了:只要消息不是以m!开头,函数会直接return终止执行,根本走不到后面写的goodnight匹配分支。
你也不能直接删掉那行拦截判断——真删了的话,所有用户发的日常闲聊,都会被强行带入「切割命令参数、匹配命令名」的流程,完全没必要还会拖慢响应速度。
可落地的简洁改法
只需要把原来串成一行的早退判断拆成分层逻辑,既能保住所有原有带前缀命令的功能,又能让无前缀的goodnight命令正常触发:
- 把和命令类型无关的通用拦截(不响应机器人自己发的消息)放在逻辑最开头,这部分不管是带前缀还是无前缀的场景都需要,不影响任何原有流程
- 把无前缀的
goodnight匹配,挪到「判断消息是否带前缀」的步骤之前,匹配到就直接执行对应命令,执行完就退出当前函数 - 等无前缀的匹配流程走完,再判断当前消息是不是带前缀的——如果不带就直接退出,剩下的逻辑完全沿用你原来写的带前缀命令解析流程就行,不用改任何原有代码
改完的消息监听部分代码如下:
client.on('message', message =>{ // 通用拦截:不处理机器人发送的消息 if (message.author.bot) return; // 无前缀命令处理:匹配到goodnight直接执行 if (message.content.trim().toLowerCase() === 'goodnight') { client.commands.get('goodnight').execute(message, []); return; // 执行完直接退出,不进入后续带前缀的命令解析流程 } // 原有带前缀命令的逻辑,和之前完全一致 if (!message.content.startsWith(prefix)) return; const args = message.content.slice(prefix.length).split(/ +/); const command = args.shift().toLowerCase(); if(command == 'ping'){ client.commands.get('pong').execute(message, args); } console.log(message.member, message, args); });
补充小细节
- 匹配
goodnight的时候加了trim()方法,可以兼容用户不小心在消息首尾打了空格的情况,避免因为多余空白字符导致匹配失效 - 无前缀命令执行完主动加
return,可以把两种命令的流程完全隔开,避免出现重复触发、逻辑交叉的问题
内容的提问来源于stack exchange,提问作者making56
相关产品推荐
相关产品推荐

