From 7858e397142bd3bb75a2c4f1f3ca81545edb1139 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Sun, 6 Oct 2024 21:24:55 +0530 Subject: [PATCH 01/22] Add autoresponder config data during serverconfig generation --- framework/isobot/db/serverconfig.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/framework/isobot/db/serverconfig.py b/framework/isobot/db/serverconfig.py index 380c5a5..c33b90d 100644 --- a/framework/isobot/db/serverconfig.py +++ b/framework/isobot/db/serverconfig.py @@ -34,7 +34,10 @@ def generate(self, server_id: int) -> int: "message": None }, "level_up_override_channel": None, - "verification_role": None + "verification_role": None, + "autoresponder": [ + + ] } self.save(serverconf) return 0 From a090a879950116f0eac4fe8f90b6d14047f6a775 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Sun, 6 Oct 2024 21:48:35 +0530 Subject: [PATCH 02/22] Add heading comments to differentiate `fetch` and `set` functions --- framework/isobot/db/serverconfig.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/framework/isobot/db/serverconfig.py b/framework/isobot/db/serverconfig.py index c33b90d..17becae 100644 --- a/framework/isobot/db/serverconfig.py +++ b/framework/isobot/db/serverconfig.py @@ -36,7 +36,7 @@ def generate(self, server_id: int) -> int: "level_up_override_channel": None, "verification_role": None, "autoresponder": [ - + ] } self.save(serverconf) @@ -47,6 +47,7 @@ def fetch_raw(self, server_id: int) -> dict: serverconf = self.load() return serverconf[str(server_id)] + # Fetch Functions def fetch_autorole(self, server_id: int) -> str: """Fetches the specified autorole for the server. Returns `None` if not set.""" return self.fetch_raw(server_id)["autorole"] @@ -67,6 +68,7 @@ def fetch_verification_role(self, server_id: int) -> str: """Fetches the verified member role for the specified guild. Returns `None` if server verification system is disabled.""" return self.fetch_raw(server_id)["verification_role"] + # Set Functions def set_autorole(self, server_id: int, role_id: int) -> int: """Sets a role id to use as autorole for the specified guild. Returns `0` if successful.""" serverconf = self.load() From 098f05c5be31f9a6bad1e5a64296c9963884b271 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:27:44 +0530 Subject: [PATCH 03/22] Switch serverconfig autoresponder data type from `list` to `dict` This allows for more flexibility with implementation of `autoresponder names` as configuration reference points. --- framework/isobot/db/serverconfig.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/isobot/db/serverconfig.py b/framework/isobot/db/serverconfig.py index 17becae..a8d74b1 100644 --- a/framework/isobot/db/serverconfig.py +++ b/framework/isobot/db/serverconfig.py @@ -35,9 +35,9 @@ def generate(self, server_id: int) -> int: }, "level_up_override_channel": None, "verification_role": None, - "autoresponder": [ + "autoresponder": { - ] + } } self.save(serverconf) return 0 From 7467086e57d6ac0d8a25c95e315afd47e8bb5be1 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:29:31 +0530 Subject: [PATCH 04/22] Make framework module functions for autoresponder configuration management Also I finally get to use typing extentions with this so yay --- framework/isobot/db/serverconfig.py | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/framework/isobot/db/serverconfig.py b/framework/isobot/db/serverconfig.py index a8d74b1..2f9a39d 100644 --- a/framework/isobot/db/serverconfig.py +++ b/framework/isobot/db/serverconfig.py @@ -2,6 +2,7 @@ # Imports import json +from typing_extensions import Literal, Union from framework.isobot.colors import Colors as colors # Functions @@ -67,6 +68,13 @@ def fetch_levelup_override_channel(self, server_id: int) -> str: def fetch_verification_role(self, server_id: int) -> str: """Fetches the verified member role for the specified guild. Returns `None` if server verification system is disabled.""" return self.fetch_raw(server_id)["verification_role"] + + def fetch_autoresponder_configuration(self, server_id: int, *, autoresponder_name: str = None) -> dict: + """Fetches a `dict` of the current configuration for autoresponders for the specified guild. Returns an empty `dict` if none are set up.""" + if autoresponder_name is not None: + return self.fetch_raw(server_id)["autoresponder"][autoresponder_name] + else: + return self.fetch_raw(server_id)["autoresponder"] # Set Functions def set_autorole(self, server_id: int, role_id: int) -> int: @@ -100,3 +108,37 @@ def set_verification_role(self, server_id: int, role_id: int) -> int: serverconf = self.load() serverconf[str(server_id)]["verification_role"] = role_id self.save(serverconf) + + # Autoresponder System Functions + def add_autoresponder( + self, + server_id: Union[int, str], + autoresponder_name: str, + autoresponder_trigger: str, + autoresponder_text: str, + autoresponder_trigger_condition: str = Literal["MATCH_MESSAGE", "WITHIN_MESSAGE"], + *, + channels: list = None, + match_case: bool = False + ): + """Adds a new autoresponder configuration for the specified guild, with the provided configuration data. Returns `0` if successful.\n\nNotes: \n- `autoreponder_name` can be considered as autoresponder id.""" + serverconf = self.load() + serverconf[str(server_id)]["autoresponder"][autoresponder_name] = { + "autoresponder_trigger": autoresponder_trigger, + "autoresponder_text": autoresponder_text, + "autoresponder_trigger_condition": autoresponder_trigger_condition, + "active_channels": channels, + "match_case": match_case + } + self.save(serverconf) + + def remove_autoresponder(self, server_id: Union[int, str], autoresponder_name: str): + """Removes an existing autoresponder from the specified guild's serverconfig data. Returns `0` if successful, returns `1` if autoresponder does not exist, returns `2` if no autoresponders set up.""" + serverconf: dict = self.load() + if autoresponder_name in serverconf[str(server_id)]["autoresponder"].keys(): + del serverconf[str(server_id)]["autoresponder"][autoresponder_name] + self.save(serverconf) + else: + if serverconf[str(server_id)]["autoresponder"].keys() == []: + return 2 + else: return 1 From b2f29b841e234fdd61f0cc7d2d78a4c6f295e7a4 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 7 Oct 2024 20:36:48 +0530 Subject: [PATCH 05/22] Add command for adding new autoresponder configurations --- cogs/serverconfig.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py index 810d732..b9c7573 100644 --- a/cogs/serverconfig.py +++ b/cogs/serverconfig.py @@ -264,6 +264,47 @@ async def verify(self, ctx: ApplicationContext, verification_code: int): json.dump(self.verification_db, f, indent=4) return await ctx.respond(f"You have been successfully verified in **{vcode_guild.name}**!") + + # Autoresponder Configuration Commands + #autoresponder_commands = SlashCommandGroup(name="autoresponder", description="Commands related to the management of server text-based autoresponders.") + + commands.slash_command( + name="autoresponder_add", + description="Add a new text-based autoresponder to your server." + ) + @option(name="autoresponder_name", description="The name (id) of the autoresponder.", type=str) + @option(name="text_trigger", description="The text on which the autoresponder is triggered.", type=str) + @option(name="text_response", description="The response you want the bot to send, when triggered.", type=str) + @option(name="trigger_condition", description="MATCH_MESSAGE: The message content must be the same as the trigger; WITHIN_MESSAGE: When trigger is found anywhere within the message", type=str, choices=["MATCH_MESSAGE", "WITHIN_MESSAGE"]) + @option(name="active_channel", description="In which channel do you want the autoresponder to be active?", type=discord.TextChannel, default=None) + @option(name="match_case", description="Do you want the trigger to be case-sensitive?", type=bool, default=False) + async def autoresponder_add(self, ctx: ApplicationContext, autoresponder_name: str, text_trigger: str, text_response: str, trigger_condition: str, active_channel: discord.TextChannel, match_case: bool): + """Add a new text-based autoresponder to your server.""" + if not ctx.author.guild_permissions.manage_messages: + return await ctx.respond("You can't use this command! You need the `Manage Messages` permission to run this.", ephemeral=True) + serverconf.add_autoresponder( + ctx.guild.id, + autoresponder_name=autoresponder_name, + autoresponder_trigger=text_trigger, + autoresponder_text=text_response, + autoresponder_trigger_condition=trigger_condition, + channels=active_channel, + match_case=match_case + ) + localembed = discord.Embed( + title=":white_check_mark: Autoresponder Successfully Created", + description=f"Autoresponder Name: `{autoresponder_name}`\n\nYou may use the autoresponder name to reference this autoresponder, for editing or deleting.", + color=discord.Color.green() + ) + localembed.add_field(name="Text Trigger", value=text_trigger) + localembed.add_field(name="Bot Response", value=text_response) + localembed.add_field(name="Autoresponder Trigger Condition", value=trigger_condition) + if active_channel == None: + localembed.add_field(name="Active Channel", value="all channels") + else: + localembed.add_field(name="Active Channel", value=f"<#{active_channel.id}>") + localembed.add_field(name="Match Case?", value=match_case) + await ctx.respond(embed=localembed) def setup(bot): bot.add_cog(ServerConfig(bot)) From 331fbd77bb244186abaa41922119d3ac85eecd96 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 7 Oct 2024 20:45:24 +0530 Subject: [PATCH 06/22] Add a command to remove an existing autoresponder configuration --- cogs/serverconfig.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py index b9c7573..96ec871 100644 --- a/cogs/serverconfig.py +++ b/cogs/serverconfig.py @@ -305,6 +305,34 @@ async def autoresponder_add(self, ctx: ApplicationContext, autoresponder_name: s localembed.add_field(name="Active Channel", value=f"<#{active_channel.id}>") localembed.add_field(name="Match Case?", value=match_case) await ctx.respond(embed=localembed) + + commands.slash_command( + name="autoresponder_remove", + description="Remove an existing autoresponder from your server." + ) + @option(name="autoresponder_name", description="The name of the autoresponder you want to remove.", type=str) + async def autoresponder_remove(self, ctx: ApplicationContext, autoresponder_name: str): + """Remove an existing autoresponder from your server.""" + if not ctx.author.guild_permissions.manage_messages: + return await ctx.respond("You can't use this command! You need the `Manage Messages` permission to run this.", ephemeral=True) + result_code = serverconf.remove_autoresponder(ctx.guild.id, autoresponder_name) + if result_code == 0: + localembed = discord.Embed( + title=f":white_check_mark: Autoresponder `{autoresponder_name}` Successfully Removed", + description="The bot will now not respond to this autoresponder's trigger.", + color=discord.Color.green() + ) + await ctx.respond(embed=localembed) + elif result_code == 1: + localembed = discord.Embed(title="Failed to Remove Autoresponder", description=f"You don't have an autoresponder set with the name `{autoresponder_name}`.", color=discord.Color.red()) + await ctx.respond(embed=localembed) + elif result_code == 2: + localembed = discord.Embed( + title="No Autoresponders Set", + description=f"You don't have any autoresponders you can remove, let alone something with the name `{autoresponder_name}`.", + color=discord.Color.orange() + ) + await ctx.respond(embed=localembed) def setup(bot): bot.add_cog(ServerConfig(bot)) From 1ce692e2ac88574b38037ba96111113470939021 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 7 Oct 2024 21:27:40 +0530 Subject: [PATCH 07/22] Add missing decorator symbols for some commands --- cogs/serverconfig.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py index 96ec871..031880f 100644 --- a/cogs/serverconfig.py +++ b/cogs/serverconfig.py @@ -268,7 +268,7 @@ async def verify(self, ctx: ApplicationContext, verification_code: int): # Autoresponder Configuration Commands #autoresponder_commands = SlashCommandGroup(name="autoresponder", description="Commands related to the management of server text-based autoresponders.") - commands.slash_command( + @commands.slash_command( name="autoresponder_add", description="Add a new text-based autoresponder to your server." ) @@ -306,7 +306,7 @@ async def autoresponder_add(self, ctx: ApplicationContext, autoresponder_name: s localembed.add_field(name="Match Case?", value=match_case) await ctx.respond(embed=localembed) - commands.slash_command( + @commands.slash_command( name="autoresponder_remove", description="Remove an existing autoresponder from your server." ) From 118ec55635415fa4f0eca42570f525a7257f3c1b Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 7 Oct 2024 21:29:18 +0530 Subject: [PATCH 08/22] Add emojis to some embed responses in `autoresponder_remove` --- cogs/serverconfig.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py index 031880f..5acc100 100644 --- a/cogs/serverconfig.py +++ b/cogs/serverconfig.py @@ -324,11 +324,11 @@ async def autoresponder_remove(self, ctx: ApplicationContext, autoresponder_name ) await ctx.respond(embed=localembed) elif result_code == 1: - localembed = discord.Embed(title="Failed to Remove Autoresponder", description=f"You don't have an autoresponder set with the name `{autoresponder_name}`.", color=discord.Color.red()) + localembed = discord.Embed(title=":x: Failed to Remove Autoresponder", description=f"You don't have an autoresponder set with the name `{autoresponder_name}`.", color=discord.Color.red()) await ctx.respond(embed=localembed) elif result_code == 2: localembed = discord.Embed( - title="No Autoresponders Set", + title=":grey_question: No Autoresponders Set", description=f"You don't have any autoresponders you can remove, let alone something with the name `{autoresponder_name}`.", color=discord.Color.orange() ) From 5e9efcd2d454dbe2e7e7b70629f993646e75a2cc Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 7 Oct 2024 21:38:36 +0530 Subject: [PATCH 09/22] Shorten the description for the option `trigger_condition` in `/autoresponder_add` --- cogs/serverconfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py index 5acc100..fba1b10 100644 --- a/cogs/serverconfig.py +++ b/cogs/serverconfig.py @@ -275,7 +275,7 @@ async def verify(self, ctx: ApplicationContext, verification_code: int): @option(name="autoresponder_name", description="The name (id) of the autoresponder.", type=str) @option(name="text_trigger", description="The text on which the autoresponder is triggered.", type=str) @option(name="text_response", description="The response you want the bot to send, when triggered.", type=str) - @option(name="trigger_condition", description="MATCH_MESSAGE: The message content must be the same as the trigger; WITHIN_MESSAGE: When trigger is found anywhere within the message", type=str, choices=["MATCH_MESSAGE", "WITHIN_MESSAGE"]) + @option(name="trigger_condition", description="How do you want the autoresponder to be triggered?", type=str, choices=["MATCH_MESSAGE", "WITHIN_MESSAGE"]) @option(name="active_channel", description="In which channel do you want the autoresponder to be active?", type=discord.TextChannel, default=None) @option(name="match_case", description="Do you want the trigger to be case-sensitive?", type=bool, default=False) async def autoresponder_add(self, ctx: ApplicationContext, autoresponder_name: str, text_trigger: str, text_response: str, trigger_condition: str, active_channel: discord.TextChannel, match_case: bool): From 85b7ee0741e8b67509e2bb84490210d323c330bb Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 7 Oct 2024 21:40:01 +0530 Subject: [PATCH 10/22] Switch `active_channels` to `active_channel` Since the option `active_channels` only currently has support for one channel (or None), it makes more logical sense to name it as `active_channel` rather than `active_channels`. --- cogs/serverconfig.py | 2 +- framework/isobot/db/serverconfig.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py index fba1b10..3431a8e 100644 --- a/cogs/serverconfig.py +++ b/cogs/serverconfig.py @@ -288,7 +288,7 @@ async def autoresponder_add(self, ctx: ApplicationContext, autoresponder_name: s autoresponder_trigger=text_trigger, autoresponder_text=text_response, autoresponder_trigger_condition=trigger_condition, - channels=active_channel, + channel=active_channel, match_case=match_case ) localembed = discord.Embed( diff --git a/framework/isobot/db/serverconfig.py b/framework/isobot/db/serverconfig.py index 2f9a39d..a0f5ab7 100644 --- a/framework/isobot/db/serverconfig.py +++ b/framework/isobot/db/serverconfig.py @@ -118,7 +118,7 @@ def add_autoresponder( autoresponder_text: str, autoresponder_trigger_condition: str = Literal["MATCH_MESSAGE", "WITHIN_MESSAGE"], *, - channels: list = None, + channel: list = None, match_case: bool = False ): """Adds a new autoresponder configuration for the specified guild, with the provided configuration data. Returns `0` if successful.\n\nNotes: \n- `autoreponder_name` can be considered as autoresponder id.""" @@ -127,7 +127,7 @@ def add_autoresponder( "autoresponder_trigger": autoresponder_trigger, "autoresponder_text": autoresponder_text, "autoresponder_trigger_condition": autoresponder_trigger_condition, - "active_channels": channels, + "active_channel": channel, "match_case": match_case } self.save(serverconf) From 1f5013d5e69c181daab15c53677b2cd7831614c5 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 7 Oct 2024 21:54:29 +0530 Subject: [PATCH 11/22] Use channel `id` property when setting active autoresponder channel --- cogs/serverconfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py index 3431a8e..ccac929 100644 --- a/cogs/serverconfig.py +++ b/cogs/serverconfig.py @@ -288,7 +288,7 @@ async def autoresponder_add(self, ctx: ApplicationContext, autoresponder_name: s autoresponder_trigger=text_trigger, autoresponder_text=text_response, autoresponder_trigger_condition=trigger_condition, - channel=active_channel, + channel=active_channel.id, match_case=match_case ) localembed = discord.Embed( From cf16c884957a3412c503f61212987416f5fd0a75 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 7 Oct 2024 21:55:26 +0530 Subject: [PATCH 12/22] Prioritize checks for function error codes before continuing with success response --- cogs/serverconfig.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py index ccac929..0e8405a 100644 --- a/cogs/serverconfig.py +++ b/cogs/serverconfig.py @@ -316,16 +316,9 @@ async def autoresponder_remove(self, ctx: ApplicationContext, autoresponder_name if not ctx.author.guild_permissions.manage_messages: return await ctx.respond("You can't use this command! You need the `Manage Messages` permission to run this.", ephemeral=True) result_code = serverconf.remove_autoresponder(ctx.guild.id, autoresponder_name) - if result_code == 0: - localembed = discord.Embed( - title=f":white_check_mark: Autoresponder `{autoresponder_name}` Successfully Removed", - description="The bot will now not respond to this autoresponder's trigger.", - color=discord.Color.green() - ) - await ctx.respond(embed=localembed) - elif result_code == 1: + if result_code == 1: localembed = discord.Embed(title=":x: Failed to Remove Autoresponder", description=f"You don't have an autoresponder set with the name `{autoresponder_name}`.", color=discord.Color.red()) - await ctx.respond(embed=localembed) + return await ctx.respond(embed=localembed) elif result_code == 2: localembed = discord.Embed( title=":grey_question: No Autoresponders Set", From a2ae62fa80694baa1f1e01dd453183a8e7e95c35 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 7 Oct 2024 21:56:05 +0530 Subject: [PATCH 13/22] Prioritize checks for function error codes before continuing with success response --- cogs/serverconfig.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py index 0e8405a..2fd944e 100644 --- a/cogs/serverconfig.py +++ b/cogs/serverconfig.py @@ -325,7 +325,13 @@ async def autoresponder_remove(self, ctx: ApplicationContext, autoresponder_name description=f"You don't have any autoresponders you can remove, let alone something with the name `{autoresponder_name}`.", color=discord.Color.orange() ) - await ctx.respond(embed=localembed) + return await ctx.respond(embed=localembed) + localembed = discord.Embed( + title=f":white_check_mark: Autoresponder `{autoresponder_name}` Successfully Removed", + description="The bot will now not respond to this autoresponder's trigger.", + color=discord.Color.green() + ) + await ctx.respond(embed=localembed) def setup(bot): bot.add_cog(ServerConfig(bot)) From 3e397a97d989c580553d8afec3dea7f354e88f67 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 7 Oct 2024 21:59:48 +0530 Subject: [PATCH 14/22] Add default values for some args --- cogs/serverconfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py index 2fd944e..7ca2deb 100644 --- a/cogs/serverconfig.py +++ b/cogs/serverconfig.py @@ -278,7 +278,7 @@ async def verify(self, ctx: ApplicationContext, verification_code: int): @option(name="trigger_condition", description="How do you want the autoresponder to be triggered?", type=str, choices=["MATCH_MESSAGE", "WITHIN_MESSAGE"]) @option(name="active_channel", description="In which channel do you want the autoresponder to be active?", type=discord.TextChannel, default=None) @option(name="match_case", description="Do you want the trigger to be case-sensitive?", type=bool, default=False) - async def autoresponder_add(self, ctx: ApplicationContext, autoresponder_name: str, text_trigger: str, text_response: str, trigger_condition: str, active_channel: discord.TextChannel, match_case: bool): + async def autoresponder_add(self, ctx: ApplicationContext, autoresponder_name: str, text_trigger: str, text_response: str, trigger_condition: str, active_channel: discord.TextChannel = None, match_case: bool = False): """Add a new text-based autoresponder to your server.""" if not ctx.author.guild_permissions.manage_messages: return await ctx.respond("You can't use this command! You need the `Manage Messages` permission to run this.", ephemeral=True) From 4e8b52d936d7af39993587b3ebb6791dbdfcb8d8 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 7 Oct 2024 22:13:35 +0530 Subject: [PATCH 15/22] Add `/autoresponder_list` to allow users to view a list of all autoresponders, or view information on a specific autoresponder --- cogs/serverconfig.py | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py index 7ca2deb..f50f60d 100644 --- a/cogs/serverconfig.py +++ b/cogs/serverconfig.py @@ -332,6 +332,56 @@ async def autoresponder_remove(self, ctx: ApplicationContext, autoresponder_name color=discord.Color.green() ) await ctx.respond(embed=localembed) + + @commands.slash_command( + name="autoresponder_list", + description="View a list of all the autoresponders in the server, or info on a specific autoresponder." + ) + @option(name="autoresponder_name", description="Which autoresponder do you want to view information about?", type=str, default=None) + async def autoresponder_list(self, ctx: ApplicationContext, autoresponder_name: str = None): + """View a list of all the autoresponders in the server, or view specific information on an autoresponder.""" + if not ctx.author.guild_permissions.manage_messages: + return await ctx.respond("You can't use this command! You need the `Manage Messages` permission to run this.", ephemeral=True) + + # For List of All Autoresponders + if autoresponder_name == None: + autoresponders_list = serverconf.fetch_autoresponder_configuration(ctx.guild.id).keys() + if autoresponders_list == []: + localembed = discord.Embed( + title=":grey_question: No Autoresponders Set", + description=f"There are no autoresponders to show here...", + color=discord.Color.orange() + ) + return await ctx.respond(embed=localembed) + parsed_output = str() + sr = 0 + for key in autoresponders_list: + sr += 1 + parsed_output += f"{sr}. `{key}`" + localembed = discord.Embed(title=f"Autoresponders List for **{ctx.guild}**", description=parsed_output, color=discord.Color.random()) + localembed.set_footer(text="Run /autoresponder_list to get more information on a specific autoresponder.") + await ctx.respond(embed=localembed) + + # For Specific Autoresponder Configuration + else: + if autoresponder_name in serverconf.fetch_autoresponder_configuration(ctx.guild.id).keys(): + autoresponder_data: dict = serverconf.fetch_autoresponder_configuration(ctx.guild.id, autoresponder_name=autoresponder_name) + localembed = discord.Embed(title=f"Information on Autoresponder `{autoresponder_name}`") + localembed.add_field(name="Text Trigger", value=autoresponder_data["autoresponder_trigger"]) + localembed.add_field(name="Bot Response", value=autoresponder_data["autoresponder_text"]) + localembed.add_field(name="Autoresponder Trigger Condition", value=autoresponder_data["autoresponder_trigger_condition"]) + if autoresponder_data["active_channel"] == None: + localembed.add_field(name="Active Channel", value="all channels") + else: + localembed.add_field(name="Active Channel", value=f"<#{autoresponder_data['active_channel']}>") + localembed.add_field(name="Match Case?", value=autoresponder_data["match_case"]) + await ctx.respond(embed=localembed) + else: + localembed = discord.Embed(title=":x: No Autoresponder Found", description=f"You don't have an autoresponder set with the name `{autoresponder_name}`.", color=discord.Color.red()) + return await ctx.respond(embed=localembed) + + + def setup(bot): bot.add_cog(ServerConfig(bot)) From 099fa1d8197c2602adfcbc4cddc7396d18f7b049 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 7 Oct 2024 22:13:47 +0530 Subject: [PATCH 16/22] Add random todo note --- cogs/serverconfig.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py index f50f60d..094e96b 100644 --- a/cogs/serverconfig.py +++ b/cogs/serverconfig.py @@ -280,6 +280,7 @@ async def verify(self, ctx: ApplicationContext, verification_code: int): @option(name="match_case", description="Do you want the trigger to be case-sensitive?", type=bool, default=False) async def autoresponder_add(self, ctx: ApplicationContext, autoresponder_name: str, text_trigger: str, text_response: str, trigger_condition: str, active_channel: discord.TextChannel = None, match_case: bool = False): """Add a new text-based autoresponder to your server.""" + # TODO: fix stuff happening when active channel is none if not ctx.author.guild_permissions.manage_messages: return await ctx.respond("You can't use this command! You need the `Manage Messages` permission to run this.", ephemeral=True) serverconf.add_autoresponder( From ac5eb00fe486cca720956c2e721e053c6aab1408 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 7 Oct 2024 22:36:31 +0530 Subject: [PATCH 17/22] Send warning message if an autoresponder already exists with the same name --- cogs/serverconfig.py | 7 +++++++ framework/isobot/db/serverconfig.py | 21 ++++++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py index 094e96b..5389443 100644 --- a/cogs/serverconfig.py +++ b/cogs/serverconfig.py @@ -292,6 +292,13 @@ async def autoresponder_add(self, ctx: ApplicationContext, autoresponder_name: s channel=active_channel.id, match_case=match_case ) + if result_code == 1: + localembed = discord.Embed( + title=":warning: An Autoresponder Already Exists With This Name", + description="Try again using a different name, or remove the existing autoresponder and run this command again.", + color=discord.Color.orange() + ) + return await ctx.respond(embed=localembed) localembed = discord.Embed( title=":white_check_mark: Autoresponder Successfully Created", description=f"Autoresponder Name: `{autoresponder_name}`\n\nYou may use the autoresponder name to reference this autoresponder, for editing or deleting.", diff --git a/framework/isobot/db/serverconfig.py b/framework/isobot/db/serverconfig.py index a0f5ab7..fbebfcf 100644 --- a/framework/isobot/db/serverconfig.py +++ b/framework/isobot/db/serverconfig.py @@ -121,16 +121,19 @@ def add_autoresponder( channel: list = None, match_case: bool = False ): - """Adds a new autoresponder configuration for the specified guild, with the provided configuration data. Returns `0` if successful.\n\nNotes: \n- `autoreponder_name` can be considered as autoresponder id.""" + """Adds a new autoresponder configuration for the specified guild, with the provided configuration data. Returns `0` if successful, returns `1` if configuration with same name already exists.\n\nNotes: \n- `autoreponder_name` can be considered as autoresponder id.""" serverconf = self.load() - serverconf[str(server_id)]["autoresponder"][autoresponder_name] = { - "autoresponder_trigger": autoresponder_trigger, - "autoresponder_text": autoresponder_text, - "autoresponder_trigger_condition": autoresponder_trigger_condition, - "active_channel": channel, - "match_case": match_case - } - self.save(serverconf) + if autoresponder_name not in serverconf[str(server_id)]["autoresponder"].keys(): + serverconf[str(server_id)]["autoresponder"][autoresponder_name] = { + "autoresponder_trigger": autoresponder_trigger, + "autoresponder_text": autoresponder_text, + "autoresponder_trigger_condition": autoresponder_trigger_condition, + "active_channel": channel, + "match_case": match_case + } + self.save(serverconf) + return 0 + else: return 1 def remove_autoresponder(self, server_id: Union[int, str], autoresponder_name: str): """Removes an existing autoresponder from the specified guild's serverconfig data. Returns `0` if successful, returns `1` if autoresponder does not exist, returns `2` if no autoresponders set up.""" From 0583a8f3df9c03bf3b147243cb3357cb327d5181 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 7 Oct 2024 22:37:38 +0530 Subject: [PATCH 18/22] Fix issue where `/autoresponder_add` would crash if `active_channel` is left blank --- cogs/serverconfig.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py index 5389443..c99d7b9 100644 --- a/cogs/serverconfig.py +++ b/cogs/serverconfig.py @@ -283,13 +283,13 @@ async def autoresponder_add(self, ctx: ApplicationContext, autoresponder_name: s # TODO: fix stuff happening when active channel is none if not ctx.author.guild_permissions.manage_messages: return await ctx.respond("You can't use this command! You need the `Manage Messages` permission to run this.", ephemeral=True) - serverconf.add_autoresponder( + result_code = serverconf.add_autoresponder( ctx.guild.id, autoresponder_name=autoresponder_name, autoresponder_trigger=text_trigger, autoresponder_text=text_response, autoresponder_trigger_condition=trigger_condition, - channel=active_channel.id, + channel=active_channel.id if active_channel is not None else None, match_case=match_case ) if result_code == 1: From 29f35ef06a330e70e314d1ac0e76bdd285fd6743 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 7 Oct 2024 22:38:11 +0530 Subject: [PATCH 19/22] Remove a reference todo note --- cogs/serverconfig.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py index c99d7b9..2fe9639 100644 --- a/cogs/serverconfig.py +++ b/cogs/serverconfig.py @@ -280,7 +280,6 @@ async def verify(self, ctx: ApplicationContext, verification_code: int): @option(name="match_case", description="Do you want the trigger to be case-sensitive?", type=bool, default=False) async def autoresponder_add(self, ctx: ApplicationContext, autoresponder_name: str, text_trigger: str, text_response: str, trigger_condition: str, active_channel: discord.TextChannel = None, match_case: bool = False): """Add a new text-based autoresponder to your server.""" - # TODO: fix stuff happening when active channel is none if not ctx.author.guild_permissions.manage_messages: return await ctx.respond("You can't use this command! You need the `Manage Messages` permission to run this.", ephemeral=True) result_code = serverconf.add_autoresponder( From de3c4968250f1cbc14aa7c8db09bcb0364f68a73 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 8 Oct 2024 14:58:39 +0530 Subject: [PATCH 20/22] Add autoresponder event trigger system to main code This contains a bunch of logic for different configuration settings and stuff --- main.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/main.py b/main.py index 59d99fc..7c4421b 100644 --- a/main.py +++ b/main.py @@ -307,6 +307,26 @@ async def on_message(ctx): # In that case isobot will automatically stop sending levelup messages to them logger.warn(f"Unable to send level up message to {ctx.author} ({ctx.author.id}), as they are not accepting DMs from isobot. This ID has been added to `levelup_messages` blacklist.", module="main/Levelling") settings.edit_setting(ctx.author.id, "levelup_messages", False) + + # Autoresponder System + server_autoresponder_config: dict = serverconfig.fetch_autoresponder_configuration(ctx.guild.id) + + for config in server_autoresponder_config.keys(): + if server_autoresponder_config[config]["active_channel"] == None or server_autoresponder_config[config]["active_channel"] == ctx.channel.id: + if server_autoresponder_config[config]["match_case"]: + if server_autoresponder_config[config]["autoresponder_trigger_condition"] == "MATCH_MESSAGE": + if ctx.content == server_autoresponder_config[config]["autoresponder_trigger"]: + await ctx.channel.send(server_autoresponder_config[config]["autoresponder_text"]) + elif server_autoresponder_config[config]["autoresponder_trigger_condition"] == "WITHIN_MESSAGE": + if server_autoresponder_config[config]["autoresponder_trigger"] in ctx.content: + await ctx.channel.send(server_autoresponder_config[config]["autoresponder_text"]) + else: + if server_autoresponder_config[config]["autoresponder_trigger_condition"] == "MATCH_MESSAGE": + if ctx.content.lower() == server_autoresponder_config[config]["autoresponder_trigger"]: + await ctx.channel.send(server_autoresponder_config[config]["autoresponder_text"]) + elif server_autoresponder_config[config]["autoresponder_trigger_condition"] == "WITHIN_MESSAGE": + if server_autoresponder_config[config]["autoresponder_trigger"] in ctx.content.lower(): + await ctx.channel.send(server_autoresponder_config[config]["autoresponder_text"]) # Error handler @client.event From b131da329141d0f5b2c737b31048f33ece121685 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 8 Oct 2024 16:12:24 +0530 Subject: [PATCH 21/22] Move all autoresponder commands to a slash command group --- cogs/serverconfig.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py index 2fe9639..bd61552 100644 --- a/cogs/serverconfig.py +++ b/cogs/serverconfig.py @@ -266,9 +266,9 @@ async def verify(self, ctx: ApplicationContext, verification_code: int): return await ctx.respond(f"You have been successfully verified in **{vcode_guild.name}**!") # Autoresponder Configuration Commands - #autoresponder_commands = SlashCommandGroup(name="autoresponder", description="Commands related to the management of server text-based autoresponders.") + autoresponder_commands = SlashCommandGroup(name="autoresponder", description="Commands related to the management of server text-based autoresponders.") - @commands.slash_command( + @autoresponder_commands.command( name="autoresponder_add", description="Add a new text-based autoresponder to your server." ) @@ -313,7 +313,7 @@ async def autoresponder_add(self, ctx: ApplicationContext, autoresponder_name: s localembed.add_field(name="Match Case?", value=match_case) await ctx.respond(embed=localembed) - @commands.slash_command( + @autoresponder_commands.command( name="autoresponder_remove", description="Remove an existing autoresponder from your server." ) @@ -340,7 +340,7 @@ async def autoresponder_remove(self, ctx: ApplicationContext, autoresponder_name ) await ctx.respond(embed=localembed) - @commands.slash_command( + @autoresponder_commands.command( name="autoresponder_list", description="View a list of all the autoresponders in the server, or info on a specific autoresponder." ) From 5e812a31f76890c17f78521cd26bfecdccec0f07 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 8 Oct 2024 16:12:53 +0530 Subject: [PATCH 22/22] Remove a bunch of extra newlines --- cogs/serverconfig.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py index bd61552..82744c2 100644 --- a/cogs/serverconfig.py +++ b/cogs/serverconfig.py @@ -387,9 +387,6 @@ async def autoresponder_list(self, ctx: ApplicationContext, autoresponder_name: localembed = discord.Embed(title=":x: No Autoresponder Found", description=f"You don't have an autoresponder set with the name `{autoresponder_name}`.", color=discord.Color.red()) return await ctx.respond(embed=localembed) - - - def setup(bot): bot.add_cog(ServerConfig(bot)) \ No newline at end of file