diff --git a/discord/app_commands/tree.py b/discord/app_commands/tree.py index 74eb6cb79..2cc95d455 100644 --- a/discord/app_commands/tree.py +++ b/discord/app_commands/tree.py @@ -113,9 +113,16 @@ class CommandTree(Generic[ClientT]): ----------- client: :class:`~discord.Client` The client instance to get application command information from. + fallback_to_global: :class:`bool` + If a guild-specific command is not found when invoked, then try falling back into + a global command in the tree. For example, if the tree locally has a ``/ping`` command + under the global namespace but the guild has a guild-specific ``/ping``, instead of failing + to find the guild-specific ``/ping`` command it will fall back to the global ``/ping`` command. + This has the potential to raise more :exc:`~discord.app_commands.CommandSignatureMismatch` errors + than usual. Defaults to ``True``. """ - def __init__(self, client: ClientT): + def __init__(self, client: ClientT, *, fallback_to_global: bool = True): self.client: ClientT = client self._http = client.http self._state = client._connection @@ -124,6 +131,7 @@ class CommandTree(Generic[ClientT]): raise ClientException('This client already has an associated command tree.') self._state._command_tree = self + self.fallback_to_global: bool = fallback_to_global self._guild_commands: Dict[int, Dict[str, Union[Command, Group]]] = {} self._global_commands: Dict[str, Union[Command, Group]] = {} # (name, guild_id, command_type): Command @@ -935,7 +943,11 @@ class CommandTree(Generic[ClientT]): def _get_context_menu(self, data: ApplicationCommandInteractionData) -> Optional[ContextMenu]: name = data['name'] guild_id = _get_as_snowflake(data, 'guild_id') - return self._context_menus.get((name, guild_id, data.get('type', 1))) + t = data.get('type', 1) + cmd = self._context_menus.get((name, guild_id, t)) + if cmd is None and self.fallback_to_global: + return self._context_menus.get((name, None, t)) + return cmd def _get_app_command_options( self, data: ApplicationCommandInteractionData @@ -948,9 +960,11 @@ class CommandTree(Generic[ClientT]): try: guild_commands = self._guild_commands[command_guild_id] except KeyError: - command = None + command = None if not self.fallback_to_global else self._global_commands.get(name) else: command = guild_commands.get(name) + if command is None and self.fallback_to_global: + command = self._global_commands.get(name) else: command = self._global_commands.get(name)