feat(events): add message update, role, and voice state update handlers

- Implemented `handle_message_update` to log message edits.
- Created role event handlers for role creation, update, and deletion.
- Added voice state update handling to log channel changes.
- Introduced a new `ready_event` handler to restore bot presence and enforce blacklist.
- Updated `mod.rs` to include new event modules.
- Enhanced `main.rs` for database connection and initialization.
- Added comprehensive permission management in `permissions.rs`.
This commit is contained in:
Puechberty Arthur
2026-04-10 02:13:04 +02:00
commit 3e69185296
169 changed files with 23909 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_channel_create(ctx: &Context, channel: &GuildChannel) {
logs_service::on_channel_create(ctx, channel).await;
}
pub async fn handle_channel_update(
ctx: &Context,
old_data_if_available: Option<GuildChannel>,
new: &GuildChannel,
) {
logs_service::on_channel_update(ctx, old_data_if_available, new).await;
}
pub async fn handle_channel_delete(ctx: &Context, channel: &GuildChannel) {
logs_service::on_channel_delete(ctx, channel).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::admin_service;
pub async fn handle_guild_create(ctx: &Context, guild: &Guild) {
admin_service::enforce_blacklist_on_guild(ctx, guild.id).await;
}
+49
View File
@@ -0,0 +1,49 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_member_addition(ctx: &Context, new_member: &Member) {
logs_service::on_member_join(ctx, new_member.guild_id, &new_member.user).await;
}
pub async fn handle_member_removal(ctx: &Context, guild_id: GuildId, user: &User) {
logs_service::on_member_leave(ctx, guild_id, user).await;
}
pub async fn handle_member_update(
ctx: &Context,
old_if_available: Option<Member>,
new: Option<Member>,
event: &GuildMemberUpdateEvent,
) {
if let (Some(old), Some(new_member)) = (old_if_available.clone(), new.clone()) {
logs_service::on_member_roles_updated(
ctx,
new_member.guild_id,
new_member.user.id,
&old.roles,
&new_member.roles,
)
.await;
logs_service::on_boost_update(
ctx,
new_member.guild_id,
new_member.user.id,
old.premium_since,
new_member.premium_since,
)
.await;
return;
}
logs_service::on_boost_update(
ctx,
event.guild_id,
event.user.id,
None,
event.premium_since,
)
.await;
}
+125
View File
@@ -0,0 +1,125 @@
use serenity::async_trait;
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::events::{
channel_event, guild_create_event, guild_member_event, interaction_create_event,
message_delete_event, message_event, message_update_event, ready_event, role_event,
voice_state_update_event,
};
pub struct Handler;
#[async_trait]
impl EventHandler for Handler {
async fn ready(&self, ctx: Context, ready: Ready) {
ready_event::handle_ready(&ctx, &ready).await;
}
async fn message(&self, ctx: Context, msg: Message) {
message_event::handle_message(&ctx, &msg).await;
}
async fn guild_create(&self, ctx: Context, guild: Guild, _is_new: Option<bool>) {
guild_create_event::handle_guild_create(&ctx, &guild).await;
}
async fn interaction_create(&self, ctx: Context, interaction: Interaction) {
interaction_create_event::handle_interaction_create(&ctx, &interaction).await;
}
async fn message_delete(
&self,
ctx: Context,
channel_id: ChannelId,
deleted_message_id: MessageId,
guild_id: Option<GuildId>,
) {
message_delete_event::handle_message_delete(&ctx, channel_id, deleted_message_id, guild_id)
.await;
}
async fn message_update(
&self,
ctx: Context,
old_if_available: Option<Message>,
new: Option<Message>,
event: MessageUpdateEvent,
) {
message_update_event::handle_message_update(&ctx, old_if_available, new, &event).await;
}
async fn voice_state_update(&self, ctx: Context, old: Option<VoiceState>, new: VoiceState) {
voice_state_update_event::handle_voice_state_update(&ctx, old, &new).await;
}
async fn guild_member_addition(&self, ctx: Context, new_member: Member) {
guild_member_event::handle_member_addition(&ctx, &new_member).await;
}
async fn guild_member_removal(
&self,
ctx: Context,
guild_id: GuildId,
user: User,
_member_data_if_available: Option<Member>,
) {
guild_member_event::handle_member_removal(&ctx, guild_id, &user).await;
}
async fn guild_member_update(
&self,
ctx: Context,
old_if_available: Option<Member>,
new: Option<Member>,
event: GuildMemberUpdateEvent,
) {
guild_member_event::handle_member_update(&ctx, old_if_available, new, &event).await;
}
async fn guild_role_create(&self, ctx: Context, new: Role) {
role_event::handle_role_create(&ctx, &new).await;
}
async fn guild_role_update(
&self,
ctx: Context,
old_data_if_available: Option<Role>,
new: Role,
) {
role_event::handle_role_update(&ctx, old_data_if_available, &new).await;
}
async fn guild_role_delete(
&self,
ctx: Context,
guild_id: GuildId,
removed_role_id: RoleId,
removed_role_data_if_available: Option<Role>,
) {
role_event::handle_role_delete(
&ctx,
guild_id,
removed_role_id,
removed_role_data_if_available,
)
.await;
}
async fn channel_create(&self, ctx: Context, guild_channel: GuildChannel) {
channel_event::handle_channel_create(&ctx, &guild_channel).await;
}
async fn channel_update(&self, ctx: Context, old: Option<GuildChannel>, new: GuildChannel) {
channel_event::handle_channel_update(&ctx, old, &new).await;
}
async fn channel_delete(
&self,
ctx: Context,
channel: GuildChannel,
_messages: Option<Vec<Message>>,
) {
channel_event::handle_channel_delete(&ctx, &channel).await;
}
}
+59
View File
@@ -0,0 +1,59 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::{advanced_tools, help, mp, perms_service, suggestion, tempvoc, ticket};
pub async fn handle_interaction_create(ctx: &Context, interaction: &Interaction) {
if let Interaction::Command(_) = interaction {
if help::handle_slash_interaction(ctx, interaction).await {
return;
}
}
if let Interaction::Component(component) = interaction {
if ticket::handle_component_interaction(ctx, component).await {
return;
}
if suggestion::handle_component_interaction(ctx, component).await {
return;
}
if tempvoc::handle_component_interaction(ctx, component).await {
return;
}
if help::handle_help_component(ctx, component).await {
return;
}
if mp::handle_mp_component(ctx, component).await {
return;
}
if perms_service::handle_allperms_component(ctx, component).await {
return;
}
let _ = advanced_tools::handle_component_interaction(ctx, component).await;
return;
}
if let Interaction::Modal(modal) = interaction {
if ticket::handle_modal_interaction(ctx, modal).await {
return;
}
if suggestion::handle_modal_interaction(ctx, modal).await {
return;
}
if tempvoc::handle_modal_interaction(ctx, modal).await {
return;
}
let _ = advanced_tools::handle_modal_interaction(ctx, modal).await;
}
}
+50
View File
@@ -0,0 +1,50 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
use crate::db::{DbPoolKey, mark_message_deleted, mark_sent_mp_deleted_by_message};
pub async fn handle_message_delete(
ctx: &Context,
channel_id: ChannelId,
deleted_message_id: MessageId,
guild_id: Option<GuildId>,
) {
let bot_id = ctx.cache.current_user().id;
let (fallback_author_id, fallback_content) =
if let Some(cached) = ctx.cache.message(channel_id, deleted_message_id) {
(Some(cached.author.id), Some(cached.content.clone()))
} else {
(None, None)
};
if let Some(pool) = {
let data = ctx.data.read().await;
data.get::<DbPoolKey>().cloned()
} {
let _ =
mark_sent_mp_deleted_by_message(&pool, bot_id, channel_id, deleted_message_id).await;
let _ = mark_message_deleted(
&pool,
bot_id,
guild_id,
channel_id,
deleted_message_id,
fallback_author_id,
fallback_content.clone(),
)
.await;
}
logs_service::on_message_deleted(
ctx,
guild_id,
channel_id,
deleted_message_id,
fallback_author_id,
fallback_content,
)
.await;
}
+421
View File
@@ -0,0 +1,421 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use std::collections::{HashSet, VecDeque};
use std::sync::{Mutex, OnceLock};
use crate::commands::moderation_tools;
use crate::commands::remove_activity;
use crate::commands::{
addrole, alias, autobackup, autoconfiglog, autoreact, backup, ban, banlist, banner, bl, blinfo,
boostembed, boosters, boostlog, bringall, button, calc, change, changeall, channel, choose,
cleanup, clear_all_sanctions, clear_bl, clear_messages, clear_owners, clear_perms,
clear_sanctions, claim, cmute, compet, create, del, del_sanction, delrole, derank, discussion,
dnd, embed, emoji, end, giveaway, help, helpsetting, hide, hideall, idle, invisible,
invite, join, kick, leave, leave_settings, listen, loading, lock, lockall, mainprefix,
massiverole, member, messagelog, modlog, mp, mute, mutelist, newsticker, nolog, online, owner,
perms, pic, ping, playto, prefix, raidlog, renew, rename, reroll, role, rolelog, rolemembers,
sanctions, say, server, serverinfo, set, set_boostembed, set_modlogs, shadowbot, showpics,
snipe, stream, sync, suggestion, tempban, tempcmute, tempmute, temprole, tempvoc, theme, tickets,
unban, unbanall, unbl, uncmute, unhide, unhideall, unlock, unlockall, unmassiverole, unmute,
unmuteall, unowner, untemprole, user, viewlogs, vocinfo, voicekick, voicelog, voicemove, warn,
watch, autopublish, ticket, ticket_member, close, tempvoc_cmd,
};
use crate::commands::{alladmins, allbots, allperms, botadmins};
use crate::db::{DbPoolKey, upsert_message_observed};
use crate::permissions;
const PROCESSED_CACHE_MAX: usize = 8192;
static PROCESSED_MESSAGES: OnceLock<Mutex<ProcessedMessages>> = OnceLock::new();
struct ProcessedMessages {
order: VecDeque<u64>,
seen: HashSet<u64>,
}
impl ProcessedMessages {
fn new() -> Self {
Self {
order: VecDeque::with_capacity(PROCESSED_CACHE_MAX),
seen: HashSet::with_capacity(PROCESSED_CACHE_MAX),
}
}
}
fn should_process_message(message_id: MessageId) -> bool {
let lock = PROCESSED_MESSAGES.get_or_init(|| Mutex::new(ProcessedMessages::new()));
let mut cache = lock.lock().expect("processed message cache poisoned");
let id = message_id.get();
if cache.seen.contains(&id) {
return false;
}
cache.seen.insert(id);
cache.order.push_back(id);
while cache.order.len() > PROCESSED_CACHE_MAX {
if let Some(oldest) = cache.order.pop_front() {
cache.seen.remove(&oldest);
}
}
true
}
pub async fn handle_message(ctx: &Context, msg: &Message) {
if !should_process_message(msg.id) {
return;
}
if crate::commands::admin_service::enforce_blacklist_on_message(ctx, msg).await {
return;
}
let bot_id = ctx.cache.current_user().id;
if let Some(pool) = {
let data = ctx.data.read().await;
data.get::<DbPoolKey>().cloned()
} {
let _ = upsert_message_observed(&pool, bot_id, msg).await;
}
if msg.author.bot {
return;
}
crate::commands::advanced_tools::apply_autoreacts(ctx, msg).await;
crate::commands::advanced_tools::maybe_run_maintenance(ctx, msg.guild_id).await;
moderation_tools::maybe_run_maintenance(ctx, msg.guild_id).await;
let content = msg.content.trim();
let prefix_value = permissions::resolve_prefix(ctx, msg.guild_id).await;
if !content.starts_with(&prefix_value) {
return;
}
let without_prefix = content.trim_start_matches(&prefix_value).trim();
if without_prefix.is_empty() {
return;
}
let mut parts = without_prefix.split_whitespace();
let mut command = parts.next().unwrap_or("").to_lowercase();
let args = parts.collect::<Vec<_>>();
// Ne laisse pas un alias écraser une commande native.
let native_commands = permissions::all_command_keys();
if !native_commands.iter().any(|cmd| cmd == &command) {
if let Some(alias_target) = alias::resolve_command_alias_name(ctx, &command).await {
command = alias_target;
} else if let Some(default_target) = crate::commands::resolve_default_alias(&command) {
command = default_target.to_string();
}
}
let command_key = permissions::command_key(&command, &args);
let can_use = permissions::can_use_command(ctx, msg, &command_key).await;
if !can_use {
let required = permissions::command_required_permission(ctx, &command_key).await;
permissions::deny_permission(ctx, msg, &command_key, required).await;
return;
}
match command.as_str() {
"ticket" => ticket::handle_ticket_settings(ctx, msg, &args).await,
"claim" => claim::handle_claim(ctx, msg, &args).await,
"rename" => rename::handle_rename(ctx, msg, &args).await,
"add" => ticket_member::handle_ticket_add(ctx, msg, &args).await,
"del"
if args
.first()
.map(|s| s.eq_ignore_ascii_case("perm"))
.unwrap_or(false) =>
{
del::handle_del(ctx, msg, &args).await
}
"del"
if args
.first()
.map(|s| s.eq_ignore_ascii_case("sanction"))
.unwrap_or(false) =>
{
del_sanction::handle_del_sanction(ctx, msg, &args).await
}
"del" => ticket_member::handle_ticket_remove(ctx, msg, &args).await,
"close" => close::handle_close(ctx, msg, &args).await,
"tickets" => tickets::handle_tickets(ctx, msg, &args).await,
"show" if args.first().map(|s| s.eq_ignore_ascii_case("pics")).unwrap_or(false) => {
showpics::handle_show_pics(ctx, msg, &args[1..]).await
}
"suggestion" => suggestion::handle_suggestion(ctx, msg, &args).await,
"autopublish" => autopublish::handle_autopublish(ctx, msg, &args).await,
"tempvoc" if args.first().map(|s| s.eq_ignore_ascii_case("cmd")).unwrap_or(false) => {
tempvoc_cmd::handle_tempvoc_cmd(ctx, msg, &args[1..]).await
}
"tempvoc" => tempvoc::handle_tempvoc(ctx, msg, &args).await,
"ping" => ping::handle_ping(ctx, msg, &args).await,
"allbots" => allbots::handle_allbots(ctx, msg, &args).await,
"alladmins" => alladmins::handle_alladmins(ctx, msg, &args).await,
"botadmins" => botadmins::handle_botadmins(ctx, msg, &args).await,
"boosters" => boosters::handle_boosters(ctx, msg, &args).await,
"rolemembers" => rolemembers::handle_rolemembers(ctx, msg, &args).await,
"serverinfo" => serverinfo::handle_serverinfo(ctx, msg, &args).await,
"vocinfo" => vocinfo::handle_vocinfo(ctx, msg, &args).await,
"role" => role::handle_role(ctx, msg, &args).await,
"channel" => channel::handle_channel(ctx, msg, &args).await,
"user" => user::handle_user(ctx, msg, &args).await,
"member" => member::handle_member(ctx, msg, &args).await,
"pic" => pic::handle_pic(ctx, msg, &args).await,
"banner" => banner::handle_banner(ctx, msg, &args).await,
"server" => server::handle_server(ctx, msg, &args).await,
"snipe" => snipe::handle_snipe(ctx, msg, &args).await,
"emoji" => emoji::handle_emoji(ctx, msg, &args).await,
"giveaway" => giveaway::handle_giveaway(ctx, msg, &args).await,
"modlog" => modlog::handle_modlog(ctx, msg, &args).await,
"messagelog" => messagelog::handle_messagelog(ctx, msg, &args).await,
"voicelog" => voicelog::handle_voicelog(ctx, msg, &args).await,
"boostlog" => boostlog::handle_boostlog(ctx, msg, &args).await,
"rolelog" => rolelog::handle_rolelog(ctx, msg, &args).await,
"raidlog" => raidlog::handle_raidlog(ctx, msg, &args).await,
"autoconfiglog" => autoconfiglog::handle_autoconfiglog(ctx, msg).await,
"join" => join::handle_join(ctx, msg, &args).await,
"boostembed" => boostembed::handle_boostembed(ctx, msg, &args).await,
"nolog" => nolog::handle_nolog(ctx, msg, &args).await,
"sanctions" => sanctions::handle_sanctions(ctx, msg, &args).await,
"end" => end::handle_end(ctx, msg, &args).await,
"reroll" => reroll::handle_reroll(ctx, msg, &args).await,
"choose" => choose::handle_choose(ctx, msg, &args).await,
"embed" => embed::handle_embed(ctx, msg, &args).await,
"backup" => backup::handle_backup(ctx, msg, &args).await,
"autobackup" => autobackup::handle_autobackup(ctx, msg, &args).await,
"loading" => loading::handle_loading(ctx, msg, &args).await,
"create" => create::handle_create(ctx, msg, &args).await,
"newsticker" => newsticker::handle_newsticker(ctx, msg, &args).await,
"massiverole" => massiverole::handle_massiverole(ctx, msg, &args).await,
"unmassiverole" => unmassiverole::handle_unmassiverole(ctx, msg, &args).await,
"voicemove" => voicemove::handle_voicemove(ctx, msg, &args).await,
"voicekick" => voicekick::handle_voicekick(ctx, msg, &args).await,
"cleanup" => cleanup::handle_cleanup(ctx, msg, &args).await,
"bringall" => bringall::handle_bringall(ctx, msg, &args).await,
"renew" => renew::handle_renew(ctx, msg, &args).await,
"unbanall" => unbanall::handle_unbanall(ctx, msg, &args).await,
"warn" => {
warn::handle_warn(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "warn", &args).await;
}
"mute" => {
mute::handle_mute(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "mute", &args).await;
}
"tempmute" => {
tempmute::handle_tempmute(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "tempmute", &args)
.await;
}
"unmute" => {
unmute::handle_unmute(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "unmute", &args).await;
}
"cmute" => {
cmute::handle_cmute(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "cmute", &args).await;
}
"tempcmute" => {
tempcmute::handle_tempcmute(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "tempcmute", &args)
.await;
}
"uncmute" => {
uncmute::handle_uncmute(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "uncmute", &args).await;
}
"mutelist" => {
mutelist::handle_mutelist(ctx, msg).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "mutelist", &args)
.await;
}
"unmuteall" => {
unmuteall::handle_unmuteall(ctx, msg).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "unmuteall", &args)
.await;
}
"kick" => {
kick::handle_kick(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "kick", &args).await;
}
"ban" => {
ban::handle_ban(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "ban", &args).await;
}
"tempban" => {
tempban::handle_tempban(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "tempban", &args).await;
}
"unban" => {
unban::handle_unban(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "unban", &args).await;
}
"banlist" => {
banlist::handle_banlist(ctx, msg).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "banlist", &args).await;
}
"lock" => {
lock::handle_lock(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "lock", &args).await;
}
"unlock" => {
unlock::handle_unlock(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "unlock", &args).await;
}
"lockall" => {
lockall::handle_lockall(ctx, msg).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "lockall", &args).await;
}
"unlockall" => {
unlockall::handle_unlockall(ctx, msg).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "unlockall", &args)
.await;
}
"hide" => {
hide::handle_hide(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "hide", &args).await;
}
"unhide" => {
unhide::handle_unhide(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "unhide", &args).await;
}
"hideall" => {
hideall::handle_hideall(ctx, msg).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "hideall", &args).await;
}
"unhideall" => {
unhideall::handle_unhideall(ctx, msg).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "unhideall", &args)
.await;
}
"addrole" => {
addrole::handle_addrole(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "addrole", &args).await;
}
"delrole" => {
delrole::handle_delrole(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "delrole", &args).await;
}
"derank" => {
derank::handle_derank(ctx, msg, &args).await;
crate::commands::logs_service::log_moderation_command(ctx, msg, "derank", &args).await;
}
"temprole" => temprole::handle_temprole(ctx, msg, &args).await,
"untemprole" => untemprole::handle_untemprole(ctx, msg, &args).await,
"sync" => sync::handle_sync(ctx, msg, &args).await,
"button" => button::handle_button(ctx, msg, &args).await,
"autoreact" => autoreact::handle_autoreact(ctx, msg, &args).await,
"calc" => calc::handle_calc(ctx, msg, &args).await,
"shadowbot" => shadowbot::handle_shadowbot(ctx, msg, &args).await,
"set"
if args
.first()
.map(|s| s.eq_ignore_ascii_case("modlogs"))
.unwrap_or(false) =>
{
set_modlogs::handle_set_modlogs(ctx, msg, &args[1..]).await
}
"set"
if args
.first()
.map(|s| s.eq_ignore_ascii_case("boostembed"))
.unwrap_or(false) =>
{
set_boostembed::handle_set_boostembed(ctx, msg, &args[1..]).await
}
"set" => set::handle_set(ctx, msg, &args).await,
"theme" => theme::handle_theme(ctx, msg, &args).await,
"playto" => playto::handle_playto(ctx, msg, &args).await,
"listen" => listen::handle_listen(ctx, msg, &args).await,
"watch" => watch::handle_watch(ctx, msg, &args).await,
"compet" => compet::handle_compet(ctx, msg, &args).await,
"stream" => stream::handle_stream(ctx, msg, &args).await,
"help" => help::handle_help(ctx, msg, &args).await,
"helpsetting" => helpsetting::handle_helpsetting(ctx, msg, &args).await,
"alias" => alias::handle_alias(ctx, msg, &args).await,
"mp" => mp::handle_mp(ctx, msg, &args).await,
"invite" => invite::handle_invite(ctx, msg, &args).await,
"leave"
if args
.first()
.map(|s| s.eq_ignore_ascii_case("settings"))
.unwrap_or(false) =>
{
leave_settings::handle_leave_settings(ctx, msg, &args).await
}
"leave" => leave::handle_leave(ctx, msg, &args).await,
"viewlogs" => viewlogs::handle_viewlogs(ctx, msg, &args).await,
"discussion" => discussion::handle_discussion(ctx, msg, &args).await,
"remove"
if args
.first()
.map(|s| s.eq_ignore_ascii_case("activity"))
.unwrap_or(false) =>
{
remove_activity::handle_remove_activity(ctx, msg).await
}
"online" => online::handle_online(ctx, msg).await,
"idle" => idle::handle_idle(ctx, msg).await,
"dnd" => dnd::handle_dnd(ctx, msg).await,
"invisible" => invisible::handle_invisible(ctx, msg).await,
"owner" => owner::handle_owner(ctx, msg, &args).await,
"unowner" => unowner::handle_unowner(ctx, msg, &args).await,
"bl" => bl::handle_bl(ctx, msg, &args).await,
"unbl" => unbl::handle_unbl(ctx, msg, &args).await,
"blinfo" => blinfo::handle_blinfo(ctx, msg, &args).await,
"say" => say::handle_say(ctx, msg, &args).await,
"change" => change::handle_change(ctx, msg, &args).await,
"changeall" => changeall::handle_changeall(ctx, msg, &args).await,
"mainprefix" => mainprefix::handle_mainprefix(ctx, msg, &args).await,
"prefix" => prefix::handle_prefix(ctx, msg, &args).await,
"perms" => perms::handle_perms(ctx, msg, &args).await,
"allperms" => allperms::handle_allperms(ctx, msg, &args).await,
"clear"
if args
.first()
.map(|s| s.eq_ignore_ascii_case("owners"))
.unwrap_or(false) =>
{
clear_owners::handle_clear_owners(ctx, msg).await
}
"clear"
if args
.first()
.map(|s| s.eq_ignore_ascii_case("bl"))
.unwrap_or(false) =>
{
clear_bl::handle_clear_bl(ctx, msg).await
}
"clear"
if args
.first()
.map(|s| s.eq_ignore_ascii_case("perms"))
.unwrap_or(false) =>
{
clear_perms::handle_clear_perms(ctx, msg).await
}
"clear"
if args
.first()
.map(|s| s.eq_ignore_ascii_case("sanctions"))
.unwrap_or(false) =>
{
clear_sanctions::handle_clear_sanctions(ctx, msg, &args).await
}
"clear"
if args.len() >= 2
&& args[0].eq_ignore_ascii_case("all")
&& args[1].eq_ignore_ascii_case("sanctions") =>
{
clear_all_sanctions::handle_clear_all_sanctions(ctx, msg).await
}
"clear" => clear_messages::handle_clear_messages(ctx, msg, &args).await,
_ => {}
}
}
+31
View File
@@ -0,0 +1,31 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_message_update(
ctx: &Context,
old_if_available: Option<Message>,
new: Option<Message>,
event: &MessageUpdateEvent,
) {
let before = old_if_available.as_ref().map(|m| m.content.clone());
let after = new
.as_ref()
.map(|m| m.content.clone())
.or_else(|| event.content.clone());
let author_id = old_if_available
.as_ref()
.map(|m| m.author.id)
.or_else(|| new.as_ref().map(|m| m.author.id));
logs_service::on_message_edited(
ctx,
event.guild_id,
event.channel_id,
author_id,
before,
after,
)
.await;
}
+11
View File
@@ -0,0 +1,11 @@
pub mod channel_event;
pub mod guild_create_event;
pub mod guild_member_event;
pub mod handler;
pub mod interaction_create_event;
pub mod message_delete_event;
pub mod message_event;
pub mod message_update_event;
pub mod ready_event;
pub mod role_event;
pub mod voice_state_update_event;
+14
View File
@@ -0,0 +1,14 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::{admin_service, botconfig_service, help};
pub async fn handle_ready(ctx: &Context, ready: &Ready) {
botconfig_service::restore_presence_from_db(ctx).await;
help::register_slash_help(ctx).await;
for guild_id in ctx.cache.guilds() {
admin_service::enforce_blacklist_on_guild(ctx, guild_id).await;
}
println!("Connecté en tant que {}", ready.user.name);
}
+27
View File
@@ -0,0 +1,27 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_role_create(ctx: &Context, new: &Role) {
logs_service::on_role_create(ctx, new.guild_id, new).await;
}
pub async fn handle_role_update(ctx: &Context, old_data_if_available: Option<Role>, new: &Role) {
logs_service::on_role_update(ctx, new.guild_id, old_data_if_available.as_ref(), new).await;
}
pub async fn handle_role_delete(
ctx: &Context,
guild_id: GuildId,
removed_role_id: RoleId,
removed_role_data_if_available: Option<Role>,
) {
logs_service::on_role_delete(
ctx,
guild_id,
removed_role_id,
removed_role_data_if_available.as_ref(),
)
.await;
}
+21
View File
@@ -0,0 +1,21 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
use crate::commands::tempvoc;
pub async fn handle_voice_state_update(ctx: &Context, old: Option<VoiceState>, new: &VoiceState) {
tempvoc::handle_voice_state_update(ctx, old.as_ref(), new).await;
let Some(guild_id) = new.guild_id else {
return;
};
let old_channel = old.and_then(|v| v.channel_id);
let new_channel = new.channel_id;
if old_channel == new_channel {
return;
}
logs_service::on_voice_update(ctx, guild_id, new.user_id, old_channel, new_channel).await;
}