Skip to content

Commit 8469e1c

Browse files
authored
Cog Spam: trigger on 5 messages in 10 seconds OR 3 messages in 2 seconds (#141)
1 parent ae73355 commit 8469e1c

File tree

1 file changed

+19
-14
lines changed

1 file changed

+19
-14
lines changed

cogs/spam.py

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
logger = logging.getLogger(__name__)
1515

1616
TITLE = "Spam Detector"
17-
REPEATED = 5
18-
DURATION = 10
17+
TRIGGER_COUNT_DURATIONS = [(5, 10), (3, 2)]
1918
DD = collections.defaultdict
2019

2120

@@ -77,12 +76,22 @@ async def send_alert(self, message: discord.Message) -> None:
7776
if not isinstance(message.channel, discord.TextChannel):
7877
return
7978
msg = f"<@&{self.mod_role_id}> Banning {message.author.name} for spam "
80-
msg += f"in {message.channel.name}. Same message {REPEATED} times.\n"
79+
msg += f"in {message.channel.name}. Same message multiple times in short period.\n"
8180
assert isinstance(self.mod_channel, discord.TextChannel)
8281
post = await self.mod_channel.send(msg)
8382
thread = await post.create_thread(name="Banned post", auto_archive_duration=1440)
8483
await thread.send(content=message.content)
8584

85+
def count_matching_messages(self, message: discord.Message, since: int) -> int:
86+
"""Return how many prior messages match since N timestamp."""
87+
return sum(
88+
1
89+
for ts, messages in self.messages.items()
90+
if ts >= since
91+
for prior in messages[message.author.id]
92+
if self.message_match(message, prior)
93+
)
94+
8695
@commands.Cog.listener()
8796
async def on_message(self, message: discord.Message) -> None:
8897
"""Detect repeated messages."""
@@ -99,24 +108,20 @@ async def on_message(self, message: discord.Message) -> None:
99108

100109
# Drop old messages
101110
now = int(time.time())
102-
cutoff = now - DURATION
111+
max_duration = max(duration for _, duration in TRIGGER_COUNT_DURATIONS)
112+
cutoff = now - max_duration
103113
drop = [i for i in self.messages if i < cutoff]
104114
for ts in drop:
105115
del self.messages[ts]
106116

107117
# Add the new message
108118
self.messages[now][message.author.id].append(message)
109119

110-
# Count occurances.
111-
matching = sum(
112-
1
113-
for messages in self.messages.values()
114-
for prior in messages[message.author.id]
115-
if self.message_match(message, prior)
116-
)
117-
118-
# Alert on spam.
119-
if matching >= REPEATED:
120+
# Check if the message triggers the filter.
121+
if any(
122+
self.count_matching_messages(message, now - duration) > count
123+
for count, duration in TRIGGER_COUNT_DURATIONS
124+
):
120125
self.prom_counter.inc()
121126
logging.info(
122127
"Spam detected. %s %s %s",

0 commit comments

Comments
 (0)