aboutsummaryrefslogtreecommitdiff
path: root/discord
diff options
context:
space:
mode:
Diffstat (limited to 'discord')
-rw-r--r--discord/http.py7
-rw-r--r--discord/message.py43
-rw-r--r--discord/raw_models.py29
-rw-r--r--discord/reaction.py22
-rw-r--r--discord/state.py17
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)