generated from Oliver/discord-bot-template
96 lines
3.0 KiB
Rust
96 lines
3.0 KiB
Rust
use once_cell::sync::Lazy;
|
|
use poise::serenity_prelude::{self as serenity, GatewayIntents};
|
|
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>;
|
|
|
|
static ENV: Lazy<BotEnv> = Lazy::new(|| {
|
|
read_env()
|
|
});
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
|
|
// Generate sick text like this:
|
|
// http://www.patorjk.com/software/taag/#p=testall&f=Graffiti&t=hello%20world
|
|
println!(r#"
|
|
Invite this bot with:
|
|
"#);
|
|
println!("https://discord.com/api/oauth2/authorize?client_id={}&permissions={}&scope=bot",
|
|
ENV.id,
|
|
ENV.intents.bits(),
|
|
);
|
|
print!("\n");
|
|
|
|
// Setup framework
|
|
let framework = poise::Framework::builder()
|
|
.options(poise::FrameworkOptions {
|
|
commands: vec![
|
|
command::index_cmd(),
|
|
command::scrape_all(),
|
|
],
|
|
..Default::default()
|
|
})
|
|
.setup(|ctx, _ready, framework| {
|
|
Box::pin(async move {
|
|
poise::builtins::register_globally(
|
|
ctx,
|
|
&framework.options().commands
|
|
).await?;
|
|
Ok(Data {})
|
|
})
|
|
})
|
|
.build();
|
|
|
|
// Start the Bot.
|
|
let client = serenity::ClientBuilder::new(&ENV.token, ENV.intents)
|
|
.framework(framework)
|
|
.await;
|
|
|
|
client.unwrap().start().await.unwrap();
|
|
}
|
|
|
|
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,
|
|
}
|
|
}
|