Discord多功能Bot登录正常但命令无响应,请求排查解决
Discord Bot命令无响应问题排查与修复
你的Bot能正常登录但所有命令无响应,核心问题有两个:事件监听API版本不匹配和缺少关键的消息内容权限Intent,以下是具体修复步骤:
1. 事件监听API错误
Discord.js v13及以上版本已将消息事件从message更改为messageCreate,你代码中监听message事件的部分(hi、!kick、!ban)完全不会触发,必须全部替换为messageCreate。
2. 缺少Message Content Intent
Discord从2022年8月开始,要求Bot必须明确申请MESSAGE_CONTENT权限才能读取消息内容。你需要:
- 登录Discord开发者后台,进入你的Bot页面,在“Privileged Gateway Intents”下开启
Message Content Intent - 在代码中更新Intents配置,加入
MessageContent权限
3. 代码优化与修复
将所有消息相关的事件监听合并到messageCreate,同时修正Intents配置,以下是修改后的完整代码:
const { Client, IntentsBitField, MessageEmbed } = require('discord.js'); const { createAudioResource, createAudioPlayer, joinVoiceChannel, StreamType, AudioPlayerStatus } = require('@discordjs/voice'); const ytdl = require('ytdl-core-discord'); const SpotifyWebApi = require('spotify-web-api-node'); // 使用IntentsBitField明确声明所需权限,避免数值混淆 const client = new Client({ intents: [ IntentsBitField.Flags.Guilds, IntentsBitField.Flags.GuildMembers, IntentsBitField.Flags.GuildBans, IntentsBitField.Flags.GuildVoiceStates, IntentsBitField.Flags.GuildMessages, IntentsBitField.Flags.DirectMessages, IntentsBitField.Flags.GuildPresences, IntentsBitField.Flags.MessageContent // 新增关键权限 ] }); require('dotenv').config(); const { TOKEN, ID, SECRET } = process.env; client.on('ready', () => { console.log(`Logged in as ${client.user.tag}!`); }); const spotifyApi = new SpotifyWebApi({ clientId: ID, clientSecret: SECRET, }); // 合并所有消息命令到同一个messageCreate事件 client.on('messageCreate', async message => { // 忽略机器人消息 if (message.author.bot) return; // 处理hi指令 if (message.content === 'hi') { message.reply('hi, how are you?'); return; } // 处理前缀命令 if (!message.content.startsWith('!')) return; const args = message.content.slice(1).trim().split(' '); const command = args.shift().toLowerCase(); // 处理!kick if (command === 'kick') { if (!message.guild) return; const user = message.mentions.users.first(); if (user) { const member = message.guild.members.cache.get(user.id); if (member) { member.kick('Information is in logs').then(() => { message.reply(`${user.tag} kicked`); }).catch(err => { message.reply('Kick was not successful!'); console.error(err); }); } else { message.reply("User is not in this server"); } } else { message.reply("You must specify a user to kick"); } return; } // 处理!ban if (command === 'ban') { if (!message.guild) return; const user = message.mentions.users.first(); if (user) { const member = message.guild.members.cache.get(user.id); if (member) { member.ban({ reason: 'Information is in logs', }).then(() => { message.reply(`${user.tag} banned`); }).catch(err => { message.reply('Ban was not successful!'); console.error(err); }); } else { message.reply("User is not in this server"); } } else { message.reply("You must specify a user to ban"); } return; } // 处理!play if (command === 'play') { if (!message.member.voice.channel) { message.reply('Please join a voice chat'); return; } const connection = joinVoiceChannel({ channelId: message.member.voice.channel.id, guildId: message.guild.id, adapterCreator: message.guild.voiceAdapterCreator, }); const link = args[0]; if (!link) { message.reply('Please enter a YouTube or Spotify link.'); return; } if (!link.includes('youtube.com') && !link.includes('youtu.be') && !link.includes('spotify.com')) { message.reply('Please enter a valid YouTube or Spotify link.'); return; } try { if (link.includes('spotify.com')) { const id = link.split('/').pop().split('?')[0]; const data = await spotifyApi.clientCredentialsGrant(); const token = data.body['access_token']; spotifyApi.setAccessToken(token); const track = await spotifyApi.getTrack(id); const stream = await ytdl(track.body.preview_url, { filter: 'audioonly' }); const resource = createAudioResource(stream, { inputType: StreamType.Opus }); const player = createAudioPlayer(); connection.subscribe(player); player.play(resource); player.on(AudioPlayerStatus.Idle, () => { connection.destroy(); }); message.reply(`The song called \`${track.body.name}\` is playing...`); } else if (link.includes('youtube.com') || link.includes('youtu.be')) { const stream = await ytdl(link, { filter: 'audioonly' }); const resource = createAudioResource(stream, { inputType: StreamType.Opus }); const player = createAudioPlayer(); connection.subscribe(player); player.play(resource); player.on(AudioPlayerStatus.Idle, () => { connection.destroy(); }); const info = await ytdl.getBasicInfo(link); message.reply(`The video called\`${info.videoDetails.title}\` is playing...`); } } catch (error) { console.error(error); message.reply('An error occured.'); } } }); client.on('voiceStateUpdate', async (oldState, newState) => { if (!oldState.channel && newState.channel) { const guild = newState.guild; const voiceChannel = guild.channels.cache.find(channel => channel.name.includes('Members: ')); if (voiceChannel) { const memberCount = guild.members.cache.filter(member => !member.user.bot).size; const onlineCount = guild.members.cache.filter(member => !member.user.bot && member.presence?.status === 'online').size; voiceChannel.setName(`Members: ${memberCount} (${onlineCount} online)`); } } }); client.login(TOKEN);
额外优化说明
- 使用
IntentsBitField.Flags代替数值,让权限配置更清晰易懂 - 合并多个消息事件监听为一个,避免逻辑分散
- 新增忽略机器人消息的判断,防止Bot响应自己的消息
- 将
message.guild.member(user)替换为message.guild.members.cache.get(user.id),适配Discord.js v13+的缓存机制
内容的提问来源于stack exchange,提问作者ozitoman
相关产品推荐
相关产品推荐

