diff --git a/discord/__init__.py b/discord/__init__.py index b936cdbe0..78b25e31d 100644 --- a/discord/__init__.py +++ b/discord/__init__.py @@ -33,7 +33,7 @@ from .guild import Guild from .flags import * from .relationship import Relationship from .member import Member, VoiceState -from .message import Message, Attachment +from .message import Message, MessageReference, Attachment from .asset import Asset from .errors import * from .calls import CallMessage, GroupCall diff --git a/discord/message.py b/discord/message.py index c7de78d18..8e6fdde7b 100644 --- a/discord/message.py +++ b/discord/message.py @@ -208,6 +208,37 @@ class Attachment: data = await self.read(use_cached=use_cached) return File(io.BytesIO(data), filename=self.filename, spoiler=spoiler) +class MessageReference: + """Represents a reference to a :class:`Message`. + + .. versionadded:: 1.5 + + Attributes + ----------- + message_id: Optional[:class:`int`] + The id of the message referenced. + channel_id: :class:`int` + The channel id of the message referenced. + guild_id: Optional[:class:`int`] + The guild id of the message referenced. + """ + + __slots__ = ('message_id', 'channel_id', 'guild_id', '_state') + + def __init__(self, state, **kwargs): + self.message_id = utils._get_as_snowflake(kwargs, 'message_id') + self.channel_id = int(kwargs.pop('channel_id')) + self.guild_id = utils._get_as_snowflake(kwargs, 'guild_id') + self._state = state + + @property + def cached_message(self): + """Optional[:class:`Message`]: The cached message, if found in the internal message cache.""" + return self._state._get_message(self.message_id) + + def __repr__(self): + return ''.format(self) + def flatten_handlers(cls): prefix = len('_handle_') cls._HANDLERS = { @@ -251,6 +282,13 @@ class Message: call: Optional[:class:`CallMessage`] The call that the message refers to. This is only applicable to messages of type :attr:`MessageType.call`. + reference: Optional[:class:`MessageReference`] + The message that this message references. This is only applicable to messages of + type :attr:`MessageType.pins_add` or crossposted messages created by a + followed channel integration. + + .. versionadded:: 1.5 + mention_everyone: :class:`bool` Specifies if the message mentions everyone. @@ -316,7 +354,7 @@ class Message: '_cs_channel_mentions', '_cs_raw_mentions', 'attachments', '_cs_clean_content', '_cs_raw_channel_mentions', 'nonce', 'pinned', 'role_mentions', '_cs_raw_role_mentions', 'type', 'call', 'flags', - '_cs_system_content', '_cs_guild', '_state', 'reactions', + '_cs_system_content', '_cs_guild', '_state', 'reactions', 'reference', 'application', 'activity') def __init__(self, *, state, channel, data): @@ -338,6 +376,9 @@ class Message: self.content = data['content'] self.nonce = data.get('nonce') + ref = data.get('message_reference') + self.reference = MessageReference(state, **ref) if ref is not None else None + for handler in ('author', 'member', 'mentions', 'mention_roles', 'call', 'flags'): try: getattr(self, '_handle_%s' % handler)(data[handler]) diff --git a/docs/api.rst b/docs/api.rst index 55f20aa8c..6b843bd1f 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -2736,6 +2736,11 @@ Widget .. autoclass:: Widget() :members: +MessageReference +~~~~~~~~~~~~~~~~~ +.. autoclass:: MessageReference() + :members: + RawMessageDeleteEvent ~~~~~~~~~~~~~~~~~~~~~~~