Discord.py 封禁/解封Slash命令Cog报错求助
Discord机器人Ban/Unban命令报错排查
问题描述
开发带有moderation cog的Discord机器人,添加ban和unban命令后无法运行。已将commands.slash_command替换为client.tree.command,但报错提示回调函数ban.ban中的reason参数缺少类型注解。
报错信息
Traceback (most recent call last): File "C:\Users\playe\PycharmProjects\pythonProject3\cogs\ban.py", line 8, in <module> class ban(commands.Cog): File "C:\Users\playe\PycharmProjects\pythonProject3\cogs\ban.py", line 12, in ban @client.tree.command(name="ban", description="Bans a member from the server.") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\playe\PycharmProjects\pythonProject3\.venv\Lib\site-packages\discord\app_commands\tree.py", line 887, in decorator command = Command( ^^^^^^^^ File "C:\Users\playe\PycharmProjects\pythonProject3\.venv\Lib\site-packages\discord\app_commands\commands.py", line 666, in __init__ self._params: Dict[str, CommandParameter] = _extract_parameters_from_callback(callback, callback.__globals__) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\playe\PycharmProjects\pythonProject3\.venv\Lib\site-packages\discord\app_commands\commands.py", line 371, in _extract_parameters_from_callback raise TypeError(f'parameter {parameter.name!r} is missing a type annotation in callback {func.__qualname__!r}') TypeError: parameter 'reason' is missing a type annotation in callback 'ban.ban' Process finished with exit code 1
修复方案
- 给
reason参数添加类型注解:Discord的app_commands(即tree.command)要求所有命令参数必须明确标注类型,包括可选参数。 - 移除cog内重复的Bot实例:cog不需要自己创建
commands.Bot对象,应使用初始化时传入的self.bot。 - 替换命令注册的Bot实例:将cog中的
client.tree.command改为self.bot.tree.command,确保使用主文件的Bot实例注册命令。 - 修正主文件的cog加载方式:主文件应通过
load_extension加载cog,而非直接调用类。
修正后的代码
主命令文件
import discord from discord.ext import commands intents = discord.Intents.default() intents.members = True # 监听on_member_join需要此权限 client = commands.Bot(intents=intents) @client.event async def on_ready(): print("Move Move Move") # 同步命令到Discord(全局同步,测试可用guild参数指定服务器) await client.tree.sync() # 加载ban cog client.load_extension("cogs.ban") client.run("你的机器人Token")
Ban Cog文件
import discord from discord.ext import commands class Ban(commands.Cog): def __init__(self, bot): self.bot = bot @self.bot.tree.command(name="ban", description="将成员从服务器封禁") @commands.has_permissions(ban_members=True) async def ban(self, ctx, member: discord.Member, reason: str = None): """将成员从服务器封禁 Args: ctx: 命令上下文 member: 要封禁的成员 reason: 封禁理由,可选,默认为None """ if member == ctx.author: await ctx.respond("你不能封禁自己!") return if member == ctx.guild.owner: await ctx.respond("我不能封禁服务器所有者!") return if member.top_role >= ctx.author.top_role: await ctx.respond("你不能封禁角色等级比你高的成员!") return try: await member.ban(reason=reason) await ctx.respond(f"{member} 已被封禁!") except discord.HTTPException as e: await ctx.respond(f"封禁 {member} 失败。错误:{e}") @self.bot.tree.command(name="unban", description="解除成员的封禁") @commands.has_permissions(ban_members=True) async def unban(self, ctx, user: discord.User, *, reason: str = None): """解除成员的封禁 Args: ctx: 命令上下文 user: 要解除封禁的用户(可使用ID) reason: 解封理由,可选,默认为None """ try: guild = ctx.guild banned_users = await guild.bans() target = [entry for entry in banned_users if entry.user == user] if not target: await ctx.respond(f"{user} 没有被封禁在此服务器!") return await guild.unban(user, reason=reason) await ctx.respond(f"{user} 已被解封!") except discord.HTTPException as e: await ctx.respond(f"解封 {user} 失败。错误:{e}") def setup(bot): bot.add_cog(Ban(bot))
内容的提问来源于stack exchange,提问作者Rstarks
相关产品推荐
相关产品推荐

