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"  |