Discord.js 12.5.3机器人在线但无法发送消息/执行命令求助
Discord.js 12.5.3机器人无响应排查与修复
问题现象
使用Discord.js 12.5.3开发的机器人显示在线,但执行命令无任何回复,控制台也没有报错。此前代码正常运行,未做修改但突然无法发送消息。
相关代码
Index.js
const Discord = require("discord.js"); const client = new Discord.Client({ disableMentions: 'everyone' }); require('dotenv').config(); const Eco = require("quick.eco"); client.eco = new Eco.Manager(); client.db = Eco.db; client.config = require("./config"); client.commands = new Discord.Collection(); client.aliases = new Discord.Collection(); const fs = require("fs"); fs.readdir("./events/", (err, files) => { if (err) return console.error(err); files.forEach(f => { if (!f.endsWith(".js")) return; const event = require(`./events/${f}`); let eventName = f.split(".")[0]; client.on(eventName, event.bind(null, client)); }); }); fs.readdir("./commands/", (err, files) => { if (err) return console.error(err); files.forEach(f => { if (!f.endsWith(".js")) return; let command = require(`./commands/${f}`); client.commands.set(command.help.name, command); command.help.aliases.forEach(alias => { client.aliases.set(alias, command.help.name); }); }); }); client.login(process.env.TOKEN);
Message.js(消息事件处理文件)
const { MessageEmbed } = require('discord.js'); const fs = require('fs'); let visitor = require('../database/visitor.json'); let level = require('../database/level.json'); let place = require('../database/place.json'); let money = require('../database/money.json'); module.exports = async (client, message) => { if (message.content === "market") { message.reply(`yup, what?`); } if(!visitor[message.author.id]){ visitor[message.author.id] = { totalvis: 0, totalbuyer: 0 }; } if(!level[message.author.id]){ level[message.author.id] = { level: 1, exp: 0 }; } if(!place[message.author.id]){ place[message.author.id] = { pla: "Hongria" }; } if(!money[message.author.id]){ money[message.author.id] = { balance: 20 }; } if(level[message.author.id].exp > 300) { let amount = Math.floor(Math.random() * 60) + 20; money[message.author.id].balance = money[message.author.id].balance + amount; level[message.author.id].level++; level[message.author.id].exp = 0; let embed = new MessageEmbed() .setTitle(`${message.author.username} Level Up`) .addField(`Rewards`, `+ ${amount} Money`) .setColor("#E5E5E5") .setTimestamp() message.channel.send(embed); } fs.writeFile('./database/visitor.json', JSON.stringify(visitor, null, 2), (err) => { if (err) console.log(err); }); fs.writeFile('./database/level.json', JSON.stringify(level, null, 2), (err) => { if (err) console.log(err); }); fs.writeFile('./database/place.json', JSON.stringify(place, null, 2), (err) => { if (err) console.log(err); }); fs.writeFile('./database/money.json', JSON.stringify(money, null, 2), (err) => { if (err) console.log(err); }); if (!message.guild || message.author.bot) return; if (message.channel.id === client.config.countChannel) require("../counter")(message, client); client.prefix = client.db.fetch(`prefix_${message.guild.id}`) ? client.db.fetch(`prefix_${message.guild.id}`) : client.config.prefix; if (!message.content.startsWith(client.prefix)) return; let args = message.content.slice(client.prefix.length).trim().split(" "); let commandName = args.shift().toLowerCase(); let command = client.commands.get(commandName) || client.commands.get(client.aliases.get(commandName)); if (!command) return; client.ecoAddUser = message.author.id; command.execute(client, message, args); };
Command.js(reboot命令文件)
const { MessageEmbed } = require("discord.js"); const fs = require('fs'); exports.execute = async (client, message, args) => { if (!client.config.admins.includes(message.author.id)) return; message.channel.send("**Rebooting system..**").then(m => { setTimeout(() => { m.edit("**Wait a sec...**").then(ms => { setTimeout(() => { ms.edit("**Done.**") }, 3000) }) }, 3000); }) .then(message => process.exit()) .then(() => client.login(process.env.TOKEN)) } exports.help = { name: "reboot", aliases: ["rb"], usage: `reboot` }
问题排查与修复
核心问题1:消息过滤逻辑位置错误
Message.js中if (!message.guild || message.author.bot) return;语句放在了文件后半段,导致:
- 机器人自己触发消息事件时,会执行到该语句直接跳出函数,后续命令解析逻辑完全不执行
- 非服务器消息(如私聊)也会触发前面的数据库操作,但最终被终止,无法执行命令
修复方式:将过滤逻辑移到函数最顶部,提前拦截无效消息:
module.exports = async (client, message) => { // 先过滤机器人消息和非服务器消息 if (!message.guild || message.author.bot) return; // 剩余原有逻辑 if (message.content === "market") { message.reply(`yup, what?`); } // ... 后面的数据库初始化、升级判断、文件写入等逻辑 }
核心问题2:异步文件写入阻塞
每次消息触发时都调用fs.writeFile写入4个JSON文件,异步操作可能导致文件锁冲突,阻塞后续消息发送逻辑,且效率极低。
优化方案:
- 改用
fs.promises.writeFile或使用同步写入(仅开发环境临时使用) - 替换为专门的JSON数据库库(如
lowdb、quick.db),避免手动文件操作 - 合并写入逻辑,仅在数据变更时执行写入,而非每次消息都写入
核心问题3:reboot命令逻辑错误
Command.js中process.exit()之后的client.login(process.env.TOKEN)永远不会执行,因为进程已退出。正确的重启需要依赖外部进程管理器(如pm2)。
修复reboot命令:
exports.execute = async (client, message, args) => { if (!client.config.admins.includes(message.author.id)) return; await message.channel.send("**Rebooting system..**"); setTimeout(async () => { await message.channel.send("**Wait a sec...**"); setTimeout(async () => { await message.channel.send("**Done.**"); // 退出进程,由外部管理器重启 process.exit(); }, 3000); }, 3000); }
其他排查点
- 权限检查:确认机器人在服务器中拥有
发送消息、嵌入链接等必要权限,频道权限未限制机器人发言 - 前缀匹配:检查
client.config.prefix是否正确,或quick.eco数据库中是否存在错误的前缀配置 - API速率限制:在Discord开发者门户查看机器人是否触发了API调用限制
内容的提问来源于stack exchange,提问作者MEF STREAM
相关产品推荐
相关产品推荐

