From 881c48685eb6ba4096da0bc73f547595d001a859 Mon Sep 17 00:00:00 2001 From: Hermes-Neo Date: Thu, 2 Jul 2026 12:52:35 +0100 Subject: [PATCH 1/3] fix: catch voice text channel messages and purge across all watched channels --- src/handlers.rs | 66 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/src/handlers.rs b/src/handlers.rs index 6b6de91..3528341 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -4,10 +4,14 @@ use serenity::all::ActivityData; use serenity::model::channel::MessageFlags; use serenity::{ async_trait, - builder::{CreateAttachment, CreateMessage}, + builder::{CreateAttachment, CreateMessage, GetMessages}, client::Context, model::{ - application::Interaction, channel::Message, gateway::Ready, guild::Guild, id::GuildId, + application::Interaction, + channel::Message, + gateway::Ready, + guild::Guild, + id::{GuildId, MessageId}, user::OnlineStatus, }, }; @@ -85,9 +89,27 @@ impl serenity::client::EventHandler for Handler { None => return, }; - match self.db.is_watched_channel(guild_id, msg.channel_id) { - Ok(true) => {} - _ => return, + // Check if the channel itself is watched, or if this message is in a + // thread (e.g. a voice text channel) whose parent channel is watched. + let is_watched = self + .db + .is_watched_channel(guild_id, msg.channel_id) + .unwrap_or(false); + + if !is_watched { + if let Some(ref thread_channel) = msg.thread { + if let Some(parent_id) = thread_channel.parent_id { + if self.db.is_watched_channel(guild_id, parent_id).unwrap_or(false) { + // This message is in a thread whose parent is watched + } else { + return; + } + } else { + return; + } + } else { + return; + } } if let Err(e) = self @@ -191,6 +213,38 @@ impl Handler { let _ = msg.delete(&ctx.http).await; + // Purge this user's messages from ALL watched channels within the past hour. + let watched = match self.db.get_watched_channels(guild_id) { + Ok(channels) => channels, + Err(e) => { + eprintln!("Failed to get watched channels: {:?}", e); + vec![] + } + }; + + let one_hour_ago = msg.id.get() - (3_600_000 << 22); + + for channel_id in watched { + let Ok(batch) = channel_id + .messages(&ctx.http, GetMessages::new().limit(10)) + .await + else { + continue; + }; + + let to_delete: Vec = batch + .iter() + .filter(|m| m.author.id == msg.author.id && m.id.get() >= one_hour_ago) + .map(|m| m.id) + .collect(); + + for chunk in to_delete.chunks(100) { + if let Err(e) = channel_id.delete_messages(&ctx.http, chunk).await { + eprintln!("Failed to bulk delete in {channel_id}: {e:?}"); + } + } + } + let ban_reason = self .db .get_ban_reason(guild_id) @@ -209,4 +263,4 @@ impl Handler { Ok(()) } -} +} \ No newline at end of file -- 2.39.5 From 5929e890a6e1bce4cdc604ca15be26122563dcfb Mon Sep 17 00:00:00 2001 From: Hermes-Neo Date: Thu, 2 Jul 2026 12:54:14 +0100 Subject: [PATCH 2/3] fix fmt --- src/handlers.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/handlers.rs b/src/handlers.rs index 3528341..28a1f73 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -99,7 +99,11 @@ impl serenity::client::EventHandler for Handler { if !is_watched { if let Some(ref thread_channel) = msg.thread { if let Some(parent_id) = thread_channel.parent_id { - if self.db.is_watched_channel(guild_id, parent_id).unwrap_or(false) { + if self + .db + .is_watched_channel(guild_id, parent_id) + .unwrap_or(false) + { // This message is in a thread whose parent is watched } else { return; -- 2.39.5 From c1430c928dd7990a192b55b6c299f736dc842b05 Mon Sep 17 00:00:00 2001 From: Hermes-Neo Date: Thu, 2 Jul 2026 12:56:01 +0100 Subject: [PATCH 3/3] fix fmt (trailing newline) --- src/handlers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/handlers.rs b/src/handlers.rs index 28a1f73..71b0925 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -267,4 +267,4 @@ impl Handler { Ok(()) } -} \ No newline at end of file +} -- 2.39.5