logs.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  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. async def get_audit_log_user(guild, action, target_id):
  151. try:
  152. async for entry in guild.audit_logs(limit=10, action=action):
  153. if entry.target.id == target_id:
  154. return entry.user
  155. except discord.Forbidden:
  156. pass
  157. return None
  158. moderator = await get_audit_log_user(role.guild, discord.AuditLogAction.role_create, role.id)
  159. embed = discord.Embed(
  160. title="Role Created",
  161. description=f"The role **{role.name}** has been created by {moderator.mention if moderator else 'Unknown'}.",
  162. color=discord.Color.green(),
  163. timestamp=discord.utils.utcnow()
  164. )
  165. embed.set_footer(text=f"Role ID: {role.id}")
  166. await log_channel.send(embed=embed)
  167. #Role deleted log
  168. @commands.Cog.listener()
  169. async def on_guild_role_delete(self, role):
  170. config = self._load_config()
  171. enable_log = config.getboolean("Logs","enable_action_log")
  172. if not enable_log:
  173. return
  174. log_channel = self._get_log_channel()
  175. if log_channel is None:
  176. return
  177. async def get_audit_log_user(guild, action, target_id):
  178. try:
  179. async for entry in guild.audit_logs(limit=10, action=action):
  180. if entry.target.id == target_id:
  181. return entry.user
  182. except discord.Forbidden:
  183. pass
  184. return None
  185. moderator = await get_audit_log_user(role.guild, discord.AuditLogAction.role_delete, role.id)
  186. embed = discord.Embed(
  187. title="Role Deleted",
  188. description=f"The role **{role.name}** has been deleted by {moderator.mention if moderator else 'Unknown'}.",
  189. color=discord.Color.red(),
  190. timestamp=discord.utils.utcnow()
  191. )
  192. embed.set_footer(text=f"Role ID: {role.id}")
  193. await log_channel.send(embed=embed)
  194. #User Role update log
  195. @commands.Cog.listener()
  196. async def on_member_update(self, before, after):
  197. config = self._load_config()
  198. enable_log = config.getboolean("Logs","enable_action_log")
  199. if not enable_log:
  200. return
  201. log_channel = self._get_log_channel()
  202. if log_channel is None:
  203. return
  204. before_roles = set(before.roles)
  205. after_roles = set(after.roles)
  206. added_roles = after_roles - before_roles
  207. removed_roles = before_roles - after_roles
  208. async def get_audit_log_user(guild, action, target_id):
  209. try:
  210. async for entry in guild.audit_logs(limit=10, action=action):
  211. if entry.target.id == target_id:
  212. return entry.user
  213. except discord.Forbidden:
  214. pass
  215. return None
  216. moderator = await get_audit_log_user(after.guild, discord.AuditLogAction.member_role_update, after.id)
  217. for role in added_roles:
  218. embed = discord.Embed(
  219. title="Role Added",
  220. description=f"The role **{role.name}** has been added to {after.mention} by {moderator.mention if moderator else 'Unknown'}.",
  221. color=discord.Color.green(),
  222. timestamp=discord.utils.utcnow()
  223. )
  224. embed.set_footer(text=f"User ID: {after.id} | Role ID: {role.id}")
  225. await log_channel.send(embed=embed)
  226. for role in removed_roles:
  227. embed = discord.Embed(
  228. title="Role Removed",
  229. description=f"The role **{role.name}** has been removed from {after.mention} by {moderator.mention if moderator else 'Unknown'}.",
  230. color=discord.Color.red(),
  231. timestamp=discord.utils.utcnow()
  232. )
  233. embed.set_footer(text=f"User ID: {after.id} | Role ID: {role.id}")
  234. await log_channel.send(embed=embed)
  235. #Server Changes Log
  236. @commands.Cog.listener()
  237. async def on_guild_update(self, before, after):
  238. config = self._load_config()
  239. enable_log = config.getboolean("Logs","enable_action_log")
  240. if not enable_log:
  241. return
  242. log_channel = self._get_log_channel()
  243. if log_channel is None:
  244. return
  245. async def get_audit_log_user(guild, action, target_id):
  246. try:
  247. async for entry in guild.audit_logs(limit=10, action=action):
  248. if entry.target.id == target_id:
  249. return entry.user
  250. except discord.Forbidden:
  251. pass
  252. return None
  253. moderator = await get_audit_log_user(after, discord.AuditLogAction.guild_update, after.id)
  254. embed = discord.Embed(
  255. title="Server Updated",
  256. description=f"The server has been updated by {moderator.mention if moderator else 'Unknown'}.",
  257. color=discord.Color.blue(),
  258. timestamp=discord.utils.utcnow()
  259. )
  260. embed.add_field(name="Before", value=f"Name: {before.name}\nDescription: {before.description}\nOwner: {before.owner}", inline=False)
  261. embed.add_field(name="After", value=f"Name: {after.name}\nDescription: {after.description}\nOwner: {after.owner}", inline=False)
  262. embed.set_footer(text=f"Server ID: {before.id}")
  263. await log_channel.send(embed=embed)
  264. #Voice channel log
  265. @commands.Cog.listener()
  266. async def on_voice_state_update(self, member, before, after):
  267. config = self._load_config()
  268. enable_log = config.getboolean("Logs","enable_action_log")
  269. if not enable_log:
  270. return
  271. log_channel = self._get_log_channel()
  272. if log_channel is None:
  273. return
  274. if before.channel is None and after.channel is not None:
  275. action = "joined"
  276. channel = after.channel
  277. elif before.channel is not None and after.channel is None:
  278. action = "left"
  279. channel = before.channel
  280. elif before.channel is not None and after.channel is not None and before.channel != after.channel:
  281. action = "moved from"
  282. channel = before.channel
  283. else:
  284. return
  285. embed = discord.Embed(
  286. title="Voice State Updated",
  287. description=f"{member.mention} has {action} the voice channel {channel.mention}.",
  288. color=discord.Color.purple(),
  289. timestamp=discord.utils.utcnow()
  290. )
  291. embed.set_footer(text=f"User ID: {member.id}")
  292. await log_channel.send(embed=embed)
  293. def setup(bot: discord.Bot):
  294. bot.add_cog(actionlog(bot))