Discord机器人跨服务器解封用户遇Unknown Member错误求助
问题:Discord机器人批量解封用户时触发404错误
我想让Discord机器人将指定ID的用户从所有它加入的服务器中解封,但输入被封禁用户ID执行命令时出现以下错误:
Traceback (most recent call last): File "C:\Users\Shadow\AppData\Local\Programs\Python\Python311\Lib\site-packages\discord\bot.py", line 1114, in invoke_application_command await ctx.command.invoke(ctx) File "C:\Users\Shadow\AppData\Local\Programs\Python\Python311\Lib\site-packages\discord\commands\core.py", line 375, in invoke await injected(ctx) File "C:\Users\Shadow\AppData\Local\Programs\Python\Python311\Lib\site-packages\discord\commands\core.py", line 132, in wrapped raise ApplicationCommandInvokeError(exc) from exc discord.errors.ApplicationCommandInvokeError: Application Command raised an exception: NotFound: 404 Not Found (error code: 10007): Unknown Member
我尝试过这段代码片段:
async for guild in self.bot.fetch_guilds(): userr = await guild.fetch_member(id) if userr in guild.bans: await guild.unban(userr) await ctx.send("Unbanned the user.")
我的完整命令代码如下:
@commands.slash_command(name="unban", description="When you have specified the user name and hashtag the bot will unban that user from all servers.") async def unban(self, ctx, id: discord.SlashCommandOptionType.string): async for guild in self.bot.fetch_guilds(): try: user = await guild.fetch_member(ctx.author.id) except discord.NotFound: continue head_admin = discord.utils.get(guild.roles, name="Head Admin") developer = discord.utils.get(guild.roles, name="Developer") owner = discord.utils.get(guild.roles, name="Owner") if head_admin or developer or owner in user.roles: async for guild in self.bot.fetch_guilds(): userr = await guild.fetch_member(id) if userr in guild.bans: await guild.unban(userr) await ctx.send("Unbanned the user.")
问题分析与修复方案
核心问题点
- 权限检查逻辑错误:第一个循环结束后
guild变量仅保留最后一个服务器,后续权限检查只针对该服务器;且head_admin or developer or owner in user.roles的判断逻辑完全错误,实际是判断前两个角色是否存在,而非用户是否拥有对应角色。 - 获取用户方式错误:
guild.fetch_member(id)只能获取当前服务器的成员,被封禁用户不在成员列表中,必然触发404错误。 - 封禁状态判断错误:
if userr in guild.bans无法正确判断用户是否被封禁,需要通过专用API检查或直接尝试解封。 - 循环与反馈逻辑混乱:原代码会在每个服务器解封成功后重复发送消息,且未处理权限不足等异常情况。
修正后的完整代码
@commands.slash_command(name="unban", description="将指定ID的用户从所有机器人加入的服务器中解封") async def unban(self, ctx, user_id: str): # 验证执行命令的用户权限(基于当前服务器角色) required_roles = {"Head Admin", "Developer", "Owner"} has_permission = any(role.name in required_roles for role in ctx.author.roles) if not has_permission: await ctx.send("你没有执行该命令的权限") return # 转换用户ID为整数,验证格式有效性 try: target_user_id = int(user_id) except ValueError: await ctx.send("请输入有效的用户ID") return # 获取目标用户对象(无需依赖服务器成员列表) try: target_user = await self.bot.fetch_user(target_user_id) except discord.NotFound: await ctx.send("找不到该用户") return unbanned_guilds = [] failed_guilds = [] async for guild in self.bot.fetch_guilds(): # 先检查机器人是否有解封权限 if not guild.me.guild_permissions.ban_members: failed_guilds.append(f"{guild.name}(机器人无解封权限)") continue try: # 直接尝试解封,无需提前检查封禁状态 await guild.unban( target_user, reason=f"批量解封操作,发起者:{ctx.author.name}({ctx.author.id})" ) unbanned_guilds.append(guild.name) except discord.NotFound: # 用户未被封禁,跳过 continue except discord.Forbidden: failed_guilds.append(f"{guild.name}(机器人权限不足)") except Exception as e: failed_guilds.append(f"{guild.name}(错误:{str(e)})") # 汇总结果发送给用户 result_msg = "批量解封操作完成\n" if unbanned_guilds: result_msg += f"✅ 已成功解封的服务器:\n- {chr(10).join(unbanned_guilds)}\n" if failed_guilds: result_msg += f"❌ 未成功解封的服务器:\n- {chr(10).join(failed_guilds)}\n" await ctx.send(result_msg)
关键改进说明
- 权限验证优化:直接检查执行命令用户在当前服务器的角色,逻辑更合理。
- 用户获取方式修正:使用
bot.fetch_user()获取用户对象,不依赖服务器成员列表,避免被封禁用户的404错误。 - 异常处理完善:区分不同错误类型,记录失败原因,提升体验。
- 结果汇总反馈:统一发送操作结果,避免重复发送消息,让用户清晰了解执行情况。
内容的提问来源于stack exchange,提问作者pixelworldrp
相关产品推荐
相关产品推荐

