From dc07a10c9ff240e6f238cfc976b20259f6194ebf Mon Sep 17 00:00:00 2001 From: Puechberty Arthur Date: Fri, 10 Apr 2026 19:05:00 +0200 Subject: [PATCH] add log events --- .../auto_moderation_action_execution.rs | 8 + src/events/auto_moderation_rule_create.rs | 8 + src/events/auto_moderation_rule_delete.rs | 8 + src/events/auto_moderation_rule_update.rs | 8 + src/events/channel_pins_update.rs | 8 + src/events/guild_ban_addition.rs | 8 + src/events/guild_ban_removal.rs | 8 + src/events/guild_integrations_update.rs | 8 + src/events/guild_scheduled_event_create.rs | 8 + src/events/guild_scheduled_event_delete.rs | 8 + src/events/guild_scheduled_event_update.rs | 8 + src/events/guild_scheduled_event_user_add.rs | 11 + .../guild_scheduled_event_user_remove.rs | 11 + src/events/integration_create.rs | 8 + src/events/integration_delete.rs | 13 + src/events/integration_update.rs | 8 + src/events/invite_create.rs | 8 + src/events/invite_delete.rs | 8 + src/events/message_delete_bulk.rs | 14 + src/events/mod.rs | 34 + src/events/reaction_add.rs | 8 + src/events/reaction_remove.rs | 8 + src/events/reaction_remove_all.rs | 12 + src/events/reaction_remove_emoji.rs | 8 + src/events/stage_instance_create.rs | 8 + src/events/stage_instance_delete.rs | 8 + src/events/stage_instance_update.rs | 8 + src/events/thread_create.rs | 8 + src/events/thread_delete.rs | 12 + src/events/thread_list_sync.rs | 8 + src/events/thread_member_update.rs | 8 + src/events/thread_members_update.rs | 8 + src/events/thread_update.rs | 8 + src/events/voice_channel_status_update.rs | 14 + src/events/webhook_update.rs | 12 + src/utils/events_handler.rs | 215 ++++- src/utils/logs_service.rs | 891 ++++++++++++++++++ 37 files changed, 1444 insertions(+), 3 deletions(-) create mode 100644 src/events/auto_moderation_action_execution.rs create mode 100644 src/events/auto_moderation_rule_create.rs create mode 100644 src/events/auto_moderation_rule_delete.rs create mode 100644 src/events/auto_moderation_rule_update.rs create mode 100644 src/events/channel_pins_update.rs create mode 100644 src/events/guild_ban_addition.rs create mode 100644 src/events/guild_ban_removal.rs create mode 100644 src/events/guild_integrations_update.rs create mode 100644 src/events/guild_scheduled_event_create.rs create mode 100644 src/events/guild_scheduled_event_delete.rs create mode 100644 src/events/guild_scheduled_event_update.rs create mode 100644 src/events/guild_scheduled_event_user_add.rs create mode 100644 src/events/guild_scheduled_event_user_remove.rs create mode 100644 src/events/integration_create.rs create mode 100644 src/events/integration_delete.rs create mode 100644 src/events/integration_update.rs create mode 100644 src/events/invite_create.rs create mode 100644 src/events/invite_delete.rs create mode 100644 src/events/message_delete_bulk.rs create mode 100644 src/events/reaction_add.rs create mode 100644 src/events/reaction_remove.rs create mode 100644 src/events/reaction_remove_all.rs create mode 100644 src/events/reaction_remove_emoji.rs create mode 100644 src/events/stage_instance_create.rs create mode 100644 src/events/stage_instance_delete.rs create mode 100644 src/events/stage_instance_update.rs create mode 100644 src/events/thread_create.rs create mode 100644 src/events/thread_delete.rs create mode 100644 src/events/thread_list_sync.rs create mode 100644 src/events/thread_member_update.rs create mode 100644 src/events/thread_members_update.rs create mode 100644 src/events/thread_update.rs create mode 100644 src/events/voice_channel_status_update.rs create mode 100644 src/events/webhook_update.rs diff --git a/src/events/auto_moderation_action_execution.rs b/src/events/auto_moderation_action_execution.rs new file mode 100644 index 0000000..eae4807 --- /dev/null +++ b/src/events/auto_moderation_action_execution.rs @@ -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; +} diff --git a/src/events/auto_moderation_rule_create.rs b/src/events/auto_moderation_rule_create.rs new file mode 100644 index 0000000..5344ba8 --- /dev/null +++ b/src/events/auto_moderation_rule_create.rs @@ -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; +} diff --git a/src/events/auto_moderation_rule_delete.rs b/src/events/auto_moderation_rule_delete.rs new file mode 100644 index 0000000..b96a5b2 --- /dev/null +++ b/src/events/auto_moderation_rule_delete.rs @@ -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; +} diff --git a/src/events/auto_moderation_rule_update.rs b/src/events/auto_moderation_rule_update.rs new file mode 100644 index 0000000..ad4ecc4 --- /dev/null +++ b/src/events/auto_moderation_rule_update.rs @@ -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; +} diff --git a/src/events/channel_pins_update.rs b/src/events/channel_pins_update.rs new file mode 100644 index 0000000..6bda145 --- /dev/null +++ b/src/events/channel_pins_update.rs @@ -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; +} diff --git a/src/events/guild_ban_addition.rs b/src/events/guild_ban_addition.rs new file mode 100644 index 0000000..b499ed2 --- /dev/null +++ b/src/events/guild_ban_addition.rs @@ -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; +} diff --git a/src/events/guild_ban_removal.rs b/src/events/guild_ban_removal.rs new file mode 100644 index 0000000..f8fa1f0 --- /dev/null +++ b/src/events/guild_ban_removal.rs @@ -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; +} diff --git a/src/events/guild_integrations_update.rs b/src/events/guild_integrations_update.rs new file mode 100644 index 0000000..23aa40b --- /dev/null +++ b/src/events/guild_integrations_update.rs @@ -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; +} diff --git a/src/events/guild_scheduled_event_create.rs b/src/events/guild_scheduled_event_create.rs new file mode 100644 index 0000000..d978632 --- /dev/null +++ b/src/events/guild_scheduled_event_create.rs @@ -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; +} diff --git a/src/events/guild_scheduled_event_delete.rs b/src/events/guild_scheduled_event_delete.rs new file mode 100644 index 0000000..40c709e --- /dev/null +++ b/src/events/guild_scheduled_event_delete.rs @@ -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; +} diff --git a/src/events/guild_scheduled_event_update.rs b/src/events/guild_scheduled_event_update.rs new file mode 100644 index 0000000..b1b4340 --- /dev/null +++ b/src/events/guild_scheduled_event_update.rs @@ -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; +} diff --git a/src/events/guild_scheduled_event_user_add.rs b/src/events/guild_scheduled_event_user_add.rs new file mode 100644 index 0000000..7199247 --- /dev/null +++ b/src/events/guild_scheduled_event_user_add.rs @@ -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; +} diff --git a/src/events/guild_scheduled_event_user_remove.rs b/src/events/guild_scheduled_event_user_remove.rs new file mode 100644 index 0000000..c89c768 --- /dev/null +++ b/src/events/guild_scheduled_event_user_remove.rs @@ -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; +} diff --git a/src/events/integration_create.rs b/src/events/integration_create.rs new file mode 100644 index 0000000..18daede --- /dev/null +++ b/src/events/integration_create.rs @@ -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; +} diff --git a/src/events/integration_delete.rs b/src/events/integration_delete.rs new file mode 100644 index 0000000..75a675d --- /dev/null +++ b/src/events/integration_delete.rs @@ -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, +) { + logs_service::on_integration_delete(ctx, integration_id, guild_id, application_id).await; +} diff --git a/src/events/integration_update.rs b/src/events/integration_update.rs new file mode 100644 index 0000000..407a2dc --- /dev/null +++ b/src/events/integration_update.rs @@ -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; +} diff --git a/src/events/invite_create.rs b/src/events/invite_create.rs new file mode 100644 index 0000000..aa8e27e --- /dev/null +++ b/src/events/invite_create.rs @@ -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; +} diff --git a/src/events/invite_delete.rs b/src/events/invite_delete.rs new file mode 100644 index 0000000..62d30f5 --- /dev/null +++ b/src/events/invite_delete.rs @@ -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; +} diff --git a/src/events/message_delete_bulk.rs b/src/events/message_delete_bulk.rs new file mode 100644 index 0000000..13b9015 --- /dev/null +++ b/src/events/message_delete_bulk.rs @@ -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, +) { + logs_service::on_message_delete_bulk(ctx, channel_id, multiple_deleted_messages_ids, guild_id) + .await; +} diff --git a/src/events/mod.rs b/src/events/mod.rs index 343eedd..e536a7d 100644 --- a/src/events/mod.rs +++ b/src/events/mod.rs @@ -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_delete; +pub mod channel_pins_update; pub mod channel_update; +pub mod guild_ban_addition; +pub mod guild_ban_removal; pub mod guild_create; +pub mod guild_integrations_update; pub mod guild_member_addition; pub mod guild_member_removal; 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"] pub mod handler; +pub mod integration_create; +pub mod integration_delete; +pub mod integration_update; pub mod interaction_create; +pub mod invite_create; +pub mod invite_delete; pub mod message; pub mod message_delete; +pub mod message_delete_bulk; 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 role_create; pub mod role_delete; 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 webhook_update; diff --git a/src/events/reaction_add.rs b/src/events/reaction_add.rs new file mode 100644 index 0000000..34a9640 --- /dev/null +++ b/src/events/reaction_add.rs @@ -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; +} diff --git a/src/events/reaction_remove.rs b/src/events/reaction_remove.rs new file mode 100644 index 0000000..85b4b12 --- /dev/null +++ b/src/events/reaction_remove.rs @@ -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; +} diff --git a/src/events/reaction_remove_all.rs b/src/events/reaction_remove_all.rs new file mode 100644 index 0000000..a61f5e3 --- /dev/null +++ b/src/events/reaction_remove_all.rs @@ -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; +} diff --git a/src/events/reaction_remove_emoji.rs b/src/events/reaction_remove_emoji.rs new file mode 100644 index 0000000..ef642b3 --- /dev/null +++ b/src/events/reaction_remove_emoji.rs @@ -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; +} diff --git a/src/events/stage_instance_create.rs b/src/events/stage_instance_create.rs new file mode 100644 index 0000000..0954840 --- /dev/null +++ b/src/events/stage_instance_create.rs @@ -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; +} diff --git a/src/events/stage_instance_delete.rs b/src/events/stage_instance_delete.rs new file mode 100644 index 0000000..0a1672a --- /dev/null +++ b/src/events/stage_instance_delete.rs @@ -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; +} diff --git a/src/events/stage_instance_update.rs b/src/events/stage_instance_update.rs new file mode 100644 index 0000000..afd5324 --- /dev/null +++ b/src/events/stage_instance_update.rs @@ -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; +} diff --git a/src/events/thread_create.rs b/src/events/thread_create.rs new file mode 100644 index 0000000..b19d153 --- /dev/null +++ b/src/events/thread_create.rs @@ -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; +} diff --git a/src/events/thread_delete.rs b/src/events/thread_delete.rs new file mode 100644 index 0000000..a3cdf30 --- /dev/null +++ b/src/events/thread_delete.rs @@ -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; +} diff --git a/src/events/thread_list_sync.rs b/src/events/thread_list_sync.rs new file mode 100644 index 0000000..564b072 --- /dev/null +++ b/src/events/thread_list_sync.rs @@ -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; +} diff --git a/src/events/thread_member_update.rs b/src/events/thread_member_update.rs new file mode 100644 index 0000000..8d45515 --- /dev/null +++ b/src/events/thread_member_update.rs @@ -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; +} diff --git a/src/events/thread_members_update.rs b/src/events/thread_members_update.rs new file mode 100644 index 0000000..d1ae39a --- /dev/null +++ b/src/events/thread_members_update.rs @@ -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; +} diff --git a/src/events/thread_update.rs b/src/events/thread_update.rs new file mode 100644 index 0000000..f6f5273 --- /dev/null +++ b/src/events/thread_update.rs @@ -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, new: &GuildChannel) { + logs_service::on_thread_update(ctx, old, new).await; +} diff --git a/src/events/voice_channel_status_update.rs b/src/events/voice_channel_status_update.rs new file mode 100644 index 0000000..54533bb --- /dev/null +++ b/src/events/voice_channel_status_update.rs @@ -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, + status: Option, + id: ChannelId, + guild_id: GuildId, +) { + logs_service::on_voice_channel_status_update(ctx, old, status, id, guild_id).await; +} diff --git a/src/events/webhook_update.rs b/src/events/webhook_update.rs new file mode 100644 index 0000000..c757b44 --- /dev/null +++ b/src/events/webhook_update.rs @@ -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; +} diff --git a/src/utils/events_handler.rs b/src/utils/events_handler.rs index 375f656..ba12724 100644 --- a/src/utils/events_handler.rs +++ b/src/utils/events_handler.rs @@ -3,9 +3,18 @@ use serenity::model::prelude::*; use serenity::prelude::*; use crate::events::{ - channel_create, channel_delete, channel_update, guild_create, guild_member_addition, - guild_member_removal, guild_member_update, interaction_create, message, message_delete, - message_update, ready, role_create, role_delete, role_update, voice_state_update, + auto_moderation_action_execution, auto_moderation_rule_create, auto_moderation_rule_delete, + auto_moderation_rule_update, channel_create, channel_delete, channel_pins_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; @@ -121,4 +130,204 @@ impl EventHandler for Handler { ) { channel_delete::handle_channel_delete(&ctx, &channel).await; } + + async fn message_delete_bulk( + &self, + ctx: Context, + channel_id: ChannelId, + multiple_deleted_messages_ids: Vec, + guild_id: Option, + ) { + 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, new: GuildChannel) { + thread_update::handle_thread_update(&ctx, old, &new).await; + } + + async fn thread_delete( + &self, + ctx: Context, + thread: PartialGuildChannel, + full_thread_data: Option, + ) { + 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, + status: Option, + 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, + ) { + 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; + } } diff --git a/src/utils/logs_service.rs b/src/utils/logs_service.rs index 6ce44ed..c041521 100644 --- a/src/utils/logs_service.rs +++ b/src/utils/logs_service.rs @@ -659,3 +659,894 @@ pub async fn on_channel_update(ctx: &Context, old_data: Option, ne ) .await; } + +async fn resolve_guild_id_from_channel(ctx: &Context, channel_id: ChannelId) -> Option { + 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, +) { + 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::>(); + 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, + 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::>() + .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::>(); + let removed = event + .removed_member_ids + .iter() + .map(|user_id| format!("<@{}>", user_id.get())) + .take(10) + .collect::>(); + + 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, + status: Option, + 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, +) { + 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; +}