discord.py中如何实现Discord机器人向指定用户发送DM私信
方案说明
先理清两个核心认知误区
- 你之前接触到的
client.author.send("message")属于上下文记混的写法:author从来不是discord.Client()实例的属性,这类写法的本质是消息事件回调中,从message对象上取发消息的用户(即message.author),对这个用户对象调用send()发私信。 - 你写的示例代码存在两个核心逻辑偏差:一是变量
user = 'example#0000'是纯字符串,根本没有send()方法;二是client.user本身代表机器人自身的账号对象,对这个对象调用send()只会尝试给机器人自己发私信,完全达不到跨用户发消息的效果。
可落地的实现逻辑
discord.py中所有能调用send()发私信的实体,必须是代表真实目标用户的discord.User或discord.Member实例,只要拿到这个实例,直接调用send()就能实现你要的user.send("message")效果,不需要绕弯。
针对你要做的$DM 'discord user' 'content'指令功能,推荐用discord.ext.commands扩展实现,比原生discord.Client的事件监听写法效率高很多:
- 前置配置:需要开启对应意图,才能正常读取指令内容、匹配目标用户
import discord from discord.ext import commands # 加载默认意图,额外开启消息内容读取权限 intents = discord.Intents.default() intents.message_content = True bot = commands.Bot(command_prefix="$", intents=intents) @bot.command() async def DM(ctx, target_user: discord.User, *, msg_content: str): # 框架会自动解析指令中传入的用户ID、@提及、带#tag的用户名,匹配为真实User实例 try: await target_user.send(msg_content) await ctx.reply(f"已成功向用户{target_user}发送私信") except discord.Forbidden: await ctx.reply("发送失败:目标用户关闭了私信权限,或机器人与该用户无共同服务器") bot.run("你的机器人API Token") - 如果你需要手动解析
用户名#tag格式的字符串做匹配,只要遍历机器人缓存的用户列表,匹配用户名和tag完全一致的对象即可:
拿到返回的async def fetch_user_by_tag(tag_str: str): username, tag = tag_str.split("#") for user in bot.users: if user.name == username and user.discriminator == tag: return user # 缓存未命中时可走API接口拉取,需注意调用频率限制 return NoneUser实例后,直接调用实例.send("内容")即可。
常见踩坑提醒
如果机器人和目标用户没有共同所在的服务器,哪怕拿到了用户ID,也大概率无法成功发送私信;另外现在Discord平台的#用户tag已经不再全局唯一,靠tag做匹配可能出现找错用户的情况,优先推荐用用户ID做标识做指令匹配。
内容的提问来源于stack exchange,提问作者Karo
相关产品推荐
相关产品推荐

