From 826db8277af0cdf2d56117d7c0427ad710f4f8ce Mon Sep 17 00:00:00 2001 From: Soheab_ <33902984+Soheab@users.noreply.github.com> Date: Wed, 25 Jun 2025 17:25:35 +0200 Subject: [PATCH] Add CommandTree.sync_command --- discord/app_commands/tree.py | 66 ++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/discord/app_commands/tree.py b/discord/app_commands/tree.py index 3099071c0..5957db1ad 100644 --- a/discord/app_commands/tree.py +++ b/discord/app_commands/tree.py @@ -1136,6 +1136,72 @@ class CommandTree(Generic[ClientT]): return [AppCommand(data=d, state=self._state) for d in data] + async def sync_command( + self, command: Union[AppCommand, Command, ContextMenu, Group], *, guild: Optional[Snowflake] = None + ) -> AppCommand: + """|coro| + + Syncs a single application command to Discord. + + .. note :: + This is not recommended for use in most cases, use :meth:`.sync` instead. + + .. versionadded:: 2.6 + + Parameters + ----------- + command: Union[:class:`AppCommand`, :class:`Command`, :class:`ContextMenu`, :class:`Group`] + The application command to sync. + If this is an :class:`AppCommand`, it will call its :meth:`AppCommand.sync` method. + guild: Optional[:class:`~discord.abc.Snowflake`] + The guild to sync the command in. If not provided, the command is synced globally. + This is not applicable for :class:`AppCommand` instances, as they are already guild- + specific. + + Raises + ------- + HTTPException + Syncing the commands failed. + CommandSyncFailure + Syncing the commands failed due to a user related error, typically because + the command has invalid data. This is equivalent to an HTTP status code of + 400. + Forbidden + The client does not have the ``applications.commands`` scope in the guild. + MissingApplicationID + The client does not have an application ID. + TranslationError + An error occurred while translating the commands. + + Returns + -------- + :class:`AppCommand` + The application command that got synced. + """ + if isinstance(command, AppCommand): + return await command.sync() + + if self.client.application_id is None: + raise MissingApplicationID + + translator = self.translator + if translator: + payload = await command.get_translated_payload(self, translator) + else: + payload = command.to_dict(self) + + try: + if guild is None: + data = await self._http.upsert_global_command(self.client.application_id, payload=payload) # type: ignore + else: + data = await self._http.upsert_guild_command(self.client.application_id, guild.id, payload=payload) # type: ignore + except HTTPException as e: + if e.status == 400 and e.code == 50035: + raise CommandSyncFailure(e, [command]) from None + raise + + return AppCommand(data=data, state=self._state) + async def _dispatch_error(self, interaction: Interaction[ClientT], error: AppCommandError, /) -> None: command = interaction.command interaction.command_failed = True