mirror of
https://github.com/wlinator/luminara.git
synced 2024-10-02 18:03:12 +00:00
Refactor trigger column name in custom_reactions table
This commit is contained in:
parent
b8f707e8f8
commit
e9a7603a19
3 changed files with 65 additions and 92 deletions
|
@ -1,7 +1,7 @@
|
|||
-- Create a table to store custom reactions
|
||||
CREATE TABLE custom_reactions (
|
||||
id SERIAL PRIMARY KEY, -- Unique identifier for each custom reaction
|
||||
trigger TEXT NOT NULL, -- The text that triggers the custom reaction
|
||||
trigger_text TEXT NOT NULL, -- The text that triggers the custom reaction
|
||||
response TEXT, -- The response text for the custom reaction (nullable for emoji reactions)
|
||||
emoji TEXT, -- The emoji for the custom reaction (nullable for text responses)
|
||||
is_emoji BOOLEAN DEFAULT FALSE, -- Indicates if the reaction is a discord emoji reaction
|
||||
|
@ -12,10 +12,10 @@ CREATE TABLE custom_reactions (
|
|||
usage_count INT DEFAULT 0, -- The number of times a custom reaction has been used
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Timestamp when the custom reaction was created
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Timestamp when the custom reaction was last updated
|
||||
CONSTRAINT unique_trigger_guild UNIQUE (trigger, guild_id) -- Ensure that the combination of trigger, guild_id, and is_full_match is unique
|
||||
CONSTRAINT unique_trigger_guild UNIQUE (trigger_text, guild_id) -- Ensure that the combination of trigger_text, guild_id, and is_full_match is unique
|
||||
);
|
||||
|
||||
-- Create indexes to speed up lookups
|
||||
CREATE INDEX idx_custom_reactions_guild_id ON custom_reactions(guild_id);
|
||||
CREATE INDEX idx_custom_reactions_creator_id ON custom_reactions(creator_id);
|
||||
CREATE INDEX idx_custom_reactions_trigger ON custom_reactions(trigger);
|
||||
CREATE INDEX idx_custom_reactions_trigger_text ON custom_reactions(trigger_text);
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
import random
|
||||
import asyncio
|
||||
from typing import List, Dict, Any
|
||||
|
||||
from discord.ext.commands import Cog
|
||||
from discord import Message
|
||||
from discord.ext.commands import Cog
|
||||
from loguru import logger
|
||||
|
||||
from config.parser import JsonCache
|
||||
from services.reactions_service import CustomReactionsService
|
||||
from services.blacklist_service import BlacklistUserService
|
||||
|
||||
|
||||
|
@ -13,68 +10,53 @@ 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.client = client
|
||||
self.message: Message = message
|
||||
self.content: str = self.message.content.lower()
|
||||
self.client = client
|
||||
|
||||
self.reaction_service = CustomReactionsService()
|
||||
|
||||
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)
|
||||
guild_id = self.message.guild.id if self.message.guild else None
|
||||
|
||||
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)
|
||||
if guild_id:
|
||||
reaction = await self.reaction_service.find_trigger(guild_id, self.content)
|
||||
if reaction:
|
||||
processed = False
|
||||
try:
|
||||
if reaction["type"] == "text":
|
||||
await self.message.reply(reaction["response"])
|
||||
processed = True
|
||||
elif reaction["type"] == "emoji":
|
||||
await self.message.add_reaction(reaction["response"])
|
||||
processed = True
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to process reaction: {e}")
|
||||
|
||||
if processed:
|
||||
await self.reaction_service.increment_reaction_usage(
|
||||
int(reaction["id"])
|
||||
)
|
||||
|
||||
|
||||
class ReactionListener(Cog):
|
||||
def __init__(self, client) -> None:
|
||||
self.client = client
|
||||
|
||||
@Cog.listener('on_message')
|
||||
@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):
|
||||
if not message.author.bot and not BlacklistUserService.is_user_blacklisted(
|
||||
message.author.id
|
||||
):
|
||||
await ReactionHandler(self.client, message).run_all_checks()
|
||||
|
||||
|
||||
|
|
|
@ -1,20 +1,3 @@
|
|||
"""
|
||||
TABLE custom_reactions:
|
||||
id SERIAL PRIMARY KEY
|
||||
trigger TEXT NOT NULL
|
||||
response TEXT
|
||||
emoji TEXT
|
||||
is_emoji BOOLEAN DEFAULT FALSE
|
||||
is_full_match BOOLEAN DEFAULT FALSE
|
||||
is_global BOOLEAN DEFAULT TRUE
|
||||
guild_id BIGINT
|
||||
creator_id BIGINT NOT NULL
|
||||
usage_count INT DEFAULT 0
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
CONSTRAINT unique_trigger_guild UNIQUE (trigger, guild_id)
|
||||
"""
|
||||
|
||||
from typing import Optional, Dict, Any
|
||||
from datetime import datetime
|
||||
from db import database
|
||||
|
@ -31,18 +14,29 @@ class CustomReactionsService:
|
|||
query = """
|
||||
SELECT * FROM custom_reactions
|
||||
WHERE (guild_id = ? OR is_global = TRUE) AND (
|
||||
(is_full_match = TRUE AND trigger = ?) OR
|
||||
(is_full_match = FALSE AND ? LIKE CONCAT('%', trigger, '%'))
|
||||
(is_full_match = TRUE AND trigger_text = ?) OR
|
||||
(is_full_match = FALSE AND ? LIKE CONCAT('%', trigger_text, '%'))
|
||||
)
|
||||
ORDER BY guild_id = ? DESC, is_global ASC
|
||||
LIMIT 1
|
||||
"""
|
||||
result = database.select_query_one(query, (guild_id, message_content, message_content, guild_id))
|
||||
result = database.select_query(query, (guild_id, message_content, message_content, guild_id))
|
||||
if result:
|
||||
reaction = dict(result)
|
||||
reaction = result[0] # Get the first result from the list
|
||||
return {
|
||||
"response": reaction.get("response"),
|
||||
"type": "emoji" if reaction.get("is_emoji") else "text"
|
||||
"id": reaction[0],
|
||||
"trigger_text": reaction[1],
|
||||
"response": reaction[2],
|
||||
"emoji": reaction[3],
|
||||
"is_emoji": reaction[4],
|
||||
"is_full_match": reaction[5],
|
||||
"is_global": reaction[6],
|
||||
"guild_id": reaction[7],
|
||||
"creator_id": reaction[8],
|
||||
"usage_count": reaction[9],
|
||||
"created_at": reaction[10],
|
||||
"updated_at": reaction[11],
|
||||
"type": "emoji" if reaction[4] else "text"
|
||||
}
|
||||
return None
|
||||
|
||||
|
@ -50,7 +44,7 @@ class CustomReactionsService:
|
|||
self,
|
||||
guild_id: int,
|
||||
creator_id: int,
|
||||
trigger: str,
|
||||
trigger_text: str,
|
||||
response: Optional[str] = None,
|
||||
emoji: Optional[str] = None,
|
||||
is_emoji: bool = False,
|
||||
|
@ -61,14 +55,14 @@ class CustomReactionsService:
|
|||
return False
|
||||
|
||||
query = """
|
||||
INSERT INTO custom_reactions (trigger, response, emoji, is_emoji, is_full_match, is_global, guild_id, creator_id)
|
||||
INSERT INTO custom_reactions (trigger_text, response, emoji, is_emoji, is_full_match, is_global, guild_id, creator_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE trigger=trigger
|
||||
ON DUPLICATE KEY UPDATE trigger_text=trigger_text
|
||||
"""
|
||||
database.execute_query(
|
||||
query,
|
||||
(
|
||||
trigger,
|
||||
trigger_text,
|
||||
response,
|
||||
emoji,
|
||||
is_emoji,
|
||||
|
@ -83,7 +77,7 @@ class CustomReactionsService:
|
|||
async def edit_custom_reaction(
|
||||
self,
|
||||
guild_id: int,
|
||||
trigger: str,
|
||||
trigger_text: str,
|
||||
new_response: Optional[str] = None,
|
||||
new_emoji: Optional[str] = None,
|
||||
is_emoji: Optional[bool] = None,
|
||||
|
@ -98,7 +92,7 @@ class CustomReactionsService:
|
|||
is_full_match = COALESCE(?, is_full_match),
|
||||
is_global = COALESCE(?, is_global),
|
||||
updated_at = ?
|
||||
WHERE guild_id = ? AND trigger = ?
|
||||
WHERE guild_id = ? AND trigger_text = ?
|
||||
"""
|
||||
database.execute_query(
|
||||
query,
|
||||
|
@ -110,17 +104,17 @@ class CustomReactionsService:
|
|||
is_global,
|
||||
datetime.utcnow(),
|
||||
guild_id,
|
||||
trigger,
|
||||
trigger_text,
|
||||
),
|
||||
)
|
||||
return True
|
||||
|
||||
async def delete_custom_reaction(self, guild_id: int, trigger: str) -> bool:
|
||||
async def delete_custom_reaction(self, guild_id: int, trigger_text: str) -> bool:
|
||||
query = """
|
||||
DELETE FROM custom_reactions
|
||||
WHERE guild_id = ? AND trigger = ?
|
||||
WHERE guild_id = ? AND trigger_text = ?
|
||||
"""
|
||||
database.execute_query(query, (guild_id, trigger))
|
||||
database.execute_query(query, (guild_id, trigger_text))
|
||||
return True
|
||||
|
||||
async def count_custom_reactions(self, guild_id: int) -> int:
|
||||
|
@ -131,19 +125,16 @@ class CustomReactionsService:
|
|||
count = database.select_query_one(query, (guild_id,))
|
||||
return count if count else 0
|
||||
|
||||
async def increment_reaction_usage(self, guild_id: int, trigger: str) -> bool:
|
||||
async def increment_reaction_usage(self, reaction_id: int) -> bool:
|
||||
query = """
|
||||
UPDATE custom_reactions
|
||||
SET usage_count = usage_count + 1,
|
||||
updated_at = ?
|
||||
WHERE guild_id = ? AND trigger = ?
|
||||
SET usage_count = usage_count + 1
|
||||
WHERE id = ?
|
||||
"""
|
||||
database.execute_query(
|
||||
query,
|
||||
(
|
||||
datetime.utcnow(),
|
||||
guild_id,
|
||||
trigger,
|
||||
reaction_id,
|
||||
),
|
||||
)
|
||||
return True
|
||||
|
|
Loading…
Reference in a new issue