logs.py 17 KB

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