diff options
| author | seth <[email protected]> | 2024-08-09 23:35:41 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-08-09 23:35:41 -0400 |
| commit | b643a6a235b0c1c9902b97421f24eff2b0d0a5ac (patch) | |
| tree | 350794c0e9330fb77367838313bc6bb97278a0aa /src/client.rs | |
| parent | 372780546b508684839916e5ad54c9e90456a94f (diff) | |
tree-wide: end of summer cleanup (#214)
* api: refactor & rename module to http
* client: split from main.rs
* tree-wide: use eyre::Report as error
* nix: alejandra -> nixfmt
* nix: start using treefmt-nix
* nix: simplify flake
* nix: refactor derivation & docker image
* nix: remove overlay
* ci: update & cleanup workflows
* commands: assign all commands automatically
* commands/copypasta: remove
* http/teawie: update response struct for upstream rust rewrite
* handlers: rename modules to events; flatten
* crates: rename self to teawie-bot
* nix: fenix -> rust-overlay
i want a specific rust version grrrrrrr
* ci: pin rust to 1.79
this is what our nix dev shell uses and what we can compile on. it seems
the time crate doesn't like v1.80 of the compiler :(
* ci: always run release gates
* nix: fix static toolchain
* nix: rust-overlay -> nixpkgs
* ci: adopt actions-rust-lang actions
* nix: use docker arch names for containers
* crates/time: 0.3.30 -> 0.3.36
fixes building on rust 1.80.0
Diffstat (limited to 'src/client.rs')
| -rw-r--r-- | src/client.rs | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/client.rs b/src/client.rs new file mode 100644 index 0000000..65c221b --- /dev/null +++ b/src/client.rs @@ -0,0 +1,99 @@ +use crate::{commands, events, http, storage::Storage}; + +use std::{sync::Arc, time::Duration}; + +use eyre::{bail, Context as _, Result}; +use log::{info, trace, warn}; +use poise::{ + serenity_prelude::{self as serenity}, + EditTracker, Framework, FrameworkOptions, PrefixFrameworkOptions, +}; + +pub type Error = eyre::Report; +pub type Context<'a> = poise::Context<'a, Data, Error>; + +#[derive(Clone, Debug, Default)] +pub struct Data { + pub http_client: http::Client, + pub storage: Option<Storage>, +} + +async fn setup(ctx: &serenity::Context) -> Result<Data> { + let storage = Storage::from_env().ok(); + + if let Some(storage) = storage.as_ref() { + if !storage.clone().is_connected() { + bail!("You specified a storage backend but there's no connection! Is it running?"); + } + trace!("Storage backend connected!"); + + poise::builtins::register_globally(ctx, &commands::global()).await?; + info!("Registered global commands!"); + + // register "extra" commands in guilds that allow it + let guilds = storage.get_opted_guilds().await?; + + for guild in guilds { + poise::builtins::register_in_guild(ctx, &commands::optional(), guild).await?; + + info!("Registered guild commands to {}", guild); + } + } else { + warn!("No storage backend was specified. Features requiring storage cannot be used"); + warn!("Registering optional commands globally since there's no storage backend"); + poise::builtins::register_globally(ctx, &commands::all()).await?; + } + + let http_client = <http::Client as http::Ext>::default(); + let data = Data { + http_client, + storage, + }; + + Ok(data) +} + +pub async fn handle_shutdown(shard_manager: Arc<serenity::ShardManager>, reason: &str) { + warn!("{reason}! Shutting down bot..."); + shard_manager.shutdown_all().await; + println!("Everything is shutdown. Goodbye!"); +} + +pub async fn get() -> Result<serenity::Client> { + let token = std::env::var("TOKEN").wrap_err("Couldn't find bot token in environment!")?; + + let intents = + serenity::GatewayIntents::non_privileged() | serenity::GatewayIntents::MESSAGE_CONTENT; + + let options = FrameworkOptions { + commands: commands::all(), + on_error: |error| Box::pin(events::error::handle(error)), + + command_check: Some(|ctx| { + Box::pin(async move { Ok(ctx.author().id != ctx.framework().bot_id) }) + }), + + event_handler: |ctx, event, _framework, data| Box::pin(events::handle(ctx, event, data)), + + prefix_options: PrefixFrameworkOptions { + prefix: Some("!".into()), + edit_tracker: Some(Arc::new(EditTracker::for_timespan(Duration::from_secs( + 3600, + )))), + ..Default::default() + }, + + ..Default::default() + }; + + let framework = Framework::builder() + .options(options) + .setup(|ctx, _ready, _framework| Box::pin(setup(ctx))) + .build(); + + let client = serenity::ClientBuilder::new(token, intents) + .framework(framework) + .await?; + + Ok(client) +} |
