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

Discord.py:用户无ban权限时发送提示而非报错的实现方案

解决Discord机器人Ban指令的权限错误提示问题

你当前用的@commands.has_permissions装饰器会直接抛出MissingPermissions异常,根本走不到你写的except逻辑里——因为异常是在命令执行前就触发的。要实现自定义提示,有两种实用思路,分情况给你说明:

一、手动检查权限(更灵活可控)

直接放弃@commands.has_permissions装饰器,在命令内部逐一检查所有权限场景,这样能精准控制每种情况的提示内容:

@bot.tree.command(name='ban', description='Ban a user. (w/ perms only)')
async def ban(ctx, member: discord.Member, *, reason: str = "No reason provided"):
    # 检查发起命令的用户有没有ban权限
    if not ctx.user.guild_permissions.ban_members:
        await ctx.response.send_message("你没有封禁成员的权限!", ephemeral=True)
        return
    
    # 检查机器人自己有没有ban权限
    if not ctx.guild.me.guild_permissions.ban_members:
        await ctx.response.send_message("我没有封禁成员的权限,请给我分配对应权限!", ephemeral=True)
        return
    
    # 检查目标是不是管理员,或者权限等级比机器人高
    if member.guild_permissions.administrator:
        await ctx.response.send_message("无法封禁管理员成员!", ephemeral=True)
        return
    if member.top_role >= ctx.guild.me.top_role:
        await ctx.response.send_message("我的权限等级不够,封不了这个成员!", ephemeral=True)
        return
    
    # 所有检查通过,执行封禁
    try:
        await member.ban(reason=reason)
        await ctx.response.send_message(f"{member.name} 已被封禁,原因:{reason}")
    except Exception as e:
        await ctx.response.send_message(f"封禁失败:{str(e)}")

二、全局错误处理器(适合多命令场景)

如果想保留装饰器,可以给机器人加个全局错误捕获器,统一处理所有命令的权限异常:

# 全局错误处理函数
@bot.tree.error
async def on_app_command_error(interaction: discord.Interaction, error: discord.app_commands.AppCommandError):
    if isinstance(error, discord.app_commands.MissingPermissions):
        await interaction.response.send_message("你没有执行这个命令的权限!", ephemeral=True)
    elif isinstance(error, discord.app_commands.BotMissingPermissions):
        await interaction.response.send_message("我权限不够,干不了这事!", ephemeral=True)
    elif isinstance(error, discord.Forbidden):
        await interaction.response.send_message("封不了这人,要么对方是管理员,要么我权限不够!", ephemeral=True)
    else:
        # 未知错误打日志,同时给用户提示
        print(f"未知错误:{error}")
        await interaction.response.send_message("执行命令时出问题了!", ephemeral=True)

# 带装饰器的原命令
@bot.tree.command(name='ban', description='Ban a user. (w/ perms only)')
@discord.app_commands.checks.has_permissions(ban_members=True)
@discord.app_commands.checks.bot_has_permissions(ban_members=True)
async def ban(ctx, member: discord.Member, *, reason: str = "No reason provided"):
    try:
        await member.ban(reason=reason)
        await ctx.response.send_message(f"{member.name} 已被封禁,原因:{reason}")
    except discord.Forbidden:
        await ctx.response.send_message("无法封禁该成员,可能对方是管理员或我的权限不足!", ephemeral=True)

小提示

  • ephemeral=True:设置消息仅命令发起者能看到,避免打扰其他人
  • 手动检查时要按顺序来:先查用户权限,再查机器人权限,最后查目标成员的权限等级,确保所有边界情况都覆盖到

内容的提问来源于stack exchange,提问作者As2Bax

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 06:15:26