Discord.py unban命令仅支持ID无法通过@用户名解封如何修复
问题原因
当前代码直接对传入的member参数执行int(member)强转,仅支持传入纯数字格式的用户ID:
- 传入
@用户格式的提及内容时,实际收到的字符串是<@用户ID>或<@!用户ID>格式,包含非数字字符,强转int会直接抛出异常 - 被封禁用户不在服务器正常成员列表内,discord.py默认的参数转换器不会自动匹配封禁列表中的用户,因此无法直接把提及内容映射为对应ID
修复方案
方案1:最小改动快速修复
仅新增ID提取逻辑,兼容纯ID、@提及两种传参方式,不改动原有代码结构:
import re # 放在文件顶部导入区即可 @commands.command() @commands.guild_only() @commands.has_guild_permissions(ban_members=True) async def unban(self, ctx, member, *, reason="xyz"): # 过滤传入字符串的非数字字符,自动提取@提及中包裹的用户ID user_id = int(re.sub(r'[^0-9]', '', member)) member = await self.bot.fetch_user(user_id) await ctx.guild.unban(member, reason=reason) await ctx.channel.send(f"***已解封{member.mention},原因:{reason}***")
注意:该方案不支持直接输入用户名匹配,传入非用户相关的含数字字符串时会出现解析错误。
方案2:完整版兼容实现
支持纯ID、@提及、用户名/全局显示名三种传参方式,自动校验用户是否在封禁列表,鲁棒性更强:
import discord from discord.ext import commands @commands.command() @commands.guild_only() @commands.has_guild_permissions(ban_members=True) async def unban(self, ctx, member, *, reason="xyz"): # 拉取当前服务器全量封禁记录 ban_list = [entry async for entry in ctx.guild.bans()] target = None # 优先尝试解析ID、@提及、用户名#判别式格式 try: parsed_user = await commands.UserConverter().convert(ctx, member) # 校验解析出的用户是否在封禁列表中 if any(ban_entry.user.id == parsed_user.id for ban_entry in ban_list): target = parsed_user except commands.UserNotFound: # 解析失败时,遍历封禁列表匹配用户名/全局显示名 for ban_entry in ban_list: clean_input = member.strip().lower() if (ban_entry.user.name.lower() == clean_input or (ban_entry.user.global_name and ban_entry.user.global_name.lower() == clean_input)): target = ban_entry.user break if not target: return await ctx.send("未找到对应封禁用户,请传入正确的用户ID、@提及用户或准确用户名") await ctx.guild.unban(target, reason=reason) await ctx.send(f"***已解封{target.mention},原因:{reason}***")
内容的提问来源于stack exchange,提问作者ProgramowanskoCompany
相关产品推荐
相关产品推荐

