Files
reminder-bot/src/hooks.rs
2025-06-18 22:08:32 +01:00

145 lines
6.5 KiB
Rust

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};
async fn macro_check(ctx: Context<'_>) -> bool {
if let Context::Application(app_ctx) = ctx {
if app_ctx.interaction_type != CommandInteractionType::Command {
return true;
}
if let Some(guild_id) = ctx.guild_id() {
if ctx.command().identifying_name != "finish_macro" {
let mut lock = ctx.data().recording_macros.write().await;
if let Some(command_macro) = lock.get_mut(&(guild_id, ctx.author().id)) {
if command_macro.commands.len() >= MACRO_MAX_COMMANDS {
let _ = ctx
.send(
CreateReply::default()
.ephemeral(true)
.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 {
match RecordedCommand::from_context(app_ctx) {
Some(recorded) => {
command_macro.commands.push(recorded);
let _ = ctx
.send(
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;
}
None => {
let _ = ctx
.send(
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;
}
}
}
return false;
}
}
}
}
true
}
async fn check_self_permissions(ctx: Context<'_>) -> bool {
let user_id = ctx.serenity_context().cache.current_user().id;
let app_permissions = match ctx {
Context::Application(app_ctx) => app_ctx.interaction.app_permissions,
_ => None,
};
match ctx.guild().map(|g| g.to_owned()) {
Some(guild) => {
let manage_webhooks = guild
.member(&ctx, user_id)
.await
.map_or(false, |m| m.permissions(&ctx).map_or(false, |p| p.manage_webhooks()));
if let Some(permissions) = app_permissions {
return if permissions.send_messages()
&& permissions.embed_links()
&& manage_webhooks
&& permissions.view_channel()
{
true
} else {
let _ = ctx
.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",
if permissions.view_channel() { "" } else { "" },
if permissions.send_messages() { "" } else { "" },
if permissions.embed_links() { "" } else { "" },
if manage_webhooks { "" } else { "" },
)))
.await;
false
};
}
manage_webhooks
}
None => true,
}
}
pub async fn all_checks(ctx: Context<'_>) -> Result<bool, Error> {
Ok(macro_check(ctx).await && check_self_permissions(ctx).await)
}