From bd6b2f51c6f65d3c35af80c6a41385ed3e86b647 Mon Sep 17 00:00:00 2001 From: Willow <42willow@pm.me> Date: Sat, 1 Jun 2024 21:54:29 +1000 Subject: [PATCH] feat: split files and register guild-specific commands --- src/commands.rs | 21 +++++++++++++ src/main.rs | 80 ++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 84 insertions(+), 17 deletions(-) create mode 100644 src/commands.rs diff --git a/src/commands.rs b/src/commands.rs new file mode 100644 index 0000000..6f290c8 --- /dev/null +++ b/src/commands.rs @@ -0,0 +1,21 @@ +use crate::{Context, Error}; + +#[poise::command(slash_command)] +pub async fn hello(ctx: Context<'_>) -> Result<(), Error> { + ctx.say("world!").await?; + Ok(()) +} + +#[poise::command(slash_command)] +pub async fn ping(ctx: Context<'_>) -> Result<(), Error> { + ctx.say("Pong!").await?; + Ok(()) +} + +#[poise::command(prefix_command)] +pub async fn register(ctx: Context<'_>) -> Result<(), Error> { + if ctx.author().id == 1182451860666318928 { + poise::builtins::register_application_commands_buttons(ctx).await?; + } + Ok(()) +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 29b9bf9..7f13e4b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,39 +1,85 @@ +// see https://github.com/serenity-rs/poise/blob/current/examples/basic_structure/main.rs + +mod commands; + use anyhow::Context as _; -use poise::serenity_prelude::{ClientBuilder, GatewayIntents}; +use poise::serenity_prelude::{ClientBuilder, GatewayIntents, GuildId}; use shuttle_runtime::SecretStore; use shuttle_serenity::ShuttleSerenity; -struct Data {} // User data, which is stored and accessible in all command invocations type Error = Box; type Context<'a> = poise::Context<'a, Data, Error>; -/// Responds with "world!" -#[poise::command(slash_command)] -async fn hello(ctx: Context<'_>) -> Result<(), Error> { - ctx.say("world!").await?; - Ok(()) +// Schooltape Guild ID +const GUILD_ID: GuildId = GuildId::new(1109737131225649283); + +pub struct Data {} + +async fn on_error(error: poise::FrameworkError<'_, Data, Error>) { + match error { + poise::FrameworkError::Setup { error, .. } => panic!("Failed to start bot: {:?}", error), + poise::FrameworkError::Command { error, ctx, .. } => { + println!("Error in command `{}`: {:?}", ctx.command().name, error,); + } + error => { + if let Err(e) = poise::builtins::on_error(error).await { + println!("Error while handling error: {}", e) + } + } + } } #[shuttle_runtime::main] async fn main(#[shuttle_runtime::Secrets] secret_store: SecretStore) -> ShuttleSerenity { - // Get the discord token set in `Secrets.toml` - let discord_token = secret_store - .get("DISCORD_TOKEN") - .context("'DISCORD_TOKEN' was not found")?; + let options = poise::FrameworkOptions { + commands: vec![ + commands::hello(), + commands::register(), + commands::ping(), + ], + // The global error handler for all error cases that may occur + on_error: |error| Box::pin(on_error(error)), + // This code is run before every command + pre_command: |ctx| { + Box::pin(async move { + println!("Executing command {}...", ctx.command().qualified_name); + }) + }, + // This code is run after a command if it was successful (returned Ok) + post_command: |ctx| { + Box::pin(async move { + println!("Executed command {}!", ctx.command().qualified_name); + }) + }, + event_handler: |_ctx, event, _framework, _data| { + Box::pin(async move { + println!( + "Got an event in event handler: {:?}", + event.snake_case_name() + ); + Ok(()) + }) + }, + ..Default::default() + }; let framework = poise::Framework::builder() - .options(poise::FrameworkOptions { - commands: vec![hello()], - ..Default::default() - }) - .setup(|ctx, _ready, framework| { + .setup(move |ctx, _ready, framework| { Box::pin(async move { - poise::builtins::register_globally(ctx, &framework.options().commands).await?; + println!("Logged in as {}", _ready.user.name); + // poise::builtins::register_globally(ctx, &framework.options().commands).await?; + poise::builtins::register_in_guild(ctx, &framework.options().commands, GUILD_ID).await?; Ok(Data {}) }) }) + .options(options) .build(); + // Get the discord token set in `Secrets.toml` + let discord_token = secret_store + .get("DISCORD_TOKEN") + .context("'DISCORD_TOKEN' was not found")?; + let client = ClientBuilder::new(discord_token, GatewayIntents::non_privileged()) .framework(framework) .await