Browse Source

Add edit and delete methods to AppCommand

pull/7999/head
z03h 3 years ago
committed by GitHub
parent
commit
bd727d2b0c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      discord/app_commands/errors.py
  2. 137
      discord/app_commands/models.py
  3. 14
      discord/app_commands/tree.py
  4. 4
      docs/interactions/api.rst

19
discord/app_commands/errors.py

@ -45,6 +45,7 @@ __all__ = (
'MissingPermissions',
'BotMissingPermissions',
'CommandOnCooldown',
'MissingApplicationID',
)
if TYPE_CHECKING:
@ -53,6 +54,11 @@ if TYPE_CHECKING:
from ..types.snowflake import Snowflake, SnowflakeList
from .checks import Cooldown
APP_ID_NOT_FOUND = (
'Client does not have an application_id set. Either the function was called before on_ready '
'was called or application_id was not passed to the Client constructor.'
)
class AppCommandError(DiscordException):
"""The base exception type for all application command related errors.
@ -391,3 +397,16 @@ class CommandSignatureMismatch(AppCommandError):
'command tree to fix this issue.'
)
super().__init__(msg)
class MissingApplicationID(AppCommandError):
"""An exception raised when the client does not have an application ID set.
An application ID is required for syncing application commands.
This inherits from :exc:`~discord.app_commands.AppCommandError`.
.. versionadded:: 2.0
"""
def __init__(self, message: Optional[str] = None):
super().__init__(message or APP_ID_NOT_FOUND)

137
discord/app_commands/models.py

@ -25,11 +25,11 @@ DEALINGS IN THE SOFTWARE.
from __future__ import annotations
from datetime import datetime
from .errors import MissingApplicationID
from ..permissions import Permissions
from ..enums import AppCommandOptionType, AppCommandType, ChannelType, try_enum
from ..mixins import Hashable
from ..utils import _get_as_snowflake, parse_time, snowflake_time
from ..utils import _get_as_snowflake, parse_time, snowflake_time, MISSING
from typing import Generic, List, TYPE_CHECKING, Optional, TypeVar, Union
__all__ = (
@ -138,6 +138,9 @@ class AppCommand(Hashable):
The default member permissions that can run this command.
dm_permission: :class:`bool`
A boolean that indicates whether this command can be run in direct messages.
guild_id: Optional[:class:`int`]
The ID of the guild this command is registered in. A value of ``None``
denotes that it is a global command.
"""
__slots__ = (
@ -146,14 +149,15 @@ class AppCommand(Hashable):
'application_id',
'name',
'description',
'guild_id',
'options',
'default_member_permissions',
'dm_permission',
'_state',
)
def __init__(self, *, data: ApplicationCommandPayload, state: Optional[ConnectionState] = None) -> None:
self._state: Optional[ConnectionState] = state
def __init__(self, *, data: ApplicationCommandPayload, state: ConnectionState) -> None:
self._state: ConnectionState = state
self._from_data(data)
def _from_data(self, data: ApplicationCommandPayload) -> None:
@ -161,6 +165,7 @@ class AppCommand(Hashable):
self.application_id: int = int(data['application_id'])
self.name: str = data['name']
self.description: str = data['description']
self.guild_id: Optional[int] = _get_as_snowflake(data, 'guild_id')
self.type: AppCommandType = try_enum(AppCommandType, data.get('type', 1))
self.options: List[Union[Argument, AppCommandGroup]] = [
app_command_option_factory(data=d, parent=self, state=self._state) for d in data.get('options', [])
@ -195,6 +200,130 @@ class AppCommand(Hashable):
def __repr__(self) -> str:
return f'<{self.__class__.__name__} id={self.id!r} name={self.name!r} type={self.type!r}>'
@property
def guild(self) -> Optional[Guild]:
"""Optional[:class:`~discord.Guild`]: Returns the guild this command is registered to
if it exists.
"""
return self._state._get_guild(self.guild_id)
async def delete(self) -> None:
"""|coro|
Deletes the application command.
Raises
-------
NotFound
The application command was not found.
Forbidden
You do not have permission to delete this application command.
HTTPException
Deleting the application command failed.
MissingApplicationID
The client does not have an application ID.
"""
state = self._state
if not state.application_id:
raise MissingApplicationID
if self.guild_id:
await state.http.delete_guild_command(
state.application_id,
self.guild_id,
self.id,
)
else:
await state.http.delete_global_command(
state.application_id,
self.id,
)
async def edit(
self,
*,
name: str = MISSING,
description: str = MISSING,
default_member_permissions: Optional[Permissions] = MISSING,
dm_permission: bool = MISSING,
options: List[Union[Argument, AppCommandGroup]] = MISSING,
) -> AppCommand:
"""|coro|
Edits the application command.
Parameters
-----------
name: :class:`str`
The new name for the application command.
description: :class:`str`
The new description for the application command.
default_member_permissions: Optional[:class:`~discord.Permissions`]
The new default permissions needed to use this application command.
Pass value of ``None`` to remove any permission requirements.
dm_permission: :class:`bool`
Indicates if the application command can be used in DMs.
options: List[Union[:class:`Argument`, :class:`AppCommandGroup`]]
List of new options for this application command.
Raises
-------
NotFound
The application command was not found.
Forbidden
You do not have permission to edit this application command.
HTTPException
Editing the application command failed.
MissingApplicationID
The client does not have an application ID.
Returns
--------
:class:`AppCommand`
The newly edited application command.
"""
state = self._state
if not state.application_id:
raise MissingApplicationID
payload = {}
if name is not MISSING:
payload['name'] = name
if description is not MISSING:
payload['description'] = description
if default_member_permissions is not MISSING:
if default_member_permissions is not None:
payload['default_member_permissions'] = default_member_permissions.value
else:
payload['default_member_permissions'] = None
if self.guild_id is None and dm_permission is not MISSING:
payload['dm_permission'] = dm_permission
if options is not MISSING:
payload['options'] = [option.to_dict() for option in options]
if not payload:
return self
if self.guild_id:
data = await state.http.edit_guild_command(
state.application_id,
self.guild_id,
self.id,
payload,
)
else:
data = await state.http.edit_global_command(
state.application_id,
self.id,
payload,
)
return AppCommand(data=data, state=state)
class Choice(Generic[ChoiceT]):
"""Represents an application command argument choice.

14
discord/app_commands/tree.py

@ -57,6 +57,7 @@ from .errors import (
CommandNotFound,
CommandSignatureMismatch,
CommandLimitReached,
MissingApplicationID,
)
from ..errors import ClientException
from ..enums import AppCommandType, InteractionType
@ -78,11 +79,6 @@ __all__ = ('CommandTree',)
ClientT = TypeVar('ClientT', bound='Client')
APP_ID_NOT_FOUND = (
'Client does not have an application_id set. Either the function was called before on_ready '
'was called or application_id was not passed to the Client constructor.'
)
def _retrieve_guild_ids(
command: Any, guild: Optional[Snowflake] = MISSING, guilds: Sequence[Snowflake] = MISSING
@ -158,7 +154,7 @@ class CommandTree(Generic[ClientT]):
-------
HTTPException
Fetching the commands failed.
ClientException
MissingApplicationID
The application ID could not be found.
Returns
@ -167,7 +163,7 @@ class CommandTree(Generic[ClientT]):
The application's commands.
"""
if self.client.application_id is None:
raise ClientException(APP_ID_NOT_FOUND)
raise MissingApplicationID
if guild is None:
commands = await self._http.get_global_commands(self.client.application_id)
@ -906,7 +902,7 @@ class CommandTree(Generic[ClientT]):
Syncing the commands failed.
Forbidden
The client does not have the ``applications.commands`` scope in the guild.
ClientException
MissingApplicationID
The client does not have an application ID.
Returns
@ -916,7 +912,7 @@ class CommandTree(Generic[ClientT]):
"""
if self.client.application_id is None:
raise ClientException(APP_ID_NOT_FOUND)
raise MissingApplicationID
commands = self._get_all_commands(guild=guild)
payload = [command.to_dict() for command in commands]

4
docs/interactions/api.rst

@ -609,6 +609,9 @@ Exceptions
.. autoexception:: discord.app_commands.CommandNotFound
:members:
.. autoexception:: discord.app_commands.MissingApplicationID
:members:
Exception Hierarchy
~~~~~~~~~~~~~~~~~~~~
@ -629,3 +632,4 @@ Exception Hierarchy
- :exc:`~discord.app_commands.CommandAlreadyRegistered`
- :exc:`~discord.app_commands.CommandSignatureMismatch`
- :exc:`~discord.app_commands.CommandNotFound`
- :exc:`~discord.app_commands.MissingApplicationID`

Loading…
Cancel
Save