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

discord.py无法检测Rich Presence 游戏活动检测功能失效

问题根因排查

你的代码完全无法运行是多个基础错误叠加导致的,逐个列示:

  • 事件注册无效:@client.event 仅支持绑定discord.py内置的网关事件,你自定义的get_all_members不属于框架认可的事件,永远不会被触发,所有逻辑从入口就不会执行。
  • 对象认知错误:活动状态(Rich Presence)是*服务器成员(Member对象)的属性,不是频道(Channel对象)*的属性,你代码里尝试读取channel.activity从根上就找错了对象,不可能拿到游戏状态。另外用户的活动是列表类型activities,支持同时存在多个活动,不存在单个activity属性。
  • 语法调用错误:client.get.channel是错误写法,正确的频道获取方法是client.get_channel(频道ID);你写的channel;client.get.channel(xxx)用分号分隔的语句没有做变量赋值,就算拿到目标频道对象也不会被后续发送逻辑使用。
  • 权限配置缺失:读取用户活动状态属于Discord的特权权限,你需要先在开发者后台开启对应网关意图,同时在客户端初始化时声明启用,否则Discord根本不会把用户的活动数据推送给你的机器人。
可直接落地的修复方案

第一步:开启特权网关意图

  1. 打开Discord开发者后台,进入你的机器人应用的Bot设置页
  2. 找到Privileged Gateway Intents板块,开启Presence Intent、Server Members Intent、Message Content Intent三个开关,保存配置
  3. 确认机器人在目标服务器拥有「发送消息」的基础权限

第二步:修正客户端初始化配置

初始化客户端时必须显式声明启用需要的意图,否则配置不生效:

import discord

# 配置意图
intents = discord.Intents.default()
intents.presences = True
intents.members = True

# 初始化客户端,替换成你自己的token即可
client = discord.Client(intents=intents)

# 业务配置
TARGET_GAMES = {"osu!"}  # 用集合做匹配效率更高,后续加游戏直接往里面放就行
NOTICE_CHANNEL_ID = 804884691328303115
# 缓存已发过提示的用户ID,避免每次状态更新都重复发消息骚扰
notified_user_set = set()

第三步:用正确的事件实现检测逻辑

使用discord.py内置的on_presence_update事件,该事件会在任意成员的在线状态、活动状态变更时自动触发,不需要轮询:

@client.event
async def on_presence_update(before: discord.Member, after: discord.Member):
    # 跳过机器人自身的状态更新
    if after.bot:
        return
    
    # 提取用户当前所有正在运行的游戏类活动名称
    current_playing_games = set()
    for act in after.activities:
        # 仅匹配「正在玩」类型的活动,过滤听歌、自定义状态等非游戏活动
        if act.type == discord.ActivityType.playing and act.name:
            current_playing_games.add(act.name.lower())
    
    # 命中目标游戏且未发过提示
    if current_playing_games & {g.lower() for g in TARGET_GAMES} and after.id not in notified_user_set:
        notice_channel = client.get_channel(NOTICE_CHANNEL_ID)
        if notice_channel:
            await notice_channel.send(f"{after.mention} 玩osu是不允许的")
            notified_user_set.add(after.id)
    
    # 可选逻辑:用户关闭目标游戏后从缓存移除,下次再打开游戏时重新触发提示
    elif not (current_playing_games & {g.lower() for g in TARGET_GAMES}) and after.id in notified_user_set:
        notified_user_set.remove(after.id)

# 补充原有机器人启动逻辑即可
# client.run("你的机器人Token")
补充说明
  • 不要用定时遍历全服务器成员的方式做检测,效率极低且很容易触发Discord的速率限制,用网关事件推送是官方推荐的最优实现
  • 如果需要匹配Rich Presence类的第三方游戏状态,只要活动类型是playing就会被上述逻辑捕获,不需要额外做适配
  • 如果频道获取失败返回None,优先检查机器人是否在该频道所在的服务器内、频道ID是否填写正确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 01:42:28