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

discord.py on_message事件角色校验失效 实现管理角色删链豁免

核心问题定位

你遇到的权限判断失效、高权限用户发的邀请链接照样被删,本质是两个代码层面的硬伤:

  1. 权限判断的逻辑运算符完全写反:原代码用or串接了四个“角色不在用户列表”的判断,等价于「只要用户缺四个豁免角色里的任意一个,就触发删除」,哪怕用户已经拥有Admin这类最高权限角色,只要没凑齐所有四个豁免角色,判断就会成立,消息照样被删。
  2. 初始的链接匹配逻辑永远不生效:原代码写if serverLink in message_content,其中serverLink是存了多个域名的列表对象,直接和字符串做in判断永远返回假,根本进不到后续的权限校验分支。
修正后可用的实现代码

直接替换原有Cog里的逻辑即可,优化了集合判断的效率,避免反复调用discord.utils.get拉取角色对象:

import discord
from discord.ext import commands

# 需拦截的邀请域名列表
server_link = ["discord.gg", "disboard.com"]
# 享有豁免权限、不被拦截链接的角色名称白名单
EXEMPT_ROLES = ["Admin", "Moderator", "Realm OP", "Bots"]

class InviteMonitorCog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.Cog.listener()
    async def on_message(self, message):
        # 跳过机器人消息、跳过私聊场景的无意义校验
        if message.author.bot or not message.guild:
            return

        # 判断消息是否包含需拦截的域名
        hit_link = any(link in message.content for link in server_link)
        if not hit_link:
            return

        # 校验用户是否拥有任意一个白名单角色
        user_role_names = {role.name for role in message.author.roles}
        has_exempt_role = not user_role_names.isdisjoint(EXEMPT_ROLES)

        # 有豁免权限直接跳过删除逻辑
        if has_exempt_role:
            return

        # 无豁免权限、命中链接的消息直接删除
        await message.delete()
关键优化点说明
  • 权限判断改用集合交集逻辑:只要用户角色和白名单角色有任意重叠,就直接放行,不需要逐个判断每个角色是否存在,代码可读性和执行效率都更高。
  • 补全了基础兜底:提前跳过机器人自身消息、私聊场景,避免不必要的API请求和权限报错。
  • 去掉了冗余的discord.utils.get角色拉取逻辑:直接从用户已经加载的角色列表里取名称做比对,减少无效的服务器请求。
  • 修正了原代码的运算符错误:如果要按原来的逐角色判断写法,正确的触发删除的条件应该写为if not (RealmOP in message.author.roles or Bots in message.author.roles or Moderator in message.author.roles or Admin in message.author.roles),也就是“用户一个豁免角色都没有的时候才执行删除”,和原代码的逻辑差了一层“非”的关系。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 14:24:08