diff --git a/src/routes/bots/edit.rs b/src/routes/bots/edit.rs index d1f7cb95..0395744f 100644 --- a/src/routes/bots/edit.rs +++ b/src/routes/bots/edit.rs @@ -99,7 +99,7 @@ pub async fn edit_bot( } } - db.update_bot(&bot.id, &partial, remove.unwrap_or_else(Vec::new)) + db.update_bot(&bot.id, &partial, remove.unwrap_or_default()) .await?; bot.apply_options(partial); diff --git a/src/routes/bots/fetch_public.rs b/src/routes/bots/fetch_public.rs index 20d3f6a4..9bd61fd5 100644 --- a/src/routes/bots/fetch_public.rs +++ b/src/routes/bots/fetch_public.rs @@ -36,6 +36,6 @@ pub async fn fetch_public_bot(db: &Db, target: Ref) -> Result> { id: bot.id, username: user.username, avatar: user.avatar, - description: user.profile.map(|p| p.content).flatten(), + description: user.profile.and_then(|p| p.content), })) } diff --git a/src/routes/channels/voice_join.rs b/src/routes/channels/voice_join.rs index 4f2bad49..5ceb2273 100644 --- a/src/routes/channels/voice_join.rs +++ b/src/routes/channels/voice_join.rs @@ -1,4 +1,9 @@ -use revolt_quark::{models::User, Ref, Result}; +use revolt_quark::{ + models::{Channel, User}, + perms, + variables::delta::{USE_VOSO, VOSO_MANAGE_TOKEN, VOSO_URL}, + Db, Error, Permission, Ref, Result, +}; use rocket::serde::json::Json; use serde::{Deserialize, Serialize}; @@ -14,7 +19,82 @@ pub struct CreateVoiceUserResponse { /// /// Asks the voice server for a token to join the call. #[openapi(tag = "Voice")] -#[post("/<_target>/join_call")] -pub async fn req(_user: User, _target: Ref) -> Result> { - unimplemented!() +#[post("//join_call")] +pub async fn req(db: &Db, user: User, target: Ref) -> Result> { + let channel = target.as_channel(db).await?; + let mut permissions = perms(&user).channel(&channel); + + permissions + .throw_permission_and_view_channel(db, Permission::Connect) + .await?; + + if !*USE_VOSO { + return Err(Error::VosoUnavailable); + } + + match channel { + Channel::SavedMessages { .. } | Channel::TextChannel { .. } => { + return Err(Error::CannotJoinCall) + } + _ => {} + } + + // To join a call: + // - Check if the room exists. + // - If not, create it. + let client = reqwest::Client::new(); + let result = client + .get(&format!("{}/room/{}", *VOSO_URL, channel.id())) + .header( + reqwest::header::AUTHORIZATION, + VOSO_MANAGE_TOKEN.to_string(), + ) + .send() + .await; + + match result { + Err(_) => return Err(Error::VosoUnavailable), + Ok(result) => match result.status() { + reqwest::StatusCode::OK => (), + reqwest::StatusCode::NOT_FOUND => { + if (client + .post(&format!("{}/room/{}", *VOSO_URL, channel.id())) + .header( + reqwest::header::AUTHORIZATION, + VOSO_MANAGE_TOKEN.to_string(), + ) + .send() + .await) + .is_err() + { + return Err(Error::VosoUnavailable); + } + } + _ => return Err(Error::VosoUnavailable), + }, + } + + // Then create a user for the room. + if let Ok(response) = client + .post(&format!( + "{}/room/{}/user/{}", + *VOSO_URL, + channel.id(), + user.id + )) + .header( + reqwest::header::AUTHORIZATION, + VOSO_MANAGE_TOKEN.to_string(), + ) + .send() + .await + { + response + .json() + .await + .map_err(|_| Error::InvalidOperation) + .map(Json) + } else { + Err(Error::VosoUnavailable) + } }