Discord反应身份组机器人变量类型错误及互斥限制失效问题排查
问题根因
- 变量名冲突覆盖:最初定义的
role为Discord身份组对象,后续互斥判断的循环复用了role作为循环变量,遍历存储int类型ID的category["roles"]列表,循环执行后原来的身份组对象被覆盖为int类型的角色ID,这是注释末尾重取代码后报错的直接原因。 - 类型不匹配导致互斥判断失效:
member.roles列表存储的是Discord的Role对象,直接将int类型的角色ID和Role对象做归属判断,永远返回False,所以check4逻辑永远不会触发,互斥限制自然不生效。 - 原代码遗漏了互斥判断触发后的移除逻辑,就算check4能触发,也没有移除用户已有同分类身份组的操作,也会导致互斥不生效。
修复方案
调整要点
- 互斥循环改用独立的循环变量名,避免覆盖原有身份组变量
- 互斥判断时先把int类型的角色ID转为
Role对象,再和用户已有身份组做判断 - 新增同分类已有身份组的移除逻辑,实现真正的互斥效果
修复后完整代码
reactionRolesDict = { message_id: { "emotes": ["1️⃣", "2️⃣"], "roles": [role_one_id, role_two_id], "exclusive": True } } @bot.event async def on_raw_reaction_add(payload): # 补全服务器对象获取逻辑 guild = bot.get_guild(payload.guild_id) if not guild: return # 循环变量改名避免和字典值冲突 for category_msg_id in reactionRolesDict: if payload.message_id == category_msg_id: category = reactionRolesDict[category_msg_id] if payload.emoji.name in category["emotes"]: emoteIndex = category["emotes"].index(payload.emoji.name) # 变量改名避免后续被覆盖 target_role = discord.utils.get(guild.roles, id=category["roles"][emoteIndex]) member = discord.utils.get(guild.members, id=payload.user_id) # 过滤无效用户和机器人自身的反应 if not member or member.bot: return print('check 1: {}'.format(target_role)) if category["exclusive"]: print('check 2: {}'.format(target_role)) # 用独立循环变量,不覆盖目标角色 for exist_role_id in category["roles"]: print('check 3: {}'.format(exist_role_id)) exist_role = discord.utils.get(guild.roles, id=exist_role_id) if exist_role in member.roles: print('check 4: {}'.format(exist_role)) # 移除同分类下已有身份组 await member.remove_roles(exist_role) break print('check 5: {}'.format(target_role)) # 变量未被覆盖无需重复获取,直接使用即可 await member.add_roles(target_role) else: print('''couldn't get role''')
内容的提问来源于stack exchange,提问作者user16634524
相关产品推荐
相关产品推荐

