S_cripted
S_cripted

Reputation: 33

How to restrict a certain role from using a command (discord.py)

I've already seen the variant where you allow a certain role to use a command. However, I'm trying to achieve the exact opposite: How to disallow a certain role from using a command.

I have searched around stack overflow and found no answer, nor did I found an answer on the official discord.py documentation. Any sort of help is appreciated.

Upvotes: 3

Views: 1414

Answers (2)

henry groves
henry groves

Reputation: 887

author.roles returns a list of discord.Role so just check if the role you specify is contained in that list, and if so, exit the command early.

Using Role Id (Preferred)

@bot.command()
async def command_without_specific_role(ctx):
    if role_id in [role.id for role in ctx.author.roles]:
        return

    ...

Using Role Name

@bot.command()
async def command_without_specific_role(ctx):
    if role_name in [role.name for role in ctx.author.roles]:
        return

    ...

Upvotes: 5

codeofandrin
codeofandrin

Reputation: 1557

Check inside command

@bot.command()
async def hello(ctx: commands.Context):
    blacklisted_role = ctx.guild.get_role(ID)

    if not any(role == blacklisted_role for role in ctx.author.roles):
        await ctx.send("world!")

Own Decorator

A more elegant way is to create your own decorator. It's more like the opposite of has_any_role.

from discord.ext import commands

def has_not_any_role(*roles):
    async def extended_check(ctx):
        return not any(role.id in roles for role in ctx.author.roles)

    return commands.check(extended_check)

@bot.command()
@has_not_any_role(492212595072434186)
async def hello(ctx: commands.Context):
    await ctx.send("world!")

If extended_check returns True the message will be sent. If it return False it throws a discord.ext.commands.errors.CheckFailure error which then can be catched in on_command_error.


References:

Upvotes: 2

Related Questions