generated from Oliver/discord-bot-template
112 lines
3.5 KiB
Rust
112 lines
3.5 KiB
Rust
use std::collections::HashSet;
|
|
|
|
use once_cell::sync::Lazy;
|
|
use poise::serenity_prelude::{self as serenity, GatewayIntents, UserId};
|
|
use tracing::{debug, error, info, warn, Level};
|
|
use tracing_subscriber::EnvFilter;
|
|
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() {
|
|
|
|
// Start the tracing subscriber
|
|
let filter = EnvFilter::builder()
|
|
.parse("discord_egress=trace,tokio=warn")
|
|
.expect("Could not create env filter.")
|
|
;
|
|
|
|
tracing_subscriber::fmt::fmt()
|
|
.with_max_level(Level::TRACE)
|
|
.with_target(true)
|
|
.with_env_filter(filter)
|
|
.with_thread_ids(false)
|
|
.with_file(false)
|
|
.init();
|
|
|
|
// Generate sick text like this:
|
|
// http://www.patorjk.com/software/taag/#p=testall&f=Graffiti&t=hello%20world
|
|
info!("Invite with: https://discord.com/api/oauth2/authorize?client_id={}&permissions={}&scope=bot",
|
|
ENV.id,
|
|
ENV.intents.bits(),
|
|
);
|
|
|
|
let mut owners = HashSet::new();
|
|
owners.insert(UserId::new(423970006334832650));
|
|
|
|
// Setup framework
|
|
let framework = poise::Framework::builder()
|
|
.options(poise::FrameworkOptions {
|
|
commands: vec![
|
|
command::index_cmd(),
|
|
command::scrape_all(),
|
|
],
|
|
owners,
|
|
..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(|_| {
|
|
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| {
|
|
debug!("What is: {msg}");
|
|
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 {
|
|
warn!("Intents integer got truncated from {} to {}!", intents_u64, intents_truncated.bits())
|
|
};
|
|
BotEnv {
|
|
intents: intents_truncated,
|
|
token,
|
|
id,
|
|
}
|
|
}
|