Browse Source

Added a reaction role system. Setup the Message with /setup_reactionrole.

BaumSplitter41 2 tuần trước cách đây
mục cha
commit
d86a387b9f

+ 163 - 0
VPD_BOT/cogs/reaction_roles.py

@@ -0,0 +1,163 @@
+import discord
+from discord.ext import commands
+from discord.commands import Option
+from discord.commands import slash_command
+import configparser
+import time
+import json
+from pathlib import Path
+
+class reactionroles(commands.Cog):
+    def __init__(self, bot: discord.Bot):
+        self.bot = bot
+    
+    def _load_config(self):
+        config = configparser.ConfigParser()
+        configFilePath = r'config.cfg'
+        config.read(configFilePath)
+        return config
+    
+    def _get_roles(self):
+        config = self._load_config()
+        role_ids = [int(role_ids.strip()) for role_id in config["Reactionroles"]["reactionroles_role_ids"].split(",")]
+        roles = [self.bot.get_roles(role_ids) for role_id in role_ids]
+        if any(role is None for role in roles):
+            print(f"One or more roles with IDs {role_ids} not found.")
+            return
+        return roles
+    def _get_emojis(self):
+        config = self._load_config()
+        emojis = [int(emojis.strip()) for emoji in config["Reactionroles"]["reactionroles_emojis"].split(",")]
+        return emojis
+    
+    #Get the reaction role embed text from the .json file
+    def _reaction_role_embed(self):
+        json_path = Path(__file__).resolve().parent.parent.joinpath("json_files", "reaction_role_msg.json")
+        if not json_path.exists():
+            print("The .json file is missing.")
+            return
+        try:
+            with json_path.open("r", encoding="utf-8") as f:
+                json_data = json.load(f)
+        except json.JSONDecodeError:
+            print("The .json file is not valid JSON.")
+            return
+        if isinstance(json_data, dict):
+            entries = [json_data]
+        elif isinstance(json_data, list):
+            entries = json_data
+        else:
+            print("The .json file has an unexpected structure.")
+            return
+        if not entries or not isinstance(entries[0], dict):
+            print("The .json file has an unexpected structure.")
+            return
+        if not entries:
+            print("The .json file is empty.")
+            return
+
+        entry = entries[0]
+        jstitle = entry.get("title", "Reaction Roles")
+        jsdesc = entry.get("desc", "No description provided.")
+        
+        embed = discord.Embed(
+            title=f"{jstitle}",
+            description=f"{jsdesc}",
+            color=discord.Color.blue()
+        )
+        embed.set_author(name="VicePD", icon_url="https://i.imgur.com/6QteFrg.png")
+        embed.set_footer(text="VicePD - Bot | Made by BaumSplitter41")
+
+        return embed
+    
+
+    #Setup the reaction role message
+    @slash_command(name="setup_reactionrole", description="Setup the reaction role message")
+    async def reactionmsg(
+            self,
+            ctx,
+            channel: discord.TextChannel = Option(discord.TextChannel, "Select Channel", required=True)
+        ):
+        if not ctx.author.guild_permissions.administrator:
+            await ctx.respond("You don't have permission to use this command.")
+            return
+        embed = self._get_reaction_role_message()
+        if embed is None:
+            await ctx.respond("Failed to load the reaction role message.")
+            return
+        message = await channel.send(embed=embed)
+        await ctx.respond(f"Reaction role message has been set up in {channel.mention}.", ephemeral=True)
+        # Add reactions to the message
+        emojis = self._reaction_role_embed()
+        if emojis is None:
+            await ctx.respond("Failed to load emojis from config.", ephemeral=True)
+            return
+        for emoji in emojis:
+            try:
+                await message.add_reaction(emoji)
+            except Exception as e:
+                await ctx.respond(f"Failed to add reaction {emoji}: {e}", ephemeral=True)
+        return message.id
+        
+#-----------------------------------------------#
+
+    #Add role to user
+    @commands.Cog.listener()
+    async def on_raw_reaction_add(self, payload):
+        #Get variables
+        user = self.bot.get_user(payload.user_id)
+        guild = self.bot.get_guild(payload.guild_id)
+        if user.bot:
+            return
+        message_id = self.reactionmsg(ctx=None) 
+        if payload.message_id != message_id:
+            return
+        emojis = self._get_emojis()
+        if emojis is None:
+            return
+        if payload.emoji.id not in emojis:
+            return
+        roles = self._get_roles()
+        if roles is None:
+            return
+        
+        #Add the role to the user
+        for emoji, role in zip(emojis, roles):
+            if payload.emoji.id == emoji:
+                await user.add_roles(role)
+                remove_reaction = discord.utils.get(guild.emojis, id=emoji)
+                await payload.member.remove_reaction(remove_reaction, payload.message_id)
+                break
+
+
+    #Remove role from user
+    @commands.Cog.listener()
+    async def on_raw_reaction_remove(self, payload):
+        #Get variables
+        user = self.bot.get_user(payload.user_id)
+        guild = self.bot.get_guild(payload.guild_id)
+        if user.bot:
+            return
+        message_id = self.reactionmsg(ctx=None) 
+        if payload.message_id != message_id:
+            return
+        emojis = self._get_emojis()
+        if emojis is None:
+            return
+        if payload.emoji.id not in emojis:
+            return
+        roles = self._get_roles()
+        if roles is None:
+            return
+        
+        #Add the role to the user
+        for emoji, role in zip(emojis, roles):
+            if payload.emoji.id == emoji:
+                await user.remove_roles(role)
+                remove_reaction = discord.utils.get(guild.emojis, id=emoji)
+                await payload.member.remove_reaction(remove_reaction, payload.message_id)
+                break
+        
+        
+def setup(bot: discord.Bot):
+    bot.add_cog(reactionroles(bot))

+ 5 - 2
VPD_BOT/config.cfg

@@ -1,8 +1,11 @@
-#Reactionroles Rules (/verify)
-[Reactionroles Rules]
+#Verification system and the reactionrole system
+[Reactionroles]
 label_rules = Verifizieren
 rules_roles = 1442528544394575892, 1482816135190679613
 
+reactionroles_role_ids = 1498348240460845186, 1498348429590397018, 1498348683631263914, 1498348483864821791
+reactionroles_emojis = 🔔, 🛠 , 🎉, 🎮
+
 
 # Channel IDs for the logs
 [Logs]

+ 4 - 0
VPD_BOT/json_files/reaction_role_msg.json

@@ -0,0 +1,4 @@
+{
+  "title": "Ping Reaction Role",
+  "desc": "Um eine Ping-Rolle auszuwählen, reagiere mit der entsprechenden Emoji auf diese Nachricht. \n\n **Rollen:** \n - <@&1498348240460845186> (🔔) → News und Ankündigungen\n - <@&1498348429590397018> (🛠) → Server Wartungsarbeiten  \n - <@&1498348683631263914> (🎉) → Events \n - <@&1498348483864821791> (🎮) → Spieler gesucht \n\n *Zum entfernen deiner Pingrolle, reagiere erneut mit dem entsprechenden Emoji."
+}