-
Notifications
You must be signed in to change notification settings - Fork 12
Add auto report of deleted messages #740
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
3f3be73
732d837
d0e0daa
0342b81
b7b8a6e
48bb5c2
f6b49d6
a665e47
63b2a31
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| """File to hold cog classes related to moderation actions and tracking.""" | ||
|
|
||
| import logging | ||
| from typing import TYPE_CHECKING | ||
|
|
||
| import discord | ||
|
|
||
| from utils import TeXBotBaseCog | ||
| from utils.error_capture_decorators import capture_guild_does_not_exist_error | ||
|
|
||
| if TYPE_CHECKING: | ||
| from collections.abc import Sequence | ||
| from logging import Logger | ||
| from typing import Final | ||
|
|
||
|
|
||
| __all__: "Sequence[str]" = ("ModerationCog",) | ||
|
|
||
|
|
||
| logger: "Final[Logger]" = logging.getLogger("TeX-Bot") | ||
|
|
||
|
|
||
| class ModerationCog(TeXBotBaseCog): | ||
| """Cog to track moderation actions and report them to the committee.""" | ||
|
|
||
| most_recently_deleted_message: discord.Message | None = None | ||
|
|
||
| async def _send_message_to_committee( | ||
| self, message: discord.Message, deleter: discord.Member | ||
| ) -> None: | ||
| discord_channel: discord.TextChannel | None = discord.utils.get( | ||
| self.bot.main_guild.text_channels, | ||
| name="discord", # TODO: Make this user-configurable # noqa: FIX002 | ||
| ) | ||
|
|
||
| if not discord_channel: | ||
| logger.error("Could not find the channel to send the message deletion report to!") | ||
| return | ||
|
|
||
| embed_content: str = "" | ||
|
|
||
| if message.content: | ||
| embed_content += message.content[:600] | ||
| if len(message.content) > 600: | ||
| embed_content += " _... (truncated to 600 characters)_" | ||
| else: | ||
| embed_content += "_Deleted message had no content_" | ||
| if len(message.attachments) > 0 or len(message.embeds) > 0: | ||
| embed_content += " _but did have one or more attachments!_" | ||
|
|
||
| embed_content += f"\n[View Original]({message.jump_url})" | ||
|
|
||
| if message.reference: | ||
| embed_content += f"\n[View Message this replied to]({message.reference.jump_url})" | ||
|
|
||
| message_author_avatar_url: str | None = message.author.display_avatar.url | ||
|
|
||
| embed_author: discord.EmbedAuthor = discord.EmbedAuthor( | ||
| name=message.author.display_name, icon_url=message_author_avatar_url | ||
| ) | ||
|
|
||
| embed_image: str | None = None | ||
| if len(message.attachments) == 1: | ||
| attachment_type: str | None = message.attachments[0].content_type | ||
| if attachment_type and "image" in attachment_type: | ||
| embed_image = message.attachments[0].url | ||
|
|
||
| await discord_channel.send( | ||
| content=( | ||
| f"{deleter.mention} deleted a message from {message.author.mention} " | ||
| f"in { | ||
| message.channel.mention | ||
| if isinstance( | ||
| message.channel, | ||
| ( | ||
| discord.TextChannel, | ||
| discord.VoiceChannel, | ||
| discord.StageChannel, | ||
| discord.Thread, | ||
| ), | ||
| ) | ||
| else message.channel | ||
| }:" | ||
| ), | ||
| embed=discord.Embed( | ||
| author=embed_author, | ||
| description=embed_content, | ||
| colour=message.author.colour, | ||
| image=embed_image, | ||
| ), | ||
| ) | ||
|
|
||
| @TeXBotBaseCog.listener() | ||
| async def on_message_delete(self, message: discord.Message) -> None: | ||
| """Listen for message deletions.""" | ||
MattyTheHacker marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if message.guild is None or message.author.bot or message.guild != self.bot.main_guild: | ||
| return | ||
|
|
||
| self.most_recently_deleted_message = message | ||
|
|
||
|
Comment on lines
+93
to
+100
|
||
| @TeXBotBaseCog.listener() | ||
| @capture_guild_does_not_exist_error | ||
| async def on_audit_log_entry(self, entry: discord.AuditLogEntry) -> None: | ||
| """Listen for audit log entries.""" | ||
| committee_role: discord.Role = await self.bot.committee_role | ||
|
|
||
| if ( | ||
| entry.action != discord.AuditLogAction.message_delete | ||
| or not self.most_recently_deleted_message | ||
| ): | ||
| return | ||
|
|
||
| deleter: discord.Member | discord.User | None = entry.user | ||
| author: discord.User | discord.Member | None = entry.target | ||
| channel: discord.TextChannel | None = entry.extra.channel # type: ignore[union-attr] | ||
|
|
||
| if ( | ||
| not isinstance(channel, discord.TextChannel) | ||
| or not isinstance(author, discord.Member) | ||
| or not isinstance(deleter, discord.Member) | ||
| ): | ||
| return | ||
|
|
||
| if ( | ||
| author != self.most_recently_deleted_message.author | ||
| or channel != self.most_recently_deleted_message.channel | ||
| or committee_role in author.roles | ||
| ): | ||
| return | ||
|
|
||
| await self._send_message_to_committee(self.most_recently_deleted_message, deleter) | ||
MattyTheHacker marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| self.most_recently_deleted_message = None | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,7 +26,9 @@ | |
| config.run_setup() | ||
|
|
||
| bot: TeXBot = TeXBot( | ||
| intents=discord.Intents.default() | discord.Intents.members | ||
| intents=discord.Intents.default() | ||
| | discord.Intents.members | ||
| | discord.Intents.message_content | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the biggest issue here. We have purposefully limited the privileges of TeX-Bot to not have access to read members messages and this is a departure from this. Making this change requires a vote of approval from CSS committee. |
||
| ) # NOTE: See https://github.com/CSSUoB/TeX-Bot-Py-V2/issues/261 | ||
|
|
||
| bot.load_extension("cogs") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_send_message_to_committeeis effectively duplicated fromStrikeContextCommandsCog._send_message_to_committee(same embed construction, truncation rules, attachment handling, etc.). Having two copies makes future changes easy to miss and risks inconsistent committee reporting behavior; consider extracting this into a shared helper (e.g. a util function or a method onTeXBotBaseCog) and reusing it from both cogs.