Discord机器人发送DM失败:Expected token to be set报错排查
Discord经济系统DM发送错误与解决方案
问题原因
"Expected token to be set for this request, but none was present" 错误核心是Discord API请求未携带有效机器人令牌,常见触发场景:
- 机器人初始化时令牌未正确传入
- 使用了脱离当前机器人上下文的用户对象(比如手动构建的User实例)
- 机器人Intents配置缺失导致无法访问DM相关接口
修复DM发送问题
1. 校验令牌初始化
确保机器人启动时正确传入令牌,以discord.py为例:
import discord from discord.ext import commands # 方式1:构造客户端时传入 intents = discord.Intents.default() intents.message_content = True intents.dm_messages = True bot = commands.Bot(command_prefix="!", intents=intents, token="你的机器人令牌") # 方式2:通过run方法传入 bot.run("你的机器人令牌")
2. 正确获取用户对象
禁止手动创建User实例,必须通过机器人的缓存或API获取:
# 优先从缓存取(更快) user = bot.get_user(target_user_id) # 缓存不存在则调用API获取 if not user: user = await bot.fetch_user(target_user_id) # 发送DM if user: try: await user.send(f"转账完成!金额:{amount},当前余额:{balance}") except discord.Forbidden: print(f"用户 {target_user_id} 关闭了DM或屏蔽了机器人")
3. 启用必要Intents
在Discord开发者门户的「Bot」页面开启Message Content Intent和Direct Messages,代码中同步声明:
intents = discord.Intents.default() intents.message_content = True intents.dm_messages = True
实现错误转发到指定频道
修复错误捕获逻辑,确保即使DM发送失败也能把错误信息转发到指定频道:
import traceback async def handle_transfer_notify(user_id, transfer_info): error_channel_id = 123456789 # 替换为你的错误频道ID error_channel = bot.get_channel(error_channel_id) if not error_channel: error_channel = await bot.fetch_channel(error_channel_id) try: user = await bot.fetch_user(user_id) await user.send(f"转账通知:{transfer_info}") except Exception as e: error_details = ( f"向用户 {user_id} 发送DM失败\n" f"错误类型:{type(e).__name__}\n" f"错误内容:{str(e)}\n" f"完整报错栈:\n```\n{traceback.format_exc()}\n```" ) if error_channel: await error_channel.send(error_details) else: print(f"错误频道未找到,无法转发:{error_details}")
排查小技巧
- 打印
bot.token(只验证是否非空,不要明文输出)确认令牌已加载 - 测试机器人能否向服务器频道发送消息,排除令牌整体失效
- 确认目标用户ID正确,且用户未删除账号或退出服务器
内容的提问来源于stack exchange,提问作者votavl
相关产品推荐
相关产品推荐

