Discord Bot无法识别命令:代码问题求助
Discord Bot命令无法识别问题排查求助
我正在开发Discord音乐Bot,但Bot完全无法识别我的命令。已经尝试调整文件路径、更换cogs加载方式,均未解决问题。以下是相关代码,请帮忙排查:
主代码
import discord from discord.ext import commands import os from help_cog import help_cog from music_cog import music_cog # Command prefix intents = discord.Intents.all() bot = commands.Bot(command_prefix="!",intents=intents) @bot.event async def on_ready(): print("Bot is up and ready!") bot.remove_command("help") bot.add_cog(help_cog(bot)) bot.add_cog(music_cog(bot)) # Run the client with open('token.txt', 'r') as file: token = file.readlines()[0] bot.run(token)
music_cog代码
import discord from discord.ext import commands from youtube_dl import YoutubeDL class music_cog(commands.Cog): def __init__(self, bot): self.bot = bot self.is_playing = False self.is_paused = False self.music_queue = [] self.YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist': 'True'} self.FFMPEG_OPTIONS = {'before_options': '-reconnect 1 - reconnect_streamed 1 -reconnected_delay_max 5', 'options': '-vn'} self.vc = None def setup(bot): bot.add_cog(music_cog(bot)) def search_yt(self, item): with YoutubeDL(self.YDL_OPTIONS) as ydl: try: info = ydl.extract_info("ytsearch:%s" % item, download=False)['entries'][0] except Exception: return False return {'source': info['formats'][0]['url'], 'title': info['title']} def play_next(self): if len(self.music_queue) > 0: self.is_playing = True m_url = self.music_queue[0][0]['source'] self.music_queue.pop(0) self.vc.play(discord.FFmpegAudio(m_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next()) else: self.is_playing = False async def play_music(self, ctx): if len(self.music_queue) > 0: self.is_playing = True m_url = self.music_queue[0][0]['sorce'] if self.vc == None or not self.vc.is_connected(): self.vc == await self.music_queue[0][1].connect() if self.vc == None: await ctx.send("Could not connect to the voice channel :-(") return else: await self.vc.move_to(self.music_queue[0][1]) self.music_queue.pop(0) self.vc.play(discord.FFmpegPCMAudio(m_url, ** self.FFMPEG_OPTIONS), after=lambda e: self.play_next()) else: self.is_playing = False # Play music command @commands.command(name="play", aliases=["p", "playing"], help="Play a song from youtube") async def play(self, ctx, *args): query = " ".join(args) voice_channel = ctx.author.voice.channel if voice_channel is None: await ctx.send("Connect to a voice channel!") elif self.is_paused: self.vc.resume() else: song = self.search_yt(query) if type(song) == type(True): await ctx.send("Could not download the song. Incorrect format, try a different keyword") else: await ctx.send("Song added to the queue") self.music_queue.append([song, voice_channel]) if self.is_playing == False: await self.play_musci(ctx) # Pause music command @commands.command(name="pause", aliases=["stop", "paused"], help="Pauses the current song being played") async def pause(self, ctx, *args): if self.is_playing: self.is_playing = False self.is_paused = True self.vc.pause() elif self.is_pause: self.is_playing = True self.is_paused = False self.vc.resume() # Resume music command @commands.command(name="resume", aliases=["r", "unpause"], help="Resumes playing the current song") async def resume(self, ctx, *args): if self.is_paused: self.is_playing = True self.is_paused = False self.vc.resume() # Skip music command @commands.command(name="skip", aliases=["s"], help="Skips the currently played song") async def skip(self, ctx, *args): if self.vc != None and self.vc: self.vc.stop() await self.play_music(ctx) # Queue command @commands.command(name="queue", aliases=["q"], help="Displays all the songs currently in the queue") async def queue(self, ctx, *args): retval = "" for i in range(0, len(self.music_queue)): if i > 4: break retval += self.music_queue[i][0]['title'] + '\n' if retval != "": await ctx.send(retval) else: await ctx.send("No music in the queue.") # Clear command @commands.command(name="clear", aliases=["c", "bin"], help="Stops the current song and clears the queue") async def clear(self, ctx, *args): if self.vc != None and self.is_playing: self.vc.stop() self.music_queue = [] await ctx.send("Music queue cleared") # Leave command @commands.command(name="leave", aliases=["disconnect", "l", "d"], help="Kick the bot from the voice channel") async def leave(self, ctx, *args): self.is_playing = False self.is_paused = False await self.vc.disconnect()
help_cog代码
import discord from discord.ext import commands class help_cog(commands.Cog): def __init__(self, bot): self.bot = bot self.help_message = """ General commands: !help - Displays all the avaiable commands !p - Finds the song on youtube and plays it in yout current channel. Will resume playing the current song if it was paused !q - Displays the current music queue !skip - Skips the current song being played !clear - Stops the music and clears the queue !leave - Disconnects the bot from the voice channel !pause - Pauses the current song being played or resumes if already paused !resume - Resumes playing the current song """ self.text_channel_text = [] def setup(bot): bot.add_cog(help_cog(bot)) @commands.Cog.listener() async def on_ready(self): for guild in self.bot.guilds: for channel in guild.text_channels: self.text_channel_text.append(channel) await self.send_to_all(self.help_message) async def send_to_all(self,msg): for text_channel in self.text_channel_text: await text_channel.send(msg) # Help command @commands.command(name='help', help="Displays all the avaiable commands") async def help(self, ctx): await ctx.send(self.help_message)
问题根源及修复方案
1. 核心问题:Cog方法缩进错误
两个cog文件中,所有类成员方法(包括命令函数、工具函数、事件监听)都缩进错误,没有被包含在类的定义范围内,导致Bot无法加载这些命令:
music_cog中,search_yt、play_next、play_music以及所有@commands.command装饰的方法,都缩进在了setup函数内部或外部,而非class music_cog内部。help_cog中,on_ready、send_to_all、help命令同样缩进错误,不属于help_cog类的成员。
修复方式:将这些方法的缩进调整到类内部,与__init__方法同级。
2. 拼写与逻辑错误
play方法中调用await self.play_musci(ctx)→ 修正为await self.play_music(ctx)(拼写错误)play_music方法中m_url = self.music_queue[0][0]['sorce']→ 修正为['source'](拼写错误)pause方法中elif self.is_pause:→ 修正为elif self.is_paused:(拼写错误)play_music方法中self.vc == await ...→ 修正为self.vc = await ...(赋值而非比较)FFMPEG_OPTIONS中参数存在空格:- reconnect_streamed→-reconnect_streamed,-reconnected_delay_max→-reconnect_delay_max(参数格式错误)
3. 修正后的示例代码(以music_cog为例)
import discord from discord.ext import commands from youtube_dl import YoutubeDL class music_cog(commands.Cog): def __init__(self, bot): self.bot = bot self.is_playing = False self.is_paused = False self.music_queue = [] self.YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist': 'True'} self.FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'} self.vc = None def search_yt(self, item): with YoutubeDL(self.YDL_OPTIONS) as ydl: try: info = ydl.extract_info("ytsearch:%s" % item, download=False)['entries'][0] except Exception: return False return {'source': info['formats'][0]['url'], 'title': info['title']} def play_next(self): if len(self.music_queue) > 0: self.is_playing = True m_url = self.music_queue[0][0]['source'] self.music_queue.pop(0) self.vc.play(discord.FFmpegPCMAudio(m_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next()) else: self.is_playing = False async def play_music(self, ctx): if len(self.music_queue) > 0: self.is_playing = True m_url = self.music_queue[0][0]['source'] if self.vc is None or not self.vc.is_connected(): self.vc = await self.music_queue[0][1].connect() if self.vc is None: await ctx.send("Could not connect to the voice channel :-(") return else: await self.vc.move_to(self.music_queue[0][1]) self.music_queue.pop(0) self.vc.play(discord.FFmpegPCMAudio(m_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next()) else: self.is_playing = False # Play music command @commands.command(name="play", aliases=["p", "playing"], help="Play a song from youtube") async def play(self, ctx, *args): query = " ".join(args) voice_channel = ctx.author.voice.channel if voice_channel is None: await ctx.send("Connect to a voice channel!") elif self.is_paused: self.vc.resume() else: song = self.search_yt(query) if type(song) == type(True): await ctx.send("Could not download the song. Incorrect format, try a different keyword") else: await ctx.send("Song added to the queue") self.music_queue.append([song, voice_channel]) if not self.is_playing: await self.play_music(ctx) # 其余命令方法按同样缩进规则修正,此处省略... def setup(bot): bot.add_cog(music_cog(bot))
4. 额外注意事项
- 确保Bot的Discord开发者门户中已启用所有必要的Intents(尤其是Message Content Intent)
- 验证
token.txt中的Bot token无多余空格或换行符 - 确保
youtube_dl和ffmpeg已正确安装(可通过pip install youtube_dl安装,FFmpeg需添加到系统PATH)
内容的提问来源于stack exchange,提问作者Tobee
相关产品推荐
相关产品推荐

