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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 05:15:00