diff options
| -rw-r--r-- | bot/cogs/filtering.py | 38 | ||||
| -rw-r--r-- | bot/constants.py | 2 | ||||
| -rw-r--r-- | config-default.yml | 18 | 
3 files changed, 47 insertions, 11 deletions
| diff --git a/bot/cogs/filtering.py b/bot/cogs/filtering.py index 99b659bff..aa0cbad97 100644 --- a/bot/cogs/filtering.py +++ b/bot/cogs/filtering.py @@ -15,8 +15,8 @@ from bot.api import ResponseCodeError  from bot.bot import Bot  from bot.cogs.moderation import ModLog  from bot.constants import ( -    Channels, Colours, -    Filter, Icons, URLs +    Channels, Colours, Filter, +    Guild, Icons, URLs  )  from bot.utils.redis_cache import RedisCache  from bot.utils.regex import INVITE_RE @@ -25,6 +25,12 @@ from bot.utils.scheduling import Scheduler  log = logging.getLogger(__name__)  # Regular expressions +CODE_BLOCK_RE = re.compile( +    r"(?P<delim>``?)[^`]+?(?P=delim)(?!`+)"  # Inline codeblock +    r"|```(.+?)```",  # Multiline codeblock +    re.DOTALL | re.MULTILINE +) +EVERYONE_PING_RE = re.compile(rf"@everyone|<@&{Guild.id}>|@here")  SPOILER_RE = re.compile(r"(\|\|.+?\|\|)", re.DOTALL)  URL_RE = re.compile(r"(https?://[^\s]+)", flags=re.IGNORECASE)  ZALGO_RE = re.compile(r"[\u0300-\u036F\u0489]") @@ -82,6 +88,19 @@ class Filtering(Cog):                  ),                  "schedule_deletion": False              }, +            "filter_everyone_ping": { +                "enabled": Filter.filter_everyone_ping, +                "function": self._has_everyone_ping, +                "type": "filter", +                "content_only": True, +                "user_notification": Filter.notify_user_everyone_ping, +                "notification_msg": ( +                    "Please don't try to ping `@everyone` or `@here`. " +                    f"Your message has been removed. {staff_mistake_str}" +                ), +                "schedule_deletion": False, +                "ping_everyone": False +            },              "watch_regex": {                  "enabled": Filter.watch_regex,                  "function": self._has_watch_regex_match, @@ -332,6 +351,9 @@ class Filtering(Cog):                          log.debug(message) +                        # Allow specific filters to override ping_everyone +                        ping_everyone = Filter.ping_everyone and _filter.get("ping_everyone", True) +                          # Send pretty mod log embed to mod-alerts                          await self.mod_log.send_log_message(                              icon_url=Icons.filtering, @@ -340,7 +362,7 @@ class Filtering(Cog):                              text=message,                              thumbnail=msg.author.avatar_url_as(static_format="png"),                              channel_id=Channels.mod_alerts, -                            ping_everyone=Filter.ping_everyone if not is_private else False, +                            ping_everyone=ping_everyone if not is_private else False,                              additional_embeds=additional_embeds,                              additional_embeds_msg=additional_embeds_msg                          ) @@ -528,6 +550,16 @@ class Filtering(Cog):                          return False          return False +    @staticmethod +    async def _has_everyone_ping(text: str) -> bool: +        """Determines if `msg` contains an @everyone or @here ping outside of a codeblock.""" +        # First pass to avoid running re.sub on every message +        if not EVERYONE_PING_RE.search(text): +            return False + +        content_without_codeblocks = CODE_BLOCK_RE.sub("", text) +        return bool(EVERYONE_PING_RE.search(content_without_codeblocks)) +      async def notify_member(self, filtered_member: Member, reason: str, channel: TextChannel) -> None:          """          Notify filtered_member about a moderation action with the reason str. diff --git a/bot/constants.py b/bot/constants.py index 17fe34e95..70b36984f 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -217,6 +217,7 @@ class Filter(metaclass=YAMLGetter):      filter_zalgo: bool      filter_invites: bool      filter_domains: bool +    filter_everyone_ping: bool      watch_regex: bool      watch_rich_embeds: bool @@ -224,6 +225,7 @@ class Filter(metaclass=YAMLGetter):      notify_user_zalgo: bool      notify_user_invites: bool      notify_user_domains: bool +    notify_user_everyone_ping: bool      ping_everyone: bool      offensive_msg_delete_days: int diff --git a/config-default.yml b/config-default.yml index c1eef713f..cf9ce8798 100644 --- a/config-default.yml +++ b/config-default.yml @@ -273,17 +273,19 @@ guild:  filter:      # What do we filter? -    filter_zalgo:       false -    filter_invites:     true -    filter_domains:     true -    watch_regex:        true -    watch_rich_embeds:  true +    filter_zalgo:          false +    filter_invites:        true +    filter_domains:        true +    filter_everyone_ping:  true +    watch_regex:           true +    watch_rich_embeds:     true      # Notify user on filter?      # Notifications are not expected for "watchlist" type filters -    notify_user_zalgo:       false -    notify_user_invites:     true -    notify_user_domains:     false +    notify_user_zalgo:          false +    notify_user_invites:        true +    notify_user_domains:        false +    notify_user_everyone_ping:  true      # Filter configuration      ping_everyone:             true | 
