# discord.py recently added full hybrid commands. They work as follows: ## Note: as I don't see a reason not to, I will present an example using a commands.Cog. ## IMPORTANT: hybrid commands only work if the signature is compatible with app commands. # this means that all parameters must have a type annotation, even if it is just `str`. # this also means that you must use `Transformers` not `Coverters` in these cases. import discord from discord.ext import commands class MyCog(commands.Cog): def __init__(self, bot: commands.Bot) -> None: self.bot: commands.Bot = bot @commands.hybrid_command(name="ping") async def ping_command(self, ctx: commands.Context) -> None: """ This command is actually used as an app command AND a message command. This means it is invoked with `?ping` and `/ping` (once synced, of course). """ await ctx.send("Hello!") # we use ctx.send and this will handle both the message command and app command of sending. # added note: you can check if this command is invoked as an app command by checking the `ctx.interaction` attribute. @commands.hybrid_group(name="parent") async def parent_command(self, ctx: commands.Context) -> None: """ We even have the use of parents. This will work as usual for ext.commands but will be un-invokable for app commands. This is a discord limitation as groups are un-invokable. """ ... # nothing we want to do in here, I guess! @parent_command.command(name="sub") async def sub_command(self, ctx: commands.Context, argument: str) -> None: """ This subcommand can now be invoked with `?parent sub ` or `/parent sub ` (once synced). """ await ctx.send(f"Hello, you sent {argument}!") async def setup(bot: commands.Bot) -> None: await bot.add_cog(MyCog(bot))