Files
corro-dj/apps/master/src/commands/testnats.rs
T
2026-03-11 00:21:56 +01:00

168 lines
4.9 KiB
Rust

use std::path::PathBuf;
use postcard::{from_bytes, to_stdvec};
use serenity::{
all::{
CommandInteraction,
Context,
CreateCommandOption,
CreateInteractionResponse,
CreateInteractionResponseMessage,
EditInteractionResponse,
},
builder::CreateCommand,
model::application::{CommandOptionType, ResolvedOption, ResolvedValue},
};
use types::{
jobs::{DownloadJob, JobResponse, Jobs, PlayJob, SearchJob},
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 url: String;
let is_url = value.starts_with("https://");
if !is_url {
let search_job = SearchJob {
uuid: new_uuid_v4(),
query: value.to_string(),
};
let response = match nats_client
.request("corro-dj.search", to_stdvec(&search_job).unwrap().into())
.await
{
Ok(resp) => resp,
Err(_why) => return Err(serenity::Error::Other("send error")),
};
let search_response: JobResponse = from_bytes(&response.payload).unwrap();
if let Some(error) = search_response.error {
interaction
.edit_response(ctx, EditInteractionResponse::new().content(error))
.await?;
return Err(serenity::Error::Other("Search error"));
} else if let Some(Jobs::Search(content)) = search_response.content {
url = content.url;
} else {
interaction
.edit_response(ctx, EditInteractionResponse::new().content("unknown error"))
.await?;
return Err(serenity::Error::Other("unknown error"));
}
} else {
url = value.to_string();
}
let download_job = DownloadJob {
uuid: new_uuid_v4(),
url,
};
println!("job {:?}", download_job);
let response = match nats_client
.request(
"corro-dj.download",
to_stdvec(&download_job).unwrap().into(),
)
.await
{
Ok(resp) => resp,
Err(_why) => return Err(serenity::Error::Other("send error")),
};
let job_response: JobResponse = from_bytes(&response.payload).unwrap();
println!("response: {:?}", job_response);
let text_response: String;
if let Some(error) = job_response.error {
text_response = error;
} else if let Some(Jobs::Download(content)) = job_response.content {
text_response = content.path.display().to_string();
} else {
text_response = "unkown".to_string();
}
interaction
.edit_response(ctx, EditInteractionResponse::new().content(&text_response))
.await?;
let guild_id = interaction.guild_id.unwrap();
let channel_id = guild_id
.get_user_voice_state(&ctx.http, interaction.user.id)
.await
.unwrap()
.channel_id
.unwrap();
let play_job = PlayJob {
uuid: new_uuid_v4(),
path: PathBuf::from(&text_response),
guild_id: guild_id.into(),
channel_id: channel_id.into(),
};
println!("job {:?}", play_job);
let _ = match nats_client
.request("corro-dj.play", to_stdvec(&play_job).unwrap().into())
.await
{
Ok(resp) => resp,
Err(_why) => return Err(serenity::Error::Other("send error")),
};
interaction
.edit_response(ctx, EditInteractionResponse::new().content("playing..."))
.await?;
} else {
interaction
.create_response(
ctx,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("Please provide a valid string"),
),
)
.await?;
}
Ok(())
}
pub fn register() -> CreateCommand {
CreateCommand::new("play")
.description("Play a song")
.add_option(
CreateCommandOption::new(
CommandOptionType::String,
"song",
"Name or url of the song to play",
)
.required(false),
)
}