168 lines
4.9 KiB
Rust
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),
|
|
)
|
|
}
|