diff options
Diffstat (limited to 'crates/bot-client')
| -rw-r--r-- | crates/bot-client/Cargo.toml | 32 | ||||
| -rw-r--r-- | crates/bot-client/src/handler.rs | 112 | ||||
| -rw-r--r-- | crates/bot-client/src/lib.rs | 79 |
3 files changed, 0 insertions, 223 deletions
diff --git a/crates/bot-client/Cargo.toml b/crates/bot-client/Cargo.toml deleted file mode 100644 index a2ba2a0..0000000 --- a/crates/bot-client/Cargo.toml +++ /dev/null @@ -1,32 +0,0 @@ -[package] -name = "bot-client" -version = "0.2.0" -edition = "2021" - -authors = ["seth <getchoo at tuta dot io>"] -description = "Discord client for nixpkgs-tracker-bot" -repository = "https://github.com/getchoo/nixpkgs-tracker-bot" - -publish = false - -[dependencies] -bot-commands = { workspace = true } -bot-config = { workspace = true } -bot-consts = { workspace = true } -bot-error = { workspace = true } -bot-http = { workspace = true } -bot-jobs = { workspace = true } -log = { workspace = true } -serenity = { workspace = true } -tokio = { workspace = true } - -[lints.rust] -unsafe_code = "forbid" - -[lints.clippy] -complexity = "warn" -correctness = "deny" -pedantic = "warn" -perf = "warn" -style = "warn" -suspicious = "deny" diff --git a/crates/bot-client/src/handler.rs b/crates/bot-client/src/handler.rs deleted file mode 100644 index 2cd0082..0000000 --- a/crates/bot-client/src/handler.rs +++ /dev/null @@ -1,112 +0,0 @@ -use crate::{SharedConfig, SharedHttp}; -use bot_error::Error; - -use log::{debug, error, info, trace, warn}; -use serenity::all::CreateBotAuthParameters; -use serenity::async_trait; -use serenity::builder::{ - CreateEmbed, CreateInteractionResponse, CreateInteractionResponseFollowup, - CreateInteractionResponseMessage, -}; -use serenity::model::{ - application::{Command, CommandInteraction, Interaction}, - colour::Colour, - gateway::Ready, -}; -use serenity::prelude::{Context, EventHandler}; - -#[derive(Clone, Copy, Debug)] -pub struct Handler; - -impl Handler { - async fn register_commands(&self, ctx: &Context) -> Result<(), Error> { - let commands = bot_commands::to_vec(); - let commands_len = commands.len(); - for command in commands { - Command::create_global_command(&ctx.http, command).await?; - } - - debug!("Registered {} commands", commands_len); - Ok(()) - } - - /// Dispatch our commands from a [`CommandInteraction`] - async fn dispatch_command(ctx: &Context, command: &CommandInteraction) -> Result<(), Error> { - let command_name = command.data.name.as_str(); - - // grab our configuration & http client from the aether - let (http, config) = { - let read = ctx.data.read().await; - let http = read - .get::<SharedHttp>() - .ok_or("Couldn't get shared HTTP client! WHY??????")? - .clone(); - let config = read - .get::<SharedConfig>() - .ok_or("Couldn't get shared bot configuration!")? - .clone(); - (http, config) - }; - - match command_name { - "about" => bot_commands::about::respond(ctx, &http, command).await?, - "ping" => bot_commands::ping::respond(ctx, command).await?, - "track" => bot_commands::track::respond(ctx, &http, &config, command).await?, - _ => { - let message = CreateInteractionResponseMessage::new().content(format!( - "It doesn't look like you can use `{command_name}`. Sorry :(" - )); - let response = CreateInteractionResponse::Message(message); - command.create_response(&ctx, response).await?; - } - }; - - Ok(()) - } - - async fn invite_link(ctx: &Context) { - if let Ok(invite_link) = CreateBotAuthParameters::new().auto_client_id(ctx).await { - let link = invite_link.build(); - info!("You can install me as an app at {link}"); - } else { - warn!("Couldn't figure out our own client ID! Something might be wrong"); - } - } -} - -#[async_trait] -impl EventHandler for Handler { - /// Dispatch our commands and try to handle errors from them - async fn interaction_create(&self, ctx: Context, interaction: Interaction) { - if let Interaction::Command(command) = interaction { - let command_name = &command.data.name; - trace!("Received command: {}", command_name); - - if let Err(why) = Handler::dispatch_command(&ctx, &command).await { - error!( - "Ran into an error while dispatching command {}:\n{why:?}", - command_name - ); - - let embed = CreateEmbed::new() - .title("An error occurred") - .description("Sorry about that!") - .color(Colour::RED); - let response = CreateInteractionResponseFollowup::new().embed(embed); - - if let Err(why) = command.create_followup(&ctx.http, response).await { - error!("Ran into an error while trying to recover from an error!\n{why:?}"); - } - } - } - } - - async fn ready(&self, ctx: Context, ready: Ready) { - info!("Connected as {}!", ready.user.name); - Handler::invite_link(&ctx).await; - - if let Err(why) = self.register_commands(&ctx).await { - error!("Couldn't register commands!\n{why:?}"); - }; - } -} diff --git a/crates/bot-client/src/lib.rs b/crates/bot-client/src/lib.rs deleted file mode 100644 index 851b853..0000000 --- a/crates/bot-client/src/lib.rs +++ /dev/null @@ -1,79 +0,0 @@ -use bot_config::Config; -use bot_error::Error; -use bot_http as http; - -use std::sync::Arc; - -use log::trace; -use serenity::prelude::{Client, GatewayIntents, TypeMapKey}; - -mod handler; - -use handler::Handler; - -/// Container for [`http::Client`] -struct SharedHttp; - -impl TypeMapKey for SharedHttp { - type Value = Arc<http::Client>; -} - -/// Container for [`Config`] -struct SharedConfig; - -impl TypeMapKey for SharedConfig { - type Value = Arc<Config>; -} - -/// Fetch our bot token -fn token() -> Result<String, Error> { - let token = std::env::var("DISCORD_BOT_TOKEN")?; - Ok(token) -} - -/// Create our client -/// -/// # Errors -/// -/// Will return [`Err`] if a [`Client`] cannot be created or configuration -/// cannot be created from the environment. -/// -/// # Panics -/// -/// Will [`panic!`] if the bot token isn't found or the ctrl+c handler can't be made -pub async fn get() -> Result<Client, Error> { - let token = token().expect("Couldn't find token in environment! Is DISCORD_BOT_TOKEN set?"); - - let intents = GatewayIntents::default(); - trace!("Creating client"); - let client = Client::builder(token, intents) - .event_handler(Handler) - .await?; - - // add state stuff - let http_client = <http::Client as http::ClientExt>::default(); - let config = Config::from_env()?; - - { - let mut data = client.data.write().await; - - data.insert::<SharedHttp>(Arc::new(http_client)); - data.insert::<SharedConfig>(Arc::new(config.clone())); - } - - let shard_manager = client.shard_manager.clone(); - - // gracefully shutdown on ctrl+c - tokio::spawn(async move { - #[cfg(target_family = "unix")] - tokio::signal::ctrl_c() - .await - .expect("Couldn't register ctrl+c handler!"); - shard_manager.shutdown_all().await; - }); - - // run our jobs - bot_jobs::dispatch(config)?; - - Ok(client) -} |
