diff --git a/.gitignore b/.gitignore index ea8c4bf..23425ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ /target +/.vscode +.env diff --git a/src/command.rs b/src/command.rs index c163314..aed3e63 100644 --- a/src/command.rs +++ b/src/command.rs @@ -1,14 +1,12 @@ use std::hint::black_box; - use anyhow::Error; - use crate::Context; - -#[poise::command(slash_command, rename = "discord's command name", guild_only)] +// NOTE!!! Make sure these names in quotes are lowercase! +#[poise::command(slash_command, rename = "cmd_name", guild_only)] pub async fn example( ctx: Context<'_>, - #[description = "input description shown in discord"] + #[description = "cmd_desc"] input: String ) -> Result<(), Error> { // Do something... diff --git a/src/main.rs b/src/main.rs index 755abd0..975a9d7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,33 +5,12 @@ mod command; pub struct Data {} // User data, which is stored and accessible in all command invocations type Context<'a> = poise::Context<'a, Data, anyhow::Error>; -const DISCORD_INTENTS: &'static str = "DISCORD_INTENTS"; -const DISCORD_TOKEN: &'static str = "DISCORD_TOKEN"; -const DISCORD_ID: &'static str = "DISCORD_ID"; - #[tokio::main] async fn main() { - // ======================================== READ ENV ======================================== - dotenv::dotenv().ok(); - let id: String = std::env::var(DISCORD_ID).expect(&format!("ERROR: Missing {DISCORD_ID}")); - let token: String = std::env::var(DISCORD_TOKEN).expect(&format!("ERROR: Missing {DISCORD_TOKEN}")); - let perm_env: String = std::env::var(DISCORD_INTENTS) - .unwrap_or_else(|msg| { - println!("DEBUG: what is: {msg}"); - println!("ERROR: Missing {DISCORD_INTENTS}"); - "0".to_string() - }); - // parse into u64, then into GatewayIntents - let perm_u64 = perm_env.parse::().unwrap_or(0u64); - let intents: GatewayIntents = GatewayIntents::from_bits(perm_u64).unwrap_or(GatewayIntents::empty()); - // Re-build into string, just incase it has changed - let perm_string = intents.bits().to_string(); - // ======================================== ENV DONE ======================================== - + let env = read_env(); // Generate sick text like this: // http://www.patorjk.com/software/taag/#p=testall&f=Graffiti&t=hello%20world println!(r#" - /$$$$$$$$ /$$ /$$ /$$$$$$$ /$$ |__ $$__/ | $$ | $$ | $$__ $$ | $$ | $$ /$$$$$$ /$$$$$$/$$$$ /$$$$$$ | $$ /$$$$$$ /$$$$$$ /$$$$$$ | $$ \ $$ /$$$$$$ /$$$$$$ @@ -47,15 +26,11 @@ async fn main() { Template Bot. Invite this bot with: - https://discord.com/api/oauth2/authorize?client_id={id}&permissions={perm_string}&scope=bot - "#); - - // Use bitlogic "OR" to combine different intents. - let intents = - intents | - GatewayIntents::non_privileged(); - + println!("https://discord.com/api/oauth2/authorize?client_id={}&permissions={}&scope=bot", + env.id, + env.intents.bits(), + ); let framework = poise::Framework::builder() .options(poise::FrameworkOptions { @@ -66,16 +41,87 @@ async fn main() { }) // un-comment songbird from Cargo.toml first. //.client_settings(songbird::register) - .token(token) - .intents(intents) + .token(env.token) + .intents(env.intents) .setup(|ctx, _ready, framework| { Box::pin(async move { poise::builtins::register_globally(ctx, &framework.options().commands).await?; - Ok(Data {}) }) }); - - framework.build().await.unwrap().start().await.unwrap(); + // Start the Bot. + // Collect all the errors into one variable, that way we can match it + // all at once. + let err: Result<(), serenity::Error> = match framework.build().await { + Ok(ok) => { + match ok.start().await { + Ok(_start) => Ok(()), + Err(err) => Err(err), + } + }, + Err(err) => Err(err), + }; + + if let Err(error) = err { + match error { + serenity::Error::Gateway(e)=>{ + match e { + serenity::GatewayError::InvalidAuthentication => println!("ERROR: Authentication Invalid, check your bot token."), + err_no_var=>println!("ERROR: {}",err_no_var.to_string()), + } + }, + serenity::Error::Decode(_, _) => println!("ERROR: Decode"), + serenity::Error::Format(_) => println!("ERROR: Format"), + serenity::Error::Io(_) => println!("ERROR: IO"), + serenity::Error::Json(_) => println!("ERROR: Json"), + serenity::Error::Model(_) => println!("ERROR: Model"), + serenity::Error::ExceededLimit(_, _) => println!("ERROR: ExceededLimit"), + serenity::Error::NotInRange(_, _, _, _) => println!("ERROR: NotInRange"), + serenity::Error::Other(_) => println!("ERROR: Other"), + serenity::Error::Url(_) => println!("ERROR: Url"), + serenity::Error::Client(_) => println!("ERROR: Client"), + serenity::Error::Collector(_) => println!("ERROR: Collector"), + serenity::Error::Http(_) => println!("ERROR: Http"), + serenity::Error::Tungstenite(_) => println!("ERROR: Tungstenite"), + _ => todo!(), + } + } } +struct BotEnv { + intents: GatewayIntents, + token: String, + id: String, +} + +fn read_env() -> BotEnv { + const DISCORD_INTENTS: &str = "DISCORD_INTENTS"; + const DISCORD_TOKEN: &str = "DISCORD_TOKEN"; + const DISCORD_ID: &str = "DISCORD_ID"; + dotenv::dotenv().ok(); + // ==================== ID =========================== + let id: String = std::env::var(DISCORD_ID) + .expect(&format!("WARN: Missing {DISCORD_ID}\n> This isn't really that problematic, just that the generated invite link won't work.")); + // ==================== Token ======================== + let token: String = std::env::var(DISCORD_TOKEN) + .expect(&format!("ERROR: Missing {DISCORD_TOKEN}")); + // ==================== Intents ====================== + let intents_env: String = std::env::var(DISCORD_INTENTS) + .unwrap_or_else(|msg| { + println!("DEBUG: what is: {msg}"); + println!("ERROR: Missing {DISCORD_INTENTS}"); + "0".to_string() + }); + // ==================== Parse Intents ================= + // parse into u64, then into GatewayIntents + let intents_u64 = intents_env.parse::().unwrap_or(0u64); + let intents_truncated: GatewayIntents = GatewayIntents::from_bits_truncate(intents_u64); + if intents_truncated.bits() != intents_u64 { + println!("WARN: Intents integer got truncated from {} to {}!", intents_u64, intents_truncated.bits()) + }; + BotEnv { + intents: intents_truncated, + token, + id, + } +}