Discord Bot异常:!decklist内on_message干扰!boh命令执行
Discord Bot 命令冲突问题解决
我的Discord Bot目前能正常执行!decklist命令,但触发if not message.attachments分支后,执行!boh命令时,机器人既会回复该分支的提示内容,又会执行!boh命令。需要解决的问题是:如何正确退出!decklist命令,避免使用其他命令时触发该分支。
原问题代码
import discord from discord.ext import commands from io import BytesIO TOKEN = 'disc_token' def run(): intents = discord.Intents.default() intents.message_content = True intents.members = True bot = commands.Bot(command_prefix="!", intents = intents) #ON_READY @bot.event async def on_ready(): #SERVER = bot.get_guild(int(1156534000890953748)) bot_name = await bot.fetch_user(int(1155959555876991098)) await bot.tree.sync() print(f'{bot_name}si è connesso a Discord') #SENDS USER EMBED TO RESPOND WITH IMAGE. @bot.command() async def decklist (ctx): """Riceve l'immagine della Decklist e la invia per la conferma""" embed = discord.Embed( colour = discord.Colour.dark_magenta(), title = ("Dreamborn"), url = ("https://dreamborn.ink/") ) embed.set_image(url="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQKCp5PneGn0VgoP-Hncj4AxiN-Ql2tqaKd6w&usqp=CAU") await ctx.send(f"Mandami l'immagine della Decklist esportata da **Dreamborn!**", ephemeral=True) await ctx.send(embed=embed) @bot.event async def on_message(message): await bot.process_commands(message) if message.author == bot.user: return if message.author.bot: return if not message.attachments: #ignore (message=bot.command()) await message.author.send('Ciao! La tua lista non è **idonea**. Mandami una **immagine!**') pass image_file = message.attachments[0] image_bytes = await image_file.read() liste = bot.get_channel(int(1156534533907288064)) istruzioni = bot.get_channel(int(1156626680794845234)) await liste.send('**' + message.author.display_name + '**') await liste.send(file=discord.File(fp=BytesIO(image_bytes), filename=image_file.filename)) await message.author.send('Oki doki, Decklist inviata! Metti la reazione al messaggio su' + istruzioni.mention + 'per essere Confermato! Se invece avevi già messo la reazione a Confermati, ignora!') await bot.process_commands(message) #REPLY WITH "HELLO" @bot.command() async def boh(ctx): await ctx.send(f"ciao!") bot.run(TOKEN) run()
问题根源
你在!decklist命令内部嵌套定义了全局的on_message事件监听器,每次调用!decklist都会新增一个监听器。后续所有消息(包括其他命令)都会被这个额外的监听器处理,导致命令冲突。
修正方案
移除命令内部的on_message事件,改用wait_for来监听用户的后续回复,这是Discord.py处理命令交互的标准方式,仅在当前命令上下文内生效,不会干扰其他命令。
修正后的完整代码
import discord from discord.ext import commands from io import BytesIO TOKEN = 'disc_token' def run(): intents = discord.Intents.default() intents.message_content = True intents.members = True bot = commands.Bot(command_prefix="!", intents=intents) # ON_READY @bot.event async def on_ready(): bot_name = await bot.fetch_user(int(1155959555876991098)) await bot.tree.sync() print(f'{bot_name} si è connesso a Discord') # SENDS USER EMBED TO RESPOND WITH IMAGE. @bot.command() async def decklist(ctx): """Riceve l'immagine della Decklist e la invia per la conferma""" embed = discord.Embed( colour=discord.Colour.dark_magenta(), title="Dreamborn", url="https://dreamborn.ink/" ) embed.set_image(url="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQKCp5PneGn0VgoP-Hncj4AxiN-Ql2tqaKd6w&usqp=CAU") await ctx.send(f"Mandami l'immagine della Decklist esportata da **Dreamborn!**", ephemeral=True) await ctx.send(embed=embed) # 仅监听当前命令发起者在同一频道的消息 def check(message): return message.author == ctx.author and message.channel == ctx.channel try: # 设置60秒超时,避免命令一直挂起 message = await bot.wait_for('message', check=check, timeout=60.0) except TimeoutError: await ctx.author.send("Timeout! Non hai inviato l'immagine in tempo.") return if not message.attachments: await message.author.send('Ciao! La tua lista non è **idonea**. Mandami una **immagine!**') return image_file = message.attachments[0] image_bytes = await image_file.read() liste = bot.get_channel(int(1156534533907288064)) istruzioni = bot.get_channel(int(1156626680794845234)) await liste.send(f'**{message.author.display_name}**') await liste.send(file=discord.File(fp=BytesIO(image_bytes), filename=image_file.filename)) await message.author.send(f'Oki doki, Decklist inviata! \nMetti la reazione al messaggio su {istruzioni.mention} per essere Confermato! \nSe invece avevi già messo la reazione a Confermati, ignora!') # REPLY WITH "HELLO" @bot.command() async def boh(ctx): await ctx.send(f"ciao!") bot.run(TOKEN) run()
关键改进点
- 使用
wait_for替代全局on_message,仅在!decklist命令的上下文内监听用户回复,不会影响其他命令。 check函数确保只处理当前命令发起者的消息,避免误处理其他人的输入。- 添加超时机制,防止命令无限等待用户输入。
内容的提问来源于stack exchange,提问作者Kain
相关产品推荐
相关产品推荐

