使用discord.py开发Discord机器人:状态消息获取与角色自动分配
实现前置准备
- 需在Discord开发者门户的机器人设置页开启Presence Intent(存在意图)和Server Members Intent(服务器成员意图),未开启特权意图的情况下无法读取用户状态、也无法执行角色分配操作
- 确保机器人在目标服务器的权限列表中勾选了管理角色权限,且机器人自身的角色在服务器角色层级列表中的位置,要高于待分配的"supporter"角色,否则会因权限不足无法完成角色分配
核心实现思路
discord.py 框架中,用户手动设置的自定义状态文本(即用户状态消息)属于discord.CustomActivity类型的活动对象,其文本内容存储在对象的name属性中。
无需做全服用户轮询扫描,直接使用框架内置的on_presence_update事件即可监听所有用户的状态变更:当用户修改自定义状态时,事件会自动触发,此时提取更新后的状态文本做字符串匹配,满足条件就执行角色分配逻辑即可。
适配discord.py 2.x+的完整实现代码
import discord from discord.ext import commands # 显式加载所需的特权意图,默认意图不包含状态、成员相关权限 intents = discord.Intents.default() intents.presences = True intents.members = True # 初始化机器人实例 bot = commands.Bot(command_prefix="!", intents=intents) @bot.event async def on_ready(): # 机器人启动成功的日志提示 print(f"机器人已登录,当前登录身份:{bot.user}") @bot.event async def on_presence_update(before: discord.Member, after: discord.Member): # 从当前服务器中匹配名为supporter的角色 supporter_role = discord.utils.get(after.guild.roles, name="supporter") # 服务器中不存在对应角色时直接返回,避免触发空对象报错 if not supporter_role: return # 遍历用户当前的所有活动,匹配自定义状态内容 status_matched = False for activity in after.activities: # 仅匹配用户手动设置的自定义文本状态,排除游戏、听歌等其他活动类型 if isinstance(activity, discord.CustomActivity): if activity.name and "Testing" in activity.name: status_matched = True break # 仅在用户满足匹配条件、且未持有目标角色时执行分配操作,避免重复接口请求 if status_matched and supporter_role not in after.roles: try: await after.add_roles( supporter_role, reason="状态文本包含Testing,自动分配supporter角色" ) except discord.Forbidden: # 捕获权限不足异常,避免机器人因报错崩溃 print(f"分配角色失败:无法给用户{after.display_name}授予supporter角色,请检查机器人权限与角色层级") # 替换为你的机器人Token后运行 bot.run("你的机器人Token值")
常见踩坑说明
- 匹配规则可按需调整:当前代码对"Testing"的匹配是区分大小写的,如果需要忽略大小写匹配,可以将判断逻辑改为
if activity.name and "testing" in activity.name.lower() - 不要轮询全服用户状态:高频全量拉取用户信息极易触发Discord接口的限流规则,使用内置事件监听的方式资源开销最低、也最稳定
- 状态内容取不到的排查方向:优先检查是否漏开Presence Intent,其次检查机器人是否已加入目标服务器、是否有读取成员信息的权限
内容的提问来源于stack exchange,提问作者Rogue
相关产品推荐
相关产品推荐

