use std::{time::Duration, sync::Mutex}; use dotenv::dotenv; use sqlx::{PgPool, postgres::PgPoolOptions}; type Error = Box; type Context<'a> = poise::Context<'a, Data, Error>; mod commands; mod handler; mod models; pub struct Data { pg: Mutex, } /// Show help menu #[poise::command(prefix_command, slash_command)] async fn help(ctx: Context<'_>, #[description = "Command to get help for"] command: Option, ) -> Result<(), Error> { poise::builtins::help(ctx, command.as_deref(), poise::builtins::HelpConfiguration::default()).await?; Ok(()) } async fn on_error(error: poise::FrameworkError<'_, Data, Error>) { match error { poise::FrameworkError::Setup { error } => panic!("Failed to start bot: {:?}", error), poise::FrameworkError::Command {error, ctx} => { println!("Error in command {}: {:?}", ctx.command().name, error); }, error => { if let Err(e) = poise::builtins::on_error(error).await { println!("Error handling error: {}", e); } } } } /// Register application commands in this guild or globally /// /// Run with no arguments to register in guild, run with argument "global" to register globally. #[poise::command(prefix_command, hide_in_help)] async fn register(ctx: Context<'_>, #[flag] global: bool) -> Result<(), Error> { poise::builtins::register_application_commands(ctx, global).await?; Ok(()) } #[tokio::main] async fn main() { dotenv().unwrap(); let options = poise::FrameworkOptions { commands: vec![ help(), register(), commands::meta::ping(), commands::meta::about(), commands::meta::userinfo(), commands::actions::boop(), commands::actions::hug(), commands::pony::randpony(), commands::pony::tpony(), commands::osu::osup(), commands::osu::osubm(), poise::Command { subcommands: vec![ commands::reactionroles::init(), ], ..commands::reactionroles::rroles() }, ], on_error: |error| Box::pin(on_error(error)), pre_command: |ctx| { Box::pin(async move { println!("Executing command {}...", ctx.command().name); }) }, post_command: |ctx| { Box::pin(async move { println!("Done executing command {}!", ctx.command().name); }) }, prefix_options: poise::PrefixFrameworkOptions { prefix: Some("~".into()), edit_tracker: Some(poise::EditTracker::for_timespan(Duration::from_secs(3600))), additional_prefixes: vec![ poise::Prefix::Literal("hey glitch"), poise::Prefix::Literal("hey glitch,"), ], ..Default::default() }, listener: |ctx, event, _, data| Box::pin(handler::event_handler(ctx, event, data)), ..Default::default() }; poise::Framework::build() .token(std::env::var("DISCORD_TOKEN").unwrap_or("BAD-TOKEN".into())) .user_data_setup(move |_ctx, _ready, _framework| { Box::pin(async move { let pool = PgPoolOptions::new() .max_connections(5) .connect(&std::env::var("DATABASE_URL").unwrap_or("postgres://postgres@localhost/glitch".to_string())) .await .expect("Couldn't connect to postgresql"); Ok(Data { pg: Mutex::new(pool) }) }) }) .options(options) .run() .await .unwrap(); }