Discord.py 教程:监听用户状态变化并发送通知消息

DDD
发布: 2025-10-01 11:18:02
原创
424人浏览过

Discord.py 教程:监听用户状态变化并发送通知消息

本教程详细讲解如何使用 Discord.py 监听服务器成员的状态变化(如在线、离线、忙碌等),并在此变化发生时向指定频道发送通知消息。我们将重点介绍 on_member_update() 事件的正确用法,以及所需的 Intents 配置,以确保您的机器人能够准确捕获并响应用户活动。

在构建 discord 机器人时,有时我们需要实时了解服务器成员的在线状态变化,例如当某个特定用户上线或下线时发送通知。早期的 discord.py 版本可能使用 on_presence_update() 事件来处理此类需求,但该事件已被弃用。本文将指导您使用当前推荐的 on_member_update() 事件来高效实现这一功能。

Discord.py 用户状态监听核心:on_member_update()

on_member_update() 是 Discord.py 中用于监听服务器成员信息更新的事件,它不仅包括用户状态(presence)的变化,还包括昵称、角色等其他成员属性的更新。

on_presence_update() 的弃用与 on_member_update() 的引入

过去,on_presence_update() 事件主要用于处理用户在线状态(presence)的更新。然而,随着 Discord API 和 Discord.py 库的演进,为了更好地整合和管理成员相关的所有更新,on_member_update() 成为了处理这类事件的首选。它提供了更全面的信息,并且是官方推荐的实现方式。

on_member_update() 事件参数解析

on_member_update() 事件回调函数接收两个 discord.Member 对象作为参数:

  • before: 表示成员更新前的状态。
  • after: 表示成员更新后的状态。

通过比较这两个对象的相关属性,我们可以精确地检测到所需的变化。对于用户状态变化,我们将重点关注 before.status 和 after.status。

通义听悟
通义听悟

阿里云通义听悟是聚焦音视频内容的工作学习AI助手,依托大模型,帮助用户记录、整理和分析音视频内容,体验用大模型做音视频笔记、整理会议记录。

通义听悟85
查看详情 通义听悟

前置条件:启用必要的 Intents

为了让机器人能够接收到成员状态更新的事件,您需要在机器人代码和 Discord 开发者门户中启用特定的 Intents(意图)。这是 Discord API 设计中一个重要的权限控制机制。

  1. 在代码中启用 Intents: 您需要启用 discord.Intents.members 和 discord.Intents.presences。

    import discord
    
    # 启用所需的Intents
    intents = discord.Intents.default()
    intents.members = True    # 允许机器人接收成员相关事件
    intents.presences = True  # 允许机器人接收成员在线状态相关事件
    
    client = discord.Client(intents=intents)
    登录后复制
  2. 在 Discord 开发者门户配置: 登录 Discord Developer Portal,选择您的机器人应用,进入“Bot”页面。在“Privileged Gateway Intents”部分,确保 PRESENCE INTENT 和 SERVER MEMBERS INTENT 都已启用。如果未启用,机器人将无法接收到相应的事件。

实现用户状态变化检测与通知

下面我们将通过一个具体的代码示例,展示如何利用 on_member_update() 事件来检测指定用户的状态变化,并向特定频道发送通知。

import discord
import os

# 1. 启用所需的Intents
intents = discord.Intents.default()
intents.members = True    # 允许机器人接收成员相关事件
intents.presences = True  # 允许机器人接收成员在线状态相关事件

client = discord.Client(intents=intents)

# 配置您的机器人Token
# 建议将Token存储在环境变量中,以提高安全性
BOT_TOKEN = os.getenv("DISCORD_BOT_TOKEN")

# 配置要监听的成员ID和通知频道ID
TARGET_MEMBER_ID = 123456789012345678  # 替换为要监听的Discord用户ID
NOTIFICATION_CHANNEL_ID = 987654321098765432 # 替换为要发送通知的频道ID

@client.event
async def on_ready():
    """机器人启动时触发的事件"""
    print(f'机器人已上线:{client.user}')
    # 尝试获取通知频道,确保其存在
    channel = client.get_channel(NOTIFICATION_CHANNEL_ID)
    if channel:
        print(f"通知频道 '{channel.name}' (ID: {channel.id}) 已找到。")
    else:
        print(f"警告:无法找到ID为 {NOTIFICATION_CHANNEL_ID} 的通知频道。请检查ID是否正确且机器人有访问权限。")

@client.event
async def on_member_update(before: discord.Member, after: discord.Member):
    """
    当服务器成员信息更新时触发的事件。
    包括状态、昵称、角色等变化。
    """
    # 2. 检查是否是目标成员
    if after.id == TARGET_MEMBER_ID:
        # 3. 检查状态是否发生变化
        if before.status != after.status:
            print(f'{after.display_name} 的状态从 {before.status} 变为 {after.status}')

            # 4. 获取通知频道并发送消息
            channel = client.get_channel(NOTIFICATION_CHANNEL_ID)
            if channel:
                # 状态枚举 discord.Status 包含 online, offline, idle, dnd (勿扰) 等
                status_map = {
                    discord.Status.online: "在线",
                    discord.Status.offline: "离线",
                    discord.Status.idle: "挂机",
                    discord.Status.dnd: "勿扰",
                    discord.Status.invisible: "隐身" # 隐身状态也会被视为offline
                }

                before_status_text = status_map.get(before.status, str(before.status))
                after_status_text = status_map.get(after.status, str(after.status))

                message = f"**{after.display_name}** 的状态已更新:从 `{before_status_text}` 变为 `{after_status_text}`。"
                await channel.send(message)
            else:
                print(f"无法向频道 {NOTIFICATION_CHANNEL_ID} 发送消息:频道未找到或机器人无权限。")

# 运行机器人
if __name__ == "__main__":
    if not BOT_TOKEN:
        print("错误:未设置 DISCORD_BOT_TOKEN 环境变量。请在运行前设置。")
    else:
        client.run(BOT_TOKEN)
登录后复制

代码解析:

  1. Intents 配置:在 discord.Client 初始化时,通过 intents=intents 传入启用了 members 和 presences 的 Intents 对象。
  2. 目标成员和频道:TARGET_MEMBER_ID 和 NOTIFICATION_CHANNEL_ID 需要替换为实际的 Discord 用户ID和频道ID。
  3. on_member_update 事件:当任何成员信息更新时,此协程都会被调用。
  4. 成员ID检查:if after.id == TARGET_MEMBER_ID: 确保我们只处理特定成员的更新。
  5. 状态变化检查:if before.status != after.status: 是检测用户状态是否发生变化的关键。before.status 和 after.status 都是 discord.Status 枚举类型。
  6. 获取频道:client.get_channel(NOTIFICATION_CHANNEL_ID) 用于获取目标通知频道对象。
  7. 发送消息:await channel.send(message) 将通知消息发送到指定频道。
  8. 状态映射:status_map 提供了一个将 discord.Status 枚举值转换为更友好的中文描述的示例。

注意事项

  • Intents 配置的双重检查:确保您的机器人代码和 Discord 开发者门户中的 PRESENCE INTENT 和 SERVER MEMBERS INTENT 都已启用。任何一方未启用都会导致机器人无法接收到相应的事件。
  • 机器人权限管理:确保您的机器人在目标服务器中拥有足够的权限:
    • 读取消息/查看频道:以便获取频道对象。
    • 发送消息:以便在频道中发送通知。
    • 读取成员:这是 SERVER MEMBERS INTENT 的一部分,确保机器人可以访问成员列表和属性。
    • 读取在线状态:这是 PRESENCE INTENT 的一部分,确保机器人可以接收状态更新。
  • 状态枚举 discord.Status:discord.Status 枚举包含 online(在线)、offline(离线)、idle(挂机)、dnd(勿扰)和 invisible(隐身)。请注意,invisible 在很多情况下会被 Discord API 视为 offline。
  • 错误处理与健壮性:在实际应用中,您可能需要添加更完善的错误处理,例如当 client.get_channel() 返回 None 时,或者发送消息失败时。
  • 大型服务器的性能考量:对于拥有大量成员的服务器,频繁的 on_member_update 事件可能会对机器人性能造成一定影响。如果只需要监听少数特定用户,可以在事件处理函数开头尽快过滤掉不相关的用户。

总结

通过本教程,您应该已经掌握了如何使用 Discord.py 的 on_member_update() 事件来监听服务器成员的状态变化,并向指定频道发送通知。记住,正确配置 Intents 是实现此功能的关键前提。遵循这些步骤,您可以构建出响应用户活动、功能强大的 Discord 机器人。

以上就是Discord.py 教程:监听用户状态变化并发送通知消息的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号