diff --git a/discord/http.py b/discord/http.py index 58f91ce6d..84d9e7a9e 100644 --- a/discord/http.py +++ b/discord/http.py @@ -25,7 +25,6 @@ DEALINGS IN THE SOFTWARE. from __future__ import annotations import asyncio -import json import logging import sys from typing import ( @@ -68,6 +67,7 @@ if TYPE_CHECKING: appinfo, audit_log, channel, + command, components, emoji, embed, @@ -1699,12 +1699,12 @@ class HTTPClient: # Application commands (global) - def get_global_commands(self, application_id: Snowflake) -> Response[List[interactions.ApplicationCommand]]: + def get_global_commands(self, application_id: Snowflake) -> Response[List[command.ApplicationCommand]]: return self.request(Route('GET', '/applications/{application_id}/commands', application_id=application_id)) def get_global_command( self, application_id: Snowflake, command_id: Snowflake - ) -> Response[interactions.ApplicationCommand]: + ) -> Response[command.ApplicationCommand]: r = Route( 'GET', '/applications/{application_id}/commands/{command_id}', @@ -1713,7 +1713,7 @@ class HTTPClient: ) return self.request(r) - def upsert_global_command(self, application_id: Snowflake, payload) -> Response[interactions.ApplicationCommand]: + def upsert_global_command(self, application_id: Snowflake, payload) -> Response[command.ApplicationCommand]: r = Route('POST', '/applications/{application_id}/commands', application_id=application_id) return self.request(r, json=payload) @@ -1721,8 +1721,8 @@ class HTTPClient: self, application_id: Snowflake, command_id: Snowflake, - payload: interactions.EditApplicationCommand, - ) -> Response[interactions.ApplicationCommand]: + payload: Dict[str, Any], + ) -> Response[command.ApplicationCommand]: valid_keys = ( 'name', 'description', @@ -1748,7 +1748,7 @@ class HTTPClient: def bulk_upsert_global_commands( self, application_id: Snowflake, payload - ) -> Response[List[interactions.ApplicationCommand]]: + ) -> Response[List[command.ApplicationCommand]]: r = Route('PUT', '/applications/{application_id}/commands', application_id=application_id) return self.request(r, json=payload) @@ -1756,7 +1756,7 @@ class HTTPClient: def get_guild_commands( self, application_id: Snowflake, guild_id: Snowflake - ) -> Response[List[interactions.ApplicationCommand]]: + ) -> Response[List[command.ApplicationCommand]]: r = Route( 'GET', '/applications/{application_id}/guilds/{guild_id}/commands', @@ -1770,7 +1770,7 @@ class HTTPClient: application_id: Snowflake, guild_id: Snowflake, command_id: Snowflake, - ) -> Response[interactions.ApplicationCommand]: + ) -> Response[command.ApplicationCommand]: r = Route( 'GET', '/applications/{application_id}/guilds/{guild_id}/commands/{command_id}', @@ -1784,8 +1784,8 @@ class HTTPClient: self, application_id: Snowflake, guild_id: Snowflake, - payload: interactions.EditApplicationCommand, - ) -> Response[interactions.ApplicationCommand]: + payload: Dict[str, Any], + ) -> Response[command.ApplicationCommand]: r = Route( 'POST', '/applications/{application_id}/guilds/{guild_id}/commands', @@ -1799,8 +1799,8 @@ class HTTPClient: application_id: Snowflake, guild_id: Snowflake, command_id: Snowflake, - payload: interactions.EditApplicationCommand, - ) -> Response[interactions.ApplicationCommand]: + payload: Dict[str, Any], + ) -> Response[command.ApplicationCommand]: valid_keys = ( 'name', 'description', @@ -1835,8 +1835,8 @@ class HTTPClient: self, application_id: Snowflake, guild_id: Snowflake, - payload: List[interactions.EditApplicationCommand], - ) -> Response[List[interactions.ApplicationCommand]]: + payload: List[Dict[str, Any]], + ) -> Response[List[command.ApplicationCommand]]: r = Route( 'PUT', '/applications/{application_id}/guilds/{guild_id}/commands', @@ -1889,7 +1889,7 @@ class HTTPClient: token: str, *, type: InteractionResponseType, - data: Optional[interactions.InteractionApplicationCommandCallbackData] = None, + data: Optional[Dict[str, Any]] = None, ) -> Response[None]: r = Route( 'POST', @@ -2003,7 +2003,7 @@ class HTTPClient: self, application_id: Snowflake, guild_id: Snowflake, - ) -> Response[List[interactions.GuildApplicationCommandPermissions]]: + ) -> Response[List[command.GuildApplicationCommandPermissions]]: r = Route( 'GET', '/applications/{application_id}/guilds/{guild_id}/commands/permissions', @@ -2017,7 +2017,7 @@ class HTTPClient: application_id: Snowflake, guild_id: Snowflake, command_id: Snowflake, - ) -> Response[interactions.GuildApplicationCommandPermissions]: + ) -> Response[command.GuildApplicationCommandPermissions]: r = Route( 'GET', '/applications/{application_id}/guilds/{guild_id}/commands/{command_id}/permissions', @@ -2032,7 +2032,7 @@ class HTTPClient: application_id: Snowflake, guild_id: Snowflake, command_id: Snowflake, - payload: interactions.BaseGuildApplicationCommandPermissions, + payload: Dict[str, Any], ) -> Response[None]: r = Route( 'PUT', @@ -2047,7 +2047,7 @@ class HTTPClient: self, application_id: Snowflake, guild_id: Snowflake, - payload: List[interactions.PartialGuildApplicationCommandPermissions], + payload: List[Dict[str, Any]], ) -> Response[None]: r = Route( 'PUT', diff --git a/discord/types/command.py b/discord/types/command.py new file mode 100644 index 000000000..04207aa55 --- /dev/null +++ b/discord/types/command.py @@ -0,0 +1,220 @@ +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +from __future__ import annotations + +from typing import List, Literal, TypedDict, Union + +from discord.types.channel import ChannelType +from discord.types.snowflake import Snowflake + +ApplicationCommandType = Literal[1, 2, 3] +ApplicationCommandOptionType = Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] + + +class _BaseApplicationCommandOption(TypedDict): + name: str + description: str + + +class _SubCommandCommandOption(_BaseApplicationCommandOption): + type: Literal[1] + options: List[_ValueApplicationCommandOption] + + +class _SubCommandGroupCommandOption(_BaseApplicationCommandOption): + type: Literal[2] + options: List[_SubCommandCommandOption] + + +class _BaseValueApplicationCommandOption(_BaseApplicationCommandOption, total=False): + required: bool + + +class _StringApplicationCommandOptionChoice(TypedDict, total=False): + name: str + value: str + + +class _StringApplicationCommandOptionOptional(_BaseValueApplicationCommandOption, total=False): + choices: List[_StringApplicationCommandOptionChoice] + autocomplete: bool + + +class _StringApplicationCommandOption(_StringApplicationCommandOptionOptional): + type: Literal[3] + + +class _IntegerApplicationCommandOptionChoice(TypedDict, total=False): + name: str + value: int + + +class _IntegerApplicationCommandOptionOptional(_BaseValueApplicationCommandOption, total=False): + min_value: int + max_value: int + choices: List[_IntegerApplicationCommandOptionChoice] + autocomplete: bool + + +class _IntegerApplicationCommandOption(_IntegerApplicationCommandOptionOptional): + type: Literal[4] + + +class _BooleanApplicationCommandOption(_BaseValueApplicationCommandOption): + type: Literal[5] + + +class _ChannelApplicationCommandOptionChoiceOptional(_BaseApplicationCommandOption, total=False): + channel_types: List[ChannelType] + + +class _ChannelApplicationCommandOptionChoice(_ChannelApplicationCommandOptionChoiceOptional): + type: Literal[7] + + +class _NonChannelSnowflakeApplicationCommandOptionChoice(_BaseValueApplicationCommandOption): + type: Literal[6, 8, 9, 11] + + +_SnowflakeApplicationCommandOptionChoice = Union[ + _ChannelApplicationCommandOptionChoice, + _NonChannelSnowflakeApplicationCommandOptionChoice, +] + + +class _NumberApplicationCommandOptionChoice(TypedDict, total=False): + name: str + value: float + + +class _NumberApplicationCommandOptionOptional(_BaseValueApplicationCommandOption, total=False): + min_value: float + max_value: float + choices: List[_NumberApplicationCommandOptionChoice] + autocomplete: bool + + +class _NumberApplicationCommandOption(_NumberApplicationCommandOptionOptional): + type: Literal[10] + + +_ValueApplicationCommandOption = Union[ + _StringApplicationCommandOption, + _IntegerApplicationCommandOption, + _BooleanApplicationCommandOption, + _SnowflakeApplicationCommandOptionChoice, + _NumberApplicationCommandOption, +] + +ApplicationCommandOption = Union[ + _SubCommandGroupCommandOption, + _SubCommandCommandOption, + _ValueApplicationCommandOption, +] + +ApplicationCommandOptionChoice = Union[ + _StringApplicationCommandOptionChoice, + _IntegerApplicationCommandOptionChoice, + _NumberApplicationCommandOptionChoice, +] + + +class _BaseApplicationCommand(TypedDict): + id: Snowflake + application_id: Snowflake + name: str + version: Snowflake + + +class _ChatInputApplicationCommandOptional(_BaseApplicationCommand, total=False): + type: Literal[1] + options: Union[ + List[_ValueApplicationCommandOption], + List[Union[_SubCommandCommandOption, _SubCommandGroupCommandOption]], + ] + + +class _ChatInputApplicationCommand(_ChatInputApplicationCommandOptional): + description: str + + +class _BaseContextMenuApplicationCommand(_BaseApplicationCommand): + description: Literal[""] + + +class _UserApplicationCommand(_BaseContextMenuApplicationCommand): + type: Literal[2] + + +class _MessageApplicationCommand(_BaseContextMenuApplicationCommand): + type: Literal[3] + + +GlobalApplicationCommand = Union[ + _ChatInputApplicationCommand, + _UserApplicationCommand, + _MessageApplicationCommand, +] + + +class _GuildChatInputApplicationCommand(_ChatInputApplicationCommand): + guild_id: Snowflake + + +class _GuildUserApplicationCommand(_UserApplicationCommand): + guild_id: Snowflake + + +class _GuildMessageApplicationCommand(_MessageApplicationCommand): + guild_id: Snowflake + + +GuildApplicationCommand = Union[ + _GuildChatInputApplicationCommand, + _GuildUserApplicationCommand, + _GuildMessageApplicationCommand, +] + + +ApplicationCommand = Union[ + GlobalApplicationCommand, + GuildApplicationCommand, +] + + +ApplicationCommandPermissionType = Literal[1, 2] + + +class ApplicationCommandPermissions(TypedDict): + id: Snowflake + type: ApplicationCommandPermissionType + permission: bool + + +class GuildApplicationCommandPermissions(TypedDict): + id: Snowflake + application_id: Snowflake + guild_id: Snowflake + permissions: List[ApplicationCommandPermissions] diff --git a/discord/types/interactions.py b/discord/types/interactions.py index b0ce156b1..672c4940c 100644 --- a/discord/types/interactions.py +++ b/discord/types/interactions.py @@ -24,195 +24,206 @@ DEALINGS IN THE SOFTWARE. from __future__ import annotations -from typing import Optional, TYPE_CHECKING, Dict, TypedDict, Union, List, Literal -from .snowflake import Snowflake -from .components import Component, ComponentType -from .embed import Embed -from .channel import ChannelType +from typing import TYPE_CHECKING, Dict, List, Literal, TypedDict, Union + +from .channel import ChannelType, ThreadMetadata from .member import Member +from .message import Attachment from .role import Role +from .snowflake import Snowflake from .user import User if TYPE_CHECKING: - from .message import AllowedMentions, Message + from .message import Message -ApplicationCommandType = Literal[1, 2, 3] +InteractionType = Literal[1, 2, 3, 4, 5] -class _ApplicationCommandOptional(TypedDict, total=False): - options: List[ApplicationCommandOption] - type: ApplicationCommandType - -class ApplicationCommand(_ApplicationCommandOptional): +class PartialChannel(TypedDict): id: Snowflake - application_id: Snowflake name: str - description: str + type: ChannelType + permissions: str -class _ApplicationCommandOptionOptional(TypedDict, total=False): - choices: List[ApplicationCommandOptionChoice] - options: List[ApplicationCommandOption] +class PartialThread(PartialChannel): + thread_metadata: ThreadMetadata + parent_id: Snowflake -ApplicationCommandOptionType = Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +class ResolvedData(TypedDict, total=False): + users: Dict[Snowflake, User] + members: Dict[Snowflake, Member] + roles: Dict[Snowflake, Role] + channels: Dict[Snowflake, Union[PartialChannel, PartialThread]] + messages: Dict[Snowflake, Message] + attachments: Dict[Snowflake, Attachment] -class ApplicationCommandOption(_ApplicationCommandOptionOptional): - type: ApplicationCommandOptionType +class _BaseApplicationCommandInteractionDataOption(TypedDict): name: str - description: str - required: bool -class ApplicationCommandOptionChoice(TypedDict): - name: str - value: Union[str, int] +class _CommandGroupApplicationCommandInteractionDataOption(_BaseApplicationCommandInteractionDataOption): + type: Literal[1, 2] + options: List[ApplicationCommandInteractionDataOption] -ApplicationCommandPermissionType = Literal[1, 2] +class _BaseValueApplicationCommandInteractionDataOption(_BaseApplicationCommandInteractionDataOption, total=False): + focused: bool -class ApplicationCommandPermissions(TypedDict): - id: Snowflake - type: ApplicationCommandPermissionType - permission: bool +class _StringValueApplicationCommandInteractionDataOption(_BaseValueApplicationCommandInteractionDataOption): + type: Literal[3] + value: str -class BaseGuildApplicationCommandPermissions(TypedDict): - permissions: List[ApplicationCommandPermissions] +class _IntegerValueApplicationCommandInteractionDataOption(_BaseValueApplicationCommandInteractionDataOption): + type: Literal[4] + value: int -class PartialGuildApplicationCommandPermissions(BaseGuildApplicationCommandPermissions): - id: Snowflake +class _BooleanValueApplicationCommandInteractionDataOption(_BaseValueApplicationCommandInteractionDataOption): + type: Literal[5] + value: bool -class GuildApplicationCommandPermissions(PartialGuildApplicationCommandPermissions): - application_id: Snowflake - guild_id: Snowflake +class _SnowflakeValueApplicationCommandInteractionDataOption(_BaseValueApplicationCommandInteractionDataOption): + type: Literal[6, 7, 8, 9, 11] + value: Snowflake + + +class _NumberValueApplicationCommandInteractionDataOption(_BaseValueApplicationCommandInteractionDataOption): + type: Literal[10] + value: float -InteractionType = Literal[1, 2, 3] +_ValueApplicationCommandInteractionDataOption = Union[ + _StringValueApplicationCommandInteractionDataOption, + _IntegerValueApplicationCommandInteractionDataOption, + _BooleanValueApplicationCommandInteractionDataOption, + _SnowflakeValueApplicationCommandInteractionDataOption, + _NumberValueApplicationCommandInteractionDataOption, +] + + +ApplicationCommandInteractionDataOption = Union[ + _CommandGroupApplicationCommandInteractionDataOption, + _ValueApplicationCommandInteractionDataOption, +] -class _ApplicationCommandInteractionDataOption(TypedDict): +class _BaseApplicationCommandInteractionDataOptional(TypedDict): + resolved: ResolvedData + + +class _BaseApplicationCommandInteractionData(_BaseApplicationCommandInteractionDataOptional): + id: Snowflake name: str -class _ApplicationCommandInteractionDataOptionSubcommand(_ApplicationCommandInteractionDataOption): - type: Literal[1, 2] +class ChatInputApplicationCommandInteractionData(_BaseApplicationCommandInteractionData, total=False): + type: Literal[1] options: List[ApplicationCommandInteractionDataOption] -class _ApplicationCommandInteractionDataOptionString(_ApplicationCommandInteractionDataOption): - type: Literal[3] - value: str +class _BaseNonChatInputApplicationCommandInteractionData(_BaseApplicationCommandInteractionData): + target_id: Snowflake -class _ApplicationCommandInteractionDataOptionInteger(_ApplicationCommandInteractionDataOption): - type: Literal[4] - value: int +class UserApplicationCommandInteractionData(_BaseNonChatInputApplicationCommandInteractionData): + type: Literal[2] -class _ApplicationCommandInteractionDataOptionBoolean(_ApplicationCommandInteractionDataOption): - type: Literal[5] - value: bool +class MessageApplicationCommandInteractionData(_BaseNonChatInputApplicationCommandInteractionData): + type: Literal[3] -class _ApplicationCommandInteractionDataOptionSnowflake(_ApplicationCommandInteractionDataOption): - type: Literal[6, 7, 8, 9] - value: Snowflake +ApplicationCommandInteractionData = Union[ + ChatInputApplicationCommandInteractionData, + UserApplicationCommandInteractionData, + MessageApplicationCommandInteractionData, +] -class _ApplicationCommandInteractionDataOptionNumber(_ApplicationCommandInteractionDataOption): - type: Literal[10] - value: float +class _BaseMessageComponentInteractionData(TypedDict): + custom_id: str -ApplicationCommandInteractionDataOption = Union[ - _ApplicationCommandInteractionDataOptionString, - _ApplicationCommandInteractionDataOptionInteger, - _ApplicationCommandInteractionDataOptionSubcommand, - _ApplicationCommandInteractionDataOptionBoolean, - _ApplicationCommandInteractionDataOptionSnowflake, - _ApplicationCommandInteractionDataOptionNumber, -] +class ButtonMessageComponentInteractionData(_BaseMessageComponentInteractionData): + type: Literal[2] -class ApplicationCommandResolvedPartialChannel(TypedDict): - id: Snowflake - type: ChannelType - permissions: str - name: str +class SelectMessageComponentInteractionData(_BaseMessageComponentInteractionData): + component_type: Literal[3] + values: List[str] -class ApplicationCommandInteractionDataResolved(TypedDict, total=False): - users: Dict[Snowflake, User] - members: Dict[Snowflake, Member] - roles: Dict[Snowflake, Role] - channels: Dict[Snowflake, ApplicationCommandResolvedPartialChannel] +MessageComponentInteractionData = Union[ButtonMessageComponentInteractionData, SelectMessageComponentInteractionData] -class _ApplicationCommandInteractionDataOptional(TypedDict, total=False): - options: List[ApplicationCommandInteractionDataOption] - resolved: ApplicationCommandInteractionDataResolved - target_id: Snowflake - type: ApplicationCommandType +class ModalSubmitInputTextInteractionData(TypedDict): + type: Literal[4] + custom_id: str + value: str -class ApplicationCommandInteractionData(_ApplicationCommandInteractionDataOptional): - id: Snowflake - name: str +ModalSubmitComponentItemInteractionData = ModalSubmitInputTextInteractionData -class _ComponentInteractionDataOptional(TypedDict, total=False): - values: List[str] +class ModalSubmitActionRowInteractionData(TypedDict): + type: Literal[1] + components: List[ModalSubmitComponentItemInteractionData] + + +ModalSubmitComponentInteractionData = Union[ModalSubmitActionRowInteractionData, ModalSubmitComponentItemInteractionData] -class ComponentInteractionData(_ComponentInteractionDataOptional): +class ModalSubmitInteractionData(TypedDict): custom_id: str - component_type: ComponentType + components: List[ModalSubmitActionRowInteractionData] -InteractionData = Union[ApplicationCommandInteractionData, ComponentInteractionData] +InteractionData = Union[ + ApplicationCommandInteractionData, + MessageComponentInteractionData, + ModalSubmitInteractionData, +] -class _InteractionOptional(TypedDict, total=False): - data: InteractionData +class _BaseInteractionOptional(TypedDict, total=False): guild_id: Snowflake channel_id: Snowflake - member: Member - user: User - message: Message -class Interaction(_InteractionOptional): +class _BaseInteraction(_BaseInteractionOptional): id: Snowflake application_id: Snowflake - type: InteractionType token: str - version: int + version: Literal[1] -class InteractionApplicationCommandCallbackData(TypedDict, total=False): - tts: bool - content: str - embeds: List[Embed] - allowed_mentions: AllowedMentions - flags: int - components: List[Component] +class PingInteraction(_BaseInteraction): + type: Literal[1] -InteractionResponseType = Literal[1, 4, 5, 6, 7] +class ApplicationCommandInteraction(_BaseInteraction): + type: Literal[2, 4] + data: ApplicationCommandInteractionData -class _InteractionResponseOptional(TypedDict, total=False): - data: InteractionApplicationCommandCallbackData +class MessageComponentInteraction(_BaseInteraction): + type: Literal[3] + data: MessageComponentInteractionData -class InteractionResponse(_InteractionResponseOptional): - type: InteractionResponseType +class ModalSubmitInteraction(_BaseInteraction): + type: Literal[5] + data: ModalSubmitInteractionData + + +Interaction = Union[PingInteraction, ApplicationCommandInteraction, MessageComponentInteraction, ModalSubmitInteraction] class MessageInteraction(TypedDict): @@ -220,17 +231,3 @@ class MessageInteraction(TypedDict): type: InteractionType name: str user: User - - - - - -class _EditApplicationCommandOptional(TypedDict, total=False): - description: str - options: Optional[List[ApplicationCommandOption]] - type: ApplicationCommandType - - -class EditApplicationCommand(_EditApplicationCommandOptional): - name: str - default_permission: bool