use std::sync::Arc; use clickhouse_pool::pool_manager::PoolManager; use event::event_handler; use poise::serenity_prelude::{GatewayIntents, Http}; use tokio::sync::oneshot; use tracing::info; use trivia::trivia; use utility::{age::age, help::help, server::servers}; use config::Config; pub mod event; pub mod helper; pub mod trivia; pub mod utility; pub struct Data { pub config: Config, pub datalake_config: Arc, pub entity_name: String, } pub type Error = Box; pub type Context<'a> = poise::Context<'a, Data, Error>; pub async fn start_bot( config: Config, datalake_config: Arc, rx: oneshot::Receiver<()>, ) -> Arc { let intents = GatewayIntents::GUILD_MESSAGES | GatewayIntents::DIRECT_MESSAGES | GatewayIntents::MESSAGE_CONTENT | GatewayIntents::GUILD_VOICE_STATES | GatewayIntents::GUILDS | GatewayIntents::GUILD_MEMBERS | GatewayIntents::GUILD_PRESENCES | GatewayIntents::GUILD_MESSAGE_REACTIONS; let token = config.token.clone(); let prefix = config.prefix.clone(); info!("Starting bot {}", config.bot_name.clone()); let framework = poise::Framework::builder() .options(poise::FrameworkOptions { commands: vec![age(), help(), servers(), trivia()], prefix_options: poise::PrefixFrameworkOptions { prefix: Some(prefix), ..Default::default() }, event_handler: |ctx, event, framework, data| { Box::pin(event_handler(ctx, event, framework, data)) }, ..Default::default() }) .setup(|ctx, _ready, framework| { Box::pin(async move { poise::builtins::register_globally(ctx, &framework.options().commands).await?; Ok(Data { config: config.clone(), datalake_config: datalake_config, entity_name: format!("{}-{}", config.bot_name, env!("CARGO_PKG_VERSION")), }) }) }) .build(); let mut client = match poise::serenity_prelude::ClientBuilder::new(token, intents) .framework(framework) .await { Ok(client) => client, Err(e) => { panic!("Failed to create client: {}", e); } }; let http = client.http.clone(); let shard_manager = client.shard_manager.clone(); tokio::spawn(async move { match rx.await { Ok(_) => { tracing::info!("Received shutdown signal"); shard_manager.shutdown_all().await; tracing::info!("Shutting down bot"); } Err(_) => { tracing::info!("Channel dropped signal"); shard_manager.shutdown_all().await; tracing::info!("Shutting down bot"); } } }); tokio::spawn(async move { info!("Bot is running..."); if let Err(why) = client.start_autosharded().await { tracing::error!("Client error: {why:?}"); } info!("Bot is stopped..."); }); http }