folders structure

This commit is contained in:
2026-03-01 18:39:22 +01:00
parent f273c60f35
commit a2a677eaaa
14 changed files with 6 additions and 3 deletions
+3
View File
@@ -0,0 +1,3 @@
pub mod modal;
pub mod ping;
pub mod testnats;
+28
View File
@@ -0,0 +1,28 @@
use serenity::{builder::*, model::prelude::*, prelude::*, utils::CreateQuickModal};
pub async fn run(ctx: &Context, interaction: &CommandInteraction) -> Result<(), serenity::Error> {
let modal = CreateQuickModal::new("About you")
.timeout(std::time::Duration::from_secs(600))
.short_field("First name")
.short_field("Last name")
.paragraph_field("Hobbies and interests");
let response = interaction.quick_modal(ctx, modal).await?.unwrap();
let inputs = response.inputs;
let (first_name, last_name, hobbies) = (&inputs[0], &inputs[1], &inputs[2]);
response
.interaction
.create_response(
ctx,
CreateInteractionResponse::Message(CreateInteractionResponseMessage::new().content(
format!("**Name**: {first_name} {last_name}\n\nHobbies and interests: {hobbies}"),
)),
)
.await?;
Ok(())
}
pub fn register() -> CreateCommand {
CreateCommand::new("modal").description("Asks some details about you")
}
+9
View File
@@ -0,0 +1,9 @@
use serenity::{builder::CreateCommand, model::application::ResolvedOption};
pub fn run(_options: &[ResolvedOption]) -> String {
"Hey, I'm alive!".to_string()
}
pub fn register() -> CreateCommand {
CreateCommand::new("ping").description("A ping command")
}
+91
View File
@@ -0,0 +1,91 @@
use std::str::from_utf8;
use postcard::to_stdvec;
use serenity::{
all::{
CommandInteraction,
Context,
CreateCommandOption,
CreateInteractionResponse,
CreateInteractionResponseMessage,
EditInteractionResponse,
},
builder::CreateCommand,
model::application::{CommandOptionType, ResolvedOption, ResolvedValue},
};
use types::{
jobs::{InnerStruct, Job, JobKind},
misc::new_uuid_v4,
};
pub async fn run(
ctx: &Context,
interaction: &CommandInteraction,
nats_client: &async_nats::Client,
) -> Result<(), serenity::Error> {
let options = interaction.data.options();
if let Some(ResolvedOption {
value: ResolvedValue::String(value),
..
}) = options.first()
{
interaction
.create_response(
ctx,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content(format!("Searching: {value}...")),
),
)
.await?;
let job = Job {
uuid: new_uuid_v4(),
kind: JobKind::Download,
inner: InnerStruct {
str: value.to_string(),
},
};
println!("job {:?}", job);
let response = match nats_client
.request("corro-dj.download", to_stdvec(&job).unwrap().into())
.await
{
Ok(resp) => resp,
Err(_why) => return Err(serenity::Error::Other("send error")),
};
println!("response: {:?}", from_utf8(&response.payload).unwrap());
interaction
.edit_response(
ctx,
EditInteractionResponse::new()
.content(format!("path: {}", from_utf8(&response.payload).unwrap())),
)
.await?;
} else {
interaction
.create_response(
ctx,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("Please provide a valid string"),
),
)
.await?;
}
Ok(())
}
pub fn register() -> CreateCommand {
CreateCommand::new("testnats")
.description("test nats")
.add_option(
CreateCommandOption::new(CommandOptionType::String, "str", "random string")
.required(false),
)
}
+92
View File
@@ -0,0 +1,92 @@
mod commands;
use std::env;
use serenity::{
Client,
all::{Context, EventHandler, GatewayIntents},
async_trait,
builder::{CreateInteractionResponse, CreateInteractionResponseMessage},
model::{
application::{Command, Interaction},
gateway::Ready,
},
};
struct Handler {
nats_client: async_nats::Client,
}
#[async_trait]
impl EventHandler for Handler {
async fn interaction_create(&self, ctx: Context, interaction: Interaction) {
if let Interaction::Command(command) = interaction {
println!("Received command interaction: {command:#?}");
let content = match command.data.name.as_str() {
"testnats" => {
commands::testnats::run(&ctx, &command, &self.nats_client)
.await
.unwrap();
None
}
"ping" => Some(commands::ping::run(&command.data.options())),
"modal" => {
commands::modal::run(&ctx, &command).await.unwrap();
None
}
_ => Some("not implemented :(".to_string()),
};
if let Some(content) = content {
let data = CreateInteractionResponseMessage::new().content(content);
let builder = CreateInteractionResponse::Message(data);
if let Err(why) = command.create_response(&ctx.http, builder).await {
println!("Cannot respond to slash command: {why}");
}
}
}
}
async fn ready(&self, ctx: Context, ready: Ready) {
println!("{} is connected!", ready.user.name);
let commands = Command::set_global_commands(
&ctx.http,
vec![
commands::ping::register(),
commands::modal::register(),
commands::testnats::register(),
],
)
.await;
println!("I now have the following slash commands: {commands:#?}");
}
}
#[tokio::main]
async fn main() {
// Configure the client with your Discord bot token in the environment.
let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
let nats_client = async_nats::connect("nats://localhost:4222")
.await
.expect("Error creating nats client");
let handler = Handler { nats_client };
// Build our client.
let mut discord_client = Client::builder(token, GatewayIntents::empty())
.event_handler(handler)
.await
.expect("Error creating discord client");
// Finally, start a single shard, and start listening to events.
//
// Shards will automatically attempt to reconnect, and will perform exponential backoff until
// it reconnects.
if let Err(why) = discord_client.start().await {
println!("Client error: {why:?}");
}
}