Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Entry Point Command #9996

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions discord/app_commands/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
AppCommandPermissionType,
ChannelType,
Locale,
EntryPointCommandHandlerType,
try_enum,
)
from ..mixins import Hashable
Expand Down Expand Up @@ -181,6 +182,10 @@ class AppCommand(Hashable):
denotes that it is a global command.
nsfw: :class:`bool`
Whether the command is NSFW and should only work in NSFW channels.
handler: Optional[:class:`~discord.EntryPointCommandHandlerType`]
Determines whether the interaction is handled by the app's interactions handler or by Discord.

This is only available for commands with type :attr:`~discord.AppCommandType.primary_entry_point`.
"""

__slots__ = (
Expand All @@ -198,6 +203,7 @@ class AppCommand(Hashable):
'allowed_contexts',
'allowed_installs',
'nsfw',
'handler',
'_state',
)

Expand Down Expand Up @@ -245,6 +251,12 @@ def _from_data(self, data: ApplicationCommandPayload) -> None:
self.name_localizations: Dict[Locale, str] = _to_locale_dict(data.get('name_localizations') or {})
self.description_localizations: Dict[Locale, str] = _to_locale_dict(data.get('description_localizations') or {})

handler = data.get('handler')
if handler is None:
self.handler = None
else:
self.handler = try_enum(EntryPointCommandHandlerType, handler)

def to_dict(self) -> ApplicationCommandPayload:
return {
'id': self.id,
Expand All @@ -257,6 +269,7 @@ def to_dict(self) -> ApplicationCommandPayload:
'contexts': self.allowed_contexts.to_array() if self.allowed_contexts is not None else None,
'integration_types': self.allowed_installs.to_array() if self.allowed_installs is not None else None,
'options': [opt.to_dict() for opt in self.options],
'handler': self.handler.value if self.handler is not None else None,
} # type: ignore # Type checker does not understand this literal.

def __str__(self) -> str:
Expand Down Expand Up @@ -317,6 +330,7 @@ async def edit(
default_member_permissions: Optional[Permissions] = MISSING,
dm_permission: bool = MISSING,
options: List[Union[Argument, AppCommandGroup]] = MISSING,
handler: Optional[EntryPointCommandHandlerType] = MISSING,
) -> AppCommand:
"""|coro|

Expand All @@ -335,6 +349,10 @@ async def edit(
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.
handler: Optional[:class:`~discord.EntryPointCommandHandlerType`]
Determines whether the interaction is handled by the app's interactions handler or by Discord.

Only available for commands with type :attr:`~discord.AppCommandType.primary_entry_point`.

Raises
-------
Expand Down Expand Up @@ -376,6 +394,9 @@ async def edit(
if options is not MISSING:
payload['options'] = [option.to_dict() for option in options]

if handler is not MISSING:
payload['handler'] = handler

if not payload:
return self

Expand Down Expand Up @@ -433,6 +454,19 @@ async def fetch_permissions(self, guild: Snowflake) -> GuildAppCommandPermission
)
return GuildAppCommandPermissions(data=data, state=state, command=self)

def is_default_entry_point_command(self) -> bool:
""":class:`bool`: Returns ``True`` if this is the default entry point command.

This is determined by the command's name and handler type.
More information can be found in the :ddocs:`official Discord
documentation <interactions/application-commands#default-entry-point-command>`.
"""
return (
self.type is AppCommandType.primary_entry_point
and self.name.casefold() == 'launch'
and self.handler is EntryPointCommandHandlerType.discord_launch_activity
)


class Choice(Generic[ChoiceT]):
"""Represents an application command argument choice.
Expand Down
6 changes: 6 additions & 0 deletions discord/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,7 @@ class AppCommandType(Enum):
chat_input = 1
user = 2
message = 3
primary_entry_point = 4


class AppCommandPermissionType(Enum):
Expand Down Expand Up @@ -862,6 +863,11 @@ class SubscriptionStatus(Enum):
inactive = 2


class EntryPointCommandHandlerType(Enum):
app_handler = 1
discord_launch_activity = 2


def create_unknown_value(cls: Type[E], val: Any) -> E:
value_cls = cls._enum_value_cls_ # type: ignore # This is narrowed below
name = f'unknown_{val}'
Expand Down
12 changes: 11 additions & 1 deletion discord/types/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from .snowflake import Snowflake
from .interactions import InteractionContextType

ApplicationCommandType = Literal[1, 2, 3]
ApplicationCommandType = Literal[1, 2, 3, 4]
ApplicationCommandOptionType = Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
ApplicationIntegrationType = Literal[0, 1]

Expand Down Expand Up @@ -162,6 +162,15 @@ class _ChatInputApplicationCommand(_BaseApplicationCommand, total=False):
]


EntryPointCommandHandlerType = Literal[1, 2]


class _PrimaryEntryPointApplicationCommand(_BaseApplicationCommand):
description: Required[str]
type: Literal[4]
handler: EntryPointCommandHandlerType


class _BaseContextMenuApplicationCommand(_BaseApplicationCommand):
description: Literal[""]

Expand All @@ -178,6 +187,7 @@ class _MessageApplicationCommand(_BaseContextMenuApplicationCommand):
_ChatInputApplicationCommand,
_UserApplicationCommand,
_MessageApplicationCommand,
_PrimaryEntryPointApplicationCommand,
]


Expand Down
20 changes: 20 additions & 0 deletions docs/interactions/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,11 @@ Enumerations
.. attribute:: message

A message context menu command.
.. attribute:: primary_entry_point

.. versionadded:: 2.5

A command that represents the primary way to invoke an app's Activity

.. class:: AppCommandPermissionType

Expand All @@ -447,6 +452,21 @@ Enumerations

The permission is for a user.

.. class:: EntryPointCommandHandlerType

Represents the type of an entry point command handler.

.. versionadded:: 2.5

.. attribute:: app_handler

The app handles the interaction using an interaction token.

.. attribute:: discord_launch_activity

Discord handles the interaction by launching an Activity and
sending a follow-up message without coordinating with the app.

.. _discord_ui_kit:

Bot UI Kit
Expand Down
Loading