Add automated warning and banning

This commit is contained in:
2025-08-14 23:18:43 -03:00
parent 8e0c591b21
commit 6dde25aa72
10 changed files with 587 additions and 36 deletions
+114 -20
View File
@@ -1,15 +1,22 @@
use std::sync::Arc;
use async_trait::async_trait;
use itertools::Itertools;
use twilight_model::{gateway::payload::incoming::MessageCreate, id::Id};
use crate::{
database::models::{Call, Channel, Message},
database::models::{Call, Channel, Message, User, UserIncident},
discord::sanitizing::SanitizeDiscordMarkdown,
framework::{
events::traits::{EventResult, OnMessageHandler},
interactions::components::ActionRow,
runtime::Runtime,
},
groups::calls::{get_display_profile, moderation::escape_message},
groups::calls::{
components::{CodeOfConductButton, NeedHelpButton},
embeds, get_display_profile,
moderation::{Action, escape_message},
},
state::State,
};
@@ -73,6 +80,16 @@ impl OnMessageHandler<State> for MessageRedirector {
return Ok(());
};
let user_incidents = UserIncident::get_for_user(event.author.id.get(), &rt.state.db)
.await?
.iter()
.filter(|incident| incident.is_active())
.count();
if user_incidents > 0 {
return Ok(());
}
let Some(opposite_channel) = Channel::get_by_id(
call.other_party_channel_id(event.channel_id.get()),
&rt.state.db,
@@ -97,31 +114,108 @@ impl OnMessageHandler<State> for MessageRedirector {
let profile = get_display_profile(event);
Message::build()
let message = Message::build()
.call_id(call.id)
.message(event.0.clone())
.profile(profile.clone())
.build()
.expect(
"The message builder was missing either the call ID, the message, or the profile",
)
.insert(&rt.state.db)
.await?;
);
message.insert(&rt.state.db).await?;
rt.http
.execute_webhook(Id::new(webhook_id), &webhook_token)
.allowed_mentions(None)
.username(&profile.name)
.avatar_url(&profile.avatar_url)
.content(&escape_message(event))
.await
.inspect_err(|e| {
log::error!(
"Failed to send message to webhook for call {} in channel {}: {e:?}",
call.id,
opposite_channel.id
);
})?;
let (content, rules) = escape_message(event);
if rules
.iter()
.any(|rule| rule.action() == &Action::BlockAndPenalty)
{
let user = User::get_by_id(event.author.id.get(), &rt.state.db).await?;
let user = if let Some(user) = user {
user
} else {
let user: User = event.author.clone().into();
user.insert(&rt.state.db).await?;
user
};
let reason = format!(
"You broke the following rules during a call:\n{}",
rules
.iter()
.map(|rule| format!("- {}", rule.name()))
.join("\n")
);
let new_incident = user
.incident(
reason.clone(),
message.data.clone(),
Some(event.author.id.get()),
&rt.state.db,
)
.await?;
rt.http
.create_message(event.channel_id)
.content(
"❌ Your message has been blocked because it broke Payphone's code of conduct. Check your DMs for more information.",
)
.await?;
rt.http
.create_message(Id::new(opposite_channel.id))
.content(&format!(
"❌ **{}** Sent a message that was blocked.\n-# If you see an inappropiate message, please report it using `Message > Apps > Report Message`.",
profile.name.sanitize(false)
))
.await?;
let dm_channel = rt
.http
.create_private_channel(event.author.id)
.await?
.model()
.await?;
let embed = if new_incident.is_first_incident {
embeds::first_warning_embed(&rt.app, &event.0, rules)
} else if new_incident.counting_incidents == 0 {
embeds::repeat_warning_embed(&rt.app, &event.0, rules)
} else if new_incident.counting_incidents == 1 {
embeds::first_ban_embed(&rt.app, &event.0, rules)
} else {
embeds::final_ban_embed(&rt.app, &event.0, rules)
};
rt.http
.create_message(dm_channel.id)
.embeds(&[embed])
.components(&[ActionRow::new(&[
(None, Arc::new(CodeOfConductButton)),
(None, Arc::new(NeedHelpButton)),
])
.build()])
.await?;
} else {
rt.http
.execute_webhook(Id::new(webhook_id), &webhook_token)
.allowed_mentions(None)
.username(&profile.name)
.avatar_url(&profile.avatar_url)
.content(&content)
.await
.inspect_err(|e| {
log::error!(
"Failed to send message to webhook for call {} in channel {}: {e:?}",
call.id,
opposite_channel.id
);
})?;
}
Ok(())
}