add log events

This commit is contained in:
Puechberty Arthur
2026-04-10 19:05:00 +02:00
parent 4e02a25802
commit dc07a10c9f
37 changed files with 1444 additions and 3 deletions
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_auto_moderation_action_execution(ctx: &Context, execution: &ActionExecution) {
logs_service::on_auto_moderation_action_execution(ctx, execution).await;
}
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_auto_moderation_rule_create(ctx: &Context, rule: &Rule) {
logs_service::on_auto_moderation_rule_create(ctx, rule).await;
}
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_auto_moderation_rule_delete(ctx: &Context, rule: &Rule) {
logs_service::on_auto_moderation_rule_delete(ctx, rule).await;
}
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_auto_moderation_rule_update(ctx: &Context, rule: &Rule) {
logs_service::on_auto_moderation_rule_update(ctx, rule).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_channel_pins_update(ctx: &Context, pin: &ChannelPinsUpdateEvent) {
logs_service::on_channel_pins_update(ctx, pin).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_guild_ban_addition(ctx: &Context, guild_id: GuildId, banned_user: &User) {
logs_service::on_guild_ban_addition(ctx, guild_id, banned_user).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_guild_ban_removal(ctx: &Context, guild_id: GuildId, unbanned_user: &User) {
logs_service::on_guild_ban_removal(ctx, guild_id, unbanned_user).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_guild_integrations_update(ctx: &Context, guild_id: GuildId) {
logs_service::on_guild_integrations_update(ctx, guild_id).await;
}
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_guild_scheduled_event_create(ctx: &Context, event: &ScheduledEvent) {
logs_service::on_guild_scheduled_event_create(ctx, event).await;
}
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_guild_scheduled_event_delete(ctx: &Context, event: &ScheduledEvent) {
logs_service::on_guild_scheduled_event_delete(ctx, event).await;
}
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_guild_scheduled_event_update(ctx: &Context, event: &ScheduledEvent) {
logs_service::on_guild_scheduled_event_update(ctx, event).await;
}
@@ -0,0 +1,11 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_guild_scheduled_event_user_add(
ctx: &Context,
subscribed: &GuildScheduledEventUserAddEvent,
) {
logs_service::on_guild_scheduled_event_user_add(ctx, subscribed).await;
}
@@ -0,0 +1,11 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_guild_scheduled_event_user_remove(
ctx: &Context,
unsubscribed: &GuildScheduledEventUserRemoveEvent,
) {
logs_service::on_guild_scheduled_event_user_remove(ctx, unsubscribed).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_integration_create(ctx: &Context, integration: &Integration) {
logs_service::on_integration_create(ctx, integration).await;
}
+13
View File
@@ -0,0 +1,13 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_integration_delete(
ctx: &Context,
integration_id: IntegrationId,
guild_id: GuildId,
application_id: Option<ApplicationId>,
) {
logs_service::on_integration_delete(ctx, integration_id, guild_id, application_id).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_integration_update(ctx: &Context, integration: &Integration) {
logs_service::on_integration_update(ctx, integration).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_invite_create(ctx: &Context, data: &InviteCreateEvent) {
logs_service::on_invite_create(ctx, data).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_invite_delete(ctx: &Context, data: &InviteDeleteEvent) {
logs_service::on_invite_delete(ctx, data).await;
}
+14
View File
@@ -0,0 +1,14 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_message_delete_bulk(
ctx: &Context,
channel_id: ChannelId,
multiple_deleted_messages_ids: &[MessageId],
guild_id: Option<GuildId>,
) {
logs_service::on_message_delete_bulk(ctx, channel_id, multiple_deleted_messages_ids, guild_id)
.await;
}
+34
View File
@@ -1,18 +1,52 @@
pub mod auto_moderation_action_execution;
pub mod auto_moderation_rule_create;
pub mod auto_moderation_rule_delete;
pub mod auto_moderation_rule_update;
pub mod channel_create; pub mod channel_create;
pub mod channel_delete; pub mod channel_delete;
pub mod channel_pins_update;
pub mod channel_update; pub mod channel_update;
pub mod guild_ban_addition;
pub mod guild_ban_removal;
pub mod guild_create; pub mod guild_create;
pub mod guild_integrations_update;
pub mod guild_member_addition; pub mod guild_member_addition;
pub mod guild_member_removal; pub mod guild_member_removal;
pub mod guild_member_update; pub mod guild_member_update;
pub mod guild_scheduled_event_create;
pub mod guild_scheduled_event_delete;
pub mod guild_scheduled_event_update;
pub mod guild_scheduled_event_user_add;
pub mod guild_scheduled_event_user_remove;
#[path = "../utils/events_handler.rs"] #[path = "../utils/events_handler.rs"]
pub mod handler; pub mod handler;
pub mod integration_create;
pub mod integration_delete;
pub mod integration_update;
pub mod interaction_create; pub mod interaction_create;
pub mod invite_create;
pub mod invite_delete;
pub mod message; pub mod message;
pub mod message_delete; pub mod message_delete;
pub mod message_delete_bulk;
pub mod message_update; pub mod message_update;
pub mod reaction_add;
pub mod reaction_remove;
pub mod reaction_remove_all;
pub mod reaction_remove_emoji;
pub mod ready; pub mod ready;
pub mod role_create; pub mod role_create;
pub mod role_delete; pub mod role_delete;
pub mod role_update; pub mod role_update;
pub mod stage_instance_create;
pub mod stage_instance_delete;
pub mod stage_instance_update;
pub mod thread_create;
pub mod thread_delete;
pub mod thread_list_sync;
pub mod thread_member_update;
pub mod thread_members_update;
pub mod thread_update;
pub mod voice_channel_status_update;
pub mod voice_state_update; pub mod voice_state_update;
pub mod webhook_update;
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_reaction_add(ctx: &Context, add_reaction: &Reaction) {
logs_service::on_reaction_add(ctx, add_reaction).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_reaction_remove(ctx: &Context, removed_reaction: &Reaction) {
logs_service::on_reaction_remove(ctx, removed_reaction).await;
}
+12
View File
@@ -0,0 +1,12 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_reaction_remove_all(
ctx: &Context,
channel_id: ChannelId,
removed_from_message_id: MessageId,
) {
logs_service::on_reaction_remove_all(ctx, channel_id, removed_from_message_id).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_reaction_remove_emoji(ctx: &Context, removed_reactions: &Reaction) {
logs_service::on_reaction_remove_emoji(ctx, removed_reactions).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_stage_instance_create(ctx: &Context, stage_instance: &StageInstance) {
logs_service::on_stage_instance_create(ctx, stage_instance).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_stage_instance_delete(ctx: &Context, stage_instance: &StageInstance) {
logs_service::on_stage_instance_delete(ctx, stage_instance).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_stage_instance_update(ctx: &Context, stage_instance: &StageInstance) {
logs_service::on_stage_instance_update(ctx, stage_instance).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_thread_create(ctx: &Context, thread: &GuildChannel) {
logs_service::on_thread_create(ctx, thread).await;
}
+12
View File
@@ -0,0 +1,12 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_thread_delete(
ctx: &Context,
thread: &PartialGuildChannel,
full_thread_data: Option<&GuildChannel>,
) {
logs_service::on_thread_delete(ctx, thread, full_thread_data).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_thread_list_sync(ctx: &Context, thread_list_sync: &ThreadListSyncEvent) {
logs_service::on_thread_list_sync(ctx, thread_list_sync).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_thread_member_update(ctx: &Context, thread_member: &ThreadMember) {
logs_service::on_thread_member_update(ctx, thread_member).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_thread_members_update(ctx: &Context, event: &ThreadMembersUpdateEvent) {
logs_service::on_thread_members_update(ctx, event).await;
}
+8
View File
@@ -0,0 +1,8 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_thread_update(ctx: &Context, old: Option<GuildChannel>, new: &GuildChannel) {
logs_service::on_thread_update(ctx, old, new).await;
}
+14
View File
@@ -0,0 +1,14 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_voice_channel_status_update(
ctx: &Context,
old: Option<String>,
status: Option<String>,
id: ChannelId,
guild_id: GuildId,
) {
logs_service::on_voice_channel_status_update(ctx, old, status, id, guild_id).await;
}
+12
View File
@@ -0,0 +1,12 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::logs_service;
pub async fn handle_webhook_update(
ctx: &Context,
guild_id: GuildId,
belongs_to_channel_id: ChannelId,
) {
logs_service::on_webhook_update(ctx, guild_id, belongs_to_channel_id).await;
}
+212 -3
View File
@@ -3,9 +3,18 @@ use serenity::model::prelude::*;
use serenity::prelude::*; use serenity::prelude::*;
use crate::events::{ use crate::events::{
channel_create, channel_delete, channel_update, guild_create, guild_member_addition, auto_moderation_action_execution, auto_moderation_rule_create, auto_moderation_rule_delete,
guild_member_removal, guild_member_update, interaction_create, message, message_delete, auto_moderation_rule_update, channel_create, channel_delete, channel_pins_update,
message_update, ready, role_create, role_delete, role_update, voice_state_update, channel_update, guild_ban_addition, guild_ban_removal, guild_create, guild_integrations_update,
guild_member_addition, guild_member_removal, guild_member_update, guild_scheduled_event_create,
guild_scheduled_event_delete, guild_scheduled_event_update, guild_scheduled_event_user_add,
guild_scheduled_event_user_remove, integration_create, integration_delete, integration_update,
interaction_create, invite_create, invite_delete, message, message_delete, message_delete_bulk,
message_update, reaction_add, reaction_remove, reaction_remove_all, reaction_remove_emoji,
ready, role_create, role_delete, role_update, stage_instance_create, stage_instance_delete,
stage_instance_update, thread_create, thread_delete, thread_list_sync, thread_member_update,
thread_members_update, thread_update, voice_channel_status_update, voice_state_update,
webhook_update,
}; };
pub struct Handler; pub struct Handler;
@@ -121,4 +130,204 @@ impl EventHandler for Handler {
) { ) {
channel_delete::handle_channel_delete(&ctx, &channel).await; channel_delete::handle_channel_delete(&ctx, &channel).await;
} }
async fn message_delete_bulk(
&self,
ctx: Context,
channel_id: ChannelId,
multiple_deleted_messages_ids: Vec<MessageId>,
guild_id: Option<GuildId>,
) {
message_delete_bulk::handle_message_delete_bulk(
&ctx,
channel_id,
&multiple_deleted_messages_ids,
guild_id,
)
.await;
}
async fn reaction_add(&self, ctx: Context, add_reaction: Reaction) {
reaction_add::handle_reaction_add(&ctx, &add_reaction).await;
}
async fn reaction_remove(&self, ctx: Context, removed_reaction: Reaction) {
reaction_remove::handle_reaction_remove(&ctx, &removed_reaction).await;
}
async fn reaction_remove_all(
&self,
ctx: Context,
channel_id: ChannelId,
removed_from_message_id: MessageId,
) {
reaction_remove_all::handle_reaction_remove_all(&ctx, channel_id, removed_from_message_id)
.await;
}
async fn reaction_remove_emoji(&self, ctx: Context, removed_reactions: Reaction) {
reaction_remove_emoji::handle_reaction_remove_emoji(&ctx, &removed_reactions).await;
}
async fn channel_pins_update(&self, ctx: Context, pin: ChannelPinsUpdateEvent) {
channel_pins_update::handle_channel_pins_update(&ctx, &pin).await;
}
async fn invite_create(&self, ctx: Context, data: InviteCreateEvent) {
invite_create::handle_invite_create(&ctx, &data).await;
}
async fn invite_delete(&self, ctx: Context, data: InviteDeleteEvent) {
invite_delete::handle_invite_delete(&ctx, &data).await;
}
async fn guild_ban_addition(&self, ctx: Context, guild_id: GuildId, banned_user: User) {
guild_ban_addition::handle_guild_ban_addition(&ctx, guild_id, &banned_user).await;
}
async fn guild_ban_removal(&self, ctx: Context, guild_id: GuildId, unbanned_user: User) {
guild_ban_removal::handle_guild_ban_removal(&ctx, guild_id, &unbanned_user).await;
}
async fn webhook_update(
&self,
ctx: Context,
guild_id: GuildId,
belongs_to_channel_id: ChannelId,
) {
webhook_update::handle_webhook_update(&ctx, guild_id, belongs_to_channel_id).await;
}
async fn thread_create(&self, ctx: Context, thread: GuildChannel) {
thread_create::handle_thread_create(&ctx, &thread).await;
}
async fn thread_update(&self, ctx: Context, old: Option<GuildChannel>, new: GuildChannel) {
thread_update::handle_thread_update(&ctx, old, &new).await;
}
async fn thread_delete(
&self,
ctx: Context,
thread: PartialGuildChannel,
full_thread_data: Option<GuildChannel>,
) {
thread_delete::handle_thread_delete(&ctx, &thread, full_thread_data.as_ref()).await;
}
async fn thread_list_sync(&self, ctx: Context, thread_list_sync_event: ThreadListSyncEvent) {
thread_list_sync::handle_thread_list_sync(&ctx, &thread_list_sync_event).await;
}
async fn thread_member_update(&self, ctx: Context, thread_member: ThreadMember) {
thread_member_update::handle_thread_member_update(&ctx, &thread_member).await;
}
async fn thread_members_update(&self, ctx: Context, event: ThreadMembersUpdateEvent) {
thread_members_update::handle_thread_members_update(&ctx, &event).await;
}
async fn auto_moderation_rule_create(&self, ctx: Context, rule: Rule) {
auto_moderation_rule_create::handle_auto_moderation_rule_create(&ctx, &rule).await;
}
async fn auto_moderation_rule_update(&self, ctx: Context, rule: Rule) {
auto_moderation_rule_update::handle_auto_moderation_rule_update(&ctx, &rule).await;
}
async fn auto_moderation_rule_delete(&self, ctx: Context, rule: Rule) {
auto_moderation_rule_delete::handle_auto_moderation_rule_delete(&ctx, &rule).await;
}
async fn auto_moderation_action_execution(&self, ctx: Context, execution: ActionExecution) {
auto_moderation_action_execution::handle_auto_moderation_action_execution(&ctx, &execution)
.await;
}
async fn stage_instance_create(&self, ctx: Context, stage_instance: StageInstance) {
stage_instance_create::handle_stage_instance_create(&ctx, &stage_instance).await;
}
async fn stage_instance_update(&self, ctx: Context, stage_instance: StageInstance) {
stage_instance_update::handle_stage_instance_update(&ctx, &stage_instance).await;
}
async fn stage_instance_delete(&self, ctx: Context, stage_instance: StageInstance) {
stage_instance_delete::handle_stage_instance_delete(&ctx, &stage_instance).await;
}
async fn voice_channel_status_update(
&self,
ctx: Context,
old: Option<String>,
status: Option<String>,
id: ChannelId,
guild_id: GuildId,
) {
voice_channel_status_update::handle_voice_channel_status_update(
&ctx, old, status, id, guild_id,
)
.await;
}
async fn guild_scheduled_event_create(&self, ctx: Context, event: ScheduledEvent) {
guild_scheduled_event_create::handle_guild_scheduled_event_create(&ctx, &event).await;
}
async fn guild_scheduled_event_update(&self, ctx: Context, event: ScheduledEvent) {
guild_scheduled_event_update::handle_guild_scheduled_event_update(&ctx, &event).await;
}
async fn guild_scheduled_event_delete(&self, ctx: Context, event: ScheduledEvent) {
guild_scheduled_event_delete::handle_guild_scheduled_event_delete(&ctx, &event).await;
}
async fn guild_scheduled_event_user_add(
&self,
ctx: Context,
subscribed: GuildScheduledEventUserAddEvent,
) {
guild_scheduled_event_user_add::handle_guild_scheduled_event_user_add(&ctx, &subscribed)
.await;
}
async fn guild_scheduled_event_user_remove(
&self,
ctx: Context,
unsubscribed: GuildScheduledEventUserRemoveEvent,
) {
guild_scheduled_event_user_remove::handle_guild_scheduled_event_user_remove(
&ctx,
&unsubscribed,
)
.await;
}
async fn integration_create(&self, ctx: Context, integration: Integration) {
integration_create::handle_integration_create(&ctx, &integration).await;
}
async fn integration_update(&self, ctx: Context, integration: Integration) {
integration_update::handle_integration_update(&ctx, &integration).await;
}
async fn integration_delete(
&self,
ctx: Context,
integration_id: IntegrationId,
guild_id: GuildId,
application_id: Option<ApplicationId>,
) {
integration_delete::handle_integration_delete(
&ctx,
integration_id,
guild_id,
application_id,
)
.await;
}
async fn guild_integrations_update(&self, ctx: Context, guild_id: GuildId) {
guild_integrations_update::handle_guild_integrations_update(&ctx, guild_id).await;
}
} }
+891
View File
@@ -659,3 +659,894 @@ pub async fn on_channel_update(ctx: &Context, old_data: Option<GuildChannel>, ne
) )
.await; .await;
} }
async fn resolve_guild_id_from_channel(ctx: &Context, channel_id: ChannelId) -> Option<GuildId> {
let channel = channel_id.to_channel(&ctx.http).await.ok()?;
match channel {
serenity::model::channel::Channel::Guild(guild_channel) => Some(guild_channel.guild_id),
_ => None,
}
}
pub async fn on_channel_pins_update(ctx: &Context, pin: &ChannelPinsUpdateEvent) {
let guild_id = if let Some(guild_id) = pin.guild_id {
guild_id
} else if let Some(guild_id) = resolve_guild_id_from_channel(ctx, pin.channel_id).await {
guild_id
} else {
return;
};
if is_nolog_channel(ctx, guild_id, pin.channel_id, "message").await {
return;
}
let last_pin_timestamp = pin
.last_pin_timestamp
.as_ref()
.map(ToString::to_string)
.unwrap_or_else(|| "Aucun pin actif".to_string());
send_log_embed(
ctx,
guild_id,
"message",
CreateEmbed::new()
.title("Pins du salon mis a jour")
.description(format!(
"Salon: <#{}>\nDernier pin: {}",
pin.channel_id.get(),
last_pin_timestamp
)),
)
.await;
}
pub async fn on_guild_ban_addition(ctx: &Context, guild_id: GuildId, banned_user: &User) {
emit_log(
ctx,
guild_id,
"moderation",
Some(banned_user.id),
None,
None,
"ban_event",
CreateEmbed::new().title("Ban detecte").description(format!(
"Utilisateur: <@{}> (`{}`)",
banned_user.id.get(),
banned_user.tag()
)),
)
.await;
}
pub async fn on_guild_ban_removal(ctx: &Context, guild_id: GuildId, unbanned_user: &User) {
emit_log(
ctx,
guild_id,
"moderation",
Some(unbanned_user.id),
None,
None,
"unban_event",
CreateEmbed::new()
.title("Deban detecte")
.description(format!(
"Utilisateur: <@{}> (`{}`)",
unbanned_user.id.get(),
unbanned_user.tag()
)),
)
.await;
}
pub async fn on_invite_create(ctx: &Context, data: &InviteCreateEvent) {
let Some(guild_id) = data.guild_id else {
return;
};
let inviter = data
.inviter
.as_ref()
.map(|user| format!("<@{}>", user.id.get()))
.unwrap_or_else(|| "Inconnu".to_string());
emit_log(
ctx,
guild_id,
"channel",
data.inviter.as_ref().map(|user| user.id),
Some(data.channel_id),
None,
"invite_create",
CreateEmbed::new()
.title("Invitation creee")
.description(format!(
"Code: `{}`\nSalon: <#{}>\nInviteur: {}\nTemporaire: {}\nMax utilisations: {}",
data.code,
data.channel_id.get(),
inviter,
data.temporary,
data.max_uses
)),
)
.await;
}
pub async fn on_invite_delete(ctx: &Context, data: &InviteDeleteEvent) {
let Some(guild_id) = data.guild_id else {
return;
};
emit_log(
ctx,
guild_id,
"channel",
None,
Some(data.channel_id),
None,
"invite_delete",
CreateEmbed::new()
.title("Invitation supprimee")
.description(format!(
"Code: `{}`\nSalon: <#{}>",
data.code,
data.channel_id.get()
)),
)
.await;
}
pub async fn on_message_delete_bulk(
ctx: &Context,
channel_id: ChannelId,
multiple_deleted_messages_ids: &[MessageId],
guild_id: Option<GuildId>,
) {
let Some(guild_id) = guild_id else {
return;
};
if is_nolog_channel(ctx, guild_id, channel_id, "message").await {
return;
}
let ids_preview = multiple_deleted_messages_ids
.iter()
.take(10)
.map(|id| format!("`{}`", id.get()))
.collect::<Vec<_>>();
let hidden = multiple_deleted_messages_ids
.len()
.saturating_sub(ids_preview.len());
let mut description = format!(
"Salon: <#{}>\nTotal supprimes: {}",
channel_id.get(),
multiple_deleted_messages_ids.len()
);
if !ids_preview.is_empty() {
description.push_str(&format!("\nExemple IDs: {}", ids_preview.join(", ")));
}
if hidden > 0 {
description.push_str(&format!("\n... et {} autres", hidden));
}
send_log_embed(
ctx,
guild_id,
"message",
CreateEmbed::new()
.title("Suppression en masse")
.description(description),
)
.await;
}
pub async fn on_reaction_add(ctx: &Context, reaction: &Reaction) {
let Some(guild_id) = reaction.guild_id else {
return;
};
if is_nolog_channel(ctx, guild_id, reaction.channel_id, "message").await {
return;
}
let user = reaction
.user_id
.map(|id| format!("<@{}>", id.get()))
.unwrap_or_else(|| "Inconnu".to_string());
send_log_embed(
ctx,
guild_id,
"message",
CreateEmbed::new()
.title("Reaction ajoutee")
.description(format!(
"Salon: <#{}>\nMessage: `{}`\nUtilisateur: {}\nEmoji: `{:?}`",
reaction.channel_id.get(),
reaction.message_id.get(),
user,
reaction.emoji
)),
)
.await;
}
pub async fn on_reaction_remove(ctx: &Context, reaction: &Reaction) {
let Some(guild_id) = reaction.guild_id else {
return;
};
if is_nolog_channel(ctx, guild_id, reaction.channel_id, "message").await {
return;
}
let user = reaction
.user_id
.map(|id| format!("<@{}>", id.get()))
.unwrap_or_else(|| "Inconnu".to_string());
send_log_embed(
ctx,
guild_id,
"message",
CreateEmbed::new()
.title("Reaction retiree")
.description(format!(
"Salon: <#{}>\nMessage: `{}`\nUtilisateur: {}\nEmoji: `{:?}`",
reaction.channel_id.get(),
reaction.message_id.get(),
user,
reaction.emoji
)),
)
.await;
}
pub async fn on_reaction_remove_all(
ctx: &Context,
channel_id: ChannelId,
removed_from_message_id: MessageId,
) {
let Some(guild_id) = resolve_guild_id_from_channel(ctx, channel_id).await else {
return;
};
if is_nolog_channel(ctx, guild_id, channel_id, "message").await {
return;
}
send_log_embed(
ctx,
guild_id,
"message",
CreateEmbed::new()
.title("Toutes les reactions retirees")
.description(format!(
"Salon: <#{}>\nMessage: `{}`",
channel_id.get(),
removed_from_message_id.get()
)),
)
.await;
}
pub async fn on_reaction_remove_emoji(ctx: &Context, removed_reactions: &Reaction) {
let Some(guild_id) = removed_reactions.guild_id else {
return;
};
if is_nolog_channel(ctx, guild_id, removed_reactions.channel_id, "message").await {
return;
}
send_log_embed(
ctx,
guild_id,
"message",
CreateEmbed::new()
.title("Emoji de reaction retire")
.description(format!(
"Salon: <#{}>\nMessage: `{}`\nEmoji: `{:?}`",
removed_reactions.channel_id.get(),
removed_reactions.message_id.get(),
removed_reactions.emoji
)),
)
.await;
}
pub async fn on_webhook_update(ctx: &Context, guild_id: GuildId, belongs_to_channel_id: ChannelId) {
emit_log(
ctx,
guild_id,
"channel",
None,
Some(belongs_to_channel_id),
None,
"webhook_update",
CreateEmbed::new()
.title("Webhook mis a jour")
.description(format!("Salon: <#{}>", belongs_to_channel_id.get())),
)
.await;
}
pub async fn on_thread_create(ctx: &Context, thread: &GuildChannel) {
emit_log(
ctx,
thread.guild_id,
"channel",
thread.owner_id,
Some(thread.id),
None,
"thread_create",
CreateEmbed::new().title("Thread cree").description(format!(
"Thread: <#{}>\nNom: `{}`\nParent: {}",
thread.id.get(),
thread.name,
thread
.parent_id
.map(|id| format!("<#{}>", id.get()))
.unwrap_or_else(|| "Aucun".to_string())
)),
)
.await;
}
pub async fn on_thread_update(
ctx: &Context,
old_thread: Option<GuildChannel>,
new_thread: &GuildChannel,
) {
let mut changes = Vec::new();
if let Some(old_thread) = old_thread {
if old_thread.name != new_thread.name {
changes.push(format!(
"Nom: `{}` -> `{}`",
old_thread.name, new_thread.name
));
}
let old_archived = old_thread.thread_metadata.map(|meta| meta.archived);
let new_archived = new_thread.thread_metadata.map(|meta| meta.archived);
if old_archived != new_archived {
changes.push(format!(
"Archive: {} -> {}",
old_archived
.map(|value| value.to_string())
.unwrap_or_else(|| "inconnu".to_string()),
new_archived
.map(|value| value.to_string())
.unwrap_or_else(|| "inconnu".to_string())
));
}
if old_thread.rate_limit_per_user != new_thread.rate_limit_per_user {
changes.push(format!(
"Slowmode: {:?} -> {:?}",
old_thread.rate_limit_per_user, new_thread.rate_limit_per_user
));
}
}
if changes.is_empty() {
changes.push("Mise a jour detectee (details indisponibles).".to_string());
}
emit_log(
ctx,
new_thread.guild_id,
"channel",
new_thread.owner_id,
Some(new_thread.id),
None,
"thread_update",
CreateEmbed::new()
.title("Thread mis a jour")
.description(format!(
"Thread: <#{}>\n{}",
new_thread.id.get(),
changes.join("\n")
)),
)
.await;
}
pub async fn on_thread_delete(
ctx: &Context,
thread: &PartialGuildChannel,
full_thread_data: Option<&GuildChannel>,
) {
let name_or_id = full_thread_data
.map(|thread_data| format!("`{}`", thread_data.name))
.unwrap_or_else(|| format!("ID `{}`", thread.id.get()));
emit_log(
ctx,
thread.guild_id,
"channel",
None,
Some(thread.id),
None,
"thread_delete",
CreateEmbed::new()
.title("Thread supprime")
.description(format!("Thread: {}", name_or_id)),
)
.await;
}
pub async fn on_thread_list_sync(ctx: &Context, thread_list_sync: &ThreadListSyncEvent) {
let parents = thread_list_sync
.channel_ids
.as_ref()
.map(|ids| {
ids.iter()
.map(|id| format!("<#{}>", id.get()))
.collect::<Vec<_>>()
.join(", ")
})
.unwrap_or_else(|| "Tous les salons".to_string());
send_log_embed(
ctx,
thread_list_sync.guild_id,
"channel",
CreateEmbed::new().title("Thread sync").description(format!(
"Parents: {}\nThreads sync: {}\nMembres renvoyes: {}",
parents,
thread_list_sync.threads.len(),
thread_list_sync.members.len()
)),
)
.await;
}
pub async fn on_thread_member_update(ctx: &Context, thread_member: &ThreadMember) {
let Some(guild_id) = thread_member.guild_id else {
return;
};
emit_log(
ctx,
guild_id,
"channel",
Some(thread_member.user_id),
Some(thread_member.id),
None,
"thread_member_update",
CreateEmbed::new()
.title("Membre de thread mis a jour")
.description(format!(
"Thread: <#{}>\nUtilisateur: <@{}>",
thread_member.id.get(),
thread_member.user_id.get()
)),
)
.await;
}
pub async fn on_thread_members_update(ctx: &Context, event: &ThreadMembersUpdateEvent) {
let added = event
.added_members
.iter()
.map(|member| format!("<@{}>", member.user_id.get()))
.take(10)
.collect::<Vec<_>>();
let removed = event
.removed_member_ids
.iter()
.map(|user_id| format!("<@{}>", user_id.get()))
.take(10)
.collect::<Vec<_>>();
send_log_embed(
ctx,
event.guild_id,
"channel",
CreateEmbed::new()
.title("Membres du thread mis a jour")
.description(format!(
"Thread: <#{}>\nMembres approx: {}\nAjoutes: {}\nRetires: {}",
event.id.get(),
event.member_count,
if added.is_empty() {
"aucun".to_string()
} else {
added.join(", ")
},
if removed.is_empty() {
"aucun".to_string()
} else {
removed.join(", ")
}
)),
)
.await;
}
pub async fn on_auto_moderation_rule_create(ctx: &Context, rule: &Rule) {
emit_log(
ctx,
rule.guild_id,
"moderation",
Some(rule.creator_id),
None,
None,
"automod_rule_create",
CreateEmbed::new()
.title("AutoMod: regle creee")
.description(format!(
"Nom: `{}`\nID: `{}`\nActive: {}\nTrigger: `{:?}`\nActions: {}",
rule.name,
rule.id.get(),
rule.enabled,
rule.trigger.kind(),
rule.actions.len()
)),
)
.await;
}
pub async fn on_auto_moderation_rule_update(ctx: &Context, rule: &Rule) {
emit_log(
ctx,
rule.guild_id,
"moderation",
Some(rule.creator_id),
None,
None,
"automod_rule_update",
CreateEmbed::new()
.title("AutoMod: regle mise a jour")
.description(format!(
"Nom: `{}`\nID: `{}`\nActive: {}\nTrigger: `{:?}`\nActions: {}",
rule.name,
rule.id.get(),
rule.enabled,
rule.trigger.kind(),
rule.actions.len()
)),
)
.await;
}
pub async fn on_auto_moderation_rule_delete(ctx: &Context, rule: &Rule) {
emit_log(
ctx,
rule.guild_id,
"moderation",
Some(rule.creator_id),
None,
None,
"automod_rule_delete",
CreateEmbed::new()
.title("AutoMod: regle supprimee")
.description(format!(
"Nom: `{}`\nID: `{}`\nTrigger: `{:?}`",
rule.name,
rule.id.get(),
rule.trigger.kind()
)),
)
.await;
}
pub async fn on_auto_moderation_action_execution(ctx: &Context, execution: &ActionExecution) {
let channel = execution
.channel_id
.map(|id| format!("<#{}>", id.get()))
.unwrap_or_else(|| "inconnu".to_string());
emit_log(
ctx,
execution.guild_id,
"moderation",
Some(execution.user_id),
execution.channel_id,
None,
"automod_action_execution",
CreateEmbed::new()
.title("AutoMod: action executee")
.description(format!(
"Regle: `{}`\nUtilisateur: <@{}>\nSalon: {}\nAction: `{:?}`\nTrigger: `{:?}`\nMot cle: {}",
execution.rule_id.get(),
execution.user_id.get(),
channel,
execution.action.kind(),
execution.trigger_type,
execution
.matched_keyword
.as_deref()
.unwrap_or("(aucun)")
)),
)
.await;
}
pub async fn on_stage_instance_create(ctx: &Context, stage_instance: &StageInstance) {
emit_log(
ctx,
stage_instance.guild_id,
"voice",
None,
Some(stage_instance.channel_id),
None,
"stage_instance_create",
CreateEmbed::new().title("Stage cree").description(format!(
"Salon: <#{}>\nTopic: {}",
stage_instance.channel_id.get(),
stage_instance.topic
)),
)
.await;
}
pub async fn on_stage_instance_update(ctx: &Context, stage_instance: &StageInstance) {
emit_log(
ctx,
stage_instance.guild_id,
"voice",
None,
Some(stage_instance.channel_id),
None,
"stage_instance_update",
CreateEmbed::new()
.title("Stage mis a jour")
.description(format!(
"Salon: <#{}>\nTopic: {}",
stage_instance.channel_id.get(),
stage_instance.topic
)),
)
.await;
}
pub async fn on_stage_instance_delete(ctx: &Context, stage_instance: &StageInstance) {
emit_log(
ctx,
stage_instance.guild_id,
"voice",
None,
Some(stage_instance.channel_id),
None,
"stage_instance_delete",
CreateEmbed::new()
.title("Stage supprime")
.description(format!(
"Salon: <#{}>\nTopic: {}",
stage_instance.channel_id.get(),
stage_instance.topic
)),
)
.await;
}
pub async fn on_voice_channel_status_update(
ctx: &Context,
old: Option<String>,
status: Option<String>,
id: ChannelId,
guild_id: GuildId,
) {
if is_nolog_channel(ctx, guild_id, id, "voice").await {
return;
}
emit_log(
ctx,
guild_id,
"voice",
None,
Some(id),
None,
"voice_channel_status_update",
CreateEmbed::new()
.title("Statut vocal mis a jour")
.description(format!(
"Salon: <#{}>\nAvant: {}\nApres: {}",
id.get(),
old.as_deref().unwrap_or("(aucun)"),
status.as_deref().unwrap_or("(aucun)")
)),
)
.await;
}
pub async fn on_guild_scheduled_event_create(ctx: &Context, event: &ScheduledEvent) {
emit_log(
ctx,
event.guild_id,
"channel",
event.creator_id,
event.channel_id,
None,
"scheduled_event_create",
CreateEmbed::new()
.title("Evenement planifie cree")
.description(format!(
"Nom: `{}`\nID: `{}`\nDebut: {}\nStatut: `{:?}`",
event.name,
event.id.get(),
event.start_time,
event.status
)),
)
.await;
}
pub async fn on_guild_scheduled_event_update(ctx: &Context, event: &ScheduledEvent) {
emit_log(
ctx,
event.guild_id,
"channel",
event.creator_id,
event.channel_id,
None,
"scheduled_event_update",
CreateEmbed::new()
.title("Evenement planifie mis a jour")
.description(format!(
"Nom: `{}`\nID: `{}`\nDebut: {}\nStatut: `{:?}`",
event.name,
event.id.get(),
event.start_time,
event.status
)),
)
.await;
}
pub async fn on_guild_scheduled_event_delete(ctx: &Context, event: &ScheduledEvent) {
emit_log(
ctx,
event.guild_id,
"channel",
event.creator_id,
event.channel_id,
None,
"scheduled_event_delete",
CreateEmbed::new()
.title("Evenement planifie supprime")
.description(format!("Nom: `{}`\nID: `{}`", event.name, event.id.get())),
)
.await;
}
pub async fn on_guild_scheduled_event_user_add(
ctx: &Context,
subscribed: &GuildScheduledEventUserAddEvent,
) {
emit_log(
ctx,
subscribed.guild_id,
"raid",
Some(subscribed.user_id),
None,
None,
"scheduled_event_user_add",
CreateEmbed::new()
.title("Inscription evenement")
.description(format!(
"Utilisateur: <@{}>\nEvenement: `{}`",
subscribed.user_id.get(),
subscribed.scheduled_event_id.get()
)),
)
.await;
}
pub async fn on_guild_scheduled_event_user_remove(
ctx: &Context,
unsubscribed: &GuildScheduledEventUserRemoveEvent,
) {
emit_log(
ctx,
unsubscribed.guild_id,
"raid",
Some(unsubscribed.user_id),
None,
None,
"scheduled_event_user_remove",
CreateEmbed::new()
.title("Desinscription evenement")
.description(format!(
"Utilisateur: <@{}>\nEvenement: `{}`",
unsubscribed.user_id.get(),
unsubscribed.scheduled_event_id.get()
)),
)
.await;
}
pub async fn on_integration_create(ctx: &Context, integration: &Integration) {
let Some(guild_id) = integration.guild_id else {
return;
};
emit_log(
ctx,
guild_id,
"moderation",
integration.user.as_ref().map(|user| user.id),
None,
integration.role_id,
"integration_create",
CreateEmbed::new()
.title("Integration creee")
.description(format!(
"Nom: `{}`\nID: `{}`\nType: `{}`\nActive: {}",
integration.name,
integration.id.get(),
integration.kind,
integration.enabled
)),
)
.await;
}
pub async fn on_integration_update(ctx: &Context, integration: &Integration) {
let Some(guild_id) = integration.guild_id else {
return;
};
emit_log(
ctx,
guild_id,
"moderation",
integration.user.as_ref().map(|user| user.id),
None,
integration.role_id,
"integration_update",
CreateEmbed::new()
.title("Integration mise a jour")
.description(format!(
"Nom: `{}`\nID: `{}`\nType: `{}`\nActive: {}",
integration.name,
integration.id.get(),
integration.kind,
integration.enabled
)),
)
.await;
}
pub async fn on_integration_delete(
ctx: &Context,
integration_id: IntegrationId,
guild_id: GuildId,
application_id: Option<ApplicationId>,
) {
emit_log(
ctx,
guild_id,
"moderation",
None,
None,
None,
"integration_delete",
CreateEmbed::new()
.title("Integration supprimee")
.description(format!(
"Integration: `{}`\nApplication: {}",
integration_id.get(),
application_id
.map(|id| id.get().to_string())
.unwrap_or_else(|| "inconnue".to_string())
)),
)
.await;
}
pub async fn on_guild_integrations_update(ctx: &Context, guild_id: GuildId) {
send_log_embed(
ctx,
guild_id,
"moderation",
CreateEmbed::new()
.title("Integrations du serveur mises a jour")
.description("Discord a signale une mise a jour globale des integrations."),
)
.await;
}