Permission Check Discord.py Bot

Euphony picture Euphony · Oct 1, 2018 · Viewed 12.5k times · Source

I am working on a discord bot for basic moderation which does kick, ban and mute for now at least. But the problem is other members can use it too. I want only a few specified role who can use it.

Don't want to work on it depending on the @role either because the name of the roles across different servers aren't the same. Also wanting to keep the bot as simple as possible.

Now, I started out as this:

@client.command(name='ban')
async def mod_ban(member: discord.User):
    try:
        await client.ban(member, delete_message_days=0)
        await client.say('**{0}** has been banned.'.format(str(member)))
    except Exception as error:
        await client.say(error)

But any member can use the commands then. So, tried follow this one = Permission System for Discord.py Bot and ended up with this:

@client.command(name='ban')
async def mod_ban(context, member: discord.User):
    if context.message.author.server_premission.administrator:
        try:
            await client.ban(member, delete_message_days=0)
            await client.say('**{0}** has been banned.'.format(str(member)))
        except Exception as error:
            await client.say(error)
    else:
        await client.say('Looks like you don\'t have the perm.')

Which lands me with this error: ;-;

raise MissingRequiredArgument('{0.name} is a required argument that is missing.'.format(param))
discord.ext.commands.errors.MissingRequiredArgument: member is a required argument that is missing.

Also, besides context.message.author.server_premission.administrator I don't only want the roles with Admin perm to use this command. I also want a few other roles with have few perms like manage message, manage roles etc. to use to command too.

Thanks in advance for the help! Also, sorry if I've missed anything stupid or silly ;-;

Answer

Patrick Haugh picture Patrick Haugh · Oct 1, 2018

You aren't passing the context into the coroutine in your second example (and as @Andrei suggests, you can only ban members):

@client.command(name='ban', pass_context=True)
async def mod_ban(context, member: discord.Member):
    ...

Also, I should probably update my answer to that question. In the context of commands, you can use the very powerful checks built into discord.ext.commands to do a lot of this for you. has_permissions does exactly what you're looking for, validating that the user has any of the necessary permissions.

from discord.ext.commands import has_permissions, CheckFailure

@client.command(name='ban', pass_context=true)
@has_permissions(administrator=True, manage_messages=True, manage_roles=True)
async def mod_ban(ctx, member: discord.Member):        
    await client.ban(member, delete_message_days=0)
    await client.say('**{0}** has been banned.'.format(str(member)))

@mod_ban.error
async def mod_ban_error(error, ctx):
    if isinstance(error, CheckFailure):
        await client.send_message(ctx.message.channel, "Looks like you don't have the perm.")