use super::super::{Context, Result}; use poise::serenity_prelude as serenity; /// Main command for logging subcommands. /// /// This command cannot be called on its own and will do nothing by /// itself. /// /// # Errors /// /// This command will never error out, even if its signature says it /// can. #[allow(clippy::unused_async)] #[poise::command( slash_command, subcommands("add_channel", "list_channels", "remove_channel"), required_permissions = "ADMINISTRATOR" )] pub async fn logging(_ctx: Context<'_>) -> Result { Ok(()) } /// Add a channel as a logger. /// /// # Errors /// /// This function will return an error if . #[poise::command(slash_command)] async fn add_channel( ctx: Context<'_>, #[description = "New logging channel"] channel: serenity::Channel, ) -> Result { let channel_id = channel.id(); let response = match ctx.guild_id() { None => "Error: Could not determine the guild's ID".to_owned(), Some(guild_id) => { match ctx .data() .database .set_logging_channel(guild_id, channel_id) .await { Ok(()) => format!( "Added channel <#{channel_id}> as a logging channel" ), Err(e) => { if let Some(db_error) = e.as_database_error() { if db_error.is_unique_violation() { format!("Channel <#{channel_id}> is already a logging channel") } else { format!("Error: {e:?}") } } else { format!( "Something bad happened with the database: {e:?}" ) } } } } }; ctx.say(response).await?; Ok(()) } /// List all channels registered as loggers for a guild. /// /// This will list all channels that are logger channels in the server /// from which the command was executed. /// /// # Errors /// /// This function will return an error if the database returns one. #[poise::command(slash_command)] async fn list_channels(ctx: Context<'_>) -> Result { let response = match ctx.guild_id() { None => "Error: Could not determine the guild's ID".to_owned(), Some(guild_id) => { match ctx.data().database.get_logging_channels(guild_id).await { Err(e) => format!("Could not retrieve loggers: {e:?}"), Ok(channels) => { if channels.is_empty() { "No channels registered as loggers".to_owned() } else { format!( "Here are the channels currently set as loggers:\n{}", channels .iter() .map(|channel| format!("- <#{channel}>")) .collect::>() .join("\n") ) } } } } }; ctx.say(response).await?; Ok(()) } /// Remove a channel as a logger in a guild. /// /// This will remove a channel from the list of logger channels in the /// guild from which the command was executed. If the channel is not a /// logger, the bot will still consider unsetting the channel as a /// logger a success. /// /// # Errors /// /// This function will return an error if the database errors. #[poise::command(slash_command)] async fn remove_channel( ctx: Context<'_>, #[description = "Logger channel to remove"] channel: serenity::Channel, ) -> Result { let channel_id = channel.id(); let response = match ctx.guild_id() { None => "Error: Could not determine the guild's ID".to_owned(), Some(guild_id) => { match ctx .data() .database .remove_logging_channel(guild_id, channel_id) .await { Ok(()) => { format!("Removed channel <#{channel_id}> as a logger") } Err(e) => { format!("Could not remove channel as a logger: {e:?}") } } } }; ctx.say(response).await?; Ok(()) }