1
Fork 0
mirror of https://github.com/wlinator/luminara.git synced 2024-10-02 18:23:12 +00:00

Refactor code for emoji conversion and reaction handling

This commit is contained in:
wlinator 2024-07-10 20:11:20 +02:00
parent a3ff3c42d5
commit 43466b86fb
3 changed files with 93 additions and 26 deletions

View file

@ -4,7 +4,7 @@ from loguru import logger
import discord
from discord.ext import bridge, commands
from discord.ext.commands import TextChannelConverter
from discord.ext.commands import TextChannelConverter, EmojiConverter
from typing import Optional
from lib import metadata
@ -66,6 +66,29 @@ class LumiBot(bridge.Bot):
commands.BadArgument,
):
return None
@staticmethod
async def convert_to_emoji(ctx: commands.Context | bridge.Context, emoji: str) -> Optional[discord.Emoji]:
"""
Converts a emoji to an Emoji object.
"""
converter = EmojiConverter()
try:
if isinstance(ctx, bridge.BridgeApplicationContext):
return # TODO: Implement this
else:
return await converter.convert(ctx, emoji)
except commands.EmojiNotFound:
logger.warning(f"Emoji not found: {emoji}")
return None
except (
discord.HTTPException,
discord.NotFound,
discord.Forbidden,
commands.BadArgument,
):
return None
@staticmethod
async def convert_to_text_channel(

View file

@ -1,9 +1,12 @@
{
"full_content_reactions": {
"full_content_responses": {
"good bot": "thanks :3",
"fuck you lumi": "Dont threaten me with a good time.",
"lumi fuck you": ":("
},
"partial_content_reactions": {
"miboca": "1250772989008674887"
},
"eightball": [
"It is certain.",
"It is decidedly so.",

View file

@ -1,42 +1,83 @@
import random
import asyncio
from typing import List, Dict, Any
from discord.ext.commands import Cog
import discord
from discord.ext.commands import Cog, Context, EmojiConverter
from discord import Message
from config.parser import JsonCache
from services.blacklist_service import BlacklistUserService
_reactions = JsonCache.read_json("reactions")
_8ball = _reactions["eightball"]
_full = _reactions["full_content_reactions"]
class ReactionHandler:
"""
Handles reactions to messages based on predefined triggers and responses.
"""
def __init__(self, client, message: Message) -> None:
self.reactions: Dict[str, Any] = JsonCache.read_json("reactions")
self.eightball: List[str] = self.reactions["eightball"]
self.full_response: Dict[str, str] = self.reactions["full_content_responses"]
self.partial_react: Dict[str, str] = self.reactions["partial_content_reactions"]
self.message: Message = message
self.content: str = self.message.content.lower()
self.client = client
async def run_all_checks(self) -> None:
"""
Runs all checks for reactions and responses.
"""
await asyncio.gather(
self.check_eightball(self.eightball),
self.check_full_response(),
self.react()
)
async def check_eightball(self, choices: List[str]) -> None:
"""
Checks if the message is a question directed at Lumi and responds with a random choice.
:param choices: List of possible responses.
"""
if (self.content.startswith("lumi ") or self.content.startswith("lumi, ")) and self.content.endswith("?"):
response: str = random.choice(choices)
await self.message.reply(content=response)
async def check_full_response(self) -> None:
"""
Checks if the message content matches any full content triggers and responds accordingly.
"""
for trigger, response in self.full_response.items():
if trigger.lower() == self.content:
await self.message.reply(response)
@staticmethod
async def respond(message):
content = message.content.lower()
if (content.startswith("lumi ") or content.startswith("lumi, ")) and content.endswith("?"):
response = random.choice(_8ball)
await message.reply(content=response)
for trigger, response in _full.items():
if trigger.lower() == content:
await message.reply(response)
async def react(self) -> None:
"""
Adds reactions to the message based on partial content triggers.
"""
ctx = await self.client.get_context(self.message)
for trigger, emoji in self.partial_react.items():
if trigger.lower() in self.content:
emoji = await self.client.convert_to_emoji(ctx, emoji)
if emoji:
await self.message.add_reaction(emoji)
class ReactionListener(Cog):
def __init__(self, client):
def __init__(self, client) -> None:
self.client = client
@Cog.listener('on_message')
async def reaction_listener(self, message):
if BlacklistUserService.is_user_blacklisted(message.author.id):
return
if not message.author.bot:
await ReactionHandler.respond(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_all_checks()
def setup(client):
def setup(client) -> None:
client.add_cog(ReactionListener(client))