Compare commits
	
		
			2 Commits
		
	
	
		
			5593c56831
			...
			1e035859fb
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 1e035859fb | |||
| 71589c3f5d | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1 +1,3 @@
 | 
				
			|||||||
/target
 | 
					/target
 | 
				
			||||||
 | 
					/.vscode
 | 
				
			||||||
 | 
					.env
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,14 +1,12 @@
 | 
				
			|||||||
use std::hint::black_box;
 | 
					use std::hint::black_box;
 | 
				
			||||||
 | 
					 | 
				
			||||||
use anyhow::Error;
 | 
					use anyhow::Error;
 | 
				
			||||||
 | 
					 | 
				
			||||||
use crate::Context;
 | 
					use crate::Context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NOTE!!! Make sure these names in quotes are lowercase!
 | 
				
			||||||
#[poise::command(slash_command, rename = "discord's command name", guild_only)]
 | 
					#[poise::command(slash_command, rename = "cmd_name", guild_only)]
 | 
				
			||||||
pub async fn example(
 | 
					pub async fn example(
 | 
				
			||||||
    ctx: Context<'_>,
 | 
					    ctx: Context<'_>,
 | 
				
			||||||
    #[description = "input description shown in discord"]
 | 
					    #[description = "cmd_desc"]
 | 
				
			||||||
    input: String
 | 
					    input: String
 | 
				
			||||||
) -> Result<(), Error> {
 | 
					) -> Result<(), Error> {
 | 
				
			||||||
    // Do something...
 | 
					    // Do something...
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										122
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										122
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -1,37 +1,15 @@
 | 
				
			|||||||
use poise::serenity_prelude::{self as serenity, GatewayIntents};
 | 
					use poise::serenity_prelude::{self as serenity, GatewayIntents};
 | 
				
			||||||
use dotenv;
 | 
					 | 
				
			||||||
mod command;
 | 
					mod command;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct Data {} // User data, which is stored and accessible in all command invocations
 | 
					pub struct Data {} // User data, which is stored and accessible in all command invocations
 | 
				
			||||||
type Context<'a> = poise::Context<'a, Data, anyhow::Error>;
 | 
					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]
 | 
					#[tokio::main]
 | 
				
			||||||
async fn main() {
 | 
					async fn main() {
 | 
				
			||||||
    // ======================================== READ ENV ======================================== 
 | 
					    let env = 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::<u64>().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 ======================================== 
 | 
					 | 
				
			||||||
     
 | 
					 | 
				
			||||||
    // Generate sick text like this: 
 | 
					    // Generate sick text like this: 
 | 
				
			||||||
    // http://www.patorjk.com/software/taag/#p=testall&f=Graffiti&t=hello%20world
 | 
					    // http://www.patorjk.com/software/taag/#p=testall&f=Graffiti&t=hello%20world
 | 
				
			||||||
    println!(r#"
 | 
					    println!(r#"
 | 
				
			||||||
 | 
					 | 
				
			||||||
     /$$$$$$$$                                /$$             /$$                     /$$$$$$$              /$$    
 | 
					     /$$$$$$$$                                /$$             /$$                     /$$$$$$$              /$$    
 | 
				
			||||||
    |__  $$__/                               | $$            | $$                    | $$__  $$            | $$    
 | 
					    |__  $$__/                               | $$            | $$                    | $$__  $$            | $$    
 | 
				
			||||||
       | $$  /$$$$$$  /$$$$$$/$$$$   /$$$$$$ | $$  /$$$$$$  /$$$$$$    /$$$$$$       | $$  \ $$  /$$$$$$  /$$$$$$  
 | 
					       | $$  /$$$$$$  /$$$$$$/$$$$   /$$$$$$ | $$  /$$$$$$  /$$$$$$    /$$$$$$       | $$  \ $$  /$$$$$$  /$$$$$$  
 | 
				
			||||||
@@ -47,15 +25,11 @@ async fn main() {
 | 
				
			|||||||
    Template Bot.
 | 
					    Template Bot.
 | 
				
			||||||
    Invite this bot with:
 | 
					    Invite this bot with:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    https://discord.com/api/oauth2/authorize?client_id={id}&permissions={perm_string}&scope=bot
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    "#);
 | 
					    "#);
 | 
				
			||||||
    
 | 
					    println!("https://discord.com/api/oauth2/authorize?client_id={}&permissions={}&scope=bot",
 | 
				
			||||||
    // Use bitlogic "OR" to combine different intents.
 | 
					        env.id,
 | 
				
			||||||
    let intents =
 | 
					        env.intents.bits(),
 | 
				
			||||||
        intents |
 | 
					    );
 | 
				
			||||||
        GatewayIntents::non_privileged();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let framework = poise::Framework::builder()
 | 
					    let framework = poise::Framework::builder()
 | 
				
			||||||
        .options(poise::FrameworkOptions {
 | 
					        .options(poise::FrameworkOptions {
 | 
				
			||||||
@@ -66,16 +40,92 @@ async fn main() {
 | 
				
			|||||||
        })
 | 
					        })
 | 
				
			||||||
        // un-comment songbird from Cargo.toml first.
 | 
					        // un-comment songbird from Cargo.toml first.
 | 
				
			||||||
        //.client_settings(songbird::register)
 | 
					        //.client_settings(songbird::register)
 | 
				
			||||||
        .token(token)
 | 
					        .token(env.token)
 | 
				
			||||||
        .intents(intents)
 | 
					        .intents(env.intents)
 | 
				
			||||||
        .setup(|ctx, _ready, framework| {
 | 
					        .setup(|ctx, _ready, framework| {
 | 
				
			||||||
            Box::pin(async move {
 | 
					            Box::pin(async move {
 | 
				
			||||||
                poise::builtins::register_globally(ctx, &framework.options().commands).await?;
 | 
					                poise::builtins::register_globally(ctx, &framework.options().commands).await?;
 | 
				
			||||||
 | 
					 | 
				
			||||||
                Ok(Data {})
 | 
					                Ok(Data {})
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    
 | 
					    // Start the Bot.
 | 
				
			||||||
    framework.build().await.unwrap().start().await.unwrap();
 | 
					    // 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)
 | 
				
			||||||
 | 
					        .unwrap_or_else(|_| {
 | 
				
			||||||
 | 
					            println!(r#"
 | 
				
			||||||
 | 
					WARN: Missing {DISCORD_ID}
 | 
				
			||||||
 | 
					> This isn't really that problematic, just that the generated invite link won't work."#);
 | 
				
			||||||
 | 
					            String::from("")
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    // ==================== Token ========================
 | 
				
			||||||
 | 
					    let token: String = std::env::var(DISCORD_TOKEN)
 | 
				
			||||||
 | 
					        .unwrap_or_else(|_| panic!("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::<u64>().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,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user