Discord Bot定时向用户发送私信失败无报错问题求助
问题排查与修复方案
已知错误点
- 文件读取语法错误:代码中
open("users.json" "r")两个参数之间缺少逗号,正确写法为open("users.json", "r"),该语法错误会直接导致代码无法运行。 fetch_user参数不匹配:client.fetch_user()仅接受用户的数字雪花ID(纯数字的唯一用户标识)作为入参,但你的JSON文件中存储的是用户名#识别码格式的用户标签,参数无效会直接抛出异常。- Task异常被默认吞没:discord.py的
tasks.loop默认不会将未捕获的异常输出到控制台,因此你看不到任何报错信息。 - 可能缺少必要权限:当前Discord API要求开发者手动在后台开启
Server Members Intent特权网关权限,否则无法正常获取非缓存用户信息、发送私信。
修复步骤
- 首先给循环添加异常捕获,方便定位问题,修改后的
dm_loop代码如下:
import traceback import json from discord import HTTPException, Forbidden, NotFound @tasks.loop(seconds=10) async def dm_loop(): # 修复open参数缺少逗号的问题 with open("users.json", "r") as file: users = json.load(file) for stgru in users: for user_tag in users[stgru]: try: # 优先通过用户标签在共同服务器中查找用户 user = None for guild in client.guilds: member = guild.get_member_named(user_tag) if member: user = member break if not user: print(f"未找到对应用户:{user_tag}") continue await user.send("hello") print(f"消息已发送至:{user_tag}") except NotFound: print(f"错误:用户{user_tag}不存在") except Forbidden: print(f"错误:无权限向{user_tag}发送私信(用户可能关闭了陌生人私信,或Bot已被对方拉黑)") except HTTPException as e: print(f"错误:向{user_tag}发送消息失败,接口返回:{e}") except Exception as e: print(f"处理用户{user_tag}时出现未知错误:") traceback.print_exc()
- (推荐)修改
users.json存储内容:将所有用户名#识别码替换为对应用户的数字雪花ID,相比用户标签,ID是永久唯一的,查询效率也更高。替换后查找用户的代码可以简化为:
# 入参为字符串格式的ID需要先转整数 user = await client.fetch_user(int(user_id))
- 开启必要的网关权限:
- 打开Discord开发者后台,进入你的Bot应用页面
- 切换到「Bot」选项卡,下拉找到
Privileged Gateway Intents板块,开启Server Members Intent和Message Content Intent - 代码初始化Client时声明对应的权限:
import discord intents = discord.Intents.default() intents.members = True intents.message_content = True # 如果使用commands.Bot,初始化逻辑同理 client = discord.Client(intents=intents) - 确认循环启动逻辑:在
on_ready中启动循环前先判断是否已经运行,避免重复启动:
@client.event async def on_ready(): if not dm_loop.is_running(): dm_loop.start() print(f"Bot已登录,当前账号:{client.user}")
注意事项
短时间内批量发送私信非常容易被Discord判定为垃圾消息行为,导致Bot账号被限制,正式使用时请拉长发送间隔、添加发送限速逻辑。
内容的提问来源于stack exchange,提问作者banachtarski
相关产品推荐
相关产品推荐

