You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

discord.py通过ID获取User对象失败?解决spam命令报错问题

解决Discord机器人发送DM Ping时的AttributeError问题

看来你的机器人突然罢工是因为client.get_user()返回了None,导致你访问user.name时触发了属性错误。我来给你拆解问题原因和修复方案:

为什么会出现这个问题?

  1. 缓存丢失:Heroku的免费实例会定期休眠重启,重启后机器人的本地用户缓存会被清空,get_user()只能从缓存里取数据,自然找不到用户返回None。
  2. 用户不在同一服务器:如果你的机器人和目标用户没有共享任何服务器,get_user()也会返回None——Discord机器人默认只能获取自己所在服务器内的用户缓存。

具体修复步骤

1. 替换get_user为fetch_user

fetch_user()会直接调用Discord API获取用户信息,不依赖本地缓存,在Heroku这种经常重启的环境里更可靠。而且它还能帮你捕获“用户不存在”的情况。

2. 增加异常处理

不管是找不到用户,还是发送DM失败(比如用户关了陌生人消息),都要加异常处理,避免整个命令崩溃。

3. 先验证用户存在再操作

在使用user对象的任何属性前,先确认它不是None,或者直接用try-except捕获API调用的异常。

修改后的可运行代码

from discord.ext import commands
import discord

token = 'MyBotTokenHere'
prefix = '.'
client = commands.Bot(command_prefix=prefix)
client.remove_command("help")

@client.event
async def on_ready():
    print('Ready')

@client.command()
async def spam(ctx, id1: int, num: int):
    # 先尝试通过API获取用户,处理找不到的情况
    try:
        user = await client.fetch_user(id1)
    except discord.NotFound:
        await ctx.send("❌ 找不到该用户,请检查用户ID是否正确,且机器人和用户在同一服务器!")
        return

    await ctx.send(f'✅ 开始给{user.name}发送{num}次Ping消息!')
    
    successful_pings = 0
    for _ in range(num):
        try:
            await user.send(f'<@{id1}>')
            successful_pings += 1
        except discord.Forbidden:
            await ctx.send(f'⚠️ 无法给{user.name}发送DM,可能用户关闭了陌生人消息或屏蔽了机器人!')
            break
        except Exception as e:
            await ctx.send(f'❌ 发送消息时出错:{str(e)}')
            break

    await ctx.send(f'🏁 Ping任务完成!成功发送{successful_pings}条消息(共请求{num}次)')

client.run(token)

额外提醒

  • 必须保证机器人和目标用户在至少一个共同服务器里,否则即使能获取用户信息,也发不了DM——这是Discord的安全限制。
  • 不要一次性发送太多Ping,避免触发Discord的API速率限制,轻则机器人被限流,重则被封禁。
  • Heroku重启后缓存清空是常态,以后尽量用fetch_user代替get_user来获取用户信息。

内容的提问来源于stack exchange,提问作者PythonSnek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 17:57:57