diff --git a/discord/raw_models.py b/discord/raw_models.py index adacbd858..211216af6 100644 --- a/discord/raw_models.py +++ b/discord/raw_models.py @@ -35,14 +35,16 @@ class RawMessageDeleteEvent: The guild ID where the deletion took place, if applicable. message_id: :class:`int` The message ID that got deleted. + cached_message: Optional[:class:`Message`] + The cached message, if found in the internal message cache. """ - __slots__ = ('message_id', 'channel_id', 'guild_id') + __slots__ = ('message_id', 'channel_id', 'guild_id', 'cached_message') def __init__(self, data): self.message_id = int(data['id']) self.channel_id = int(data['channel_id']) - + self.cached_message = None try: self.guild_id = int(data['guild_id']) except KeyError: @@ -59,13 +61,16 @@ class RawBulkMessageDeleteEvent: The channel ID where the message got deleted. guild_id: Optional[:class:`int`] The guild ID where the message got deleted, if applicable. + cached_messages: List[:class:`Message`] + The cached messages, if found in the internal message cache. """ - __slots__ = ('message_ids', 'channel_id', 'guild_id') + __slots__ = ('message_ids', 'channel_id', 'guild_id', 'cached_messages') def __init__(self, data): self.message_ids = {int(x) for x in data.get('ids', [])} self.channel_id = int(data['channel_id']) + self.cached_messages = [] try: self.guild_id = int(data['guild_id']) diff --git a/discord/state.py b/discord/state.py index ebde9ec07..11c586125 100644 --- a/discord/state.py +++ b/discord/state.py @@ -366,21 +366,22 @@ class ConnectionState: def parse_message_delete(self, data): raw = RawMessageDeleteEvent(data) - self.dispatch('raw_message_delete', raw) - found = self._get_message(raw.message_id) + raw.cached_message = found + self.dispatch('raw_message_delete', raw) if found is not None: self.dispatch('message_delete', found) self._messages.remove(found) def parse_message_delete_bulk(self, data): raw = RawBulkMessageDeleteEvent(data) + found_messages = [message for message in self._messages if message.id in raw.message_ids] + raw.cached_messages = found_messages self.dispatch('raw_bulk_message_delete', raw) - - to_be_deleted = [message for message in self._messages if message.id in raw.message_ids] - for msg in to_be_deleted: - self.dispatch('message_delete', msg) - self._messages.remove(msg) + if found_messages: + self.dispatch('bulk_message_delete', found_messages) + for msg in found_messages: + self._messages.remove(msg) def parse_message_update(self, data): raw = RawMessageUpdateEvent(data) diff --git a/docs/api.rst b/docs/api.rst index 0c36ffe2f..7ba1a9962 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -227,25 +227,45 @@ to handle it, which defaults to print a traceback and ignoring the exception. .. function:: on_message_delete(message) Called when a message is deleted. If the message is not found in the - internal message cache, then these events will not be called. This - happens if the message is too old or the client is participating in high - traffic guilds. To fix this, increase the ``max_messages`` option of - :class:`Client`. + internal message cache, then this event will not be called. + Messages might not be in cache if the message is too old + or the client is participating in high traffic guilds. + + If this occurs increase the :attr:`Client.max_messages` attribute. :param message: A :class:`Message` of the deleted message. +.. function:: on_bulk_message_delete(messages) + + Called when messages are bulk deleted. If none of the messages deleted + are found in the internal message cache, then this event will not be called. + If individual messages were not found in the internal message cache, + this event will still be called, but the messages not found will not be included in + the messages list. Messages might not be in cache if the message is too old + or the client is participating in high traffic guilds. + + If this occurs increase the :attr:`Client.max_messages` attribute. + + :param messages: A :class:`list` of :class:`Message` that have been deleted. + .. function:: on_raw_message_delete(payload) Called when a message is deleted. Unlike :func:`on_message_delete`, this is called regardless of the message being in the internal message cache or not. + If the message is found in the message cache, + it can be accessed via:attr:`RawMessageDeleteEvent.cached_message` + :param payload: The raw event payload data. :type payload: :class:`RawMessageDeleteEvent` .. function:: on_raw_bulk_message_delete(payload) - Called when a bulk delete is triggered. This event is called regardless - of the message IDs being in the internal message cache or not. + Called when a bulk delete is triggered. Unlike :func:`on_bulk_message_delete`, this is + called regardless of the messages being in the internal message cache or not. + + If the messages are found in the message cache, + they can be accessed via :attr:`RawBulkMessageDeleteEvent.cached_messages` :param payload: The raw event payload data. :type payload: :class:`RawBulkMessageDeleteEvent` @@ -254,8 +274,10 @@ to handle it, which defaults to print a traceback and ignoring the exception. Called when a :class:`Message` receives an update event. If the message is not found in the internal message cache, then these events will not be called. - This happens if the message is too old or the client is participating in high - traffic guilds. To fix this, increase the ``max_messages`` option of :class:`Client`. + Messages might not be in cache if the message is too old + or the client is participating in high traffic guilds. + + If this occurs increase the :attr:`Client.max_messages` attribute. The following non-exhaustive cases trigger this event: @@ -288,7 +310,7 @@ to handle it, which defaults to print a traceback and ignoring the exception. .. function:: on_reaction_add(reaction, user) - Called when a message has a reaction added to it. Similar to on_message_edit, + Called when a message has a reaction added to it. Similar to :func:`on_message_edit`, if the message is not found in the internal message cache, then this event will not be called.