discord.py中Member.activity仅返回自定义状态无法获取游戏状态的问题
问题原因
你当前代码调用的after.activity/before.activity属性仅会返回用户优先级最高的单个活动,当用户设置了自定义状态时,自定义状态会优先被该属性返回,游戏类活动会被覆盖,导致无法匹配到游戏名称,同时原逻辑的角色移除规则存在漏判场景。
修复方案
Discord.py 中Member对象提供了activities属性,类型为列表,会包含用户当前所有生效的活动(自定义状态、正在运行的游戏、Spotify 听歌状态、直播状态等),遍历该列表即可准确识别用户是否在运行目标游戏,不会被自定义状态干扰。
修正后的完整实现代码:
@client.event async def on_member_update(before, after): # 提前获取目标角色,不存在则直接终止逻辑避免报错 target_role = discord.utils.get(after.guild.roles, name="roleName") if not target_role: return target_games = {"Escape from Tarkov"} # 遍历所有活动,检查是否存在目标游戏 is_running_target_game = False for activity in after.activities: # 过滤无name属性的特殊活动类型,避免属性报错 if hasattr(activity, "name") and activity.name in target_games: is_running_target_game = True break if is_running_target_game: # 仅当用户未持有角色时发起加角色请求,减少冗余API调用 if target_role not in after.roles: await after.add_roles(target_role) else: # 确认用户未运行目标游戏且持有角色时,移除对应角色 if target_role in after.roles: await after.remove_roles(target_role)
优化点说明
- 替换单活动取值为全活动列表遍历,彻底解决自定义状态覆盖游戏活动的问题,用户无法通过设置自定义状态绕过检测
- 修复原逻辑的移除漏判问题:原逻辑仅在
after.activity为空时才触发移除,当用户从游戏状态切换到听歌、直播、自定义状态等非空活动时,不会触发角色回收,新逻辑只要检测到当前无目标游戏运行就会回收角色 - 新增多层存在性校验,避免角色不存在、属性不存在、重复加/卸角色导致的API报错
内容的提问来源于stack exchange,提问作者Yarman53
相关产品推荐
相关产品推荐

