制作Discord音乐机器人遇/help命令未找到错误求助
Discord机器人
/help命令找不到问题排查 问题现象
执行/help命令时触发以下错误:
discord.ext.commands.bot: Ignoring exception in command None
discord.ext.commands.errors.CommandNotFound: Command "help" is not found
代码文件
main.py
import discord from discord.ext import commands import os from music_cog import MusicCog from help_cog import HelpCog intents = discord.Intents.all() bot = commands.Bot(command_prefix="/", intents=intents) bot.remove_command('help') async def setup(bot): await bot.add_cog(HelpCog(bot)) async def set(bot): await bot.add_cog(MusicCog(bot)) os.environ['TOKEN'] = '' bot.run(os.getenv('TOKEN'))
help_cog.py
from discord.ext import commands class HelpCog(commands.Cog): def __init__(self, bot): self.bot = bot self.help_message = """ ''' All Commands: /help - Display all commands /play - Search and play music from YouTube /queue - View the music queue /skip - Skip to the next song /clear - Clear the music queue /leave - Disconnect the bot from the voice channel /pause - Pause the current song /resume - Resume playing the music ''' """ 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, mess): for text_channel in self.text_channel_text: await text_channel.send(mess) @commands.command(name='help', help='Display all commands') async def help(self, ctx): await ctx.send(self.help_message)
music_cog.py
import discord from discord.ext import commands from youtube_dl import YoutubeDL class MusicCog(commands.Cog): def __init__(self, bot): self.bot = bot self.is_playing = False self.is_pause = 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('Cannot 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()) @commands.command(name='play', aliases=['p', 'P', 'playing'], help='Play song from yt') 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 channel to hear music') elif self.is_pause: self.vc.resume() else: if query.startswith('https://www.youtube.com/'): # YouTube URL song_info = self.search_yt(query) else: # Search query song_info = self.search_yt(f'ytsearch:{query}') if song_info: await ctx.send('Song added to queue') self.music_queue.append([song_info, voice_channel]) if not self.is_playing: await self.play_music(ctx) else: await ctx.send("Couldn't find the song, try other keywords") @commands.command(name='pause', help='Pause the current song') async def pause(self, ctx): if self.is_playing: self.is_playing = False self.is_pause = True self.vc.pause() elif self.is_pause: self.is_playing = True self.is_pause = False self.vc.resume() @commands.command(name='resume', aliases=['r', 'R'], help='Resume playing the music') async def resume(self, ctx): if self.is_pause: self.is_playing = True self.is_pause = False self.vc.resume() @commands.command(name='skip', aliases=['S', 'skip', 's'], help='Go to the next song') async def skip(self, ctx): if self.vc is not None and self.vc.is_playing(): self.vc.stop() await self.play_music(ctx) @commands.command(name='queue', aliases=['q', 'Q'], help='Show all music in the queue') async def queue(self, ctx): retval = '' for i in range(min(len(self.music_queue), 10)): retval += f"{i + 1}. {self.music_queue[i][0]['title']}\n" if retval != '': await ctx.send(retval) else: await ctx.send('No music in the queue') @commands.command(name='clear', aliases=['c', 'C'], help='Remove all music from the queue') async def clear(self, ctx): if self.vc is not None and self.is_playing: self.vc.stop() self.music_queue = [] await ctx.send('Queue cleared!') @commands.command(name='leave', aliases=['l', 'L', 'leave'], help='Remove bot from the voice channel') async def leave(self, ctx): if self.vc and self.vc.is_connected(): self.is_playing = False self.is_pause = False await self.vc.disconnect()
问题原因及修复方案
1. Cog未被加载(核心问题)
main.py中定义了setup和set函数用于添加Cog,但从未调用这些函数,导致HelpCog和MusicCog完全没有被加载到机器人中,自然找不到/help命令。
修改main.py,替换原有加载逻辑:
import discord from discord.ext import commands import os import asyncio from music_cog import MusicCog from help_cog import HelpCog intents = discord.Intents.all() bot = commands.Bot(command_prefix="/", intents=intents) bot.remove_command('help') async def main(): # 加载Cog await bot.add_cog(HelpCog(bot)) await bot.add_cog(MusicCog(bot)) # 启动机器人 await bot.start(os.getenv('TOKEN')) os.environ['TOKEN'] = '你的机器人Token' asyncio.run(main())
2. MusicCog中play方法缩进错误
music_cog.py中的play方法没有缩进到MusicCog类内部,导致该命令无法被识别。将play方法整体缩进,与类内其他方法保持同级:
修改后music_cog.py中的play部分:
async def play_music(self, ctx): # 原有代码不变... @commands.command(name='play', aliases=['p', 'P', 'playing'], help='Play song from yt') 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 channel to hear music') elif self.is_pause: self.vc.resume() else: if query.startswith('https://www.youtube.com/'): # YouTube URL song_info = self.search_yt(query) else: # Search query song_info = self.search_yt(f'ytsearch:{query}') if song_info: await ctx.send('Song added to queue') self.music_queue.append([song_info, voice_channel]) if not self.is_playing: await self.play_music(ctx) else: await ctx.send("Couldn't find the song, try other keywords")
3. 可选优化:HelpCog的批量发送消息可能触发限流
HelpCog的on_ready方法会给所有文本频道发送帮助消息,容易触发Discord的请求限流。建议改为仅在机器人就绪后打印日志,或发送到指定频道:
@commands.Cog.listener() async def on_ready(self): print(f'{self.bot.user} 已就绪!') # 若需要发送帮助消息,可指定频道: # channel = self.bot.get_channel(你的频道ID) # await channel.send(self.help_message)
完成以上修改后,重启机器人,/help命令即可正常使用。
内容的提问来源于stack exchange,提问作者Nguyễn Trung Kiến
相关产品推荐
相关产品推荐

