reminder-bot/src/main.rs

161 lines
4.3 KiB
Rust
Raw Normal View History

#![feature(int_roundings)]
2020-08-26 17:26:28 +00:00
#[macro_use]
extern crate lazy_static;
2020-08-09 22:59:31 +00:00
mod commands;
2021-09-11 19:40:58 +00:00
mod component_models;
mod consts;
mod event_handlers;
mod framework;
mod hooks;
2022-02-01 23:04:31 +00:00
mod interval_parser;
mod models;
mod time_parser;
mod utils;
2020-08-06 14:22:13 +00:00
2021-12-20 13:48:18 +00:00
use std::{
collections::HashMap,
env,
sync::{atomic::AtomicBool, Arc},
2021-12-20 13:48:18 +00:00
};
use chrono_tz::Tz;
use dotenv::dotenv;
use log::info;
2020-08-06 14:22:13 +00:00
use serenity::{
2022-02-01 23:04:31 +00:00
client::Client,
http::client::Http,
model::{
gateway::GatewayIntents,
id::{GuildId, UserId},
},
prelude::TypeMapKey,
2020-08-06 14:22:13 +00:00
};
use sqlx::mysql::MySqlPool;
2022-02-06 15:47:59 +00:00
use tokio::sync::RwLock;
2020-08-06 14:22:13 +00:00
use crate::{
2021-09-24 11:55:35 +00:00
commands::{info_cmds, moderation_cmds, reminder_cmds, todo_cmds},
2021-09-11 19:40:58 +00:00
component_models::ComponentDataModel,
consts::THEME_COLOR,
framework::RegexFramework,
2021-10-26 20:10:14 +00:00
models::command_macro::CommandMacro,
2020-08-09 22:59:31 +00:00
};
2020-08-06 14:22:13 +00:00
struct SQLPool;
impl TypeMapKey for SQLPool {
type Value = MySqlPool;
2020-08-06 14:22:13 +00:00
}
struct ReqwestClient;
impl TypeMapKey for ReqwestClient {
type Value = Arc<reqwest::Client>;
}
struct PopularTimezones;
impl TypeMapKey for PopularTimezones {
type Value = Arc<Vec<Tz>>;
}
struct RecordingMacros;
impl TypeMapKey for RecordingMacros {
type Value = Arc<RwLock<HashMap<(GuildId, UserId), CommandMacro>>>;
}
2021-12-20 13:48:18 +00:00
struct Handler {
is_loop_running: AtomicBool,
}
2020-08-06 14:22:13 +00:00
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
2020-10-17 22:56:19 +00:00
env_logger::init();
2020-08-06 14:22:13 +00:00
dotenv()?;
let token = env::var("DISCORD_TOKEN").expect("Missing DISCORD_TOKEN from environment");
2021-12-20 13:48:18 +00:00
let application_id = {
let http = Http::new_with_token(&token);
2021-12-20 13:48:18 +00:00
http.get_current_application_info().await?.id
};
let dm_enabled = env::var("DM_ENABLED").map_or(true, |var| var == "1");
let framework = RegexFramework::new()
.ignore_bots(env::var("IGNORE_BOTS").map_or(true, |var| var == "1"))
2021-09-10 17:09:25 +00:00
.debug_guild(env::var("DEBUG_GUILD").map_or(None, |g| {
Some(GuildId(g.parse::<u64>().expect("DEBUG_GUILD must be a guild ID")))
2021-09-10 17:09:25 +00:00
}))
.dm_enabled(dm_enabled)
// info commands
2021-11-13 14:12:37 +00:00
.add_command(&info_cmds::HELP_COMMAND)
.add_command(&info_cmds::INFO_COMMAND)
.add_command(&info_cmds::DONATE_COMMAND)
2021-09-10 17:09:25 +00:00
.add_command(&info_cmds::DASHBOARD_COMMAND)
.add_command(&info_cmds::CLOCK_COMMAND)
// reminder commands
.add_command(&reminder_cmds::TIMER_COMMAND)
2021-09-18 12:40:30 +00:00
.add_command(&reminder_cmds::REMIND_COMMAND)
2021-09-16 17:30:16 +00:00
// management commands
.add_command(&reminder_cmds::DELETE_COMMAND)
2021-09-11 19:40:58 +00:00
.add_command(&reminder_cmds::LOOK_COMMAND)
.add_command(&reminder_cmds::PAUSE_COMMAND)
2021-09-11 19:40:58 +00:00
.add_command(&reminder_cmds::OFFSET_COMMAND)
.add_command(&reminder_cmds::NUDGE_COMMAND)
// to-do commands
2021-09-24 11:55:35 +00:00
.add_command(&todo_cmds::TODO_COMMAND)
// moderation commands
.add_command(&moderation_cmds::TIMEZONE_COMMAND)
.add_command(&moderation_cmds::MACRO_CMD_COMMAND)
.add_hook(&hooks::CHECK_SELF_PERMISSIONS_HOOK)
.add_hook(&hooks::MACRO_CHECK_HOOK);
2020-08-06 14:22:13 +00:00
let framework_arc = Arc::new(framework);
let mut client = Client::builder(&token)
.intents(GatewayIntents::GUILDS)
.application_id(application_id.0)
2021-12-20 13:48:18 +00:00
.event_handler(Handler { is_loop_running: AtomicBool::from(false) })
.await
.expect("Error occurred creating client");
2020-08-06 14:22:13 +00:00
{
let pool = MySqlPool::connect(
&env::var("DATABASE_URL").expect("Missing DATABASE_URL from environment"),
)
.await
.unwrap();
let popular_timezones = sqlx::query!(
"SELECT timezone FROM users GROUP BY timezone ORDER BY COUNT(timezone) DESC LIMIT 21"
)
.fetch_all(&pool)
.await
.unwrap()
.iter()
.map(|t| t.timezone.parse::<Tz>().unwrap())
.collect::<Vec<Tz>>();
let mut data = client.data.write().await;
data.insert::<SQLPool>(pool);
data.insert::<PopularTimezones>(Arc::new(popular_timezones));
data.insert::<ReqwestClient>(Arc::new(reqwest::Client::new()));
2021-09-10 17:09:25 +00:00
data.insert::<RegexFramework>(framework_arc.clone());
data.insert::<RecordingMacros>(Arc::new(RwLock::new(HashMap::new())));
}
2021-11-13 14:12:37 +00:00
framework_arc.build_slash(&client.cache_and_http.http).await;
info!("Starting client as autosharded");
2020-10-17 22:56:19 +00:00
client.start_autosharded().await?;
2020-08-06 14:22:13 +00:00
Ok(())
}