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

Discord Bot仅执行最后一段代码问题求助

Discord Bot命令仅最后一个生效的问题解决

问题情况

之前正常运行的Discord Bot,重启后出现异常:只有最后一段代码对应的命令能正常执行——删除!slap的代码段后,只剩!punch命令可用;删除!punch代码段后,仅!help、!hello等前面的命令恢复。多次重新输入代码、修改函数都无法解决。

问题根源

你重复定义了多个@client.event async def on_message(message)事件处理函数。在Discord.py中,同一个事件(比如on_message)只能有一个生效的处理函数,最后注册的那个会覆盖之前所有的同名事件处理,这就是为什么只有最后一段代码的命令能工作。

解决方案

下面提供两种可行的修复方式:


方案1:合并所有逻辑到单个on_message事件

把所有命令的判断逻辑整合到同一个on_message函数中,让所有命令都能被依次检查执行:

# installed: discord api
import discord
import random
from datetime import date
from discord.ext import commands
from discord.embeds import Embed
from discord import colour

TOKEN = '***********'

intents = discord.Intents.all()
intents.message_content = True
client = discord.Client(intents=intents)

@client.event
async def on_ready():
    print(f"Bot logged in as {client.user}")

@client.event
async def on_message(message):
    if message.author == client.user:
        return  # 跳过机器人自己发的消息,避免重复处理

    # !hello 命令
    if message.content.lower().startswith('!hello'):
        await message.channel.send(f"Wassup, `{message.author}`")

    # !help 命令
    elif message.content.lower().startswith('!help'):
        await message.channel.send(f"`{message.author}` \nHere are all my commands:\n \n!hello ~ greet the bot \n"
                                   f"!roll ~ the bot will give a random value between 1 and 100 \n"
                                   f"!day ~ the bot will give the date and time \n"
                                   f"!punch ~ the bot will send a punching gif ( not nsfw )\n"
                                   f"!slap ~ the bot will send a slapping gif\n"
                                   f"")

    # !roll 命令
    elif message.content.lower().startswith('!roll'):
        number = str(random.randint(1, 100))
        await message.channel.send('Your number is: ' + number)

    # !day 命令
    elif message.content.lower().startswith('!day'):
        today = date.today()
        await message.channel.send(f"The local date today is {today}")

    # !punch 命令
    elif message.content.lower().startswith('!punch'):
        punch_gifs = ['https://media.tenor.com/6Cp5tiRwh-YAAAAC/meme-memes.gif']
        punch_names = ['Punched You']
        embed = discord.Embed(
            colour=(discord.Colour.random()),
            description=f'{message.author.mention} {random.choice(punch_names)}'
        )
        embed.set_image(url=(random.choice(punch_gifs)))
        await message.channel.send(embed=embed)

    # !slap 命令
    elif message.content.lower().startswith('!slap'):
        slap_gifs = ['https://media.tenor.com/mNAs5CO1deIAAAAC/slap.gif']
        slap_names = ['slapped you']
        embed = discord.Embed(
            colour=(discord.Colour.random()),
            description=f'{message.author.mention} {random.choice(slap_names)}'
        )
        embed.set_image(url=(random.choice(slap_gifs)))
        await message.channel.send(embed=embed)

client.run(TOKEN)

方案2:使用commands框架(更规范的写法)

你已经导入了discord.ext.commands并创建了bot实例,建议用框架自带的命令装饰器来定义命令,不仅避免事件覆盖问题,代码结构也更清晰:

# installed: discord api
import discord
import random
from datetime import date
from discord.ext import commands
from discord.embeds import Embed
from discord import colour

TOKEN = '***********'

intents = discord.Intents.all()
intents.message_content = True
# 直接使用commands.Bot实例,不需要再创建discord.Client
bot = commands.Bot(command_prefix='!', intents=intents)

@bot.event
async def on_ready():
    print(f"Bot logged in as {bot.user}")

# !hello 命令
@bot.command()
async def hello(ctx):
    await ctx.send(f"Wassup, `{ctx.author}`")

# !help 命令(可以自定义help内容,也可以用框架默认的)
@bot.command()
async def help(ctx):
    await ctx.send(f"`{ctx.author}` \nHere are all my commands:\n \n!hello ~ greet the bot \n"
                   f"!roll ~ the bot will give a random value between 1 and 100 \n"
                   f"!day ~ the bot will give the date and time \n"
                   f"!punch ~ the bot will send a punching gif ( not nsfw )\n"
                   f"!slap ~ the bot will send a slapping gif\n"
                   f"")

# !roll 命令
@bot.command()
async def roll(ctx):
    number = str(random.randint(1, 100))
    await ctx.send('Your number is: ' + number)

# !day 命令
@bot.command()
async def day(ctx):
    today = date.today()
    await ctx.send(f"The local date today is {today}")

# !punch 命令
@bot.command()
async def punch(ctx):
    punch_gifs = ['https://media.tenor.com/6Cp5tiRwh-YAAAAC/meme-memes.gif']
    punch_names = ['Punched You']
    embed = discord.Embed(
        colour=(discord.Colour.random()),
        description=f'{ctx.author.mention} {random.choice(punch_names)}'
    )
    embed.set_image(url=(random.choice(punch_gifs)))
    await ctx.send(embed=embed)

# !slap 命令
@bot.command()
async def slap(ctx):
    slap_gifs = ['https://media.tenor.com/mNAs5CO1deIAAAAC/slap.gif']
    slap_names = ['slapped you']
    embed = discord.Embed(
        colour=(discord.Colour.random()),
        description=f'{ctx.author.mention} {random.choice(slap_names)}'
    )
    embed.set_image(url=(random.choice(slap_gifs)))
    await ctx.send(embed=embed)

bot.run(TOKEN)

说明

方案2更符合Discord.py的最佳实践,后续添加新命令也更方便,还能利用框架自带的错误处理、命令别名等功能。

内容的提问来源于stack exchange,提问作者xanebot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 00:20:38