aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/cogs/filtering.py131
-rw-r--r--bot/constants.py10
-rw-r--r--config-default.yml47
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"