From a584990e0c32ec990bbbf6b491a4e1958daf4a8e Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Sat, 4 May 2024 23:31:16 +0530 Subject: [PATCH] Add `/serverconfig autorole` to allow server managers to automatically assign roles to newly-joined members --- cogs/serverconfig.py | 45 +++++++++++++++++ framework/isobot/db/serverconfig.py | 75 +++++++++++++++++++++++++++++ main.py | 16 +++++- 3 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 cogs/serverconfig.py create mode 100644 framework/isobot/db/serverconfig.py diff --git a/cogs/serverconfig.py b/cogs/serverconfig.py new file mode 100644 index 0000000..5b979ca --- /dev/null +++ b/cogs/serverconfig.py @@ -0,0 +1,45 @@ +# Imports +import discord +from discord import option, ApplicationContext +from discord.commands import SlashCommandGroup +from discord.ext import commands +from framework.isobot.db import serverconfig + +# Variables +serverconf = serverconfig.ServerConfig() + +# Functions +class ServerConfig(commands.Cog): + def __init__(self, bot): + self.bot = bot + + serverconfig_cmds = SlashCommandGroup(name="serverconfig", description="Commands related to server customization and configuration.") + + @serverconfig_cmds.command( + name="autorole", + description="Set a role to provide to all newly-joined members of the server." + ) + @option(name="role", description="The role that you want to automatically give to all new members.", type=discord.Role, default=None) + async def autorole(self, ctx: ApplicationContext, role: discord.Role = None): + """Set a role to provide to all newly-joined members of the server.""" + if not ctx.author.guild_permissions.manage_guild: + return await ctx.respond("You can't use this command! You need the `Manage Server` permission to run this.", ephemeral=True) + if role != None: + serverconf.set_autorole(ctx.guild.id, role.id) + localembed = discord.Embed( + title=f":white_check_mark: Autorole successfully set for **{ctx.guild.name}**!", + description=f"From now onwards, all new members will receive the {role.mention} role.", + color=discord.Color.green() + ) + else: + serverconf.set_autorole(ctx.guild.id, None) + localembed = discord.Embed( + title=f":white_check_mark: Autorole successfully disabled for **{ctx.guild.name}**", + description="New members will not automatically receive any roles anymore.", + color=discord.Color.green() + ) + await ctx.respond(embed=localembed) + +def setup(bot): + bot.add_cog(ServerConfig(bot)) + \ No newline at end of file diff --git a/framework/isobot/db/serverconfig.py b/framework/isobot/db/serverconfig.py new file mode 100644 index 0000000..d2cb187 --- /dev/null +++ b/framework/isobot/db/serverconfig.py @@ -0,0 +1,75 @@ +"""The framework module library used for managing server setup configurations.""" + +# Imports +import json +from framework.isobot.colors import Colors as colors + +# Functions +class ServerConfig: + def __init__(self): + print(f"[framework/db/Automod] {colors.green}ServerConfig db library initialized.{colors.end}") + + def load(self) -> dict: + """Fetches and returns the latest data from the items database.""" + with open("database/serverconfig.json", 'r', encoding="utf8") as f: db = json.load(f) + return db + + def save(self, data: dict) -> int: + """Dumps all cached data to your local machine.""" + with open("database/serverconfig.json", 'w+', encoding="utf8") as f: json.dump(data, f) + return 0 + + def generate(self, server_id: int) -> int: + """Generates a new database key for the specified server/guild id in the automod database.""" + serverconf = self.load() + if str(server_id) not in serverconf: + serverconf[str(server_id)] = { + "autorole": None, + "welcome_message": { + "channel": None, + "message": None + }, + "goodbye_message": { + "channel": None, + "message": None + } + } + self.save(serverconf) + return 0 + + def fetch_raw(self, server_id: int) -> dict: + """Fetches the current server configuration data for the specified guild id, and returns it as a `dict`.""" + serverconf = self.load() + return serverconf[str(server_id)] + + def fetch_autorole(self, server_id: int) -> str: + """Fetch the specified autorole for the server. Returns `None` if not set.""" + return self.fetch_raw(server_id)["autorole"] + + def fetch_welcome_message(self, server_id: int) -> dict: + """Fetches the welcome message and set channel for the server as `dict`.\n\nReturns `None` for `channel` and `message` values if not set.""" + return self.fetch_raw(server_id)["welcome_message"] + + def fetch_goodbye_message(self, server_id: int) -> dict: + """Fetches the goodbye message and set channel for the server as `dict`.\n\nReturns `None` for `channel` and `message` values if not set.""" + return self.fetch_raw(server_id)["goodbye_message"] + + 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() + serverconf[str(server_id)]["autorole"] = role_id + self.save(serverconf) + + def set_welcome_message(self, server_id: int, channel_id: int, message: str) -> int: + """Sets a channel id to send a custom welcome message to, for the specified guild. Returns `0` if successful.""" + serverconf = self.load() + serverconf[str(server_id)]["welcome_message"]["channel"] = channel_id + serverconf[str(server_id)]["welcome_message"]["message"] = message + self.save(serverconf) + + def set_goodbye_message(self, server_id: int, channel_id: int, message: str) -> int: + """Sets a channel id to send a custom goodbye message to, for the specified guild. Returns `0` if successful.""" + serverconf = self.load() + serverconf[str(server_id)]["goodbye_message"]["channel"] = channel_id + serverconf[str(server_id)]["goodbye_message"]["message"] = message + self.save(serverconf) diff --git a/main.py b/main.py index bccf00e..a8cb17b 100644 --- a/main.py +++ b/main.py @@ -13,7 +13,7 @@ from random import randint from framework.isobot import currency, colors, settings, commands as _commands from framework.isobot.shop import ShopData -from framework.isobot.db import levelling, items, userdata, automod, weather, warnings, presence as _presence +from framework.isobot.db import levelling, items, userdata, automod, weather, warnings, presence as _presence, serverconfig from discord import ApplicationContext, option from discord.ext import commands from cogs.isocoin import create_isocoin_key @@ -21,6 +21,7 @@ # Variables intents = discord.Intents.default() intents.message_content = True +intents.members = True client = discord.Bot(intents=intents) color = discord.Color.random() start_time = "" @@ -46,6 +47,7 @@ def initial_setup(): "isocard", "items", "levels", + "serverconfig", "warnings", "presence", "user_data", @@ -113,6 +115,7 @@ def initial_setup(): settings = settings.Configurator() levelling = levelling.Levelling() items = items.Items() +serverconfig = serverconfig.ServerConfig() warningsdb = warnings.Warnings() userdata = userdata.UserData() automod = automod.Automod() @@ -162,6 +165,15 @@ async def on_ready(): ping.host() time.sleep(5) +@client.event +async def on_member_join(ctx): + """This event is fired whenever a new member joins a server.""" + # Automatically assigning roles to new members (autorole) + autorole = serverconfig.fetch_autorole(ctx.guild.id) + if autorole is not None: + role = discord.Guild.get_role(ctx.guild, int(autorole)) + await ctx.add_roles(role, reason="Role assigned due to autoroles.") + @client.event async def on_message(ctx): """This event is fired whenever a message is sent (in a readable channel).""" @@ -198,6 +210,7 @@ async def on_message(ctx): levelling.generate(ctx.author.id) try: automod.generate(ctx.guild.id) + serverconfig.generate(ctx.guild.id) warningsdb.generate(ctx.guild.id, ctx.author.id) except AttributeError: pass @@ -508,6 +521,7 @@ async def credits(ctx: ApplicationContext): "moderation", "minigames", "automod", + "serverconfig", "isobank", "levelling", "fun",