Skip to content

Commit

Permalink
feat: implement new attributes for ForwardedMessage class and fix doc…
Browse files Browse the repository at this point in the history
…strings
  • Loading branch information
Snipy7374 committed Nov 14, 2024
1 parent f5da391 commit c572922
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 73 deletions.
126 changes: 56 additions & 70 deletions disnake/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,11 +573,11 @@ class MessageReference:
.. versionadded:: 2.10
message_id: Optional[:class:`int`]
The ID of the message referenced. In case of forwarding this should be the id of the message to forward.
The ID of the message referenced/forwarded.
channel_id: :class:`int`
The channel ID of the message referenced. In case of forwarding this should be the id of the channel where to forward the message.
The channel ID of the message referenced/forwarded.
guild_id: Optional[:class:`int`]
The guild ID of the message referenced. In case of forwarding this should be the id of the guild where to forward the message.
The guild ID of the message referenced/forwarded.
fail_if_not_exists: :class:`bool`
Whether replying to the referenced message should raise :class:`HTTPException`
if the message no longer exists or Discord could not fetch the message.
Expand Down Expand Up @@ -643,8 +643,6 @@ def from_message(
message: Message,
*,
type: MessageReferenceType = MessageReferenceType.default,
channel_id: Optional[int] = None,
guild_id: Optional[int] = None,
fail_if_not_exists: bool = True,
) -> Self:
"""Creates a :class:`MessageReference` from an existing :class:`~disnake.Message`.
Expand All @@ -661,16 +659,6 @@ def from_message(
.. versionadded:: 2.10
channel_id: Optional[:class:`int`]
The channel id where the message forward should be sent. This parameter is required to be passed only in case of message forwarding.
.. versionadded:: 2.10
guild_id: Optional[:class:`int`]
The guild id where the message forward should be sent. This parameter is used in message forwarding. Unlike ``channel_id`` this can be None even when forwarding.
.. versionadded:: 2.10
fail_if_not_exists: :class:`bool`
Whether replying to the referenced message should raise :class:`HTTPException`
if the message no longer exists or Discord could not fetch the message.
Expand All @@ -688,20 +676,12 @@ def from_message(
A reference to the message.
"""
channel_id_ = message.channel.id
if type is MessageReferenceType.forward:
if not channel_id:
raise ValueError("channel_id must be passed in case of message forwarding")
channel_id_ = channel_id

self = cls(
type=type,
message_id=message.id,
channel_id=channel_id_,
guild_id=(
getattr(message.guild, "id", None)
if type is MessageReferenceType.default
else guild_id
),
guild_id=getattr(message.guild, "id", None),
fail_if_not_exists=fail_if_not_exists,
)
self._state = message._state
Expand Down Expand Up @@ -1068,7 +1048,6 @@ def __init__(
self.message_snapshots: List[ForwardedMessage] = [
ForwardedMessage(
state=self._state,
guild_id=utils._get_as_snowflake(a, "guild_id"),
data=a["message"],
)
for a in data.get("message_snapshots", [])
Expand Down Expand Up @@ -2172,14 +2151,22 @@ async def reply(
A shortcut method to :meth:`.abc.Messageable.send` to reply to the
:class:`.Message`.
.. versionadded:: 2.10
.. versionadded:: 1.6
.. versionchanged:: 2.3
Added ``fail_if_not_exists`` keyword argument. Defaults to ``True``.
.. versionchanged:: 2.6
Raises :exc:`TypeError` or :exc:`ValueError` instead of ``InvalidArgument``.
Parameters
----------
fail_if_not_exists: :class:`bool`
Whether replying using the message reference should raise :exc:`~disnake.HTTPException`
if the message no longer exists or Discord could not fetch the message.
.. versionadded:: 2.3
Raises
------
HTTPException
Expand All @@ -2204,10 +2191,8 @@ async def reply(

async def forward(
self,
content: Optional[str] = None,
*,
channel_id: int,
guild_id: Optional[int] = None,
channel: MessageableChannel,
fail_if_not_exists: bool = True,
**kwargs: Any,
) -> Message:
Expand All @@ -2220,13 +2205,8 @@ async def forward(
Parameters
----------
channel_id: :class:`int`
The channel id where the message forward should be sent.
.. versionadded:: 2.10
guild_id: Optional[:class:`int`]
The guild id where the message forward should be sent. Unlike ``channel_id`` this can be None.
channel: Union[:class:`TextChannel`, :class:`VoiceChannel`, :class:`StageChannel`, :class:`Thread`, :class:`DMChannel`, :class:`GroupChannel`, :class:`PartialMessageable`]
The channel where the message should be forwarded to.
.. versionadded:: 2.10
Expand All @@ -2251,25 +2231,20 @@ async def forward(
The message that was sent.
"""
if not fail_if_not_exists:
reference = MessageReference.from_message(
self,
type=MessageReferenceType.forward,
channel_id=channel_id,
guild_id=guild_id,
reference = self.to_reference(
reference_type=MessageReferenceType.forward,
fail_if_not_exists=False,
)
else:
reference = MessageReference.from_message(
self, type=MessageReferenceType.forward, channel_id=channel_id, guild_id=guild_id
reference = self.to_reference(
reference_type=MessageReferenceType.forward,
)
return await self.channel.send(content, reference=reference, **kwargs)
return await channel.send(reference=reference, **kwargs)

def to_reference(
self,
*,
reference_type: MessageReferenceType = MessageReferenceType.default,
channel_id: Optional[int] = None,
guild_id: Optional[int] = None,
fail_if_not_exists: bool = True,
) -> MessageReference:
"""Creates a :class:`~disnake.MessageReference` from the current message.
Expand All @@ -2284,16 +2259,6 @@ def to_reference(
.. versionadded:: 2.10
channel_id: Optional[:class:`int`]
The channel id where the message forward should be sent. This parameter is required to be passed only in case of message forwarding.
.. versionadded:: 2.10
guild_id: Optional[:class:`int`]
The guild id where the message forward should be sent. This parameter is used in message forwarding. Unlike ``channel_id`` this can be None even when forwarding.
.. versionadded:: 2.10
fail_if_not_exists: :class:`bool`
Whether replying using the message reference should raise :class:`HTTPException`
if the message no longer exists or Discord could not fetch the message.
Expand All @@ -2308,8 +2273,6 @@ def to_reference(
return MessageReference.from_message(
self,
type=reference_type,
channel_id=channel_id,
guild_id=guild_id,
fail_if_not_exists=fail_if_not_exists,
)

Expand Down Expand Up @@ -2688,10 +2651,9 @@ class ForwardedMessage:
Attributes
----------
guild_id: Optional[:class:`int`]
The guild id from which the message come from. This should never be None.
guild: Optional[:class:`Guild`]
The guild from which the message come from. This is None if the guild is not cached.
type: :class:`MessageType`
The type of message. In most cases this should not be checked, but it is helpful
in cases where it might be a system message for :attr:`system_content`.
content: :class:`str`
The actual contents of the message.
embeds: List[:class:`Embed`]
Expand All @@ -2700,24 +2662,41 @@ class ForwardedMessage:
A list of attachments given to a message.
flags: :class:`MessageFlags`
Extra features of the message.
mentions: List[:class:`abc.User`]
A list of :class:`Member` that were mentioned. If the message is in a private message
then the list will be of :class:`User` instead. For messages that are not of type
:attr:`MessageType.default`\\, this array can be used to aid in system messages.
For more information, see :attr:`system_content`.
.. warning::
The order of the mentions list is not in any particular order so you should
not rely on it. This is a Discord limitation, not one with the library.
mention_roles: List[:class:`Role`]
A list of :class:`Role` that were mentioned. If the message is in a private message
then the list is always empty.
stickers: List[:class:`StickerItem`]
A list of sticker items given to the message.
components: List[:class:`Component`]
A list of components in the message.
"""

__slots__ = (
"guild_id",
"guild",
"type",
"content",
"embeds",
"attachments",
"_timestamp",
"_edited_timestamp",
"flags",
"mentions",
"mention_roles",
"stickers",
"components",
)

def __init__(
self, *, state: ConnectionState, guild_id: Optional[int], data: ForwardedMessagePayload
) -> None:
self.guild_id: Optional[int] = guild_id
self.guild: Optional[Guild] = state._get_guild(guild_id)
def __init__(self, *, state: ConnectionState, data: ForwardedMessagePayload) -> None:
self.type: MessageType = try_enum(MessageType, data["type"])
self.content: str = data["content"]
self.embeds: List[Embed] = [Embed.from_dict(a) for a in data["embeds"]]
self.attachments: List[Attachment] = [
Expand All @@ -2728,9 +2707,16 @@ def __init__(
data["edited_timestamp"]
)
self.flags: MessageFlags = MessageFlags._from_value(data.get("flags", 0))
self.stickers: List[StickerItem] = [
StickerItem(data=d, state=state) for d in data.get("sticker_items", [])
]
self.components = [
_component_factory(d, type=ActionRow[MessageComponent])
for d in data.get("components", [])
]

def __repr__(self) -> str:
return f"<{self.__class__.__name__} guild_id={self.guild_id}>"
return f"<{self.__class__.__name__}>"

@property
def created_at(self) -> datetime.datetime:
Expand Down
8 changes: 7 additions & 1 deletion disnake/types/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,24 @@ class MessageReference(TypedDict):
fail_if_not_exists: NotRequired[bool]


# TODO: check if these attrs are unpacked in message.py (i think they are)
class ForwardedMessage(TypedDict):
type: MessageType
content: str
embeds: List[Embed]
attachments: List[Attachment]
timestamp: str
edited_timestamp: Optional[str]
flags: NotRequired[int]
mentions: Union[List[User], List[UserWithMember]]
mention_roles: SnowflakeList
stickers: ...
sticker_items: NotRequired[List[StickerItem]]
components: NotRequired[List[Component]]


class MessageSnapshot(TypedDict):
message: ForwardedMessage
guild_id: NotRequired[Snowflake]


class RoleSubscriptionData(TypedDict):
Expand Down
26 changes: 24 additions & 2 deletions docs/api/messages.rst
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ ForwardedMessage
.. attributetable:: ForwardedMessage

.. autoclass:: ForwardedMessage
:members:

Enumerations
------------
Expand Down Expand Up @@ -356,8 +357,29 @@ MessageType

.. versionadded:: 2.8

.. autoclass:: MessageReferenceType
:members:
.. class:: MessageReferenceType

Specifies the type of :class:`MessageReference`. This is used to denote
if a message is normal or not (e.g replying or forwarding).

.. versionadded:: 2.10

.. collapse:: operations

.. describe:: x == y

Checks if two messages are equal.
.. describe:: x != y

Checks if two messages are not equal.

.. attribute:: default

A standard message reference used in message replies.

.. attribute:: forward

Reference used to point to a message at a point in time (forward).

Events
------
Expand Down

0 comments on commit c572922

Please sign in to comment.