Discord.py无法向成员发送私信:'ClientUser'对象缺少'create_dm'属性问题排查
解决Discord.py无法向成员发送私信的问题
你在这里其实绕了个没必要的弯路——根本不需要用message.guild.get_member(message.author.id)来获取消息发送者,这正是触发ClientUser错误的核心原因。
问题根源
当message.author是机器人自身时(虽然你后面有排除判断,但那行代码在获取member之后执行),message.guild.get_member()会返回ClientUser对象,而这个对象没有发送私信所需的create_dm方法。更关键的是:当消息来自服务器频道时,message.author本身就是合法的Member对象,完全可以直接用来发送私信。
修复方案
直接替换你代码里的相关逻辑:
# 移除这行多余的代码 # member = message.guild.get_member(message.author.id) # 直接使用message.author即可 member = message.author # 你同时调用了member.send和message.author.send,会发两次私信,保留一个就行 await member.send(embed=level_up) # 角色修改逻辑保持不变 old_role = discord.utils.get(message.guild.roles, name="Level " + str(level_before)) await member.remove_roles(old_role) await member.add_roles(new_role)
额外优化建议
- 提前过滤机器人消息:把判断机器人的逻辑放在函数最开头,避免不必要的计算和错误触发:
@commands.Cog.listener() async def on_message(self, message): # 先跳过机器人发送的消息,从根源避免后续逻辑异常 if message.author.bot: return # 你的原有业务逻辑...
- 添加私信失败异常处理:有些用户可能关闭了陌生人私信,或者机器人没有权限发送,建议捕获异常做友好提示:
try: await member.send(embed=level_up) except discord.Forbidden: # 在频道内提示用户,或者选择忽略 await message.channel.send(f"@{member.mention} 恭喜你升级到 **Level {level_after}**!但我无法给你发送私信,请检查你的隐私设置哦~")
这样修改后,你不仅能解决当前的AttributeError问题,还能让代码更简洁高效,同时覆盖了潜在的异常场景。
内容的提问来源于stack exchange,提问作者hydroxide
相关产品推荐
相关产品推荐

