Skip to content

Wall_e Discord.py Coding Tips

Jace Manshadi edited this page Sep 15, 2024 · 3 revisions

1. Text Command Tips

1.1. Text Command Help Message Configurations

Please follow the format below when adding a new help message so that layout is unified across all commands

    @commands.command(
        brief="short help message in main help embed",
        help=(
            'Description of command purpose.\n'
            'Arguments:\n'
            '---argument_1: argument_1 description\n'
            '---argument_2: argument_2 description\n\n'
            'Example:\n'
            '.command_name "foo"\n'
            '.command_name "foo" "bar"\n\n'
        ),
        usage='foo [bar]'
    )
    async def command_name(self, ctx, *args):


1.2. Text Command Privilege Configurations

Role Based Validation

    @commands.has_any_role("role1", "role2")
    async def command_name(self, ctx, *args):

OR

    @commands.has_role("role1")
    async def command_name(self, ctx, *args):

Permission Based Validation

    @commands.has_guild_permissions(administrator=True, manage_roles=True) # this does an AND
    async def command_name(self, ctx, *args):

Customizable Permission Checking

If the above examples don't provide a way for the sort of permission checking you are attempting, you can write your own logic using the below example

    def user_has_perms(ctx):
        return ctx.author.guild_permissions.administrator or ctx.author.guild_permissions.manage_roles

    @commands.check(user_has_perms)
    async def command_name(self, ctx, *args):

2. Slash Command Tips

2.1. Slash Command Help Message Configurations

    @app_commands.command(name="command_name", description="command description")
    @app_commands.describe(argument_name="argument description")
    async def function_name(self, interaction: discord.Interaction, argument_name: str):


2.2. Slash Command Privilege Configurations

Role Based Validation

    @app_commands.checks.has_role("role1")
    async def command_name(self, interaction: discord.Interaction):

OR

    @app_commands.checks.has_any_role("role1", "role2")
    async def command_name(self, interaction: discord.Interaction):

Permission Based Validation

    @app_commands.checks.has_permissions(administrator=True, manage_roles=True) # this does an AND
    async def command_name(self, interaction: discord.Interaction):

If the above examples don't provide a way for the sort of permission checking you are attempting, you can write your own logic using the below example

    def user_permission_check(interaction: discord.Interaction) -> bool:
        return interaction.user.guild_permissions.administrator or interaction.user.guild_permissions.manage_roles

    @app_commands.check(user_permission_check)
    async def command_name(self, interaction: discord.Interaction):

2.3. Implementing Slash Commands Auto-Complete Menu

slash commands introduced the ability to provide users with a menu of options they can choose from for a command's argument. You can see this in action with the /iam command on the CSSS Discord guild OR

    @app_commands.autocomplete(argument_name=[
        # list of app_commands.Choice items
        # choice object example: app_commands.Choice(name="string that will be shown in discord, value="value passed to the command")
    ])
    async def command_name(self, interaction: discord.Interaction, argument_name: str):

If the options you want to provide need to be pulled from discord in some way, you can extend the functionality of the autocomplete function like this:

    async def argument_options(interaction: discord.Interaction, current: str) -> List[app_commands.Choice[str]]:
        // create choice object using data pulled from interaction and using "current" as a filter to pass the objects through
        return [choice]

    @app_commands.autocomplete(argument_name=argument_options)
    async def command_name(self, interaction: discord.Interaction, argument_name: str):

3. Adding a New Cog Class

General layout to follow when adding a new cog class

class NewCog(commands.Cog):

    def __init__(self, bot, config, bot_channel_manager):
        log_info = Loggers.get_logger(logger_name="NewCog")
        self.logger = log_info[0]
        self.debug_log_file_absolute_path = log_info[1]
        self.error_log_file_absolute_path = log_info[2]
        self.logger.info("[NewCog __init__()] initializing NewCog")
        self.bot = bot
        self.config = config
        self.guild: discord.Guild = None
        self.bot_channel_manager = bot_channel_manager

    @commands.Cog.listener(name="on_ready")
    async def get_guild(self):
        self.guild = self.bot.guilds[0]

    @commands.Cog.listener(name="on_ready")
    async def upload_debug_logs(self):
        if self.config.get_config_value('basic_config', 'ENVIRONMENT') != 'TEST':
            while self.guild is None:
                await asyncio.sleep(2)
            await start_file_uploading(
                self.logger, self.guild, self.bot, self.config, self.debug_log_file_absolute_path, "new_cog_debug"
            )

    @commands.Cog.listener(name="on_ready")
    async def upload_error_logs(self):
        if self.config.get_config_value('basic_config', 'ENVIRONMENT') != 'TEST':
            while self.guild is None:
                await asyncio.sleep(2)
            await start_file_uploading(
                self.logger, self.guild, self.bot, self.config, self.error_log_file_absolute_path, "new_cog_error"
            )

# specify any new command to listeners below

Adding to .ini files

Add the cog to the .ini files in the https://github.com/CSSS/wall_e/tree/master/wall_e/utilities/config folder

Listeners

If you need to add any logic to the cog class that the bot will execute as soon as the on_ready signal has been received [when its logged into the discord guild], use the below template

    @commands.Cog.listener(name='on_ready')
    async def function_name(self):
        while self.guild is None:
            await asyncio.sleep(2)
        # function logic

You can see the list of discord events that a discord bot can listen for here

4. App Commands Walk-through

the above documentation was adapted from

Clone this wiki locally