1
Fork 0
mirror of https://github.com/wlinator/luminara.git synced 2024-10-02 22:23:13 +00:00
Lumi/handlers/reaction_handler.py

85 lines
2.8 KiB
Python

import contextlib
from discord import Message
from discord.ext.commands import Cog
from loguru import logger
from services.blacklist_service import BlacklistUserService
from services.reactions_service import CustomReactionsService
class ReactionHandler:
"""
Handles reactions to messages based on predefined triggers and responses.
"""
def __init__(self, client, message: Message) -> None:
self.client = client
self.message: Message = message
self.content: str = self.message.content.lower()
self.reaction_service = CustomReactionsService()
async def run_checks(self) -> None:
"""
Runs checks for reactions and responses.
Guild triggers are prioritized over global triggers if they are identical.
"""
guild_id = self.message.guild.id if self.message.guild else None
if guild_id:
data = await self.reaction_service.find_trigger(guild_id, self.content)
if data:
processed = False
try:
if data["type"] == "text":
processed = await self.try_respond(data)
elif data["type"] == "emoji":
processed = await self.try_react(data)
except Exception as e:
logger.warning(f"Failed to process reaction: {e}")
if processed:
await self.reaction_service.increment_reaction_usage(
int(data["id"]),
)
async def try_respond(self, data) -> bool:
"""
Tries to respond to the message.
"""
if response := data.get("response"):
with contextlib.suppress(Exception):
await self.message.reply(response)
return True
return False
async def try_react(self, data) -> bool:
"""
Tries to react to the message.
"""
if emoji_id := data.get("emoji_id"):
with contextlib.suppress(Exception):
if emoji := self.client.get_emoji(emoji_id):
await self.message.add_reaction(emoji)
return True
return False
class ReactionListener(Cog):
def __init__(self, client) -> None:
self.client = client
@Cog.listener("on_message")
async def reaction_listener(self, message: Message) -> None:
"""
Listens for new messages and processes them if the author is not a bot and not blacklisted.
:param message: The message to process.
"""
if not message.author.bot and not BlacklistUserService.is_user_blacklisted(
message.author.id,
):
await ReactionHandler(self.client, message).run_checks()
def setup(client) -> None:
client.add_cog(ReactionListener(client))