From 62c2f1d81fa67a9e2001074f3040f085baf76a95 Mon Sep 17 00:00:00 2001 From: "Nyeki.py" <84998222+Nekidev@users.noreply.github.com> Date: Wed, 23 Oct 2024 15:27:03 -0300 Subject: [PATCH] feat(bot): :sparkles: Add support for reactions. --- payphone/bot.py | 4 +- payphone/cogs/calls/cog.py | 124 +++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 2 deletions(-) diff --git a/payphone/bot.py b/payphone/bot.py index ff05553..2015c8f 100644 --- a/payphone/bot.py +++ b/payphone/bot.py @@ -85,14 +85,14 @@ class Payphone(commands.AutoShardedBot): async def get_or_fetch_channel( self, channel_id: int - ) -> abc.GuildChannel | abc.PrivateChannel | None: + ) -> abc.GuildChannel | abc.PrivateChannel | discord.Thread | None: """Get's a channel from the bot's cache, or fetches it from Discord if it's not available. Args: channel_id (int): The channel's ID. Returns: - (abc.GuildChannel | abc.PrivateChannel | None): The channel, or None if not found. + (abc.GuildChannel | abc.PrivateChannel | discord.Thread | None): The channel, or None if not found. """ channel = self.get_channel(channel_id) diff --git a/payphone/cogs/calls/cog.py b/payphone/cogs/calls/cog.py index 093fad0..9a595bc 100644 --- a/payphone/cogs/calls/cog.py +++ b/payphone/cogs/calls/cog.py @@ -1101,6 +1101,130 @@ class Calls(base.Cog): # TODO: Edit replies. + @commands.Cog.listener() + async def on_raw_reaction_add( + self, payload: discord.RawReactionActionEvent + ) -> None: + if payload.user_id == self.bot.user.id: + return + + channel = await models.Channel.get_or_none(id=payload.channel_id) + + if channel is None: + return + + if channel.call_id is None: + return + + call_id = channel.call_id + + other_channel_id = None + other_channel_message_id = await redis.hget( + constants.CALL_MESSAGE_FROM_PROPAGATION_TEMPLATE % call_id, + payload.message_id, + ) + + if other_channel_message_id is None: + other_channel_message_json = await redis.hget( + constants.CALL_MESSAGES_TEMPLATE % call_id, payload.message_id + ) + + if other_channel_message_json is None: + return + + other_channel_message_dict = orjson.loads(other_channel_message_json) + + if other_channel_message_dict["propagation_id"] is None: + # The message wasn't propagated + return + + other_channel_id = other_channel_message_dict["propagation_channel_id"] + other_channel_message_id = other_channel_message_dict["propagation_id"] + + else: + other_channel = await models.Channel.get_or_none( + call_id=call_id, id__not=payload.channel_id + ) + + if other_channel is not None: + other_channel_id = other_channel.id + + else: + return + + other_channel_message_id = int(other_channel_message_id) + + channel = await self.bot.get_or_fetch_channel(other_channel_id) + + if channel is None: + return + + await channel.get_partial_message(other_channel_message_id).add_reaction( + payload.emoji + ) + + @commands.Cog.listener() + async def on_raw_reaction_remove( + self, payload: discord.RawReactionActionEvent + ) -> None: + if payload.user_id == self.bot.user.id: + return + + channel = await models.Channel.get_or_none(id=payload.channel_id) + + if channel is None: + return + + if channel.call_id is None: + return + + call_id = channel.call_id + + other_channel_id = None + other_channel_message_id = await redis.hget( + constants.CALL_MESSAGE_FROM_PROPAGATION_TEMPLATE % call_id, + payload.message_id, + ) + + if other_channel_message_id is None: + other_channel_message_json = await redis.hget( + constants.CALL_MESSAGES_TEMPLATE % call_id, payload.message_id + ) + + if other_channel_message_json is None: + return + + other_channel_message_dict = orjson.loads(other_channel_message_json) + + if other_channel_message_dict["propagation_id"] is None: + # The message wasn't propagated + return + + other_channel_id = other_channel_message_dict["propagation_channel_id"] + other_channel_message_id = other_channel_message_dict["propagation_id"] + + else: + other_channel = await models.Channel.get_or_none( + call_id=call_id, id__not=payload.channel_id + ) + + if other_channel is not None: + other_channel_id = other_channel.id + + else: + return + + other_channel_message_id = int(other_channel_message_id) + + channel = await self.bot.get_or_fetch_channel(other_channel_id) + + if channel is None: + return + + await channel.get_partial_message(other_channel_message_id).remove_reaction( + payload.emoji, self.bot.user + ) + def setup(b: bot.Payphone) -> None: """Load the cog into the bot.