Skip to content

Instantly share code, notes, and snippets.

@voidoak
Last active April 23, 2024 12:24
Show Gist options
  • Save voidoak/4f34922888eeca04e1bba8c0ebd2f948 to your computer and use it in GitHub Desktop.
Save voidoak/4f34922888eeca04e1bba8c0ebd2f948 to your computer and use it in GitHub Desktop.
Implementing your own help command in discord.py

Custom Help Command in discord.py

If you've ever built a bot, you've probably wanted to create a custom help command so it will present your commands and their features in exactly the manner you'd like. Perhaps you don't like the default help command, with its simple code block formatting and presenting all the commands, split up into different messages if you have a good amount of them. Perhaps you've seen other developers' custom help commands, but don't want or like to use embed fields. Well in that case, you can easily create and design your own help command to handle the output exactly the way you want it.

To do so, we'll be implementing a helpful base class that comes packaged in discord.py; namely, commands.HelpCommand. There are other help command base classes, but we'll be focusing on commands.HelpCommand.

To start off, we'll first create a class, which will inherit from commands.HelpCommand.

import discord
from discord.ext import commands

class MyHelpCommand(commands.HelpCommand):
    ...

Now, the commands.HelpCommand base class comes with several class methods that we'll implement and find very useful in achieving our goal. The coroutine methods supplied are called when specific arguments are passed to the help command. Don't worry, you don't have to set up this functionality to determine which method to use when help is called; discord.py handles this for us in the background. This behaviour can be overwritten and reimplemented to do as we want, but that's outside the scope of this example.

Let's say you have two cogs: Fun and Info. Fun contains the commands meme and spam, with Info containing pfp and stats. When we send the command help to our bot, we want it to display the names of the cogs in a list. To do this we simply format the base case for the help command (eg. what the bot will send if you use help without any arguments), which is implemented by overwriting the send_bot_help method. Inside our MyHelpCommand class, we might do something like this:

    async def send_bot_help(self, mapping):
        embed = discord.Embed(title="Bot help")
        # `mapping` is a dict of the bot's cogs, which map to their commands
        for cog, cmds in mapping.items():  # get the cog and its commands separately
            embed.add_field(
                name = cog.qualified_name,       # get the cog name
                value = f"{len(cmds) commands}"  # get a count of the commands in the cog.
            )
            
        channel = self.get_destination()  # this method is inherited from `HelpCommand`, and gets the channel in context
        await channel.send(embed=embed)

The above code would result in a simple embed, with only the names of the cogs and a count of their commands listed. From this you could change the behaviour of the help command to do whatever you'd like, to format it as you wish and/or need. The methods provided by the HelpCommand base class that will handle calls to the help command are as follows:

  • send_bot_help: when the help command is called without arguments (as shown above)
  • send_command_help: when the help command is called with a command name (eg. help meme)
  • send_group_help: when the help command is called with a group name (eg. help somegroupcmd)
  • send_cog_help: when the help command is called with a cog name (eg. help Fun)

From this, you should be able to create and customize your own bot's help command to your heart's content. See how I did it in my bot's help command!

@AgentStrawberry
Copy link

Why is there commands after len(cmds) in the value = f"{len(cmds) commands}"

@0xhimangshu
Copy link

Why is there commands after len(cmds) in the value = f"{len(cmds) commands}"

yeah , i hav problem with this

@Nukestye
Copy link

Nukestye commented Dec 24, 2022

Why is there commands after len(cmds) in the value = f"{len(cmds) commands}"

I believe it was meant to be value = f"{len(cmds)} commands".

@NNKTV28
Copy link

NNKTV28 commented Mar 8, 2023

i like bread

@3060PlayZ-github
Copy link

i like bread

You do?

@NNKTV28
Copy link

NNKTV28 commented Mar 31, 2024

i like bread

You do?

i really do

@3060PlayZ-github
Copy link

i like bread

You do?

i really do

me too lol

@Fraged0
Copy link

Fraged0 commented Apr 23, 2024

i like bread

the bread has been.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment