use crate::botv2::cmd::meme::main::meme; use crate::botv2::cmd::server_config::server::server; use crate::botv2::cmd::{help::help, ping::ping}; use crate::config::Config; use crate::event::schedule_job::ScheduleJob; use crate::{botv2::handler::event_handler, img::config_file::ConfigFile}; use poise::serenity_prelude::{self as serenity, Http}; use serenity::GatewayIntents; use std::fs; use std::sync::Arc; use tokio::sync::oneshot; use tracing::{info, instrument}; use super::cmd::concour::main::concour; pub struct Data { pub config_img: ConfigFile, pub config: Config, pub entity_name: String, pub scheduler: ScheduleJob, } // Types used by all command functions pub type Error = Box; pub type Context<'a> = poise::Context<'a, Data, Error>; #[instrument(skip(ctx), level = "info")] #[poise::command(slash_command, prefix_command)] async fn age( ctx: Context<'_>, #[description = "Selected user"] user: Option, ) -> Result<(), Error> { let u = user.as_ref().unwrap_or_else(|| ctx.author()); let response = format!("{}'s account was created at {}", u.name, u.created_at()); ctx.say(response).await?; Ok(()) } pub async fn start_bot( config: Config, rx: oneshot::Receiver<()>, scheduler: ScheduleJob, ) -> Arc { let config_img = match fs::read_to_string(format!("{}/config.yaml", config.image.path)) { Ok(content) => content, Err(err) => { tracing::error!("Error while opening config.yaml : {:?}", err); panic!("Error while opening config.yaml : {:?}", err) } }; let config_parsed = match ConfigFile::parse_config(config_img) { Ok(config) => config, Err(err) => { tracing::error!("Error while parsing config.yaml : {:?}", err); panic!("Error while parsing config.yaml : {:?}", err) } }; 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(); let framework = poise::Framework::builder() .options(poise::FrameworkOptions { commands: vec![age(), ping(), help(), meme(), server(), concour()], 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_img: config_parsed, config: config.clone(), scheduler, entity_name: format!( "{}-{}", config.bot_name.clone(), env!("CARGO_PKG_VERSION") ), }) }) }) .build(); let mut client = serenity::ClientBuilder::new(token, intents) .framework(framework) .await .expect("Error creating client"); 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 }