diff --git a/src/commands/command_macro/record_macro.rs b/src/commands/command_macro/record_macro.rs index b60bcec..d51561f 100644 --- a/src/commands/command_macro/record_macro.rs +++ b/src/commands/command_macro/record_macro.rs @@ -75,8 +75,8 @@ Please select a unique name for your macro.", CreateEmbed::new() .title("Macro Recording Started") .description( - "Run up to 5 commands, or type `/macro finish` to stop at any point. -Any commands ran as part of recording will be inconsequential", + "Run up to 5 commands to record in this macro. Use `/macro finish` to stop recording at any point. +Any commands performed during recording won't take any actual action- they are only captured for the macro.", ) .color(*THEME_COLOR), ), diff --git a/src/hooks.rs b/src/hooks.rs index d122a0b..2372485 100644 --- a/src/hooks.rs +++ b/src/hooks.rs @@ -1,4 +1,6 @@ -use poise::{CommandInteractionType, CreateReply}; +use crate::consts::THEME_COLOR; +use poise::{serenity_prelude::CreateEmbed, CommandInteractionType, CreateReply}; +use serenity::builder::CreateEmbedFooter; use crate::{consts::MACRO_MAX_COMMANDS, models::command_macro::RecordedCommand, Context, Error}; @@ -18,7 +20,18 @@ async fn macro_check(ctx: Context<'_>) -> bool { .send( CreateReply::default() .ephemeral(true) - .content(format!("{} commands already recorded. Please use `/macro finish` to end recording.", MACRO_MAX_COMMANDS)) + .embed(CreateEmbed::new() + .title("💾 Currently recording macro") + .description( + format!("{} commands already recorded. Please use `/macro finish` to end recording.", MACRO_MAX_COMMANDS), + ) + .footer( + CreateEmbedFooter::new( + "Any commands performed during recording won't take any actual action- they are only captured for the macro" + ) + ) + .color(*THEME_COLOR), + ), ) .await; } else { @@ -28,9 +41,19 @@ async fn macro_check(ctx: Context<'_>) -> bool { let _ = ctx .send( - CreateReply::default() - .ephemeral(true) - .content("Command recorded to macro"), + CreateReply::default().ephemeral(true).embed( + CreateEmbed::new() + .title("💾 Currently recording macro") + .description( + "Command recorded. Use `/macro finish` to end recording.", + ) + .footer( + CreateEmbedFooter::new( + "Any commands performed during recording won't take any actual action- they are only captured for the macro" + ) + ) + .color(*THEME_COLOR), + ), ) .await; } @@ -38,8 +61,18 @@ async fn macro_check(ctx: Context<'_>) -> bool { None => { let _ = ctx .send( - CreateReply::default().ephemeral(true).content( - "This command is not supported in macros yet.", + CreateReply::default().ephemeral(true).embed( + CreateEmbed::new() + .title("💾 Currently recording macro") + .description( + "This command is not supported in macros, so it hasn't been recorded. Use `/macro finish` to end recording.", + ) + .footer( + CreateEmbedFooter::new( + "Any commands performed during recording won't take any actual action- they are only captured for the macro" + ) + ) + .color(*THEME_COLOR), ), ) .await; @@ -74,6 +107,7 @@ async fn check_self_permissions(ctx: Context<'_>) -> bool { return if permissions.send_messages() && permissions.embed_links() && manage_webhooks + && permissions.view_channel() { true } else { @@ -81,12 +115,13 @@ async fn check_self_permissions(ctx: Context<'_>) -> bool { .send(CreateReply::default().content(format!( "The bot appears to be missing some permissions: +{} **View Channels** {} **Send Message** {} **Embed Links** {} **Manage Webhooks** -Please check the bot's roles, and any channel overrides. Alternatively, giving the bot -\"Administrator\" will bypass permission checks", +Please check the bot's roles, and any channel overrides. Alternatively, giving the bot \"Administrator\" will bypass permission checks", + if permissions.view_channel() { "✅" } else { "❌" }, if permissions.send_messages() { "✅" } else { "❌" }, if permissions.embed_links() { "✅" } else { "❌" }, if manage_webhooks { "✅" } else { "❌" }, @@ -100,9 +135,7 @@ Please check the bot's roles, and any channel overrides. Alternatively, giving t manage_webhooks } - None => { - return true; - } + None => true, } } diff --git a/src/web/mod.rs b/src/web/mod.rs index 0d2aed8..19be638 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -92,6 +92,8 @@ enum Error { SQLx(sqlx::Error), #[allow(unused)] Serenity(serenity::Error), + #[allow(unused)] + MissingDiscordPermission(&'static str), } pub async fn initialize( diff --git a/src/web/routes/dashboard/api/guild/reminders.rs b/src/web/routes/dashboard/api/guild/reminders.rs index c6ba793..691f329 100644 --- a/src/web/routes/dashboard/api/guild/reminders.rs +++ b/src/web/routes/dashboard/api/guild/reminders.rs @@ -305,7 +305,15 @@ pub async fn edit_reminder( Err(e) => { warn!("`create_database_channel` returned an error code: {:?}", e); - error.push("Failed to configure channel for reminders. Please check the bot permissions".to_string()); + // Provide more specific error messages based on the error type + match e { + crate::web::Error::MissingDiscordPermission(permission) => { + error.push(format!("Please ensure the bot has the \"{}\" permission in the channel", permission)); + } + _ => { + error.push("Failed to configure channel for reminders. Please check the bot permissions".to_string()); + } + } } } } diff --git a/src/web/routes/dashboard/api/user/models.rs b/src/web/routes/dashboard/api/user/models.rs index 1e4d1aa..8705fef 100644 --- a/src/web/routes/dashboard/api/user/models.rs +++ b/src/web/routes/dashboard/api/user/models.rs @@ -65,7 +65,16 @@ pub async fn create_reminder( if let Err(e) = channel { warn!("`create_database_channel` returned an error code: {:?}", e); - return Err(json!({"error": "Failed to configure channel for reminders."})); + // Provide more specific error messages based on the error type + let error_msg = match e { + Error::MissingDiscordPermission(permission) => format!( + "Please ensure the bot has the \"{}\" permission in the channel", + permission + ), + _ => "Failed to configure channel for reminders.".to_string(), + }; + + return Err(json!({"error": error_msg})); } let channel = channel.unwrap(); diff --git a/src/web/routes/dashboard/mod.rs b/src/web/routes/dashboard/mod.rs index efaf41a..745d132 100644 --- a/src/web/routes/dashboard/mod.rs +++ b/src/web/routes/dashboard/mod.rs @@ -10,6 +10,7 @@ use rocket::{ use rocket_dyn_templates::Template; use secrecy::ExposeSecret; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; +use serenity::http::HttpError; use serenity::{ all::CacheHttp, builder::CreateWebhook, @@ -404,9 +405,19 @@ pub(crate) async fn create_reminder( if let Err(e) = channel { warn!("`create_database_channel` returned an error code: {:?}", e); - return Err( - json!({"error": "Failed to configure channel for reminders. Please check the bot permissions"}), - ); + // Provide more specific error messages based on the error type + let error_msg = match e { + Error::MissingDiscordPermission(permission) => { + format!( + "Please ensure the bot has the \"{}\" permission in the channel", + permission + ) + } + _ => "Failed to configure channel for reminders. Please check the bot permissions" + .to_string(), + }; + + return Err(json!({"error": error_msg})); } let channel = channel.unwrap(); @@ -716,13 +727,36 @@ async fn create_database_channel( match row { Ok(row) => { - let is_dm = - channel.to_channel(&ctx).await.map_err(|e| Error::Serenity(e))?.private().is_some(); + let is_dm = channel + .to_channel(&ctx) + .await + .map_err(|e| { + if let serenity::Error::Http(http_error) = &e { + if let HttpError::UnsuccessfulRequest(response) = http_error { + if response.error.code == 50001 { + return Error::MissingDiscordPermission("View Channel"); + } + } + } + + Error::Serenity(e) + })? + .private() + .is_some(); if !is_dm && (row.webhook_token.is_none() || row.webhook_id.is_none()) { let webhook = channel .create_webhook(&ctx, CreateWebhook::new("Reminder").avatar(&*DEFAULT_AVATAR)) .await - .map_err(|e| Error::Serenity(e))?; + .map_err(|e| match &e { + serenity::Error::Http(HttpError::UnsuccessfulRequest(response)) => { + match response.error.code { + 50001 => Error::MissingDiscordPermission("View Channel"), + 50013 => Error::MissingDiscordPermission("Manage Webhooks"), + _ => Error::Serenity(e), + } + } + _ => Error::Serenity(e), + })?; let token = webhook.token.unwrap(); @@ -747,7 +781,16 @@ async fn create_database_channel( let webhook = channel .create_webhook(&ctx, CreateWebhook::new("Reminder").avatar(&*DEFAULT_AVATAR)) .await - .map_err(|e| Error::Serenity(e))?; + .map_err(|e| match &e { + serenity::Error::Http(HttpError::UnsuccessfulRequest(response)) => { + match response.error.code { + 50001 => Error::MissingDiscordPermission("View Channel"), + 50013 => Error::MissingDiscordPermission("Manage Webhooks"), + _ => Error::Serenity(e), + } + } + _ => Error::Serenity(e), + })?; let token = webhook.token.unwrap();