Discord自机器人登录无on_ready输出及dmall命令故障求助
问题排查与修复方案
嘿,我帮你梳理下代码里的几个关键问题,这些就是导致on_ready事件不触发和dmall命令故障的核心原因:
1. 事件与命令的注册顺序完全错误
你把@client.event和@client.command装饰的函数放在了Bot_run()函数内部,而且还在client.run()之后定义——Discord.py的规则是:所有事件监听和命令必须在客户端启动(client.run())之前完成注册,不然客户端启动时根本识别不到这些代码,自然不会触发on_ready,也无法响应dmall命令。
2. 未配置Discord强制要求的Intents权限
现在Discord API的权限管控很严格,要获取服务器成员列表(也就是ctx.guild.members),必须手动开启成员意图(Members Intent),不然你拿到的成员列表会是空的,dmall命令等于没干活。另外,读取命令内容也需要开启message_content权限。
3. dmall命令的逻辑存在明显bug
- 你把
await ctx.message.delete()放在了循环里,第一次循环删完消息后,后面的循环再执行这个语句就会报错,因为消息已经不存在了; - 代码没有跳过机器人自身,会尝试给自己发消息,完全是无效操作;
- 没有添加权限限制,随便哪个用户都能调用这个命令,很容易引发滥用问题。
修复后的完整代码
import discord from discord.ext import commands import requests # 先配置Intents,这是当前Discord机器人的必备操作 intents = discord.Intents.default() intents.members = True # 必须开启才能获取服务器成员列表 intents.message_content = True # 要读取命令内容就得开启这个 # 初始化客户端,指定命令前缀和配置好的intents client = commands.Bot(command_prefix="!", intents=intents) # 事件必须在client.run()之前定义 @client.event async def on_ready(): print('status : online') print(f'当前登录账号: {client.user}') # 命令也得在client.run()之前定义 @client.command() @commands.has_permissions(administrator=True) # 仅限管理员使用,防止命令被滥用 async def dmall(ctx, *, message): # 先删除触发命令的消息,只执行一次即可 await ctx.message.delete() success_count = 0 fail_count = 0 # 遍历服务器成员,跳过机器人账号 for member in ctx.guild.members: if member.bot: continue try: await member.send(message) print(f'已发送DM给: {member.name}') success_count += 1 except Exception as e: print(f'发送DM给{member.name}失败 | 错误原因: {str(e)}') fail_count += 1 # 给管理员发送结果通知(10秒后自动删除) await ctx.send(f'DM发送完成:成功{success_count}条,失败{fail_count}条', delete_after=10) def Bot_run(): Token = input("DISCORD TOKEN : ") request_url = "https://canary.discordapp.com/api/v6/users/@me" req = requests.get(request_url, headers={'authorization': Token}) if req.status_code == 401: print(f"The token : {Token} is invalid") input("press enter to close") exit() if req.status_code == 200: print(f"The token : {Token} is valid") # 重要提醒:用bot=False登录是普通用户账号,Discord官方禁止这种自机器人,可能会导致账号被封禁! client.run(Token, bot=False) if __name__ == "__main__": Bot_run()
额外必看注意事项
- 除了代码里配置Intents,你还得去Discord开发者门户找到你的应用,进入机器人页面,手动开启"Server Members Intent"和"Message Content Intent",不然代码里的Intents配置不会生效;
- 关于
bot=False:Discord的服务条款明确禁止使用普通用户账号作为机器人运行,一旦被检测到很可能会封禁账号,建议你创建一个正式的机器人账号,改用bot=True登录; - 如果修复后仍有问题,先检查你的Token是否正确,以及网络环境能否正常连接Discord的API。
内容的提问来源于stack exchange,提问作者Ardil Mc
相关产品推荐
相关产品推荐

