aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar kosayoda <[email protected]>2020-09-08 12:04:20 +0800
committerGravatar kosayoda <[email protected]>2020-09-08 12:04:20 +0800
commitab4eb39fcdde62cc9f558f9e41a5f48d9a587d38 (patch)
treee26e5491b1759bc78c43b6df7443a78e338054ee
parentRemove everyone_ping rule from antispam. (diff)
Add everyone_ping filter.
-rw-r--r--bot/cogs/filtering.py38
-rw-r--r--bot/constants.py2
-rw-r--r--config-default.yml18
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