mirror of
https://github.com/MelisaDev/melisa.git
synced 2024-11-11 19:07:28 +03:00
feat(interactions): slashcommands base
This commit is contained in:
parent
b4128f8c80
commit
9b1d710bce
5 changed files with 228 additions and 148 deletions
|
@ -70,9 +70,9 @@ class HTTPClient:
|
||||||
*,
|
*,
|
||||||
_ttl: int = None,
|
_ttl: int = None,
|
||||||
headers: Optional[Dict[str, Any]] = None,
|
headers: Optional[Dict[str, Any]] = None,
|
||||||
params: Optional[Dict] = None,
|
params: Optional[Dict[str, Any]] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> Optional[Dict]:
|
) -> Optional[Dict[str, Any]]:
|
||||||
"""Send an API request to the Discord API."""
|
"""Send an API request to the Discord API."""
|
||||||
|
|
||||||
ttl = _ttl or self.max_ttl
|
ttl = _ttl or self.max_ttl
|
||||||
|
@ -113,7 +113,7 @@ class HTTPClient:
|
||||||
*,
|
*,
|
||||||
_ttl: int = None,
|
_ttl: int = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> Optional[Dict]:
|
) -> Optional[Dict[str, Any]]:
|
||||||
"""Handle responses from the Discord API."""
|
"""Handle responses from the Discord API."""
|
||||||
|
|
||||||
_logger.debug(f"Received response for the {endpoint} ({await res.text()})")
|
_logger.debug(f"Received response for the {endpoint} ({await res.text()})")
|
||||||
|
@ -165,7 +165,7 @@ class HTTPClient:
|
||||||
|
|
||||||
return await self.__send(method, endpoint, _ttl=_ttl - 1, **kwargs)
|
return await self.__send(method, endpoint, _ttl=_ttl - 1, **kwargs)
|
||||||
|
|
||||||
async def get(self, route: str, *, params: Optional[Dict] = None) -> Optional[Dict]:
|
async def get(self, route: str, *, params: Optional[Dict[str, Any]] = None) -> Optional[Dict[str, Any]]:
|
||||||
"""|coro|
|
"""|coro|
|
||||||
Sends a GET request to a Discord REST API endpoint.
|
Sends a GET request to a Discord REST API endpoint.
|
||||||
|
|
||||||
|
@ -187,22 +187,22 @@ class HTTPClient:
|
||||||
self,
|
self,
|
||||||
route: str,
|
route: str,
|
||||||
*,
|
*,
|
||||||
headers: dict = None,
|
headers: Dict[str, Any] = None,
|
||||||
json: Optional[Dict] = None,
|
json: Optional[Dict[str, Any]] = None,
|
||||||
data=None,
|
data: Optional[Dict[str, Any]] = None,
|
||||||
) -> Optional[Dict]:
|
) -> Optional[Dict[str, Any]]:
|
||||||
"""|coro|
|
"""|coro|
|
||||||
Sends a POST request to a Discord REST API endpoint.
|
Sends a POST request to a Discord REST API endpoint.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
route : :class:`str`
|
route: :class:`str`
|
||||||
The endpoint to send the request to.
|
The endpoint to send the request to.
|
||||||
json : Dict
|
json: Dict[str, Any]
|
||||||
Json data to post
|
Json data to post
|
||||||
data : Any
|
data: Any
|
||||||
Data to post
|
Data to post
|
||||||
headers : :class:`dict`
|
headers: Dict[str, Any]
|
||||||
Custom request headers
|
Custom request headers
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
|
@ -212,7 +212,7 @@ class HTTPClient:
|
||||||
"""
|
"""
|
||||||
return await self.__send("POST", route, json=json, data=data, headers=headers)
|
return await self.__send("POST", route, json=json, data=data, headers=headers)
|
||||||
|
|
||||||
async def delete(self, route: str, *, headers: dict = None) -> Optional[Dict]:
|
async def delete(self, route: str, *, headers: Dict[str, Any] = None) -> Optional[Dict[str, Any]]:
|
||||||
"""|coro|
|
"""|coro|
|
||||||
Sends a DELETE request to a Discord REST API endpoint.
|
Sends a DELETE request to a Discord REST API endpoint.
|
||||||
|
|
||||||
|
@ -234,10 +234,10 @@ class HTTPClient:
|
||||||
self,
|
self,
|
||||||
route: str,
|
route: str,
|
||||||
*,
|
*,
|
||||||
headers: dict = None,
|
headers: Dict[str, Any] = None,
|
||||||
json: Optional[Dict] = None,
|
json: Optional[Dict[str, Any]] = None,
|
||||||
data=None,
|
data: Optional[Dict[str, Any]] = None,
|
||||||
) -> Optional[Dict]:
|
) -> Optional[Dict[str, Any]]:
|
||||||
"""|coro|
|
"""|coro|
|
||||||
Sends a PATCH request to a Discord REST API endpoint.
|
Sends a PATCH request to a Discord REST API endpoint.
|
||||||
|
|
||||||
|
@ -260,8 +260,8 @@ class HTTPClient:
|
||||||
return await self.__send("PATCH", route, json=json, data=data, headers=headers)
|
return await self.__send("PATCH", route, json=json, data=data, headers=headers)
|
||||||
|
|
||||||
async def put(
|
async def put(
|
||||||
self, route: str, *, headers: dict = None, data: Optional[Dict] = None
|
self, route: str, *, headers: Dict[str, Any] = None, data: Optional[Dict[str, Any]] = None
|
||||||
) -> Optional[Dict]:
|
) -> Optional[Dict[str, Any]]:
|
||||||
"""|coro|
|
"""|coro|
|
||||||
Sends a PUT request to a Discord REST API endpoint.
|
Sends a PUT request to a Discord REST API endpoint.
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Copyright MelisaDev 2022 - Present
|
# Copyright MelisaDev 2022 - Present
|
||||||
# Full MIT License can be found in `LICENSE.txt` at the project root.
|
# Full MIT License can be found in `LICENSE.txt` at the project root.
|
||||||
|
|
||||||
from .commands import ApplicationCommandTypes
|
from .commands import ApplicationCommandType
|
||||||
|
|
||||||
|
|
||||||
__all__ = "ApplicationCommandTypes"
|
__all__ = "ApplicationCommandTypes"
|
||||||
|
|
|
@ -6,14 +6,15 @@ from __future__ import annotations
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
from typing import Optional, Dict, Union, Any, List
|
from typing import Optional, Dict, Union, Any, List
|
||||||
|
|
||||||
|
from .i18n import LocalizedField
|
||||||
from ..guild.channel import ChannelType
|
from ..guild.channel import ChannelType
|
||||||
from ...utils.snowflake import Snowflake
|
from ...utils.snowflake import Snowflake
|
||||||
from ...utils.conversion import try_enum
|
from ...utils.conversion import try_enum
|
||||||
from ...utils.api_model import APIModelBase
|
from ...utils.api_model import APIModelBase
|
||||||
|
|
||||||
|
|
||||||
class ApplicationCommandTypes(IntEnum):
|
class ApplicationCommandType(IntEnum):
|
||||||
"""Application Command Types
|
"""Application Command Type
|
||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
----------
|
----------
|
||||||
|
@ -33,8 +34,8 @@ class ApplicationCommandTypes(IntEnum):
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
|
|
||||||
class ApplicationCommandOptionTypes(IntEnum):
|
class SlashCommandOptionType(IntEnum):
|
||||||
"""Application Command Option Types
|
"""Application Command Option Type
|
||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
----------
|
----------
|
||||||
|
@ -78,43 +79,27 @@ class ApplicationCommandOptionTypes(IntEnum):
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
|
|
||||||
class ApplicationCommand(APIModelBase):
|
class PartialApplicationCommand(APIModelBase):
|
||||||
"""Application Command
|
"""Represents Partial Application Command
|
||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
----------
|
----------
|
||||||
id: :class:`~melisa.utils.snowflake.Snowflake`
|
id: :class:`~melisa.utils.snowflake.Snowflake`
|
||||||
Unique ID of command
|
Unique ID of command
|
||||||
type: Optional[:class:`~melisa.interactions.commands.ApplicationCommandTypes`]
|
type: Optional[:class:`~melisa.interactions.commands.SlashCommandType`]
|
||||||
Type of command, defaults to ``1``
|
Type of command, defaults to ``1``
|
||||||
application_id: :class:`~melisa.utils.snowflake.Snowflake`
|
application_id: :class:`~melisa.utils.snowflake.Snowflake`
|
||||||
ID of the parent application
|
ID of the parent application
|
||||||
guild_id: Optional[:class:`~melisa.utils.snowflake.Snowflake`]
|
guild_id: Optional[:class:`~melisa.utils.snowflake.Snowflake`]
|
||||||
guild id of the command, if not global
|
guild id of the command, if not global
|
||||||
name: str
|
name: :class:`~melisa.models.interactions.i18n.LocalizedField`
|
||||||
Name of command, 1-32 characters
|
Name of the command
|
||||||
name_localizations: Optional[Dict[str, str]]
|
default_member_permissions: str
|
||||||
Localization dictionary for ``name`` field.
|
|
||||||
Values follow the same restrictions as ``name``
|
|
||||||
description: str
|
|
||||||
Description for ``CHAT_INPUT`` commands, 1-100 characters.
|
|
||||||
Empty string for ``USER`` and ``MESSAGE`` commands
|
|
||||||
description_localizations: Optional[Dict[str, str]]
|
|
||||||
Localization dictionary for ``description`` field.
|
|
||||||
Values follow the same restrictions as ``description``
|
|
||||||
options: Optional[List[:class:`~melisa.models.interactions.commands.ApplicationCommandOption`]]
|
|
||||||
Parameters for the command, max of 25.
|
|
||||||
Only available for ``CHAT_INPUT`` command type.
|
|
||||||
default_member_permissions: Optional[str]
|
|
||||||
Set of permissions represented as a bit set
|
Set of permissions represented as a bit set
|
||||||
dm_permission: Optional[bool]
|
dm_permission: bool
|
||||||
Indicates whether the command is available
|
Indicates whether the command is available
|
||||||
in DMs with the app, only for globally-scoped commands.
|
in DMs with the app, only for globally-scoped commands.
|
||||||
By default, commands are visible.
|
By default, commands are visible.
|
||||||
default_permission: Optional[bool]
|
|
||||||
Not recommended for use as field will soon be deprecated.
|
|
||||||
Indicates whether the command is enabled by default
|
|
||||||
when the app is added to a guild, defaults to true
|
|
||||||
version: :class:`~melisa.utils.snowflake.Snowflake`
|
version: :class:`~melisa.utils.snowflake.Snowflake`
|
||||||
Autoincrementing version identifier updated during substantial record changes
|
Autoincrementing version identifier updated during substantial record changes
|
||||||
"""
|
"""
|
||||||
|
@ -122,17 +107,12 @@ class ApplicationCommand(APIModelBase):
|
||||||
# ToDo: Better Permissions
|
# ToDo: Better Permissions
|
||||||
|
|
||||||
id: Snowflake = None
|
id: Snowflake = None
|
||||||
type: Optional[ApplicationCommandTypes] = 1
|
type: Optional[ApplicationCommandType] = 1
|
||||||
application_id: Snowflake = None
|
application_id: Snowflake = None
|
||||||
guild_id: Optional[Snowflake] = None
|
guild_id: Optional[Snowflake] = None
|
||||||
name: str = None
|
name: LocalizedField = None
|
||||||
name_localizations: Optional[Dict[str, str]] = None
|
default_member_permissions: str = None
|
||||||
description: str = None
|
dm_permission: bool = True
|
||||||
description_localizations: Optional[Dict[str, str]] = None
|
|
||||||
options: Optional[List[ApplicationCommandOption]] = None
|
|
||||||
default_member_permissions: Optional[str] = None
|
|
||||||
dm_permission: Optional[bool] = True
|
|
||||||
default_permission: Optional[bool] = True
|
|
||||||
version: Snowflake = None
|
version: Snowflake = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -142,32 +122,76 @@ class ApplicationCommand(APIModelBase):
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
data: :class:`dict`
|
data: :class:`dict`
|
||||||
The dictionary to convert into a ApplicationCommand.
|
The dictionary to convert into a PartialApplicationCommand.
|
||||||
"""
|
"""
|
||||||
self: ApplicationCommand = super().__new__(cls)
|
self: PartialApplicationCommand = super().__new__(cls)
|
||||||
|
|
||||||
self.id = Snowflake(data.get("id", 0))
|
self.id = Snowflake(data.get("id", 0))
|
||||||
self.type = data.get("type", 1)
|
self.type = try_enum(ApplicationCommandType, data.get("type", 1))
|
||||||
|
self.application_id = Snowflake(data.get("application_id"))
|
||||||
|
self.guild_id = (
|
||||||
|
Snowflake(data["guild_id"]) if data.get("guild_id") is not None else None
|
||||||
|
)
|
||||||
|
|
||||||
|
name = data.get("name")
|
||||||
|
name_localizations = data.get("name_localizations")
|
||||||
|
|
||||||
|
self.name = LocalizedField(name, name_localizations)
|
||||||
|
|
||||||
|
self.default_member_permissions = data.get("default_member_permissions", "")
|
||||||
|
self.dm_permission = data.get("dm_permission", True)
|
||||||
|
self.version = Snowflake(data.get("version", 0))
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
class SlashCommand(PartialApplicationCommand):
|
||||||
|
"""Represents SlashCommand
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
description: :class:`~melisa.models.interactions.i18n.LocalizedField`
|
||||||
|
Description of command
|
||||||
|
"""
|
||||||
|
|
||||||
|
description: LocalizedField = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, data: Dict[str, Any]):
|
||||||
|
"""Generate a SlashCommand from the given data.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
data: :class:`dict`
|
||||||
|
The dictionary to convert into a SlashCommand.
|
||||||
|
"""
|
||||||
|
self: SlashCommand = super().__new__(cls)
|
||||||
|
|
||||||
|
self.id = Snowflake(data.get("id", 0))
|
||||||
|
self.type = try_enum(ApplicationCommandType, data.get("type", 1))
|
||||||
self.application_id = Snowflake(data.get("application_id"))
|
self.application_id = Snowflake(data.get("application_id"))
|
||||||
self.guild_id = (
|
self.guild_id = (
|
||||||
Snowflake(data["guild_id"]) if data.get("guild_id") is not None else None
|
Snowflake(data["guild_id"]) if data.get("guild_id") is not None else None
|
||||||
)
|
)
|
||||||
self.name = data.get("name")
|
self.name = data.get("name")
|
||||||
self.name_localizations = data.get("name_localizations")
|
self.name_localizations = data.get("name_localizations")
|
||||||
self.description = data.get("description")
|
|
||||||
self.description_localizations = data.get("description_localizations")
|
description = data.get("description")
|
||||||
|
description_localizations = data.get("description_localizations")
|
||||||
|
|
||||||
|
self.description = LocalizedField(description, description_localizations)
|
||||||
|
|
||||||
self.options = [
|
self.options = [
|
||||||
ApplicationCommandOption.from_dict(x) for x in data.get("options", [])
|
SlashCommandOption.from_dict(x) for x in data.get("options", [])
|
||||||
]
|
]
|
||||||
self.default_member_permissions = data.get("default_member_permissions")
|
self.default_member_permissions = data.get("default_member_permissions", "")
|
||||||
self.dm_permission = data.get("dm_permission", True)
|
self.dm_permission = data.get("dm_permission", True)
|
||||||
self.default_permission = data.get("default_permission", True)
|
|
||||||
self.version = Snowflake(data.get("version", 0))
|
self.version = Snowflake(data.get("version", 0))
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
class ApplicationCommandOption(APIModelBase):
|
class SlashCommandOption(APIModelBase):
|
||||||
"""Application Command Option
|
"""Application Command Option
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
@ -176,7 +200,7 @@ class ApplicationCommandOption(APIModelBase):
|
||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
----------
|
----------
|
||||||
type: :class:`~melisa.models.interactions.commands.ApplicationCommandOptionTypes`
|
type: :class:`~melisa.models.interactions.commands.SlashCommandOptionType`
|
||||||
Type of option
|
Type of option
|
||||||
name: str
|
name: str
|
||||||
1-32 character name
|
1-32 character name
|
||||||
|
@ -190,10 +214,10 @@ class ApplicationCommandOption(APIModelBase):
|
||||||
Values follow the same restrictions as ``description``
|
Values follow the same restrictions as ``description``
|
||||||
required: Optional[bool]
|
required: Optional[bool]
|
||||||
If the parameter is required or optional--default false
|
If the parameter is required or optional--default false
|
||||||
choices: Optional[List[:class:`~melisa.models.interactions.commands.ApplicationCommandOptionChoice`]]
|
choices: Optional[List[:class:`~melisa.models.interactions.commands.SlashCommandOptionChoice`]]
|
||||||
Choices for ``STRING``, ``INTEGER``, and ``NUMBER``
|
Choices for ``STRING``, ``INTEGER``, and ``NUMBER``
|
||||||
types for the user to pick from, max 25
|
types for the user to pick from, max 25
|
||||||
options: Optional[List[ApplicationCommandOption]]
|
options: Optional[List[SlashCommandOption]]
|
||||||
If the option is a subcommand or subcommand group type,
|
If the option is a subcommand or subcommand group type,
|
||||||
these nested options will be the parameters
|
these nested options will be the parameters
|
||||||
channel_types: Optional[List[:class:`~melisa.models.guild.channel.ChannelType`]]
|
channel_types: Optional[List[:class:`~melisa.models.guild.channel.ChannelType`]]
|
||||||
|
@ -210,14 +234,14 @@ class ApplicationCommandOption(APIModelBase):
|
||||||
``int``, or ``float`` type option
|
``int``, or ``float`` type option
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type: ApplicationCommandOptionTypes = None
|
type: SlashCommandOptionType = None
|
||||||
name: str = None
|
name: str = None
|
||||||
name_localizations: Dict[str, str] = None
|
name_localizations: Dict[str, str] = None
|
||||||
description: str
|
description: str
|
||||||
description_localizations: Dict[str, str] = None
|
description_localizations: Dict[str, str] = None
|
||||||
required: Optional[bool] = False
|
required: Optional[bool] = False
|
||||||
choices: Optional[List[ApplicationCommandOptionChoice]] = None
|
choices: Optional[List[SlashCommandOptionChoice]] = None
|
||||||
options: Optional[List[ApplicationCommandOption]] = None
|
options: Optional[List[SlashCommandOption]] = None
|
||||||
channel_types: Optional[List[ChannelType]] = None
|
channel_types: Optional[List[ChannelType]] = None
|
||||||
min_value: Optional[int, float] = None
|
min_value: Optional[int, float] = None
|
||||||
max_value: Optional[int, float] = None
|
max_value: Optional[int, float] = None
|
||||||
|
@ -225,26 +249,26 @@ class ApplicationCommandOption(APIModelBase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, data: Dict[str, Any]):
|
def from_dict(cls, data: Dict[str, Any]):
|
||||||
"""Generate a ApplicationCommandOption from the given data.
|
"""Generate a SlashCommandOption from the given data.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
data: :class:`dict`
|
data: :class:`dict`
|
||||||
The dictionary to convert into a ApplicationCommandOption.
|
The dictionary to convert into a SlashCommandOption.
|
||||||
"""
|
"""
|
||||||
self: ApplicationCommandOption = super().__new__(cls)
|
self: SlashCommandOption = super().__new__(cls)
|
||||||
|
|
||||||
self.type = try_enum(ApplicationCommandOptionTypes, data.get("type", 0))
|
self.type = try_enum(SlashCommandOptionType, data.get("type", 0))
|
||||||
self.name = data.get("name")
|
self.name = data.get("name")
|
||||||
self.name_localizations = data.get("name_localizations")
|
self.name_localizations = data.get("name_localizations")
|
||||||
self.description = data.get("description")
|
self.description = data.get("description")
|
||||||
self.description_localizations = data.get("description_localizations")
|
self.description_localizations = data.get("description_localizations")
|
||||||
self.required = data.get("required", False)
|
self.required = data.get("required", False)
|
||||||
self.choices = [
|
self.choices = [
|
||||||
try_enum(ApplicationCommandOptionChoice, x) for x in data.get("choices", [])
|
try_enum(SlashCommandOptionChoice, x) for x in data.get("choices", [])
|
||||||
]
|
]
|
||||||
self.options = [
|
self.options = [
|
||||||
ApplicationCommandOption.from_dict(x) for x in data.get("options", [])
|
SlashCommandOption.from_dict(x) for x in data.get("options", [])
|
||||||
]
|
]
|
||||||
self.channel_types = [
|
self.channel_types = [
|
||||||
try_enum(ChannelType, x) for x in data.get("channel_types", [])
|
try_enum(ChannelType, x) for x in data.get("channel_types", [])
|
||||||
|
@ -256,7 +280,7 @@ class ApplicationCommandOption(APIModelBase):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
class ApplicationCommandOptionChoice(APIModelBase):
|
class SlashCommandOptionChoice(APIModelBase):
|
||||||
"""Application Command Option Choice
|
"""Application Command Option Choice
|
||||||
|
|
||||||
If you specify ``choices`` for an option,
|
If you specify ``choices`` for an option,
|
||||||
|
@ -283,14 +307,14 @@ class ApplicationCommandOptionChoice(APIModelBase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, data: Dict[str, Any]):
|
def from_dict(cls, data: Dict[str, Any]):
|
||||||
"""Generate a ApplicationCommandOptionChoice from the given data.
|
"""Generate a SlashCommandOptionChoice from the given data.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
data: :class:`dict`
|
data: :class:`dict`
|
||||||
The dictionary to convert into a ApplicationCommandOptionChoice.
|
The dictionary to convert into a SlashCommandOptionChoice.
|
||||||
"""
|
"""
|
||||||
self: ApplicationCommandOptionChoice = super().__new__(cls)
|
self: SlashCommandOptionChoice = super().__new__(cls)
|
||||||
|
|
||||||
self.name = data.get("name")
|
self.name = data.get("name")
|
||||||
self.name_localizations = data.get("name_localizations")
|
self.name_localizations = data.get("name_localizations")
|
||||||
|
@ -299,8 +323,8 @@ class ApplicationCommandOptionChoice(APIModelBase):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
class ApplicationCommandInteractionDataOption(APIModelBase):
|
class SlashCommandInteractionDataOption(APIModelBase):
|
||||||
"""Application Command Interaction Data Option
|
"""Slash Command Interaction Data Option
|
||||||
|
|
||||||
All options have names, and an option can either be a parameter
|
All options have names, and an option can either be a parameter
|
||||||
and input value--in which case ``value`` will be set--or it
|
and input value--in which case ``value`` will be set--or it
|
||||||
|
@ -313,40 +337,53 @@ class ApplicationCommandInteractionDataOption(APIModelBase):
|
||||||
----------
|
----------
|
||||||
name: :class:`str`
|
name: :class:`str`
|
||||||
Name of the parameter
|
Name of the parameter
|
||||||
type: :class:`~melisa.models.interactions.commands.ApplicationCommandOptionTypes`
|
type: :class:`~melisa.models.interactions.commands.SlashCommandOptionType`
|
||||||
Value of :class:`~melisa.models.interactions.commands.ApplicationCommandOptionTypes`
|
Value of :class:`~melisa.models.interactions.commands.SlashCommandOptionType`
|
||||||
value: Optional[Union[str, int, float]]
|
value: Optional[Union[str, int, float]]
|
||||||
Value of the option resulting from user input
|
Value of the option resulting from user input
|
||||||
options: Optional[List[ApplicationCommandInteractionDataOption]]
|
options: Optional[List[SlashCommandInteractionDataOption]]
|
||||||
Present if this option is a group or subcommand
|
Present if this option is a group or subcommand
|
||||||
focused: Optional[bool]
|
focused: Optional[bool]
|
||||||
``true`` if this option is the currently focused option for autocomplete
|
``true`` if this option is the currently focused option for autocomplete
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name: str = None
|
name: str = None
|
||||||
type: ApplicationCommandOptionTypes = None
|
type: SlashCommandOptionType = None
|
||||||
value: Optional[Union[str, int, float]] = None
|
value: Optional[Union[str, int, float]] = None
|
||||||
options: Optional[List[ApplicationCommandInteractionDataOption]] = None
|
options: Optional[List[SlashCommandInteractionDataOption]] = None
|
||||||
focused: Optional[bool] = None
|
focused: bool = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, data: Dict[str, Any]):
|
def from_dict(cls, data: Dict[str, Any]):
|
||||||
"""Generate a ApplicationCommandInteractionDataOption from the given data.
|
"""Generate a SlashCommandInteractionDataOption from the given data.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
data: :class:`dict`
|
data: :class:`dict`
|
||||||
The dictionary to convert into a ApplicationCommandInteractionDataOption.
|
The dictionary to convert into a SlashCommandInteractionDataOption.
|
||||||
"""
|
"""
|
||||||
self: ApplicationCommandInteractionDataOption = super().__new__(cls)
|
self: SlashCommandInteractionDataOption = super().__new__(cls)
|
||||||
|
|
||||||
self.name = data.get("name")
|
self.name = data.get("name")
|
||||||
self.type = try_enum(ApplicationCommandOptionTypes, data.get("type", 0))
|
self.type = try_enum(SlashCommandOptionType, data.get("type", 0))
|
||||||
self.value = data.get("value")
|
self.value = data.get("value")
|
||||||
self.options = [
|
self.options = [
|
||||||
ApplicationCommandInteractionDataOption.from_dict(x)
|
SlashCommandInteractionDataOption.from_dict(x)
|
||||||
for x in data.get("options", [])
|
for x in data.get("options", [])
|
||||||
]
|
]
|
||||||
self.focused = data.get("focused")
|
self.focused = data.get("focused", False)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyTypeChecker
|
||||||
|
command_types_for_converting: Dict[ApplicationCommandType, PartialApplicationCommand] = {
|
||||||
|
ApplicationCommandType.CHAT_INPUT: SlashCommand
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _choose_command_type(data):
|
||||||
|
data.update({"type": ApplicationCommandType(data.pop("type"))})
|
||||||
|
|
||||||
|
command_cls = command_types_for_converting.get(data["type"], PartialApplicationCommand)
|
||||||
|
return command_cls.from_dict(data)
|
||||||
|
|
57
melisa/models/interactions/i18n.py
Normal file
57
melisa/models/interactions/i18n.py
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
# Copyright MelisaDev 2022 - Present
|
||||||
|
# Full MIT License can be found in `LICENSE.txt` at the project root.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
|
|
||||||
|
class LocalizedField:
|
||||||
|
original: str
|
||||||
|
localizations: str
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
original: str = None,
|
||||||
|
localizations: Dict[str, str] = None,
|
||||||
|
):
|
||||||
|
self.original: str = original
|
||||||
|
self.localizations: Dict[str, str] = localizations
|
||||||
|
|
||||||
|
def insert(self, locale: str, value: str) -> LocalizedField:
|
||||||
|
self.localizations[locale] = value
|
||||||
|
return self
|
||||||
|
|
||||||
|
def remove(self, locale: str) -> LocalizedField:
|
||||||
|
self.localizations.pop(locale, None)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<LocalizedField original={self.original} localizations={self.localizations}>"
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return self.original == other.original and self.localizations == other.localizations
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash((self.original, self.localizations))
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return self.localizations[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
self.localizations[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key):
|
||||||
|
self.localizations.pop(key, None)
|
||||||
|
|
||||||
|
def __contains__(self, key):
|
||||||
|
return key in self.localizations
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return iter(self.localizations)
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.localizations)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.original
|
|
@ -6,8 +6,10 @@ from typing import Union, Optional, List, Dict, Any, AsyncIterator
|
||||||
|
|
||||||
from aiohttp import FormData
|
from aiohttp import FormData
|
||||||
|
|
||||||
from .models.interactions import ApplicationCommandTypes
|
from .models.interactions import ApplicationCommandType
|
||||||
from .models.interactions.commands import ApplicationCommandOption, ApplicationCommand
|
from .models.interactions.commands import SlashCommandOption, SlashCommand, PartialApplicationCommand, \
|
||||||
|
_choose_command_type
|
||||||
|
from .models.interactions.i18n import LocalizedField
|
||||||
from .models.message import Embed, File, AllowedMentions, Message
|
from .models.message import Embed, File, AllowedMentions, Message
|
||||||
from .exceptions import EmbedFieldError
|
from .exceptions import EmbedFieldError
|
||||||
from .core.http import HTTPClient
|
from .core.http import HTTPClient
|
||||||
|
@ -856,7 +858,7 @@ class RESTApp:
|
||||||
application_id: Union[int, str, Snowflake],
|
application_id: Union[int, str, Snowflake],
|
||||||
*,
|
*,
|
||||||
with_localizations: Optional[bool] = False,
|
with_localizations: Optional[bool] = False,
|
||||||
) -> List[ApplicationCommand]:
|
) -> List[PartialApplicationCommand]:
|
||||||
"""|coro|
|
"""|coro|
|
||||||
|
|
||||||
[**REST API**] Fetch all of the global commands for your application.
|
[**REST API**] Fetch all of the global commands for your application.
|
||||||
|
@ -882,7 +884,7 @@ class RESTApp:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return [
|
return [
|
||||||
ApplicationCommand.from_dict(x)
|
_choose_command_type(x)
|
||||||
for x in await self._http.get(
|
for x in await self._http.get(
|
||||||
f"/applications/{application_id}/commands?with_localizations={with_localizations}"
|
f"/applications/{application_id}/commands?with_localizations={with_localizations}"
|
||||||
)
|
)
|
||||||
|
@ -891,17 +893,15 @@ class RESTApp:
|
||||||
async def create_global_application_command(
|
async def create_global_application_command(
|
||||||
self,
|
self,
|
||||||
application_id: Union[int, str, Snowflake],
|
application_id: Union[int, str, Snowflake],
|
||||||
command_type: ApplicationCommandTypes,
|
command_type: ApplicationCommandType,
|
||||||
name: str,
|
name: LocalizedField,
|
||||||
description: str = None,
|
description: LocalizedField = None,
|
||||||
*,
|
*,
|
||||||
name_localizations: Optional[Dict[str, str]] = None,
|
options: Optional[List[SlashCommandOption]] = None,
|
||||||
description_localizations: Optional[Dict[str, str]] = None,
|
|
||||||
options: Optional[List[ApplicationCommandOption]] = None,
|
|
||||||
default_member_permissions: Optional[str] = None,
|
default_member_permissions: Optional[str] = None,
|
||||||
dm_permission: Optional[bool] = None,
|
dm_permission: Optional[bool] = None,
|
||||||
default_permission: Optional[bool] = None,
|
default_permission: Optional[bool] = None,
|
||||||
) -> ApplicationCommand:
|
) -> PartialApplicationCommand:
|
||||||
"""|coro|
|
"""|coro|
|
||||||
|
|
||||||
[**REST API**] Create a new global command.
|
[**REST API**] Create a new global command.
|
||||||
|
@ -910,20 +910,14 @@ class RESTApp:
|
||||||
----------
|
----------
|
||||||
application_id: :class:`~melisa.utils.snowflake.Snowflake`
|
application_id: :class:`~melisa.utils.snowflake.Snowflake`
|
||||||
ID of the parent application
|
ID of the parent application
|
||||||
command_type: Optional[:class:`~melisa.interactions.commands.ApplicationCommandTypes`]
|
command_type: Optional[:class:`~melisa.interactions.commands.ApplicationCommandType`]
|
||||||
Type of command, defaults to ``1``
|
Type of command, defaults to ``1``
|
||||||
name: str
|
name: :class:`~melisa.models.interactions.i18n.LocalizedField`
|
||||||
Name of command, 1-32 characters
|
Name of command, 1-32 characters
|
||||||
description: str
|
description: Optional[:class:`~melisa.models.interactions.i18n.LocalizedField`]
|
||||||
Description for ``CHAT_INPUT`` commands, 1-100 characters.
|
Description for ``CHAT_INPUT`` commands, 1-100 characters.
|
||||||
Empty string for ``USER`` and ``MESSAGE`` commands
|
Empty string for ``USER`` and ``MESSAGE`` commands
|
||||||
name_localizations: Optional[Dict[str, str]]
|
options: Optional[List[:class:`~melisa.models.interactions.commands.SlashCommandOption`]]
|
||||||
Localization dictionary for ``name`` field.
|
|
||||||
Values follow the same restrictions as ``name``
|
|
||||||
description_localizations: Optional[Dict[str, str]]
|
|
||||||
Localization dictionary for ``description`` field.
|
|
||||||
Values follow the same restrictions as ``description``
|
|
||||||
options: Optional[List[:class:`~melisa.models.interactions.commands.ApplicationCommandOption`]]
|
|
||||||
Parameters for the command, max of 25.
|
Parameters for the command, max of 25.
|
||||||
Only available for ``CHAT_INPUT`` command type.
|
Only available for ``CHAT_INPUT`` command type.
|
||||||
default_member_permissions: Optional[str]
|
default_member_permissions: Optional[str]
|
||||||
|
@ -948,16 +942,16 @@ class RESTApp:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
"name": name,
|
"name": name.original,
|
||||||
"description": description,
|
"description": description.original,
|
||||||
"type": int(command_type),
|
"type": int(command_type),
|
||||||
}
|
}
|
||||||
|
|
||||||
if name_localizations is not None:
|
if name.localizations is not None:
|
||||||
data["name_localizations"] = name_localizations
|
data["name_localizations"] = name.localizations
|
||||||
|
|
||||||
if description_localizations is not None:
|
if description.localizations is not None:
|
||||||
data["description_localizations"] = description_localizations
|
data["description_localizations"] = description.localizations
|
||||||
|
|
||||||
if default_member_permissions is not None:
|
if default_member_permissions is not None:
|
||||||
data["default_member_permissions"] = default_member_permissions
|
data["default_member_permissions"] = default_member_permissions
|
||||||
|
@ -971,7 +965,7 @@ class RESTApp:
|
||||||
if default_permission is not None:
|
if default_permission is not None:
|
||||||
data["default_permission"] = default_permission
|
data["default_permission"] = default_permission
|
||||||
|
|
||||||
return ApplicationCommand.from_dict(
|
return _choose_command_type(
|
||||||
await self._http.post(f"/applications/{application_id}/commands", json=data)
|
await self._http.post(f"/applications/{application_id}/commands", json=data)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -979,7 +973,7 @@ class RESTApp:
|
||||||
self,
|
self,
|
||||||
application_id: Union[int, str, Snowflake],
|
application_id: Union[int, str, Snowflake],
|
||||||
command_id: Union[int, str, Snowflake],
|
command_id: Union[int, str, Snowflake],
|
||||||
) -> ApplicationCommand:
|
) -> PartialApplicationCommand:
|
||||||
"""|coro|
|
"""|coro|
|
||||||
|
|
||||||
[**REST API**] Fetch a global command for your application.
|
[**REST API**] Fetch a global command for your application.
|
||||||
|
@ -1001,7 +995,7 @@ class RESTApp:
|
||||||
You provided a wrong arguments
|
You provided a wrong arguments
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return ApplicationCommand.from_dict(
|
return _choose_command_type(
|
||||||
await self._http.get(
|
await self._http.get(
|
||||||
f"/applications/{application_id}/commands/{command_id}"
|
f"/applications/{application_id}/commands/{command_id}"
|
||||||
)
|
)
|
||||||
|
@ -1012,15 +1006,13 @@ class RESTApp:
|
||||||
application_id: Union[int, str, Snowflake],
|
application_id: Union[int, str, Snowflake],
|
||||||
command_id: Union[int, str, Snowflake],
|
command_id: Union[int, str, Snowflake],
|
||||||
*,
|
*,
|
||||||
name: Optional[str] = None,
|
name: Optional[LocalizedField] = None,
|
||||||
description: Optional[str] = None,
|
description: Optional[LocalizedField] = None,
|
||||||
name_localizations: Optional[Dict[str, str]] = None,
|
options: Optional[List[SlashCommandOption]] = None,
|
||||||
description_localizations: Optional[Dict[str, str]] = None,
|
|
||||||
options: Optional[List[ApplicationCommandOption]] = None,
|
|
||||||
default_member_permissions: Optional[str] = None,
|
default_member_permissions: Optional[str] = None,
|
||||||
dm_permission: Optional[bool] = None,
|
dm_permission: Optional[bool] = None,
|
||||||
default_permission: Optional[bool] = None,
|
default_permission: Optional[bool] = None,
|
||||||
) -> ApplicationCommand:
|
) -> PartialApplicationCommand:
|
||||||
"""|coro|
|
"""|coro|
|
||||||
|
|
||||||
All parameters are optional, but any parameters
|
All parameters are optional, but any parameters
|
||||||
|
@ -1034,17 +1026,11 @@ class RESTApp:
|
||||||
ID of the parent application
|
ID of the parent application
|
||||||
command_id: Optional[bool]
|
command_id: Optional[bool]
|
||||||
ID of command to edit.
|
ID of command to edit.
|
||||||
name: Optional[str]
|
name: Optional[:class:`~melisa.models.interactions.i18n.LocalizedField`]
|
||||||
Name of command, 1-32 characters
|
Name of command, 1-32 characters
|
||||||
description: Optional[str]
|
description: Optional[:class:`~melisa.models.interactions.i18n.LocalizedField`]
|
||||||
Description for ``CHAT_INPUT`` commands, 1-100 characters.
|
Description for ``CHAT_INPUT`` commands, 1-100 characters.
|
||||||
Empty string for ``USER`` and ``MESSAGE`` commands
|
Empty string for ``USER`` and ``MESSAGE`` commands
|
||||||
name_localizations: Optional[Dict[str, str]]
|
|
||||||
Localization dictionary for ``name`` field.
|
|
||||||
Values follow the same restrictions as ``name``
|
|
||||||
description_localizations: Optional[Dict[str, str]]
|
|
||||||
Localization dictionary for ``description`` field.
|
|
||||||
Values follow the same restrictions as ``description``
|
|
||||||
options: Optional[List[:class:`~melisa.models.interactions.commands.ApplicationCommandOption`]]
|
options: Optional[List[:class:`~melisa.models.interactions.commands.ApplicationCommandOption`]]
|
||||||
Parameters for the command, max of 25.
|
Parameters for the command, max of 25.
|
||||||
Only available for ``CHAT_INPUT`` command type.
|
Only available for ``CHAT_INPUT`` command type.
|
||||||
|
@ -1071,17 +1057,17 @@ class RESTApp:
|
||||||
|
|
||||||
data = {}
|
data = {}
|
||||||
|
|
||||||
if name is not None:
|
if name.original is not None:
|
||||||
data["name"] = name
|
data["name"] = name.original
|
||||||
|
|
||||||
if description is not None:
|
if description.original is not None:
|
||||||
data["description"] = description
|
data["description"] = description.original
|
||||||
|
|
||||||
if name_localizations is not None:
|
if name.localizations is not None:
|
||||||
data["name_localizations"] = name_localizations
|
data["name_localizations"] = name.localizations
|
||||||
|
|
||||||
if description_localizations is not None:
|
if description.localizations is not None:
|
||||||
data["description_localizations"] = description_localizations
|
data["description_localizations"] = description.localizations
|
||||||
|
|
||||||
if default_member_permissions is not None:
|
if default_member_permissions is not None:
|
||||||
data["default_member_permissions"] = default_member_permissions
|
data["default_member_permissions"] = default_member_permissions
|
||||||
|
@ -1095,7 +1081,7 @@ class RESTApp:
|
||||||
if default_permission is not None:
|
if default_permission is not None:
|
||||||
data["default_permission"] = default_permission
|
data["default_permission"] = default_permission
|
||||||
|
|
||||||
return ApplicationCommand.from_dict(
|
return _choose_command_type(
|
||||||
await self._http.patch(
|
await self._http.patch(
|
||||||
f"/applications/{application_id}/commands/{command_id}", json=data
|
f"/applications/{application_id}/commands/{command_id}", json=data
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue