mod commands; use anyhow::{Error, Result}; use poise::serenity_prelude as serenity; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; use tracing_subscriber::{EnvFilter, Registry}; use tracing_tree::HierarchicalLayer; const DISCORD_TOKEN: &str = "DISCORD_TOKEN"; const BUSCEMI_DATA: &str = "BUSCEMI_DATA"; const BUSCEMI_DATA_PATH: &str = "./buscemi.ron"; #[tokio::main] async fn main() -> Result<()> { init_tracing(); let framework = init_discord(); tracing::info!("it's beneath me. i'm mr. pink. let's move on."); framework.run().await?; Ok(()) } fn init_tracing() { Registry::default() .with(EnvFilter::from_default_env()) .with(HierarchicalLayer::default()) .init() } // #[tracing::instrument(level = "debug")] // async fn pre_command(ctx: commands::Context<'_>) { // // TODO: set up tracing span? // } #[tracing::instrument(level = "debug")] async fn post_command(ctx: commands::Context<'_>) { ctx.data() .commit() .await .unwrap_or_else(|e| tracing::error!("failed to commit brain to disk: {e}")) } #[tracing::instrument(level = "debug")] async fn on_error(error: poise::FrameworkError<'_, commands::Data, Error>) { if let Err(e) = poise::builtins::on_error(error).await { tracing::error!("unhandled error: {e}") } } fn init_discord() -> poise::FrameworkBuilder { let options = poise::FrameworkOptions { commands: commands::commands(), // pre_command: |ctx| Box::pin(pre_command(ctx)), post_command: |ctx| Box::pin(post_command(ctx)), on_error: |error| Box::pin(on_error(error)), ..Default::default() }; poise::Framework::builder() .options(options) .token(std::env::var(DISCORD_TOKEN).expect("failed to find DISCORD_TOKEN in env")) .intents(serenity::GatewayIntents::non_privileged()) .setup(|ctx, ready, framework| { Box::pin(async move { for guild in &ready.guilds { poise::builtins::register_in_guild( ctx, &framework.options().commands, guild.id, ) .await .unwrap_or_else(|e| tracing::error!("failed to register commands: {e}")); tracing::debug!("registered commands on {guild:?}") } tracing::info!("registered commands"); let data_path = std::env::var(BUSCEMI_DATA).unwrap_or_else(|_| String::from(BUSCEMI_DATA_PATH)); commands::Data::from_path(data_path).await }) }) }