feat: create a BotDataManager abstraction by copying and pasting then editing UserDataManager
This commit is contained in:
185
src/command/info.rs
Normal file
185
src/command/info.rs
Normal file
@@ -0,0 +1,185 @@
|
||||
use futures::TryStreamExt;
|
||||
use snafu::{OptionExt, Snafu};
|
||||
use std::sync::LazyLock;
|
||||
use twilight_model::{
|
||||
application::{
|
||||
command::{Command, CommandType},
|
||||
interaction::Interaction,
|
||||
},
|
||||
channel::message::{Embed, MessageFlags},
|
||||
http::interaction::{InteractionResponse, InteractionResponseType},
|
||||
id::{Id, marker::UserMarker},
|
||||
};
|
||||
use twilight_util::builder::{
|
||||
InteractionResponseDataBuilder,
|
||||
command::CommandBuilder,
|
||||
embed::{EmbedAuthorBuilder, EmbedBuilder, EmbedFieldBuilder},
|
||||
};
|
||||
|
||||
use crate::command::State;
|
||||
|
||||
const NAME: &str = "info";
|
||||
const DESCRIPTION: &str = "Show various information";
|
||||
|
||||
pub static COMMAND: LazyLock<Command> = LazyLock::new(|| {
|
||||
CommandBuilder::new(NAME, DESCRIPTION, CommandType::ChatInput)
|
||||
.validate()
|
||||
.expect("command wasn't correct")
|
||||
.build()
|
||||
});
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
enum NoPermission {
|
||||
/// there isn't a user who invoked this command
|
||||
NoUser,
|
||||
|
||||
/// the user isn't allowed to use this command because they're not the bot owner
|
||||
NotInvokedByBotOwner,
|
||||
}
|
||||
|
||||
fn no_permission_to_embed(error: NoPermission) -> Embed {
|
||||
match error {
|
||||
NoPermission::NoUser => {
|
||||
EmbedBuilder::new().title("Not invoked by a user").description("This command works by joining the same VC as the user, but this bot didn't receive any user data. So did no user invoke it?! (This error should be impossible!)").validate().unwrap().build()
|
||||
},
|
||||
NoPermission::NotInvokedByBotOwner => {
|
||||
EmbedBuilder::new().title("No permission to see debug info").description("Only the owner of this bot is allowed to see its information for debugging purposes.").validate().unwrap().build()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn check_permission(
|
||||
interaction: &Interaction,
|
||||
bot_owner_user_id: Id<UserMarker>,
|
||||
) -> Result<(), NoPermission> {
|
||||
let user_id = interaction
|
||||
.member
|
||||
.as_ref()
|
||||
.and_then(|member| member.user.as_ref().map(|user| user.id))
|
||||
.context(NoUserSnafu)?;
|
||||
|
||||
if user_id != bot_owner_user_id {
|
||||
return Err(NoPermission::NotInvokedByBotOwner);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub async fn handle(state: State, interaction: Interaction) {
|
||||
if let Err(no_permission) = check_permission(&interaction, state.discord_bot_owner_user_id) {
|
||||
state
|
||||
.discord_client
|
||||
.interaction(state.discord_application_id)
|
||||
.create_response(
|
||||
interaction.id,
|
||||
&interaction.token,
|
||||
&InteractionResponse {
|
||||
kind: InteractionResponseType::ChannelMessageWithSource,
|
||||
data: Some(
|
||||
InteractionResponseDataBuilder::new()
|
||||
.embeds([no_permission_to_embed(no_permission)])
|
||||
.flags(MessageFlags::EPHEMERAL)
|
||||
.build(),
|
||||
),
|
||||
},
|
||||
)
|
||||
.await
|
||||
.expect("TODO");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
state
|
||||
.discord_client
|
||||
.interaction(state.discord_application_id)
|
||||
.create_response(
|
||||
interaction.id,
|
||||
&interaction.token,
|
||||
&InteractionResponse {
|
||||
kind: InteractionResponseType::ChannelMessageWithSource,
|
||||
data: Some(
|
||||
InteractionResponseDataBuilder::new()
|
||||
.flags(MessageFlags::EPHEMERAL)
|
||||
.content("some debug info is coming your way!")
|
||||
.build(),
|
||||
),
|
||||
},
|
||||
)
|
||||
.await
|
||||
.expect("TODO");
|
||||
|
||||
let heat_script_description = state
|
||||
.bot_data_manager
|
||||
.with(|bot_data| {
|
||||
let heat_script_option = bot_data.has_heat_script().then(|| {
|
||||
bot_data
|
||||
.get_heat_script()
|
||||
.expect("TODO")
|
||||
.to_string()
|
||||
.expect("TODO")
|
||||
});
|
||||
heat_script_option.map_or("none set yet".into(), |heat_script| {
|
||||
format!("```\n{heat_script}\n```")
|
||||
})
|
||||
})
|
||||
.await
|
||||
.expect("TODO");
|
||||
|
||||
state
|
||||
.discord_client
|
||||
.interaction(state.discord_application_id)
|
||||
.create_followup(&interaction.token)
|
||||
.embeds(&[EmbedBuilder::new()
|
||||
.field(EmbedFieldBuilder::new("Heat Script", heat_script_description).build())
|
||||
.validate()
|
||||
.unwrap()
|
||||
.build()])
|
||||
.flags(MessageFlags::EPHEMERAL)
|
||||
.await
|
||||
.expect("TODO");
|
||||
|
||||
let mut user_id_stream = state.user_data_manager.list().await.expect("TODO");
|
||||
|
||||
while let Some(user_id) = user_id_stream.try_next().await.expect("TODO") {
|
||||
let (consent, notification_script) = state
|
||||
.user_data_manager
|
||||
.with(user_id, |user_data| {
|
||||
let consent = user_data.get_voice_recording_consent().unwrap();
|
||||
let notification_script = user_data.has_notification_script().then_some(
|
||||
user_data
|
||||
.get_notification_script()
|
||||
.expect("TODO")
|
||||
.to_string()
|
||||
.expect("TODO"),
|
||||
);
|
||||
|
||||
(consent, notification_script)
|
||||
})
|
||||
.await
|
||||
.expect("TODO");
|
||||
|
||||
let user_mention = format!("<@{user_id}>");
|
||||
|
||||
state
|
||||
.discord_client
|
||||
.interaction(state.discord_application_id)
|
||||
.create_followup(&interaction.token)
|
||||
.embeds(&[EmbedBuilder::new()
|
||||
.author(EmbedAuthorBuilder::new(user_mention))
|
||||
.field(EmbedFieldBuilder::new("Consent", format!("{consent:?}")).build())
|
||||
.field(
|
||||
EmbedFieldBuilder::new(
|
||||
"Notification Script",
|
||||
format!("{notification_script:?}"),
|
||||
)
|
||||
.build(),
|
||||
)
|
||||
.validate()
|
||||
.unwrap()
|
||||
.build()])
|
||||
.flags(MessageFlags::EPHEMERAL)
|
||||
.await
|
||||
.expect("TODO");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user