reaction_roles.py 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. import discord
  2. from discord.ext import commands
  3. from discord.commands import Option
  4. from discord.commands import slash_command
  5. import configparser
  6. import time
  7. import json
  8. from pathlib import Path
  9. class Reactionroles(commands.Cog):
  10. def __init__(self, bot: discord.Bot):
  11. self.bot = bot
  12. def _load_config(self):
  13. config = configparser.ConfigParser()
  14. configFilePath = r'config.cfg'
  15. config.read(configFilePath)
  16. return config
  17. def _get_roles(self):
  18. config = self._load_config()
  19. role_ids = [int(role_id.strip()) for role_id in config["Reactionroles"]["reactionroles_role_ids"].split(",")]
  20. return role_ids
  21. def _get_emojis(self):
  22. config = self._load_config()
  23. emojis = [emoji.strip() for emoji in config["Reactionroles"]["reactionroles_emojis"].split(",")]
  24. return emojis
  25. def _get_message_id(self):
  26. config = self._load_config()
  27. message_id = int(config["Reactionroles"]["reactionroles_message_id"].strip())
  28. return message_id
  29. #Get the reaction role embed text from the .json file
  30. def _reaction_role_embed(self):
  31. json_path = Path(__file__).resolve().parent.parent.joinpath("json_files", "reaction_role_msg.json")
  32. if not json_path.exists():
  33. print("The .json file is missing.")
  34. return
  35. try:
  36. with json_path.open("r", encoding="utf-8") as f:
  37. json_data = json.load(f)
  38. except json.JSONDecodeError:
  39. print("The .json file is not valid JSON.")
  40. return
  41. if isinstance(json_data, dict):
  42. entries = [json_data]
  43. elif isinstance(json_data, list):
  44. entries = json_data
  45. else:
  46. print("The .json file has an unexpected structure.")
  47. return
  48. if not entries or not isinstance(entries[0], dict):
  49. print("The .json file has an unexpected structure.")
  50. return
  51. entry = entries[0]
  52. jstitle = entry.get("title", "Reaction Roles")
  53. jsdesc = entry.get("desc", "No description provided.")
  54. embed = discord.Embed(
  55. title=f"{jstitle}",
  56. description=f"{jsdesc}",
  57. color=discord.Color.blue()
  58. )
  59. embed.set_author(name="VicePD", icon_url="https://i.imgur.com/6QteFrg.png")
  60. embed.set_footer(text="VicePD - Bot | Made by BaumSplitter41")
  61. return embed
  62. #Setup the reaction role message
  63. @slash_command(name="setup_reactionrole", description="Setup the reaction role message")
  64. async def reactionmsg(
  65. self,
  66. ctx,
  67. channel: discord.TextChannel = Option(discord.TextChannel, "Select Channel", required=True)
  68. ):
  69. if not ctx.author.guild_permissions.administrator:
  70. await ctx.respond("You don't have permission to use this command.")
  71. return
  72. embed = self._reaction_role_embed()
  73. if embed is None:
  74. await ctx.respond("Failed to load the reaction role message.")
  75. return
  76. message = await channel.send(embed=embed)
  77. await ctx.respond(f"Reaction role message has been set up in {channel.mention}.", ephemeral=True)
  78. # Add reactions to the message
  79. emojis = self._get_emojis()
  80. if emojis is None:
  81. await ctx.respond("Failed to load emojis from config.", ephemeral=True)
  82. return
  83. for emoji in emojis:
  84. try:
  85. await message.add_reaction(emoji)
  86. except Exception as e:
  87. await ctx.respond(f"Failed to add reaction {emoji}: {e}", ephemeral=True)
  88. #-----------------------------------------------#
  89. #Add role to user
  90. @commands.Cog.listener()
  91. async def on_raw_reaction_add(self, payload: discord.RawReactionActionEvent):
  92. #Get variables
  93. print(payload.emoji)
  94. guild = self.bot.get_guild(payload.guild_id)
  95. if guild is None:
  96. return
  97. member = payload.member or guild.get_member(payload.user_id)
  98. if member is None or member.bot:
  99. return
  100. message_id = self._get_message_id()
  101. emojis = self._get_emojis()
  102. if emojis is None:
  103. print("Emojis are not set in config.")
  104. return
  105. for emoji in emojis:
  106. if payload.emoji.name != emoji:
  107. print(f"Emoji {payload.emoji} does not match {emoji}.")
  108. return
  109. role_ids = self._get_roles()
  110. if role_ids is None:
  111. print("Roles are not set in config.")
  112. return
  113. for role_id in role_ids:
  114. if guild.get_role(role_id) is None:
  115. print(f"Role with ID {role_id} not found.")
  116. return
  117. roles = [guild.get_role(role_id) for role_id in role_ids]
  118. #Add role function
  119. for i in range(len(emojis)):
  120. if payload.emoji.name == emojis[i]:
  121. print(f"Adding role {roles[i].name} to user {member.name} for emoji {emojis[i]}.")
  122. try:
  123. await member.add_roles(roles[i])
  124. print(f"Added role {roles[i].name} to user {member.name}.")
  125. except Exception as e:
  126. print(f"Failed to add role {roles[i].name} to user {member.name}: {e}")
  127. break
  128. try:
  129. channel = self.bot.get_channel(payload.channel_id)
  130. if channel is not None:
  131. message = await channel.fetch_message(message_id)
  132. await message.remove_reaction(payload.emoji, member)
  133. break
  134. except Exception as e:
  135. print(f"Failed to remove reaction {payload.emoji} from user {member.name}: {e}")
  136. break
  137. else:
  138. print(f"Emoji {payload.emoji} does not match {emojis[i]} for role {roles[i].name}.")
  139. """or emoji, role in zip(emojis, roles):
  140. if payload.emoji.name == emoji:
  141. print(f"Adding role {role.name} to user {member.name} for emoji {emoji}.")
  142. try:
  143. await member.add_roles(role)
  144. print(f"Added role {role.name} to user {member.name}.")
  145. except Exception as e:
  146. print(f"Failed to add role {role.name} to user {member.name}: {e}")
  147. break
  148. try:
  149. channel = self.bot.get_channel(payload.channel_id)
  150. if channel is not None:
  151. message = await channel.fetch_message(message_id)
  152. await message.remove_reaction(payload.emoji, member)
  153. break
  154. except Exception as e:
  155. print(f"Failed to remove reaction {payload.emoji} from user {member.name}: {e}")
  156. break
  157. else:
  158. print(f"Emoji {payload.emoji} does not match {emoji} for role {role.name}.")"""
  159. #Remove role from user
  160. @commands.Cog.listener()
  161. async def on_raw_reaction_remove(self, payload: discord.RawReactionActionEvent):
  162. #Get variables
  163. guild = self.bot.get_guild(payload.guild_id)
  164. if guild is None:
  165. return
  166. member = guild.get_member(payload.user_id)
  167. if member is None or member.bot:
  168. return
  169. message_id = self._get_message_id()
  170. if message_id is None:
  171. print("Message ID is not set in config.")
  172. return
  173. emojis = self._get_emojis()
  174. if emojis is None:
  175. print("Emojis are not set in config.")
  176. return
  177. for emoji in emojis:
  178. if payload.emoji.name != emoji:
  179. print(f"Emoji {payload.emoji} does not match {emoji}.")
  180. return
  181. role_ids = self._get_roles()
  182. if role_ids is None:
  183. print("Roles are not set in config.")
  184. return
  185. for role_id in role_ids:
  186. if guild.get_role(role_id) is None:
  187. print(f"Role with ID {role_id} not found.")
  188. return
  189. roles = [guild.get_role(role_id) for role_id in role_ids]
  190. #Role remove function
  191. for emoji, role in zip(emojis, roles):
  192. if payload.emoji.name == emoji:
  193. print(f"Removing role {role.name} from user {member.name} for emoji {emoji}.")
  194. try:
  195. await member.remove_roles(role)
  196. print(f"Removed role {role.name} from user {member.name}.")
  197. except Exception as e:
  198. print(f"Failed to remove role {role.name} from user {member.name}: {e}")
  199. break
  200. try:
  201. channel = self.bot.get_channel(payload.channel_id)
  202. if channel is not None:
  203. message = await channel.fetch_message(message_id)
  204. await message.remove_reaction(payload.emoji, member)
  205. break
  206. except Exception as e:
  207. print(f"Failed to remove reaction {payload.emoji} from user {member.name}: {e}")
  208. break
  209. else:
  210. print(f"Emoji {payload.emoji} does not match {emoji} for role {role.name}.")
  211. def setup(bot: discord.Bot):
  212. bot.add_cog(Reactionroles(bot))