|
1 | 1 | from typing import TYPE_CHECKING
|
2 | 2 |
|
3 | 3 | import interactions.api.events as events
|
4 |
| -from interactions.models import PartialEmoji, Reaction |
| 4 | +from interactions.models import PartialEmoji, Reaction, Message, Permissions |
5 | 5 |
|
6 | 6 | from ._template import EventMixinTemplate, Processor
|
7 | 7 |
|
|
12 | 12 |
|
13 | 13 |
|
14 | 14 | class ReactionEvents(EventMixinTemplate):
|
| 15 | + async def _check_message_fetch_permissions(self, channel_id: str, guild_id: str | None) -> bool: |
| 16 | + """ |
| 17 | + Check if the bot has permissions to fetch a message in the given channel. |
| 18 | +
|
| 19 | + Args: |
| 20 | + channel_id: The ID of the channel to check |
| 21 | + guild_id: The ID of the guild, if any |
| 22 | +
|
| 23 | + Returns: |
| 24 | + bool: True if the bot has permission to fetch messages, False otherwise |
| 25 | +
|
| 26 | + """ |
| 27 | + if not guild_id: # DMs always have permission |
| 28 | + return True |
| 29 | + |
| 30 | + channel = await self.cache.fetch_channel(channel_id) |
| 31 | + if not channel: |
| 32 | + return False |
| 33 | + |
| 34 | + bot_member = channel.guild.me |
| 35 | + ctx_perms = channel.permissions_for(bot_member) |
| 36 | + return Permissions.READ_MESSAGE_HISTORY in ctx_perms |
| 37 | + |
15 | 38 | async def _handle_message_reaction_change(self, event: "RawGatewayEvent", add: bool) -> None:
|
16 | 39 | if member := event.data.get("member"):
|
17 | 40 | author = self.cache.place_member_data(event.data.get("guild_id"), member)
|
@@ -53,11 +76,27 @@ async def _handle_message_reaction_change(self, event: "RawGatewayEvent", add: b
|
53 | 76 | message.reactions.append(reaction)
|
54 | 77 |
|
55 | 78 | else:
|
56 |
| - message = await self.cache.fetch_message(event.data.get("channel_id"), event.data.get("message_id")) |
57 |
| - for r in message.reactions: |
58 |
| - if r.emoji == emoji: |
59 |
| - reaction = r |
60 |
| - break |
| 79 | + guild_id = event.data.get("guild_id") |
| 80 | + channel_id = event.data.get("channel_id") |
| 81 | + |
| 82 | + if await self._check_message_fetch_permissions(channel_id, guild_id): |
| 83 | + message = await self.cache.fetch_message(channel_id, event.data.get("message_id")) |
| 84 | + for r in message.reactions: |
| 85 | + if r.emoji == emoji: |
| 86 | + reaction = r |
| 87 | + break |
| 88 | + |
| 89 | + if not message: # otherwise construct skeleton message with no reactions |
| 90 | + message = Message.from_dict( |
| 91 | + { |
| 92 | + "id": event.data.get("message_id"), |
| 93 | + "channel_id": channel_id, |
| 94 | + "guild_id": guild_id, |
| 95 | + "reactions": [], |
| 96 | + }, |
| 97 | + self, |
| 98 | + ) |
| 99 | + |
61 | 100 | if add:
|
62 | 101 | self.dispatch(events.MessageReactionAdd(message=message, emoji=emoji, author=author, reaction=reaction))
|
63 | 102 | else:
|
|
0 commit comments