discord.py如何仅通过已知用户名向指定Discord用户发送私信
核心错误原因
你之前尝试的两个方案失败的根本原因是对API入参规则理解错误:
fetch_user()、get_user()两个方法仅接受用户的数字ID作为唯一合法入参,不支持传入用户名#判别器格式的字符串,直接传入该格式字符串会触发参数校验错误,对应你碰到的400错误(错误码50035)、返回None的问题。- Discord官方未开放全局通过「用户名+判别器」直接查询用户对象的公开接口,所有基于该格式信息匹配用户的逻辑,都需要基于机器人所在服务器的成员列表做匹配,不存在完全跳过成员列表匹配的实现方式。你可以使用框架内置的优化查询方法,不需要手动写循环遍历逻辑。
可行实现步骤
1. 前置配置
初始化机器人客户端时必须开启成员意图,否则无法拿到完整的服务器成员缓存:
import discord from discord.utils import get intents = discord.Intents.default() intents.members = True # 开启成员拉取权限 client = discord.Client(intents=intents)
2. 拆分用户名与判别器
把你持有的something#0000格式字符串拆分为独立的用户名、4位判别器两部分:
full_tag = "something#0000" username, discriminator = full_tag.split("#", 1)
3. 匹配目标Member对象
使用框架内置的get()方法匹配目标对象,该方法为C层实现的优化查询,效率远高于手写Python层循环,不需要手动遍历成员列表:
target_member = None # 遍历机器人加入的所有服务器做匹配 for guild in client.guilds: target_member = get(guild.members, name=username, discriminator=discriminator) if target_member: break
提示:如果你明确知道目标用户和机器人共通的服务器ID,可以直接通过
client.get_guild(服务器ID)拿到指定服务器对象后再做成员匹配,不需要遍历所有服务器,查询速度会更快。
4. 发送私信
匹配到对象后直接调用发送方法即可:
if target_member: await target_member.send("这里填写你要发送的私信内容") else: # 未找到用户的兜底逻辑:通常是标签输入错误、用户已退出共通服务器、成员缓存未加载完成 print("目标用户匹配失败")
注意事项
- 不要在机器人刚启动时就执行查询逻辑,此时成员缓存还未加载完成会导致匹配失败,可以在
on_ready事件触发后再执行主动查询逻辑 - Discord正在逐步淘汰旧的
#4位判别器用户名体系,新体系下用户使用全局唯一的无后缀用户名,后续适配新体系时需要把匹配字段改为global_name - 若你后续能拿到目标用户的数字ID,可直接用
client.fetch_user(数字ID)拿到用户对象后调用send()方法发私信,不需要匹配服务器成员,这是效率最高的实现方式。
内容的提问来源于stack exchange,提问作者Eight Rice
相关产品推荐
相关产品推荐

