cleaner job send function

This commit is contained in:
2026-03-14 00:07:06 +01:00
parent 8ed01f2049
commit b63982714b
13 changed files with 186 additions and 89 deletions
+1
View File
@@ -5,6 +5,7 @@ edition = "2024"
[dependencies]
async-nats = { version = "0.46.0" }
nats = { path = "../../libs/nats" }
postcard = { version = "1.1.3", features = ["use-std"] }
serenity = { version = "0.12.5", default-features = false, features = [
"cache",
+79 -18
View File
@@ -1,16 +1,18 @@
use std::path::PathBuf;
use postcard::{from_bytes, to_stdvec};
use nats::functions::JobClient;
use serenity::{
all::{
CommandInteraction, Context, CreateCommandOption, CreateInteractionResponse,
CreateInteractionResponseMessage, EditInteractionResponse,
CommandInteraction,
Context,
CreateCommandOption,
CreateInteractionResponse,
CreateInteractionResponseMessage,
EditInteractionResponse,
},
builder::CreateCommand,
model::application::{CommandOptionType, ResolvedOption, ResolvedValue},
};
use types::{
jobs::{DownloadJob, JobResponse, Jobs, PlayJob, SearchJob},
jobs::{DownloadJob, JobsMap, JobsResponseMap, PlayJob, SearchJob},
misc::{new_uuid_v4, parse_url_or_default},
};
use url::Url;
@@ -27,26 +29,85 @@ pub async fn run(
..
}) = options.first()
{
interaction
.create_response(
ctx,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content(format!("Searching: {value}...")),
),
)
.await?;
let url: Url;
let is_url = value.starts_with("https://") || value.starts_with("http://");
if !is_url {
let response = match nats_client
.request(
"corro-dj.search",
to_stdvec(&SearchJob {
uuid: new_uuid_v4(),
query: value.to_string(),
})
.unwrap()
.into(),
)
let search_response = match nats_client
.send_job(JobsMap::Search(SearchJob {
uuid: new_uuid_v4(),
query: value.to_string(),
}))
.await
{
Ok(resp) => resp,
Ok(resp) => match resp {
JobsResponseMap::Search(resp) => resp,
_ => return Err(serenity::Error::Other("Unexpected return type")),
},
Err(_why) => return Err(serenity::Error::Other("send error")),
};
println!("{:?}", &search_response);
url = search_response.song.url;
} else {
url = parse_url_or_default(value.to_string());
}
let download_response = match nats_client
.send_job(JobsMap::Download(DownloadJob {
uuid: new_uuid_v4(),
url,
}))
.await
{
Ok(resp) => match resp {
JobsResponseMap::Download(resp) => resp,
_ => return Err(serenity::Error::Other("Unexpected return type")),
},
Err(_why) => return Err(serenity::Error::Other("send error")),
};
println!("{:?}", &download_response);
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 _ = match 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(serenity::Error::Other("Unexpected return type")),
},
Err(_why) => return Err(serenity::Error::Other("send error")),
};
interaction
.edit_response(ctx, EditInteractionResponse::new().content("Playing..."))
.await?;
}
Ok(())
}
@@ -60,6 +121,6 @@ pub fn register() -> CreateCommand {
"song",
"Name or url of the song to play",
)
.required(false),
.required(true),
)
}
+3 -3
View File
@@ -14,7 +14,7 @@ use serenity::{
model::application::{CommandOptionType, ResolvedOption, ResolvedValue},
};
use types::{
jobs::{DownloadJob, JobResponse, Jobs, PlayJob, SearchJob},
jobs::{DownloadJob, JobResponse, JobsResponseMap, PlayJob, SearchJob},
misc::{new_uuid_v4, parse_url_or_default},
};
use url::Url;
@@ -65,7 +65,7 @@ pub async fn run(
.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 {
} else if let Some(JobsResponseMap::Search(content)) = search_response.content {
url = content.song.url;
} else {
interaction
@@ -102,7 +102,7 @@ pub async fn run(
let text_response: String;
if let Some(error) = job_response.error {
text_response = error;
} else if let Some(Jobs::Download(content)) = job_response.content {
} else if let Some(JobsResponseMap::Download(content)) = job_response.content {
text_response = content.path.display().to_string();
} else {
text_response = "unkown".to_string();
-5
View File
@@ -2,7 +2,6 @@ mod commands;
use std::env;
use async_nats::Client;
use serenity::{
Client,
all::{Context, EventHandler, GatewayIntents},
@@ -69,10 +68,6 @@ impl EventHandler for Handler {
}
}
impl A for Client {
}
#[tokio::main]
async fn main() {
// Configure the client with your Discord bot token in the environment.
+5 -2
View File
@@ -7,8 +7,11 @@ edition = "2024"
async-nats = { version = "0.46.0" }
futures = { version = "0.3.32" }
futures-executor = { version = "0.3.32" }
nats = { path = "../../libs/nats" }
postcard = { version = "1.1.3", features = ["use-std"] }
rustls = { version = "0.23.37", default-features = false, features = ["aws-lc-rs"] }
rustls = { version = "0.23.37", default-features = false, features = [
"aws-lc-rs",
] }
serenity = { version = "0.12.5", default-features = false, features = [
"cache",
"rustls_backend",
@@ -19,4 +22,4 @@ symphonia = { version = "0.5.5" }
tokio = { version = "1.50.0", features = ["macros", "rt-multi-thread"] }
types = { path = "../../libs/types" }
which = { version = "8.0.2" }
yt-dlp = { version = "2.5.0" }
yt-dlp = { version = "2.6.0" }
+20 -24
View File
@@ -10,7 +10,7 @@ use serenity::{
async_trait,
};
use songbird::SerenityInit;
use types::jobs::{JobResponse, Jobs};
use types::jobs::{JobResponse, JobsMap, JobsResponseMap};
use which::which;
use yt_dlp::{Downloader, client::Libraries};
@@ -36,36 +36,32 @@ impl EventHandler for Handler {
while let Some(message) = subscriber.next().await {
println!("Received message {:?}", message);
let subject = message.subject.split(".").collect::<Vec<&str>>()[1];
// let subject = message.subject.split(".").collect::<Vec<&str>>()[1];
let payload: JobsMap = from_bytes(&message.payload).unwrap();
let result = match subject {
"download" => workers::download::download(
&self.downloader,
from_bytes(&message.payload).unwrap(),
)
.await
.map(|res| JobResponse {
content: res.content.map(Jobs::Download),
error: res.error,
}),
"play" => {
workers::play::play(&voice_manager, from_bytes(&message.payload).unwrap())
let result =
match payload {
JobsMap::Download(payload) => {
workers::download::download(&self.downloader, payload)
.await
.map(|res| JobResponse {
content: res.content.map(JobsResponseMap::Download),
error: res.error,
})
}
JobsMap::Play(payload) => workers::play::play(&voice_manager, payload)
.await
.map(|res| JobResponse {
content: res.content.map(Jobs::Play),
content: res.content.map(JobsResponseMap::Play),
error: res.error,
})
}
"search" => {
workers::search::search(&self.downloader, from_bytes(&message.payload).unwrap())
}),
JobsMap::Search(payload) => workers::search::search(&self.downloader, payload)
.await
.map(|res| JobResponse {
content: res.content.map(Jobs::Search),
content: res.content.map(JobsResponseMap::Search),
error: res.error,
})
}
_ => Err(format!("subject {subject} does not exists")),
};
}),
};
let response = match result {
Ok(response) => response,
+5 -2
View File
@@ -28,10 +28,13 @@ pub async fn download(
Err(err) => return Err(err.to_string()),
};
println!("reply: {:?}", audio_path);
println!("audio_path: {:?}", &audio_path);
Ok(JobResponse {
content: Some(DownloadResponse { path: audio_path }),
content: Some(DownloadResponse {
path: audio_path.clone(),
test: audio_path.display().to_string(),
}),
error: None,
})
}
-4
View File
@@ -37,12 +37,8 @@ pub async fn play(
let track_handle = handler.play_input(src.into());
println!("before info {:?}", track_handle);
println!("{:?}", track_handle.get_info().await);
println!("after info");
Ok(JobResponse {
content: Some(PlayResponse {}),
error: None,