Skip to content

Instantly share code, notes, and snippets.

@zekroTJA
Last active June 12, 2019 23:36
Show Gist options
  • Save zekroTJA/3cbca5f1277b7f52f1d8c31e657fee0a to your computer and use it in GitHub Desktop.
Save zekroTJA/3cbca5f1277b7f52f1d8c31e657fee0a to your computer and use it in GitHub Desktop.
discord.py - Permission system

0 - /settings.json

First of all, you can define your roles, you want to set for each specific level, in a external JSON file to change the settings without editing the source code.

{
    "perms":
    {
        "lvl1": ["Supporter", "Rolle2"],
        "lvl2": ["Admin", "Moderator"],
        "lvl3": ["Owner"]
    }
}

1 - /perms.py

Let's create a new class in root directory (or somewhere you want...)

import json  # for json parsing


# Open the json file with the role settings and pars it with JSON.
with open("settings.json") as f:
    settings = json.load(f)


# Save json properties into variables for better handling.
lvl1 = settings["perms"]["lvl1"]
lvl2 = settings["perms"]["lvl2"]
lvl3 = settings["perms"]["lvl3"]


def get(memb):
    lvl = [0]
    # Tests if the role in roles is existent in one of the role name arrays
    # and adds the level of the role array to the "lvl" integer array.
    # HINT: For better safety, you can set role ID's in JSON and here
    # instead of the role names.
    for r in memb.roles:
        if r.name in lvl3:
            lvl.append(3)
        elif r.name in lvl2:
            lvl.append(2)
        elif r.name in lvl1:
            lvl.append(1)
    print(lvl, max(lvl))
    # Returns the maximum level in "lvl" array
    # EXP: '[0, 1, 1, 2, 1]' -> returns '2'
    return max(lvl)

# Checks in the max role level is bigger than the required level
def check(memb, lvl):
    return get(memb) >= lvl

2 - /commands/cmd_example.py

Now get your commands you want to set a required permission level.

# ...

perm = 1  # minimum required permission level

async def ex(args, message, client, invoke):
    # ...

3 - /main.py

Let's grab your main file and add it to the command parser.

# ...
import perms  # import created perms class to use methods of it

# ...

@client.event
async def on_message(message):
    if message.content.startswith(STATICS.PREFIX):
        invoke = message.content[len(STATICS.PREFIX):].split(" ")[0]
        args = message.content.split(" ")[1:]
        if commands.__contains__(invoke):
            
            # save the command class in a variable for better handling
            cmd = commands[invoke]
            
            # this 'try except' clause is for that case, if you don't want to set
            # a permission level variable in command classes without required
            # permission rules, yo ou just can pass the exception
            try:
                # use check of perms class
                if not perms.check(message.author, cmd.perm):
                    await client.send_message(message.channel, embed=Embed(color=discord.Color.red(), description="You are not allowed to access this command!"))
                    return
                await cmd.ex(args, message, client, invoke)
            except:
                await cmd.ex(args, message, client, invoke)
                pass
                
# ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment