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

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特权网关权限,否则无法正常获取非缓存用户信息、发送私信。

修复步骤

  1. 首先给循环添加异常捕获,方便定位问题,修改后的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()
  1. (推荐)修改users.json存储内容:将所有用户名#识别码替换为对应用户的数字雪花ID,相比用户标签,ID是永久唯一的,查询效率也更高。替换后查找用户的代码可以简化为:
# 入参为字符串格式的ID需要先转整数
user = await client.fetch_user(int(user_id))
  1. 开启必要的网关权限:
    • 打开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)
    
  2. 确认循环启动逻辑:在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 11:18:01