diff --git a/melisa/models/guild/channel.py b/melisa/models/guild/channel.py index 0528be6..c899a06 100644 --- a/melisa/models/guild/channel.py +++ b/melisa/models/guild/channel.py @@ -18,7 +18,7 @@ from typing import ( ) from ..message.file import File, create_form -from ..message.message import Message +from ..message.message import Message, AllowedMentions from ...exceptions import EmbedFieldError from ...models.message.embed import Embed from ...utils import Snowflake, Timestamp @@ -519,6 +519,7 @@ class MessageableChannel(Channel): embeds: List[Embed] = None, file: File = None, files: List[File] = None, + allowed_mentions: AllowedMentions = None, ) -> Message: """|coro| @@ -567,7 +568,9 @@ class MessageableChannel(Channel): payload["embeds"] = embeds - print(create_form(payload, files)) + # ToDo: add auto allowed_mentions from client + if allowed_mentions is not None: + payload["allowed_mentions"] = allowed_mentions.to_dict() content_type, data = create_form(payload, files) @@ -575,7 +578,7 @@ class MessageableChannel(Channel): await self._http.post( f"/channels/{self.id}/messages", data=data, - headers={"Content-Type": content_type} + headers={"Content-Type": content_type}, ) ) diff --git a/melisa/models/message/file.py b/melisa/models/message/file.py index 314acbf..8d17915 100644 --- a/melisa/models/message/file.py +++ b/melisa/models/message/file.py @@ -28,7 +28,7 @@ def create_form(payload: Dict[str, Any], files: List[File]): ) payload = form() - return payload.headers['Content-Type'], payload + return payload.headers["Content-Type"], payload class File: diff --git a/melisa/models/message/message.py b/melisa/models/message/message.py index b5a2a70..86cc3ff 100644 --- a/melisa/models/message/message.py +++ b/melisa/models/message/message.py @@ -5,7 +5,7 @@ from __future__ import annotations from dataclasses import dataclass from enum import IntEnum -from typing import List, TYPE_CHECKING, Optional, Dict, Any +from typing import List, TYPE_CHECKING, Optional, Dict, Any, Union from .embed import Embed from ...utils import Snowflake, Timestamp, try_enum, APIModelBase @@ -100,6 +100,79 @@ class MessageFlags(IntEnum): return self.value +@dataclass(repr=False) +class AllowedMentions: + """A class that represents what mentions are allowed in a message. + + Attributes + ---------- + everyone: :class:`bool` + Whether to allow everyone and here mentions. Defaults to ``True``. + users: Union[:class:`bool`, List[:class:`~melisa.utils.snowflake.Snowflake`]] + Controls the users being mentioned. If ``True`` (the default) then + users are mentioned based on the message content. If ``False`` then + users are not mentioned at all. Or you can specify list of ids. + roles: Union[:class:`bool`, List[:class:`~melisa.utils.snowflake.Snowflake`]] + Controls the roles being mentioned. If ``True`` then + roles are mentioned based on the message content. If ``False`` then + roles are not mentioned at all. + replied_user: :class:`bool` + Whether to mention the author of the message being replied to. + """ + + __slots__ = ("everyone", "users", "roles", "replied_user") + + def __init__( + self, + *, + everyone: bool = True, + users: Union[bool, List[Union[Snowflake, int, str]]] = True, + roles: Union[bool, List[Union[Snowflake, int, str]]] = True, + replied_user: bool = True, + ): + self.everyone = everyone + self.users = users + self.roles = roles + self.replied_user = replied_user + + @classmethod + def enabled(cls): + """A factory method that returns a :class:`AllowedMentions` + with all fields explicitly set to ``True``""" + return cls(everyone=True, users=True, roles=True, replied_user=True) + + @classmethod + def disabled(cls): + """A factory method that returns a :class:`AllowedMentions` + with all fields set to ``False``""" + return cls(everyone=False, users=False, roles=False, replied_user=False) + + def to_dict(self): + to_parse = [] + data = {} + + if self.everyone: + to_parse.append("everyone") + + # `None` cannot be specified by the default + if self.users is True: + to_parse.append("users") + elif self.users is not False: + data["users"] = [str(user) for user in self.users] + + if self.roles is True: + to_parse.append("roles") + elif self.roles is not False: + data["roles"] = [str(role) for role in self.roles] + + if self.replied_user: + data["replied_user"] = True + + data["parse"] = to_parse + + return data + + @dataclass(repr=False) class Message(APIModelBase): """Represents a message sent in a channel within Discord.