logs.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  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):
  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. # Fetch audit log to find who deleted the message
  36. try:
  37. async for entry in message.guild.audit_logs(limit=1, action=discord.AuditLogAction.message_delete):
  38. if entry.extra.channel.id == message.channel.id:
  39. deleter = entry.user
  40. break
  41. else:
  42. deleter = None
  43. except:
  44. deleter = None
  45. if message.content is None and not message.attachments:
  46. content = "No content available"
  47. elif message.content is None:
  48. content = "Content not available, but there are attachments."
  49. else:
  50. content = message.content
  51. embed = discord.Embed(
  52. title="Message Deleted",
  53. description=f"A message by {message.author.mention} was deleted in {message.channel.mention}." + (f"\nDeleted by: {deleter.mention}" if deleter else ""),
  54. color=discord.Color.red(),
  55. timestamp=message.created_at
  56. )
  57. embed.add_field(name="Message Content", value=content[:1024], inline=False)
  58. embed.set_footer(text=f"User ID: {message.author.id} | Message ID: {message.id}")
  59. await log_channel.send(embed=embed)
  60. #Edited Message Log
  61. @commands.Cog.listener()
  62. async def on_message_edit(self, before, after):
  63. config = self._load_config()
  64. enable_log = config.getboolean("Logs","enable_action_log")
  65. if not enable_log:
  66. return
  67. log_channel = self._get_log_channel()
  68. if log_channel is None:
  69. return
  70. if before.author.bot:
  71. return
  72. if before.content == after.content:
  73. return
  74. else:
  75. embed = discord.Embed(
  76. title="Message Edited",
  77. description=f"A message by {before.author.mention} was edited in {before.channel.mention}.",
  78. color=discord.Color.orange(),
  79. timestamp=after.edited_at or discord.utils.utcnow()
  80. )
  81. embed.add_field(name="Before", value=before.content or "No content", inline=False)
  82. embed.add_field(name="After", value=after.content or "No content", inline=False)
  83. embed.set_footer(text=f"User ID: {before.author.id} | Message ID: {before.id}")
  84. await log_channel.send(embed=embed)
  85. #Member Join Log
  86. @commands.Cog.listener()
  87. async def on_member_join(self, member):
  88. config = self._load_config()
  89. enable_log = config.getboolean("Logs","enable_action_log")
  90. if not enable_log:
  91. return
  92. log_channel = self._get_log_channel()
  93. if log_channel is None:
  94. return
  95. embed = discord.Embed(
  96. title="Member Joined",
  97. description=f"{member.mention} has joined the server. Account created at: {member.created_at}",
  98. color=discord.Color.green(),
  99. timestamp=discord.utils.utcnow()
  100. )
  101. embed.set_footer(text=f"User ID: {member.id}")
  102. await log_channel.send(embed=embed)
  103. #Member Leave Log
  104. @commands.Cog.listener()
  105. async def on_member_remove(self, member):
  106. config = self._load_config()
  107. enable_log = config.getboolean("Logs","enable_action_log")
  108. if not enable_log:
  109. return
  110. log_channel = self._get_log_channel()
  111. if log_channel is None:
  112. return
  113. embed = discord.Embed(
  114. title="Member Left",
  115. description=f"{member.mention} has left the server. Joined at: {member.joined_at}",
  116. color=discord.Color.dark_red(),
  117. timestamp=discord.utils.utcnow()
  118. )
  119. embed.set_footer(text=f"User ID: {member.id}")
  120. await log_channel.send(embed=embed)
  121. #Role Update Log
  122. @commands.Cog.listener()
  123. async def on_guild_role_update(self, before, after):
  124. config = self._load_config()
  125. enable_log = config.getboolean("Logs","enable_action_log")
  126. if not enable_log:
  127. return
  128. log_channel = self._get_log_channel()
  129. if log_channel is None:
  130. return
  131. embed = discord.Embed(
  132. title="Role Updated",
  133. description=f"The role **{before.name}** has been updated.",
  134. color=discord.Color.blue(),
  135. timestamp=discord.utils.utcnow()
  136. )
  137. embed.add_field(name="Before", value=f"Name: {before.name}\nColor: {before.color}\nPermissions: {before.permissions}", inline=False)
  138. embed.add_field(name="After", value=f"Name: {after.name}\nColor: {after.color}\nPermissions: {after.permissions}", inline=False)
  139. embed.set_footer(text=f"Role ID: {before.id}")
  140. await log_channel.send(embed=embed)
  141. #Role added log
  142. @commands.Cog.listener()
  143. async def on_guild_role_create(self, role):
  144. config = self._load_config()
  145. enable_log = config.getboolean("Logs","enable_action_log")
  146. if not enable_log:
  147. return
  148. log_channel = self._get_log_channel()
  149. if log_channel is None:
  150. return
  151. embed = discord.Embed(
  152. title="Role Created",
  153. description=f"The role **{role.name}** has been created.",
  154. color=discord.Color.green(),
  155. timestamp=discord.utils.utcnow()
  156. )
  157. embed.set_footer(text=f"Role ID: {role.id}")
  158. await log_channel.send(embed=embed)
  159. #Role deleted log
  160. @commands.Cog.listener()
  161. async def on_guild_role_delete(self, role):
  162. config = self._load_config()
  163. enable_log = config.getboolean("Logs","enable_action_log")
  164. if not enable_log:
  165. return
  166. log_channel = self._get_log_channel()
  167. if log_channel is None:
  168. return
  169. embed = discord.Embed(
  170. title="Role Deleted",
  171. description=f"The role **{role.name}** has been deleted.",
  172. color=discord.Color.red(),
  173. timestamp=discord.utils.utcnow()
  174. )
  175. embed.set_footer(text=f"Role ID: {role.id}")
  176. await log_channel.send(embed=embed)
  177. #User Role update log
  178. @commands.Cog.listener()
  179. async def on_member_update(self, before, after):
  180. config = self._load_config()
  181. enable_log = config.getboolean("Logs","enable_action_log")
  182. if not enable_log:
  183. return
  184. log_channel = self._get_log_channel()
  185. if log_channel is None:
  186. return
  187. before_roles = set(before.roles)
  188. after_roles = set(after.roles)
  189. added_roles = after_roles - before_roles
  190. removed_roles = before_roles - after_roles
  191. for role in added_roles:
  192. embed = discord.Embed(
  193. title="Role Added",
  194. description=f"The role **{role.name}** has been added to {after.mention}.",
  195. color=discord.Color.green(),
  196. timestamp=discord.utils.utcnow()
  197. )
  198. embed.set_footer(text=f"User ID: {after.id} | Role ID: {role.id}")
  199. await log_channel.send(embed=embed)
  200. for role in removed_roles:
  201. embed = discord.Embed(
  202. title="Role Removed",
  203. description=f"The role **{role.name}** has been removed from {after.mention}.",
  204. color=discord.Color.red(),
  205. timestamp=discord.utils.utcnow()
  206. )
  207. embed.set_footer(text=f"User ID: {after.id} | Role ID: {role.id}")
  208. await log_channel.send(embed=embed)
  209. #Server Changes Log
  210. @commands.Cog.listener()
  211. async def on_guild_update(self, before, after):
  212. config = self._load_config()
  213. enable_log = config.getboolean("Logs","enable_action_log")
  214. if not enable_log:
  215. return
  216. log_channel = self._get_log_channel()
  217. if log_channel is None:
  218. return
  219. embed = discord.Embed(
  220. title="Server Updated",
  221. description=f"The server has been updated.",
  222. color=discord.Color.blue(),
  223. timestamp=discord.utils.utcnow()
  224. )
  225. embed.add_field(name="Before", value=f"Name: {before.name}\nDescription: {before.description}", inline=False)
  226. embed.add_field(name="After", value=f"Name: {after.name}\nDescription: {after.description}", inline=False)
  227. embed.set_footer(text=f"Server ID: {before.id}")
  228. await log_channel.send(embed=embed)
  229. #Voice channel log
  230. @commands.Cog.listener()
  231. async def on_voice_state_update(self, member, before, after):
  232. config = self._load_config()
  233. enable_log = config.getboolean("Logs","enable_action_log")
  234. if not enable_log:
  235. return
  236. log_channel = self._get_log_channel()
  237. if log_channel is None:
  238. return
  239. if before.channel is None and after.channel is not None:
  240. action = "joined"
  241. channel1 = after.channel
  242. embed = discord.Embed(
  243. title="Voice State Updated",
  244. description=f"{member.mention} has {action} the voice channel {channel1.mention}.",
  245. color=discord.Color.purple(),
  246. timestamp=discord.utils.utcnow()
  247. )
  248. elif before.channel is not None and after.channel is None:
  249. action = "left"
  250. channel1 = before.channel
  251. embed = discord.Embed(
  252. title="Voice State Updated",
  253. description=f"{member.mention} has {action} the voice channel {channel1.mention}.",
  254. color=discord.Color.purple(),
  255. timestamp=discord.utils.utcnow()
  256. )
  257. elif before.channel is not None and after.channel is not None and before.channel != after.channel:
  258. channel1 = before.channel
  259. channel2 = after.channel
  260. action = "moved from"
  261. embed = discord.Embed(
  262. title="Voice State Updated",
  263. description=f"{member.mention} has {action} the voice channel {channel1.mention} to {channel2.mention}.",
  264. color=discord.Color.purple(),
  265. timestamp=discord.utils.utcnow()
  266. )
  267. else:
  268. return
  269. embed.set_footer(text=f"User ID: {member.id}")
  270. await log_channel.send(embed=embed)
  271. #Channel Update Log
  272. @commands.Cog.listener()
  273. async def on_guild_channel_update(self, before, after):
  274. config = self._load_config()
  275. enable_log = config.getboolean("Logs","enable_action_log")
  276. if not enable_log:
  277. return
  278. log_channel = self._get_log_channel()
  279. if log_channel is None:
  280. return
  281. embed = discord.Embed(
  282. title="Channel Updated",
  283. description=f"The channel **{before.name}** has been updated.",
  284. color=discord.Color.blue(),
  285. timestamp=discord.utils.utcnow()
  286. )
  287. embed.add_field(name="Before", value=f"Name: {before.name}\nType: {before.type}", inline=False)
  288. embed.add_field(name="After", value=f"Name: {after.name}\nType: {after.type}", inline=False)
  289. embed.set_footer(text=f"Channel ID: {before.id}")
  290. await log_channel.send(embed=embed)
  291. #Channel Create Log
  292. @commands.Cog.listener()
  293. async def on_guild_channel_create(self, channel):
  294. config = self._load_config()
  295. enable_log = config.getboolean("Logs","enable_action_log")
  296. if not enable_log:
  297. return
  298. log_channel = self._get_log_channel()
  299. if log_channel is None:
  300. return
  301. embed = discord.Embed(
  302. title="Channel Created",
  303. description=f"The channel **{channel.name}** has been created.",
  304. color=discord.Color.green(),
  305. timestamp=discord.utils.utcnow()
  306. )
  307. embed.set_footer(text=f"Channel ID: {channel.id}")
  308. await log_channel.send(embed=embed)
  309. #Channel Delete Log
  310. @commands.Cog.listener()
  311. async def on_guild_channel_delete(self, channel):
  312. config = self._load_config()
  313. enable_log = config.getboolean("Logs","enable_action_log")
  314. if not enable_log:
  315. return
  316. log_channel = self._get_log_channel()
  317. if log_channel is None:
  318. return
  319. embed = discord.Embed(
  320. title="Channel Deleted",
  321. description=f"The channel **{channel.name}** has been deleted.",
  322. color=discord.Color.red(),
  323. timestamp=discord.utils.utcnow()
  324. )
  325. embed.set_footer(text=f"Channel ID: {channel.id}")
  326. await log_channel.send(embed=embed)
  327. def setup(bot: discord.Bot):
  328. bot.add_cog(actionlog(bot))