diff --git a/docs/faq.rst b/docs/faq.rst index 16d03362a..76e2e1b8a 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -500,3 +500,82 @@ My bot's commands are not showing up! ``https://discord.com/oauth2/authorize?client_id=&scope=applications.commands+bot``. Alternatively, if you use :func:`utils.oauth_url`, you can call the function as such: ``oauth_url(, scopes=("bot", "applications.commands"))``. + +How do I restrict a command to a specific guild? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To restrict an application command to one or more guilds, you must register it as a **guild command** instead of a +global command. Guild commands are only available in the specified guild(s). + +The most straightforward way is to use the :meth:`~app_commands.guilds` decorator on your command or GroupCog. + +``123456789012345678`` should be replaced with the actual guild ID you want to restrict the command to. + +.. code-block:: python3 + + @app_commands.command() # or @tree.command() + @app_commands.guilds(123456789012345678) # or @app_commands.guilds(discord.Object(123456789012345678)) + async def ping(interaction: Interaction): + await interaction.response.send_message("Pong!") + + # or GroupCog (applies to all subcommands): + + @app_commands.guilds(123456789012345678) + class MyGroup(commands.GroupCog): + @app_commands.command() + async def pong(self, interaction: Interaction): + await interaction.response.send_message("Ping!") + +After that, you must :meth:`~app_commands.CommandTree.sync` the command tree for each guild: + +.. code-block:: python3 + + await tree.sync(guild=discord.Object(123456789012345678)) + +Other methods to restrict commands to specific guilds include: + +- Using the ``guild`` or ``guilds`` argument in the :meth:`~app_commands.CommandTree.command` decorator: + + .. code-block:: python3 + + @tree.command(guild=discord.Object(123456789012345678)) + async def ping(interaction: Interaction): + await interaction.response.send_message("Pong!") + +- Adding commands with :meth:`~app_commands.CommandTree.add_command` and specifying ``guild`` or ``guilds``: + + .. code-block:: python3 + + @app_commands.command() + async def ping(interaction: Interaction): + await interaction.response.send_message("Pong!") + + tree.add_command(ping, guild=discord.Object(123456789012345678)) + + .. warning:: + + Do not combine this method with the :meth:`~app_commands.CommandTree.command` decorator, + as it will cause duplicate commands. + +- Using ``guild`` or ``guilds`` in :meth:`~ext.commands.Bot.add_cog`: + + This is mainly for :class:`~ext.commands.GroupCog`, but also works for cogs with application commands. + Note: This does not work with hybrid app commands (:issue:`9366`). + + .. code-block:: python3 + + class MyCog(commands.Cog): + @app_commands.command() + async def ping(self, interaction: Interaction): + await interaction.response.send_message("Pong!") + + async def setup(bot: commands.Bot) -> None: + await bot.add_cog(MyCog(...), guild=discord.Object(123456789012345678)) + +- Using :meth:`~app_commands.CommandTree.copy_global_to`: + + This copies all global commands to a specific guild. This is mainly for development purposes. + + .. code-block:: python3 + + tree.copy_global_to(guild=discord.Object(123456789012345678))