179 lines
5.2 KiB
Rust
179 lines
5.2 KiB
Rust
use nats_libs::{job::JobClient, kv::KVClient};
|
|
use serenity::{
|
|
all::{CommandInteraction, Context, CreateCommandOption},
|
|
builder::CreateCommand,
|
|
model::application::{CommandOptionType, ResolvedOption, ResolvedValue},
|
|
};
|
|
use serenity_libs::functions::CustomInteraction;
|
|
use types::{
|
|
error::{CorroError, CorroErrorType},
|
|
jobs::{DownloadJob, JobsMap, JobsResponseMap, PlayJob, SearchJob},
|
|
misc::{new_uuid_v4, parse_url_or_default},
|
|
queue::{Queue, YoutubeSong},
|
|
};
|
|
use url::Url;
|
|
|
|
use crate::common::Services;
|
|
|
|
pub async fn run(
|
|
services: &Services,
|
|
ctx: &Context,
|
|
interaction: &CommandInteraction,
|
|
) -> Result<(), CorroError> {
|
|
let options = interaction.data.options();
|
|
|
|
if let Some(ResolvedOption {
|
|
value: ResolvedValue::String(value),
|
|
..
|
|
}) = options.first()
|
|
{
|
|
let guild_id = interaction.guild_id.unwrap();
|
|
|
|
let mut queue = match services.jetstream_kv.get_queue(guild_id.into()).await {
|
|
Ok(queue) => queue,
|
|
Err(_why) => {
|
|
let queue = Queue {
|
|
guild_id: guild_id.into(),
|
|
uuid: new_uuid_v4(),
|
|
songs: vec![],
|
|
};
|
|
match services
|
|
.jetstream_kv
|
|
.set_queue(guild_id.into(), &queue)
|
|
.await
|
|
{
|
|
Ok(_sequence) => queue,
|
|
Err(why) => {
|
|
return Err(why);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
println!("{:?}", queue);
|
|
|
|
match interaction
|
|
.create_text_response(ctx, format!("Searching: {value}..."))
|
|
.await
|
|
{
|
|
Ok(_) => {}
|
|
Err(why) => return Err(why),
|
|
};
|
|
|
|
let url: Url;
|
|
let is_url = value.starts_with("https://") || value.starts_with("http://");
|
|
|
|
if !is_url {
|
|
let search_response = match services
|
|
.nats_client
|
|
.send_job(JobsMap::Search(SearchJob {
|
|
uuid: new_uuid_v4(),
|
|
query: value.to_string(),
|
|
}))
|
|
.await
|
|
{
|
|
Ok(resp) => match resp {
|
|
JobsResponseMap::Search(resp) => resp,
|
|
_ => {
|
|
return Err(CorroError {
|
|
error_type: CorroErrorType::JobError,
|
|
message: "Unexpected return type".to_string(),
|
|
});
|
|
}
|
|
},
|
|
Err(why) => return Err(why),
|
|
};
|
|
|
|
url = search_response.song.url;
|
|
} else {
|
|
url = parse_url_or_default(value.to_string());
|
|
}
|
|
|
|
let download_response = match services
|
|
.nats_client
|
|
.send_job(JobsMap::Download(DownloadJob {
|
|
uuid: new_uuid_v4(),
|
|
url,
|
|
}))
|
|
.await
|
|
{
|
|
Ok(resp) => match resp {
|
|
JobsResponseMap::Download(resp) => resp,
|
|
_ => {
|
|
return Err(CorroError {
|
|
error_type: CorroErrorType::JobError,
|
|
message: "Unexpected return type".to_string(),
|
|
});
|
|
}
|
|
},
|
|
Err(why) => return Err(why),
|
|
};
|
|
|
|
queue.songs.push(YoutubeSong {
|
|
title: download_response.test.clone(),
|
|
thumbnail_url: Url::parse("https://example.com").unwrap(),
|
|
url: Url::parse("https://example.com").unwrap(),
|
|
artist: download_response.test,
|
|
});
|
|
|
|
match services.jetstream_kv.set_queue(guild_id.into(), &queue).await {
|
|
Ok(_sequence) => (),
|
|
Err(why) => {
|
|
return Err(why);
|
|
}
|
|
}
|
|
|
|
let channel_id = guild_id
|
|
.get_user_voice_state(&ctx.http, interaction.user.id)
|
|
.await
|
|
.unwrap()
|
|
.channel_id
|
|
.unwrap();
|
|
|
|
match services
|
|
.nats_client
|
|
.send_job(JobsMap::Play(PlayJob {
|
|
uuid: new_uuid_v4(),
|
|
path: download_response.path,
|
|
channel_id: channel_id.into(),
|
|
guild_id: guild_id.into(),
|
|
}))
|
|
.await
|
|
{
|
|
Ok(resp) => match resp {
|
|
JobsResponseMap::Play(resp) => resp,
|
|
_ => {
|
|
return Err(CorroError {
|
|
error_type: CorroErrorType::JobError,
|
|
message: "Unexpected return type".to_string(),
|
|
});
|
|
}
|
|
},
|
|
Err(why) => return Err(why),
|
|
};
|
|
|
|
match interaction
|
|
.edit_text_response(ctx, "Playing...".to_string())
|
|
.await
|
|
{
|
|
Ok(_) => {}
|
|
Err(why) => return Err(why),
|
|
};
|
|
}
|
|
|
|
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(true),
|
|
)
|
|
}
|