diff options
| -rw-r--r-- | bot/cogs/filtering.py | 131 | ||||
| -rw-r--r-- | bot/constants.py | 10 | ||||
| -rw-r--r-- | config-default.yml | 47 |
3 files changed, 157 insertions, 31 deletions
diff --git a/bot/cogs/filtering.py b/bot/cogs/filtering.py index eee1dbd16..1da378c08 100644 --- a/bot/cogs/filtering.py +++ b/bot/cogs/filtering.py @@ -31,28 +31,127 @@ class Filtering: def __init__(self, bot: Bot): self.bot = bot + self.filters = { + "filter_zalgo": { + "enabled": Filter.filter_zalgo, + "function": self._has_zalgo, + "type": "filter" + }, + "filter_invites": { + "enabled": Filter.filter_invites, + "function": self._has_invites, + "type": "filter" + }, + "filter_domains": { + "enabled": Filter.filter_domains, + "function": self._has_urls, + "type": "filter" + }, + "watch_words": { + "enabled": Filter.watch_words, + "function": self._has_watchlist_words, + "type": "watchlist" + }, + "watch_tokens": { + "enabled": Filter.watch_tokens, + "function": self._has_watchlist_tokens, + "type": "watchlist" + }, + } + async def on_message(self, msg: Message): + """ + Whenever a message is received, + run it through our filters to see if it + violates any of our rules, and then respond + accordingly. + """ - if msg.channel.id == Channels.devtest and not msg.author.bot: + # Check if the sender has a role that is whitelisted + role_whitelisted = False + for role in msg.author.roles: + if role.id in Filter.role_whitelist: + role_whitelisted = True + + # Is the channel whitelisted or is the sender a bot? + filter_message = ( + msg.channel.id not in Filter.channel_whitelist + and not role_whitelisted + and not msg.author.bot + ) + + filter_message = not msg.author.bot and msg.channel.id == Channels.modlog # for testing + + # If none of the above, we can start filtering. + if filter_message: + for filter_name, _filter in self.filters.items(): + + # Is the filter enabled in the config? + if _filter["enabled"]: + triggered = await _filter["function"](msg.content) + + if triggered: + # If a filter is triggered, we should automod it. + if _filter["type"] == "filter": + log.debug( + f"The {filter_name} filter was triggered " + f"by {msg.author.name} in {msg.channel.name} with " + f"the following message:\n{msg.content}." + ) + + # Replace this with actual automod + await self.bot.get_channel(msg.channel.id).send( + content=f"The **{filter_name}** filter triggered!" + ) + + # If a watchlist triggers, we should send a mod alert. + elif _filter["type"] == "watchlist": + log.debug( + f"The {filter_name} watchlist was triggered " + f"by {msg.author.name} in {msg.channel.name} with " + f"the following message:\n{msg.content}." + ) + + # Replace this with actual mod alerts! + await self.bot.get_channel(msg.channel.id).send( + content=f"The **{filter_name}** watchlist was triggered!" + ) + + break # We don't want multiple filters to trigger - has_zalgo = await self._has_zalgo(msg.content) - has_invites = await self._has_invites(msg.content) - has_urls = await self._has_urls(msg.content) + @staticmethod + async def _has_watchlist_words(text): + """ + Returns True if the text contains + one of the regular expressions from the + word_watchlist in our filter config. - if has_zalgo: - await self.bot.get_channel(msg.channel.id).send( - content="ZALGO!" - ) + Only matches words with boundaries before + and after the expression. + """ + + for expression in Filter.word_watchlist: + if re.search(fr"\b{expression}\b", text.lower()): + return True - if has_invites: - await self.bot.get_channel(msg.channel.id).send( - content="INVITES!" - ) + return False - if has_urls: - await self.bot.get_channel(msg.channel.id).send( - content="EVIL ILLEGAL HITLER DOMAINS!" - ) + @staticmethod + async def _has_watchlist_tokens(text): + """ + Returns True if the text contains + one of the regular expressions from the + token_watchlist in our filter config. + + This will match the expression even if it + does not have boundaries before and after + """ + + for expression in Filter.token_watchlist: + if re.search(fr"{expression}", text.lower()): + return True + + return False @staticmethod async def _has_urls(text): diff --git a/bot/constants.py b/bot/constants.py index 597c7c4a7..2dd41b1e5 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -196,13 +196,15 @@ class Filter(metaclass=YAMLGetter): filter_zalgo: bool filter_invites: bool - filter_domain: bool - watch_expressions: bool + filter_domains: bool + watch_words: bool + watch_tokens: bool - domain_blacklist: List[str] - watched_expressions: List[str] guild_invite_whitelist: List[str] vanity_url_whitelist: List[str] + domain_blacklist: List[str] + word_watchlist: List[str] + token_watchlist: List[str] channel_whitelist: List[int] role_whitelist: List[int] diff --git a/config-default.yml b/config-default.yml index 06117ef05..405a50b8a 100644 --- a/config-default.yml +++ b/config-default.yml @@ -82,7 +82,7 @@ guild: announcements: 463658397560995840 champion: 430492892331769857 contributor: 295488872404484098 - devops: 409416496733880320 + devops: &DEVOPS_ROLE 409416496733880320 jammer: 423054537079783434 moderator: &MOD_ROLE 267629731250176001 owner: &OWNER_ROLE 267627879762755584 @@ -93,18 +93,13 @@ guild: filter: # What do we filter? - filter_zalgo: true - filter_invites: true - filter_domains: true - watch_expressions: true + filter_zalgo: true + filter_invites: true + filter_domains: true + watch_words: true + watch_tokens: true # Filter configuration - domain_blacklist: - - pornhub.com - - watched_expressions: - - .*ni[g]*er.* - guild_invite_whitelist: - vywQPxd # Code Monkeys - kWJYurV # Functional Programming @@ -114,6 +109,35 @@ filter: vanity_url_whitelist: - python # Python Discord + domain_blacklist: + - pornhub.com + + word_watchlist: + - goo+k + - ky+s+ + - g[ae]+y+ + - ki+ke+ + - beane?r* + - coo+n + - nig+lets? + - slant-eye + - towe?l-?head+ + - chi*n+k+ + - spick* + - kill* +(?:yo)?urself+ + - jew+s* + - suicide + - rape + - re+tar+d+ + - cunt + + token_watchlist: + - fa+g+s* + - 卐 + - cuck + - nigg+(?:e*r+|a+)s? + - fag+o+t+s* + # Censor doesn't apply to these channel_whitelist: - *ADMINS @@ -128,6 +152,7 @@ filter: - *ADMIN_ROLE - *MOD_ROLE - *OWNER_ROLE + - *DEVOPS_ROLE keys: deploy_bot: !ENV "DEPLOY_BOT_KEY" |