From c2e3982cc54a2165aa4e001faadc1a3bcc0fd5bc Mon Sep 17 00:00:00 2001 From: Fluffy-Bean Date: Sat, 25 Feb 2023 12:56:24 +0000 Subject: [PATCH] Followed Serenity's example code --- src/commands/attachmentinput.rs | 35 +++++++++++++ src/commands/id.rs | 33 ++++++++++++ src/commands/mod.rs | 5 ++ src/commands/numberinput.rs | 30 +++++++++++ src/commands/ping.rs | 12 +++++ src/commands/wonderful_command.rs | 5 ++ src/main.rs | 84 +++++++++++++++++++++++-------- 7 files changed, 184 insertions(+), 20 deletions(-) create mode 100644 src/commands/attachmentinput.rs create mode 100644 src/commands/id.rs create mode 100644 src/commands/mod.rs create mode 100644 src/commands/numberinput.rs create mode 100644 src/commands/ping.rs create mode 100644 src/commands/wonderful_command.rs diff --git a/src/commands/attachmentinput.rs b/src/commands/attachmentinput.rs new file mode 100644 index 0000000..5698362 --- /dev/null +++ b/src/commands/attachmentinput.rs @@ -0,0 +1,35 @@ +use serenity::{ + builder::CreateApplicationCommand, + model::prelude::command::CommandOptionType, + model::prelude::interaction::application_command::{ + CommandDataOption, + CommandDataOptionValue, + } +}; + +pub fn run(options: &[CommandDataOption]) -> String { + let option = options + .get(0) + .expect("Expected attachment option") + .resolved + .as_ref() + .expect("Expected attachment object"); + + if let CommandDataOptionValue::Attachment(attachment) = option { + format!("Attachment name: {}, attachment size: {}", attachment.filename, attachment.size) + } else { + "Please provice a valid attachment".to_string() + } +} + +pub fn register(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand { + command.name("attachmentinput").description("Test command for attachment input").create_option( + |option| { + option + .name("attachment") + .description("A file") + .kind(CommandOptionType::Attachment) + .required(true) + } + ) +} \ No newline at end of file diff --git a/src/commands/id.rs b/src/commands/id.rs new file mode 100644 index 0000000..3f19c74 --- /dev/null +++ b/src/commands/id.rs @@ -0,0 +1,33 @@ +use serenity::{ + builder::CreateApplicationCommand, + model::prelude::command::CommandOptionType, + model::prelude::interaction::application_command::{ + CommandDataOption, + CommandDataOptionValue, + } +}; + +pub fn run(options: &[CommandDataOption]) -> String { + let option = options + .get(0) + .expect("Expected user option") + .resolved + .as_ref() + .expect("Expected user object"); + + if let CommandDataOptionValue::User(user, _member) = option { + format!("{}'s id is {}", user.tag(), user.id) + } else { + "Please provide a valid user".to_string() + } +} + +pub fn register(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand { + command.name("id").description("Get a user id").create_option(|option| { + option + .name("id") + .description("The user to lookup") + .kind(CommandOptionType::User) + .required(true) + }) +} \ No newline at end of file diff --git a/src/commands/mod.rs b/src/commands/mod.rs new file mode 100644 index 0000000..46b52eb --- /dev/null +++ b/src/commands/mod.rs @@ -0,0 +1,5 @@ +pub mod attachmentinput; +pub mod id; +pub mod numberinput; +pub mod ping; +pub mod wonderful_command; \ No newline at end of file diff --git a/src/commands/numberinput.rs b/src/commands/numberinput.rs new file mode 100644 index 0000000..1c4edc1 --- /dev/null +++ b/src/commands/numberinput.rs @@ -0,0 +1,30 @@ +use serenity::{ + builder, + model::prelude::command::CommandOptionType, +}; + +pub fn register( + command: &mut builder::CreateApplicationCommand, +) -> &mut builder::CreateApplicationCommand { + command + .name("numberinput") + .description("Test command for number input") + .create_option(|option| { + option + .name("int") + .description("An integer from 1 to 69") + .kind(CommandOptionType::Integer) + .min_int_value(1) + .max_int_value(69) + .required(true) + }) + .create_option(|option| { + option + .name("float") + .description("A float from -2.1 to 621.69") + .kind(CommandOptionType::Number) + .min_number_value(-2.1) + .max_number_value(621.69) + .required(true) + }) +} diff --git a/src/commands/ping.rs b/src/commands/ping.rs new file mode 100644 index 0000000..2652e9b --- /dev/null +++ b/src/commands/ping.rs @@ -0,0 +1,12 @@ +use serenity::{ + builder::CreateApplicationCommand, + model::prelude::interaction::application_command::CommandDataOption, +}; + +pub fn run(_options: &[CommandDataOption]) -> String { + "Pong! :3".to_string() +} + +pub fn register(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand { + command.name("ping").description("Ping the bot") +} \ No newline at end of file diff --git a/src/commands/wonderful_command.rs b/src/commands/wonderful_command.rs new file mode 100644 index 0000000..912ca81 --- /dev/null +++ b/src/commands/wonderful_command.rs @@ -0,0 +1,5 @@ +use serenity::builder::CreateApplicationCommand; + +pub fn _register(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand { + command.name("wonderful_command").description("A wonderful command") +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index bc13af9..01ecb02 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,17 @@ +mod commands; + use dotenv::dotenv; use std::env; use serenity::{ async_trait, - model::{channel::Message, gateway::Ready}, +// model::application::command::Command, + model::application::interaction::{ + Interaction, + InteractionResponseType, + }, + model::gateway::Ready, + model::id::GuildId, prelude::*, }; @@ -12,33 +20,69 @@ struct Handler; #[async_trait] impl EventHandler for Handler { - // Create a handler for a new message event - async fn message(&self, ctx: Context, msg: Message) { - if msg.content == "ping" { - // Set Reply to "pong" - let reply: &str = "pong"; + // Create a handler for slash commands + async fn interaction_create(&self, ctx: Context, interaction: Interaction) { + if let Interaction::ApplicationCommand(command) = interaction { + println!("Heard command: {:?}", command); - if let Err(why) = msg.channel_id.say(&ctx.http, reply).await { - // If an error occurs, display it - println!("Error sending message: {:?}", why); - } - } + // Create a string to hold the response + let content = match command.data.name.as_str() { + "ping" => commands::ping::run(&command.data.options), + "id" => commands::id::run(&command.data.options), + "attachmentinput" => commands::attachmentinput::run(&command.data.options), + _ => "Not implemented :c".to_string(), + }; - if msg.content == "pale" { - // Set Reply to "We should ban this guy" - let reply: &str = "We should ban this guy"; - - if let Err(why) = msg.channel_id.say(&ctx.http, reply).await { - // If an error occurs, display it - println!("Error sending message: {:?}", why); + // Respond to the command + if let Err(why) = command + .create_interaction_response(&ctx.http, |response| { + response + .kind(InteractionResponseType::ChannelMessageWithSource) + .interaction_response_data(|message| message.content(content)) + }) + .await + { + // Oups, something went wrong D: + println!("Error responding to command: {:?}", why); } } } // Create a handler for when the bot is ready - async fn ready(&self, _: Context, ready: Ready) { + async fn ready(&self, ctx: Context, ready: Ready) { // Display that the bot is ready along with the username println!("{} is ready Bitch!", ready.user.name); + + // Set guild to register commands in + // Much faster than waiting for commands to be avaiable globally + let guild_id = GuildId( + env::var("GUILD_ID") + .expect("No GUILD_ID variable found!!!!!") + .parse() + .expect("GUILD_ID must be an intiger :<") + ); + + let _commands = GuildId::set_application_commands(&guild_id, &ctx.http, |commands| { + commands + .create_application_command(|command| commands::ping::register(command)) + .create_application_command(|command| commands::id::register(command)) + .create_application_command(|command| commands::numberinput::register(command)) + .create_application_command(|command| commands::attachmentinput::register(command)) + }) + .await; + + println!("Guild {} has been registered!", guild_id); // commands + + // Set global commands + // This is slow and should be commented out when testing + /* + let guild_command = Command::create_global_application_command(&ctx.http, |command| { + commands::wonderful_command::register(command) + }) + .await; + + println!("Following comamnds available globally!: {:#?}", guild_command); + */ } } @@ -46,7 +90,7 @@ impl EventHandler for Handler { async fn main() { // Load dotenv file and yoink the token dotenv().ok(); - let token = env::var("DISCORD_TOKEN").expect("No Env enviroment variable found!"); + let token = env::var("DISCORD_TOKEN").expect("No DISCORD_TOKEN variable found!!!!!"); // Set the bots intents let intents = GatewayIntents::GUILD_MESSAGES