logs.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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. class actionlog(commands.Cog):
  8. def __init__(self, bot: discord.Bot):
  9. self.bot = bot
  10. def _load_config(self):
  11. config = configparser.ConfigParser()
  12. configFilePath = r'config.cfg'
  13. config.read(configFilePath)
  14. return config
  15. def _get_log_channel(self):
  16. config = self._load_config()
  17. log_channel_id = int(config["Logs"]["action_log"])
  18. log_channel = self.bot.get_channel(log_channel_id)
  19. if log_channel is None:
  20. print(f"Log channel with ID {log_channel_id} not found.")
  21. return None
  22. return log_channel
  23. #Deleted Message Log
  24. @commands.Cog.listener()
  25. async def on_message_delete(self, message: discord.Message, moderator: discord.Member):
  26. if message.author.bot:
  27. return
  28. config = self._load_config()
  29. enable_log = config.getboolean("Logs","enable_action_log")
  30. if not enable_log:
  31. return
  32. log_channel = self._get_log_channel()
  33. if log_channel is None:
  34. return
  35. else:
  36. if message.content is None and not message.attachments:
  37. content = "No content available"
  38. elif message.content is None:
  39. content = "Content not available, but there are attachments."
  40. else:
  41. content = message.content
  42. moderator = self.bot.get_user(moderator)
  43. embed = discord.Embed(
  44. title="Message Deleted",
  45. description=f"A message by {message.author.mention} was deleted in {message.channel.mention} by {moderator.mention}.",
  46. color=discord.Color.red(),
  47. timestamp=message.created_at
  48. )
  49. embed.add_field(name="Message Content", value=content[:1024], inline=False)
  50. embed.set_footer(text=f"User ID: {message.author.id} | Message ID: {message.id}")
  51. await log_channel.send(embed=embed)
  52. #Edited Message Log
  53. @commands.Cog.listener()
  54. async def on_message_edit(self, before, after):
  55. config = self._load_config()
  56. enable_log = config.getboolean("Logs","enable_action_log")
  57. if not enable_log:
  58. return
  59. log_channel = self._get_log_channel()
  60. if log_channel is None:
  61. return
  62. if before.author.bot:
  63. return
  64. else:
  65. embed = discord.Embed(
  66. title="Message Edited",
  67. description=f"A message by {before.author.mention} was edited in {before.channel.mention}.",
  68. color=discord.Color.orange(),
  69. timestamp=after.edited_at or discord.utils.utcnow()
  70. )
  71. embed.add_field(name="Before", value=before.content or "No content", inline=False)
  72. embed.add_field(name="After", value=after.content or "No content", inline=False)
  73. embed.set_footer(text=f"User ID: {before.author.id} | Message ID: {before.id}")
  74. await log_channel.send(embed=embed)
  75. #Member Join Log
  76. @commands.Cog.listener()
  77. async def on_member_join(self, member):
  78. config = self._load_config()
  79. enable_log = config.getboolean("Logs","enable_action_log")
  80. if not enable_log:
  81. return
  82. log_channel = self._get_log_channel()
  83. if log_channel is None:
  84. return
  85. embed = discord.Embed(
  86. title="Member Joined",
  87. description=f"{member.mention} has joined the server. Account created at: {member.created_at}",
  88. color=discord.Color.green(),
  89. timestamp=discord.utils.utcnow()
  90. )
  91. embed.set_footer(text=f"User ID: {member.id}")
  92. await log_channel.send(embed=embed)
  93. #Member Leave Log
  94. @commands.Cog.listener()
  95. async def on_member_remove(self, member):
  96. config = self._load_config()
  97. enable_log = config.getboolean("Logs","enable_action_log")
  98. if not enable_log:
  99. return
  100. log_channel = self._get_log_channel()
  101. if log_channel is None:
  102. return
  103. embed = discord.Embed(
  104. title="Member Left",
  105. description=f"{member.mention} has left the server. Joined at: {member.joined_at}",
  106. color=discord.Color.dark_red(),
  107. timestamp=discord.utils.utcnow()
  108. )
  109. embed.set_footer(text=f"User ID: {member.id}")
  110. await log_channel.send(embed=embed)
  111. #Role Update Log
  112. @commands.Cog.listener()
  113. async def on_guild_role_update(self, before, after):
  114. config = self._load_config()
  115. enable_log = config.getboolean("Logs","enable_action_log")
  116. if not enable_log:
  117. return
  118. log_channel = self._get_log_channel()
  119. if log_channel is None:
  120. return
  121. async def get_audit_log_user(guild, action, target_id):
  122. try:
  123. async for entry in guild.audit_logs(limit=10, action=action):
  124. if entry.target.id == target_id:
  125. return entry.user
  126. except discord.Forbidden:
  127. pass
  128. return None
  129. moderator = await get_audit_log_user(after.guild, discord.AuditLogAction.role_update, after.id)
  130. embed = discord.Embed(
  131. title="Role Updated",
  132. description=f"The role **{before.name}** has been updated by {moderator.mention if moderator else 'Unknown'}.",
  133. color=discord.Color.blue(),
  134. timestamp=discord.utils.utcnow()
  135. )
  136. embed.add_field(name="Before", value=f"Name: {before.name}\nColor: {before.color}\nPermissions: {before.permissions}", inline=False)
  137. embed.add_field(name="After", value=f"Name: {after.name}\nColor: {after.color}\nPermissions: {after.permissions}", inline=False)
  138. embed.set_footer(text=f"Role ID: {before.id}")
  139. await log_channel.send(embed=embed)
  140. #Role added log
  141. @commands.Cog.listener()
  142. async def on_guild_role_create(self, role):
  143. config = self._load_config()
  144. enable_log = config.getboolean("Logs","enable_action_log")
  145. if not enable_log:
  146. return
  147. log_channel = self._get_log_channel()
  148. if log_channel is None:
  149. return
  150. embed = discord.Embed(
  151. title="Role Created",
  152. description=f"The role **{role.name}** has been created by {role.guild.get_member(role.id).mention if role.guild else 'Unknown'}.",
  153. color=discord.Color.green(),
  154. timestamp=discord.utils.utcnow()
  155. )
  156. embed.set_footer(text=f"Role ID: {role.id}")
  157. await log_channel.send(embed=embed)
  158. #Role deleted log
  159. @commands.Cog.listener()
  160. async def on_guild_role_delete(self, role):
  161. config = self._load_config()
  162. enable_log = config.getboolean("Logs","enable_action_log")
  163. if not enable_log:
  164. return
  165. log_channel = self._get_log_channel()
  166. if log_channel is None:
  167. return
  168. embed = discord.Embed(
  169. title="Role Deleted",
  170. description=f"The role **{role.name}** has been deleted by {role.guild.get_member(role.id).mention if role.guild else 'Unknown'}.",
  171. color=discord.Color.red(),
  172. timestamp=discord.utils.utcnow()
  173. )
  174. embed.set_footer(text=f"Role ID: {role.id}")
  175. await log_channel.send(embed=embed)
  176. #User Role update log
  177. @commands.Cog.listener()
  178. async def on_member_update(self, before, after):
  179. config = self._load_config()
  180. enable_log = config.getboolean("Logs","enable_action_log")
  181. if not enable_log:
  182. return
  183. log_channel = self._get_log_channel()
  184. if log_channel is None:
  185. return
  186. before_roles = set(before.roles)
  187. after_roles = set(after.roles)
  188. added_roles = after_roles - before_roles
  189. removed_roles = before_roles - after_roles
  190. for role in added_roles:
  191. embed = discord.Embed(
  192. title="Role Added",
  193. description=f"The role **{role.name}** has been added to {after.mention} by {after.guild.get_member(after.id).mention if after.guild else 'Unknown'}.",
  194. color=discord.Color.green(),
  195. timestamp=discord.utils.utcnow()
  196. )
  197. embed.set_footer(text=f"User ID: {after.id} | Role ID: {role.id}")
  198. await log_channel.send(embed=embed)
  199. for role in removed_roles:
  200. embed = discord.Embed(
  201. title="Role Removed",
  202. description=f"The role **{role.name}** has been removed from {after.mention} by {after.guild.get_member(after.id).mention if after.guild else 'Unknown'}.",
  203. color=discord.Color.red(),
  204. timestamp=discord.utils.utcnow()
  205. )
  206. embed.set_footer(text=f"User ID: {after.id} | Role ID: {role.id}")
  207. await log_channel.send(embed=embed)
  208. #Server Changes Log
  209. @commands.Cog.listener()
  210. async def on_guild_update(self, before, after):
  211. config = self._load_config()
  212. enable_log = config.getboolean("Logs","enable_action_log")
  213. if not enable_log:
  214. return
  215. log_channel = self._get_log_channel()
  216. if log_channel is None:
  217. return
  218. embed = discord.Embed(
  219. title="Server Updated",
  220. description=f"The server has been updated by {after.guild.get_member(after.id).mention if after.guild else 'Unknown'}.",
  221. color=discord.Color.blue(),
  222. timestamp=discord.utils.utcnow()
  223. )
  224. embed.add_field(name="Before", value=f"Name: {before.name}\nDescription: {before.description}\nOwner: {before.owner}", inline=False)
  225. embed.add_field(name="After", value=f"Name: {after.name}\nDescription: {after.description}\nOwner: {after.owner}", inline=False)
  226. embed.set_footer(text=f"Server ID: {before.id}")
  227. await log_channel.send(embed=embed)
  228. #Voice channel log
  229. @commands.Cog.listener()
  230. async def on_voice_state_update(self, member, before, after):
  231. config = self._load_config()
  232. enable_log = config.getboolean("Logs","enable_action_log")
  233. if not enable_log:
  234. return
  235. log_channel = self._get_log_channel()
  236. if log_channel is None:
  237. return
  238. if before.channel is None and after.channel is not None:
  239. action = "joined"
  240. channel = after.channel
  241. elif before.channel is not None and after.channel is None:
  242. action = "left"
  243. channel = before.channel
  244. elif before.channel is not None and after.channel is not None and before.channel != after.channel:
  245. action = "moved from"
  246. channel = before.channel
  247. else:
  248. return
  249. embed = discord.Embed(
  250. title="Voice State Updated",
  251. description=f"{member.mention} has {action} the voice channel {channel.mention}.",
  252. color=discord.Color.purple(),
  253. timestamp=discord.utils.utcnow()
  254. )
  255. embed.set_footer(text=f"User ID: {member.id}")
  256. await log_channel.send(embed=embed)
  257. def setup(bot: discord.Bot):
  258. bot.add_cog(actionlog(bot))