mirror of
https://github.com/wlinator/luminara.git
synced 2024-10-02 22:23:13 +00:00
Add and remove custom reactions with commands
This commit is contained in:
parent
26db690687
commit
4ffcf473ae
5 changed files with 161 additions and 9 deletions
|
@ -7,7 +7,8 @@
|
||||||
"exclaim": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_exclaim.png?_=3",
|
"exclaim": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_exclaim.png?_=3",
|
||||||
"question": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_question.png?_=2",
|
"question": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_question.png?_=2",
|
||||||
"hammer": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_hammer.png?_=1",
|
"hammer": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_hammer.png?_=1",
|
||||||
"cross": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_cross.png?_=1",
|
"cross": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_cross.png?_=2",
|
||||||
|
"check": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_check.png?_=1",
|
||||||
"streak": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_streak.png?_=2",
|
"streak": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_streak.png?_=2",
|
||||||
"streak_bronze": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_streak_bronze.png?_=1",
|
"streak_bronze": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_streak_bronze.png?_=1",
|
||||||
"streak_silver": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_streak_silver.png?_=1",
|
"streak_silver": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_streak_silver.png?_=1",
|
||||||
|
|
49
lib/embeds/triggers.py
Normal file
49
lib/embeds/triggers.py
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
import discord
|
||||||
|
from typing import Optional
|
||||||
|
from config.parser import JsonCache
|
||||||
|
from lib import formatter
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
resources = JsonCache.read_json("art")
|
||||||
|
|
||||||
|
check_icon = resources["icons"]["check"]
|
||||||
|
cross_icon = resources["icons"]["cross"]
|
||||||
|
logo = resources["logo"]["transparent"]
|
||||||
|
|
||||||
|
def create_embed(title: str, description: str, color: int, icon_url: str) -> discord.Embed:
|
||||||
|
embed = discord.Embed(
|
||||||
|
color=color,
|
||||||
|
description=description
|
||||||
|
)
|
||||||
|
embed.set_author(name=title, icon_url=icon_url)
|
||||||
|
embed.set_footer(text="Reaction Service", icon_url=logo)
|
||||||
|
embed.timestamp = datetime.datetime.utcnow()
|
||||||
|
return embed
|
||||||
|
|
||||||
|
|
||||||
|
def create_creation_embed(trigger_text: str, response: Optional[str], emoji_id: Optional[int], is_emoji: bool, is_full_match: bool) -> discord.Embed:
|
||||||
|
trigger_text = formatter.shorten(trigger_text, 50)
|
||||||
|
if response:
|
||||||
|
response = formatter.shorten(response, 50)
|
||||||
|
|
||||||
|
description = (
|
||||||
|
f"**Trigger Text:** `{trigger_text}`\n"
|
||||||
|
f"**Reaction Type:** {'Emoji' if is_emoji else 'Text'}\n"
|
||||||
|
f"{f'**Emoji ID:** `{str(emoji_id)}`' if is_emoji else f'**Response:** `{response}`'}\n"
|
||||||
|
f"**Full Match:** `{is_full_match}`"
|
||||||
|
)
|
||||||
|
return create_embed("Custom Reaction Created", description, 0xFF8C00, check_icon)
|
||||||
|
|
||||||
|
def create_failure_embed(trigger_text: str, is_emoji: bool, limit_reached: bool = False, trigger_already_exists: bool = False) -> discord.Embed:
|
||||||
|
trigger_text = formatter.shorten(trigger_text, 50)
|
||||||
|
|
||||||
|
description = f"**Trigger Text:** `{trigger_text}`\n"
|
||||||
|
|
||||||
|
if limit_reached:
|
||||||
|
description += "Failed to add custom reaction. You have reached the limit of 100 custom reactions for this server."
|
||||||
|
elif trigger_already_exists:
|
||||||
|
description += "Failed to add custom reaction. This text already contains another trigger. To avoid unexpected behavior, please delete it before adding a new one."
|
||||||
|
else:
|
||||||
|
description += "Failed to add custom reaction."
|
||||||
|
|
||||||
|
return create_embed("Custom Reaction Creation Failed", description, 0xFF0000, cross_icon)
|
53
modules/triggers/__init__.py
Normal file
53
modules/triggers/__init__.py
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
|
||||||
|
from discord.commands import SlashCommandGroup
|
||||||
|
from discord.ext import commands
|
||||||
|
import discord
|
||||||
|
|
||||||
|
from lib import checks
|
||||||
|
from Client import LumiBot
|
||||||
|
from modules.triggers.add import add_reaction
|
||||||
|
|
||||||
|
|
||||||
|
class Triggers(commands.Cog):
|
||||||
|
def __init__(self, client: LumiBot):
|
||||||
|
self.client = client
|
||||||
|
|
||||||
|
trigger = SlashCommandGroup(
|
||||||
|
"trigger", "Manage custom reactions.", guild_only=True
|
||||||
|
)
|
||||||
|
add = trigger.create_subgroup("add", "Add new custom reactions.")
|
||||||
|
|
||||||
|
@add.command(
|
||||||
|
name="response",
|
||||||
|
description="Add a new custom text reaction.",
|
||||||
|
help="Add a new custom text reaction to the database.",
|
||||||
|
)
|
||||||
|
@commands.guild_only()
|
||||||
|
@checks.allowed_in_channel()
|
||||||
|
async def add_text_reaction_command(
|
||||||
|
self,
|
||||||
|
ctx,
|
||||||
|
trigger_text: str,
|
||||||
|
response: str,
|
||||||
|
is_full_match: bool
|
||||||
|
):
|
||||||
|
await add_reaction(ctx, trigger_text, response, None, False, is_full_match)
|
||||||
|
|
||||||
|
@add.command(
|
||||||
|
name="emoji",
|
||||||
|
description="Add a new custom emoji reaction.",
|
||||||
|
help="Add a new custom emoji reaction to the database.",
|
||||||
|
)
|
||||||
|
@commands.guild_only()
|
||||||
|
@checks.allowed_in_channel()
|
||||||
|
async def add_emoji_reaction_command(
|
||||||
|
self,
|
||||||
|
ctx,
|
||||||
|
trigger_text: str,
|
||||||
|
emoji: discord.Emoji,
|
||||||
|
is_full_match: bool
|
||||||
|
):
|
||||||
|
await add_reaction(ctx, trigger_text, None, emoji.id, True, is_full_match)
|
||||||
|
|
||||||
|
def setup(client: LumiBot):
|
||||||
|
client.add_cog(Triggers(client))
|
51
modules/triggers/add.py
Normal file
51
modules/triggers/add.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
from discord.ext import bridge
|
||||||
|
from typing import Optional
|
||||||
|
from services.reactions_service import CustomReactionsService
|
||||||
|
from lib.embeds.triggers import create_creation_embed, create_failure_embed
|
||||||
|
|
||||||
|
async def add_reaction(ctx: bridge.Context, trigger_text: str, response: Optional[str], emoji_id: Optional[int], is_emoji: bool, is_full_match: bool) -> None:
|
||||||
|
if ctx.guild is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
reaction_service = CustomReactionsService()
|
||||||
|
guild_id: int = ctx.guild.id
|
||||||
|
creator_id: int = ctx.author.id
|
||||||
|
|
||||||
|
if not await check_reaction_limit(ctx, reaction_service, guild_id, trigger_text, is_emoji):
|
||||||
|
return
|
||||||
|
|
||||||
|
if not await check_existing_trigger(ctx, reaction_service, guild_id, trigger_text, is_emoji):
|
||||||
|
return
|
||||||
|
|
||||||
|
success: bool = await reaction_service.create_custom_reaction(
|
||||||
|
guild_id=guild_id,
|
||||||
|
creator_id=creator_id,
|
||||||
|
trigger_text=trigger_text,
|
||||||
|
response=response,
|
||||||
|
emoji_id=emoji_id,
|
||||||
|
is_emoji=is_emoji,
|
||||||
|
is_full_match=is_full_match,
|
||||||
|
is_global=False, # only bot admins can create global custom reactions
|
||||||
|
)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
embed = create_creation_embed(trigger_text, response, emoji_id, is_emoji, is_full_match)
|
||||||
|
await ctx.respond(embed=embed)
|
||||||
|
else:
|
||||||
|
embed = create_failure_embed(trigger_text, is_emoji)
|
||||||
|
await ctx.respond(embed=embed)
|
||||||
|
|
||||||
|
async def check_reaction_limit(ctx: bridge.Context, reaction_service: CustomReactionsService, guild_id: int, trigger_text: str, is_emoji: bool) -> bool:
|
||||||
|
if await reaction_service.count_custom_reactions(guild_id) >= 100:
|
||||||
|
embed = create_failure_embed(trigger_text, is_emoji, limit_reached=True)
|
||||||
|
await ctx.respond(embed=embed)
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
async def check_existing_trigger(ctx: bridge.Context, reaction_service: CustomReactionsService, guild_id: int, trigger_text: str, is_emoji: bool) -> bool:
|
||||||
|
existing_trigger = await reaction_service.find_trigger(guild_id, trigger_text)
|
||||||
|
if existing_trigger:
|
||||||
|
embed = create_failure_embed(trigger_text, is_emoji, trigger_already_exists=True)
|
||||||
|
await ctx.respond(embed=embed)
|
||||||
|
return False
|
||||||
|
return True
|
|
@ -76,8 +76,7 @@ class CustomReactionsService:
|
||||||
|
|
||||||
async def edit_custom_reaction(
|
async def edit_custom_reaction(
|
||||||
self,
|
self,
|
||||||
guild_id: int,
|
reaction_id: int,
|
||||||
trigger_text: str,
|
|
||||||
new_response: Optional[str] = None,
|
new_response: Optional[str] = None,
|
||||||
new_emoji_id: Optional[int] = None,
|
new_emoji_id: Optional[int] = None,
|
||||||
is_emoji: Optional[bool] = None,
|
is_emoji: Optional[bool] = None,
|
||||||
|
@ -92,7 +91,7 @@ class CustomReactionsService:
|
||||||
is_full_match = COALESCE(?, is_full_match),
|
is_full_match = COALESCE(?, is_full_match),
|
||||||
is_global = COALESCE(?, is_global),
|
is_global = COALESCE(?, is_global),
|
||||||
updated_at = ?
|
updated_at = ?
|
||||||
WHERE guild_id = ? AND trigger_text = ?
|
WHERE id = ?
|
||||||
"""
|
"""
|
||||||
database.execute_query(
|
database.execute_query(
|
||||||
query,
|
query,
|
||||||
|
@ -103,18 +102,17 @@ class CustomReactionsService:
|
||||||
is_full_match,
|
is_full_match,
|
||||||
is_global,
|
is_global,
|
||||||
datetime.utcnow(),
|
datetime.utcnow(),
|
||||||
guild_id,
|
reaction_id,
|
||||||
trigger_text,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def delete_custom_reaction(self, guild_id: int, trigger_text: str) -> bool:
|
async def delete_custom_reaction(self, reaction_id: int) -> bool:
|
||||||
query = """
|
query = """
|
||||||
DELETE FROM custom_reactions
|
DELETE FROM custom_reactions
|
||||||
WHERE guild_id = ? AND trigger_text = ?
|
WHERE id = ?
|
||||||
"""
|
"""
|
||||||
database.execute_query(query, (guild_id, trigger_text))
|
database.execute_query(query, (reaction_id,))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def count_custom_reactions(self, guild_id: int) -> int:
|
async def count_custom_reactions(self, guild_id: int) -> int:
|
||||||
|
|
Loading…
Reference in a new issue