Discord.py如何修复on_message事件触发后消息循环发送故障
问题排查与修复方案
核心问题1:反复刷屏的原因
on_message事件会监听频道内所有消息,包括机器人自身发送的消息:你触发条件后机器人发送Wait for support!,这条消息本身又会触发on_message事件,再次匹配到频道分类+管理员全离线的条件,就会重复发送消息形成死循环。
核心问题2:部分代码被忽略的原因
你的条件分支逻辑存在冲突:
- 你先用
if 频道属于指定分类做第一层判断,满足就走管理员离线逻辑,后续的elif ctx.mentions分支会直接被跳过 - 哪怕消息同时满足「在指定分类」和「包含艾特」两个条件,也永远不会走到艾特处理的分支,且第二层elif里重复判断频道分类属于冗余代码
其他隐藏问题
process_commands调用位置不规范,重复调用且遗漏场景- 未对get_member返回的admin对象做判空处理,如果对应ID的用户已经离开服务器,访问status属性会直接抛出异常
- 频道分类判断写了重复的长条件,可读性和可维护性差
修复后的代码
@bot.event async def on_message(ctx): # 第一步:过滤机器人自身的消息,直接阻止死循环 if ctx.author.bot: return # 统一处理命令,放在最前面避免分支逻辑跳过 await bot.process_commands(ctx) # 把重复判断的分类ID放到集合里,简化代码 target_category_ids = {909114663868973106, 838806063418966057, 909114621980454962} if ctx.channel.category.id not in target_category_ids: return # 处理管理员离线场景 admin_ids = [640961296665149440, 708704382828544071, 838159011605512202, 895743036338884689] all_admin_offline = True for aid in admin_ids: admin = ctx.guild.get_member(aid) # 判空避免用户不存在报错,不存在的管理员默认按离线处理 if admin and admin.status != discord.Status.offline: all_admin_offline = False break if all_admin_offline: await ctx.add_reaction('⏳') await ctx.channel.send("Wait for support!") # 处理管理员艾特场景,用独立if不要用elif,避免被前面的分支跳过 if ctx.mentions and ctx.author.guild_permissions.administrator: await ctx.add_reaction('✅') # 直接获取被艾特的第一个用户,不需要调用query_members user = ctx.mentions[0] embed=discord.Embed(color=0xe5f476) embed.add_field(name="You have been mentioned by an administrator!!", value=f"You have been mentioned by an administrator in **{ctx.channel.mention}** channel.\nMention usually is for an update in ur ticket, most likely something important!\nCheck the server for more information about this staff mention.\n", inline=False) embed.set_footer(text=f"⭐ Use -tagnotif on #{ctx.channel.name} for stopping this messages. ⭐") await user.send(embed=embed)
内容的提问来源于stack exchange,提问作者peter_linux OS
相关产品推荐
相关产品推荐

