Python Discord机器人报错:CommandNotFound,play命令未找到
Discord机器人
play命令找不到的问题排查与修复 我跟着教程做了个Discord机器人,输入命令时一直报错:discord.ext.commands.errors.CommandNotFound: Command "play" is not found。机器人已经在服务器显示在线,权限也给全了,反复检查代码没找到问题,求帮忙。下面是我的文件代码:
main.py
import discord from discord.ext import commands import os from help_cog import help_cog from music_cog import music_cog bot = commands.Bot(command_prefix="?", intents=discord.Intents.all()) bot.remove_command("help") bot.add_cog(help_cog(bot)) bot.add_cog(music_cog(bot)) bot.run(os.getenv("TOKEN"))
music_cog.py
import discord from discord.ext import commands from yt_dlp import YoutubeDL import yt_dlp as youtube_dl 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", "postprocessors": [{"key": "FFmpegExtractAudio", "preferredcodec": "mp3", "preferredquality": "192",}]} self.FFMPEG_OPTIONS = {"before_options": "-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5", "options": "-vn"} self.vc = None print("Success") def search_yt(self, item): with YoutubeDL(self.YDL_OPTIONS) as ydl: try: info = ydl.extract_info(f"ytsearch:{item}", download=False)["entries"][0] except Exception: return False return {"source": info["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 == 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 @commands.command(name="play", aliases=["p", "playing"], help="Play the selected 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 queue") self.music_queue.append([song, voice_channel]) if self.is_playing == False: await self.play_music(ctx) @commands.command(name="pause", 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_paused: self.is_playing = True self.is_paused = False self.vc.resume() @commands.command(name="resume", aliases=["r"], 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() @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) @commands.command(name="queue", aliases=["q"], help="Displays all the songs currently in queue") async def queue(self, ctx): 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 current queue") @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") @commands.command(name="leave", aliases=["disconnect", "l", "d"], help="Kick the bot from the voice channel") async def leave(self, ctx): self.is_playing = False self.is_paused = False await self.vc.disconnect()
help_cog.py
import discord from discord.ext import commands class help_cog(commands.Cog): def __init__(self, bot): self.bot = bot self.help_message = """ Help message """ self.text_channel_text = [] @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) @commands.command(name="help", help="Displays all the available commands") async def help(self, ctx): await ctx.send(self.help_message)
问题排查与修复方案
1. 确认Cog是否成功加载
在main.py中添加就绪事件日志,检查cog加载状态:
@bot.event async def on_ready(): print(f'已登录为 {bot.user.name} (ID: {bot.user.id})') print('------') # 打印已加载的cog列表 print(f"已加载的Cog: {list(bot.cogs.keys())}")
运行后如果控制台没显示music_cog和help_cog,说明文件路径错误,确保help_cog.py、music_cog.py和main.py在同一目录下。
2. 修复help_cog的on_ready异常
help_cog的on_ready方法会遍历所有文本频道发消息,若频道权限不足或服务器数量多,会抛出异常中断程序。修改该方法添加异常捕获:
@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) # 捕获发送消息的异常,避免程序崩溃 try: await self.send_to_all(self.help_message) except Exception as e: print(f"发送帮助消息失败: {e}")
或者直接注释掉await self.send_to_all(self.help_message),先测试命令是否可用。
3. 检查命令前缀和输入格式
确保输入命令时使用正确的前缀?,比如输入?play 歌曲名,而非直接输入play。
4. 开启Discord后台的特权意图
登录Discord开发者后台,进入Bot页面,开启Privileged Gateway Intents下的「服务器成员意图」和「消息内容意图」,否则机器人无法接收命令消息。
5. 修复music_cog的语音连接异常
play_music方法中连接语音频道可能抛出异常,添加捕获逻辑避免程序中断:
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 == None or not self.vc.is_connected(): try: self.vc = await self.music_queue[0][1].connect() except Exception as e: await ctx.send(f"连接语音频道失败: {e}") self.music_queue.pop(0) self.is_playing = False return if self.vc == None: await ctx.send("无法连接到语音频道") return else: try: await self.vc.move_to(self.music_queue[0][1]) except Exception as e: await ctx.send(f"切换语音频道失败: {e}") self.music_queue.pop(0) self.is_playing = False return 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
内容的提问来源于stack exchange,提问作者Skely
相关产品推荐
相关产品推荐

