use std::env; use std::collections::HashSet; use std::sync::Arc; use serenity::http::Http; use serenity::prelude::*; use songbird::{SerenityInit, Songbird}; use reqwest::Client as HttpClient; use crate::bot::handler::Handler; mod bot; mod database; mod dnd; mod error; pub struct HttpKey; impl TypeMapKey for HttpKey { type Value = HttpClient; } #[tokio::main] async fn main() { dotenv::dotenv().ok(); env_logger::init_from_env(env_logger::Env::default().filter_or("RUST_LOG", "warn,siren=info")); if let Err(err) = database::initialize().await { log::error!("Failed to initialize database: {err}"); return; }; let token: String = env::var("DISCORD_TOKEN").expect("Expected a token in the environment"); let intents: GatewayIntents = GatewayIntents::all(); let http: Http = Http::new(&token); let (_owners, _bot_id) = match http.get_current_application_info().await { Ok(info) => { let mut owners: HashSet = HashSet::new(); if let Some(team) = info.team { owners.insert(team.owner_user_id); } else { owners.insert(info.owner.unwrap().id); } match http.get_current_user().await { Ok(bot) => (owners, bot.id), Err(why) => panic!("Could not access the bot id: {why:?}"), } } Err(why) => panic!("Could not access application info: {why:?}"), }; let handler = match env::var("OPENAI_API_KEY") { Ok(token) => { log::info!("OpenAI functionality enabled"); let default_model = env::var("OPENAI_API_MODEL").unwrap_or("gpt-4o-mini".to_string()); Handler { oai: Some(bot::oai::OAI { client: reqwest::Client::new(), base_url: "https://api.openai.com/v1".to_string(), // max_attempts: 5, token, max_conversation_history: 30, max_tokens: 8192, default_model, }), } } Err(err) => { log::trace!("No OPENAI_API_KEY found: {err}"); log::warn!("OpenAI functionality disabled"); Handler { oai: None } } }; let songbird = Songbird::serenity(); let mut client = Client::builder(token, intents) .event_handler(handler) // .framework(StandardFramework::new().configure(|c| c.owners(owners))) .register_songbird_with(Arc::clone(&songbird)) .type_map_insert::(HttpClient::new()) .await .expect("Error creating client"); // Handle shutdown signals let shard_manager = Arc::clone(&client.shard_manager); tokio::spawn(async move { shard_manager.shutdown_all().await; }); // Start listening for events by starting a single shard if let Err(why) = client.start_autosharded().await { log::error!("Client error: {why:?}"); } }