You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 23:45:28