diff options
| author | Rapptz <[email protected]> | 2020-01-17 19:48:46 -0500 |
|---|---|---|
| committer | Rapptz <[email protected]> | 2020-01-17 19:53:28 -0500 |
| commit | 87f9dcff9c5af9c4fa6e6b148663320522a3c82f (patch) | |
| tree | 2a46dc76aafa9e10ad134c681705684bdb4cf29c /discord | |
| parent | Add support for on_invite_create and on_invite_delete (diff) | |
| download | discord.py-87f9dcff9c5af9c4fa6e6b148663320522a3c82f.tar.xz discord.py-87f9dcff9c5af9c4fa6e6b148663320522a3c82f.zip | |
Add support for clearing a specific reaction.
Closes #2440
Diffstat (limited to 'discord')
| -rw-r--r-- | discord/http.py | 7 | ||||
| -rw-r--r-- | discord/message.py | 43 | ||||
| -rw-r--r-- | discord/raw_models.py | 29 | ||||
| -rw-r--r-- | discord/reaction.py | 22 | ||||
| -rw-r--r-- | discord/state.py | 17 |
5 files changed, 117 insertions, 1 deletions
diff --git a/discord/http.py b/discord/http.py index 0c0a5497..3789b3c8 100644 --- a/discord/http.py +++ b/discord/http.py @@ -402,6 +402,11 @@ class HTTPClient: return self.request(r) + def clear_single_reaction(self, channel_id, message_id, emoji): + r = Route('DELETE', '/channels/{channel_id}/messages/{message_id}/reactions/{emoji}', + channel_id=channel_id, message_id=message_id, emoji=emoji) + return self.request(r) + def get_message(self, channel_id, message_id): r = Route('GET', '/channels/{channel_id}/messages/{message_id}', channel_id=channel_id, message_id=message_id) return self.request(r) @@ -425,7 +430,7 @@ class HTTPClient: return self.request(Route('GET', '/channels/{channel_id}/messages', channel_id=channel_id), params=params) def publish_message(self, channel_id, message_id): - return self.request(Route('POST', '/channels/{channel_id}/messages/{message_id}/crosspost', + return self.request(Route('POST', '/channels/{channel_id}/messages/{message_id}/crosspost', channel_id=channel_id, message_id=message_id)) def pin_message(self, channel_id, message_id): diff --git a/discord/message.py b/discord/message.py index e2ae7193..4010a2c3 100644 --- a/discord/message.py +++ b/discord/message.py @@ -371,6 +371,18 @@ class Message: return reaction + def _clear_emoji(self, emoji): + to_check = str(emoji) + for index, reaction in enumerate(self.reactions): + if str(reaction.emoji) == to_check: + break + else: + # didn't find anything so just return + return + + del self.reactions[index] + return reaction + def _update(self, data): handlers = self._HANDLERS for key, value in data.items(): @@ -945,6 +957,37 @@ class Message: else: await self._state.http.remove_reaction(self.channel.id, self.id, emoji, member.id) + async def clear_reaction(self, emoji): + """|coro| + + Clears a specific reaction from the message. + + The emoji may be a unicode emoji or a custom guild :class:`Emoji`. + + You need the :attr:`~Permissions.manage_messages` permission to use this. + + .. versionadded:: 1.3 + + Parameters + ----------- + emoji: Union[:class:`Emoji`, :class:`Reaction`, :class:`PartialEmoji`, :class:`str`] + The emoji to clear. + + Raises + -------- + HTTPException + Clearing the reaction failed. + Forbidden + You do not have the proper permissions to clear the reaction. + NotFound + The emoji you specified was not found. + InvalidArgument + The emoji parameter is invalid. + """ + + emoji = self._emoji_reaction(emoji) + await self._state.http.clear_single_reaction(self.channel.id, self.id, emoji) + @staticmethod def _emoji_reaction(emoji): if isinstance(emoji, Reaction): diff --git a/discord/raw_models.py b/discord/raw_models.py index 1f318564..dc094e34 100644 --- a/discord/raw_models.py +++ b/discord/raw_models.py @@ -177,3 +177,32 @@ class RawReactionClearEvent(_RawReprMixin): self.guild_id = int(data['guild_id']) except KeyError: self.guild_id = None + +class RawReactionClearEmojiEvent(_RawReprMixin): + """Represents the payload for a :func:`on_raw_reaction_clear_emoji` event. + + .. versionadded:: 1.3.0 + + Attributes + ----------- + message_id: :class:`int` + The message ID that got its reactions cleared. + channel_id: :class:`int` + The channel ID where the reactions got cleared. + guild_id: Optional[:class:`int`] + The guild ID where the reactions got cleared. + emoji: :class:`PartialEmoji` + The custom or unicode emoji being removed. + """ + + __slots__ = ('message_id', 'channel_id', 'guild_id', 'emoji') + + def __init__(self, data, emoji): + self.emoji = emoji + self.message_id = int(data['message_id']) + self.channel_id = int(data['channel_id']) + + try: + self.guild_id = int(data['guild_id']) + except KeyError: + self.guild_id = None diff --git a/discord/reaction.py b/discord/reaction.py index c7f2ef77..79c8efe2 100644 --- a/discord/reaction.py +++ b/discord/reaction.py @@ -121,6 +121,28 @@ class Reaction: await self.message.remove_reaction(self.emoji, user) + async def clear(self): + """|coro| + + Clears this reaction from the message. + + You need the :attr:`~Permissions.manage_messages` permission to use this. + + .. versionadded:: 1.3 + + Raises + -------- + HTTPException + Clearing the reaction failed. + Forbidden + You do not have the proper permissions to clear the reaction. + NotFound + The emoji you specified was not found. + InvalidArgument + The emoji parameter is invalid. + """ + await self.message.clear_reaction(self.emoji) + def users(self, limit=None, after=None): """Returns an :class:`AsyncIterator` representing the users that have reacted to the message. diff --git a/discord/state.py b/discord/state.py index aea0984d..a3a8e243 100644 --- a/discord/state.py +++ b/discord/state.py @@ -509,6 +509,23 @@ class ConnectionState: if user: self.dispatch('reaction_remove', reaction, user) + def parse_message_reaction_remove_emoji(self, data): + emoji = data['emoji'] + emoji_id = utils._get_as_snowflake(emoji, 'id') + emoji = PartialEmoji.with_state(self, animated=emoji.get('animated', False), id=emoji_id, name=emoji['name']) + raw = RawReactionClearEmojiEvent(data, emoji) + self.dispatch('raw_reaction_clear_emoji', raw) + + message = self._get_message(raw.message_id) + if message is not None: + try: + reaction = message._clear_emoji(emoji) + except (AttributeError, ValueError): # eventual consistency lol + pass + else: + if reaction: + self.dispatch('reaction_clear_emoji', reaction) + def parse_presence_update(self, data): guild_id = utils._get_as_snowflake(data, 'guild_id') guild = self._get_guild(guild_id) |