use std::collections::HashSet; use std::env; use commands::audio::create_response; use dotenv::dotenv; use log::{error, warn, info}; use serenity::async_trait; use serenity::framework::StandardFramework; use serenity::model::application::interaction::Interaction; use serenity::model::gateway::Ready; use serenity::http::Http; use serenity::prelude::*; use songbird::SerenityInit; mod commands; struct Handler; #[async_trait] impl EventHandler for Handler { async fn interaction_create(&self, ctx: Context, interaction: Interaction) { if let Interaction::ApplicationCommand(command) = interaction { match command.data.name.as_str() { "play" => commands::audio::play::run(&ctx, &command).await, "stop" => commands::audio::stop::run(&ctx, &command).await, "pause" => commands::audio::pause::run(&ctx, &command).await, "resume" => commands::audio::resume::run(&ctx, &command).await, "skip" => commands::audio::skip::run(&ctx, &command).await, _ => { let content: String = match command.data.name.as_str() { "ping" => commands::ping::run(&command.data.options), _ => "Unknown command".to_string() }; if let Err(why) = create_response(&ctx, &command, content).await { warn!("Cannot respond to slash command: {}", why); } } } } } async fn ready(&self, ctx: Context, ready: Ready) { if ready.guilds.is_empty() { warn!("No ready guilds found"); } for guild in ready.guilds { let commands = guild.id.set_application_commands(&ctx.http, |commands| { commands.create_application_command(|command: &mut serenity::builder::CreateApplicationCommand| { commands::ping::register(command) }) .create_application_command(|command: &mut serenity::builder::CreateApplicationCommand| { commands::audio::play::register(command) }) .create_application_command(|command: &mut serenity::builder::CreateApplicationCommand| { commands::audio::stop::register(command) }) .create_application_command(|command: &mut serenity::builder::CreateApplicationCommand| { commands::audio::pause::register(command) }) .create_application_command(|command: &mut serenity::builder::CreateApplicationCommand| { commands::audio::resume::register(command) }) .create_application_command(|command: &mut serenity::builder::CreateApplicationCommand| { commands::audio::skip::register(command) }) }).await; match commands { Ok(c) => info!("Registered {} commands for guild {}", c.len(), guild.id.0), Err(why) => error!("Could not register commands for guild {}: {:?}", guild.id.0, why) }; } } } #[tokio::main] async fn main() { dotenv().ok(); env_logger::init(); 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.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 framework = StandardFramework::new() .configure(|c| c .owners(owners) .prefix("!") ); let mut client = Client::builder(token, intents) .event_handler(Handler) .framework(framework) .register_songbird() .await .expect("Error creating client"); if let Err(why) = client.start_autosharded().await { error!("An error occurred while running the client: {:?}", why); } }