From b58729e9192c160e1771f07c11b4bcbe6115ed00 Mon Sep 17 00:00:00 2001 From: Alex-Emmet Date: Thu, 29 Jan 2026 21:51:17 +0100 Subject: [PATCH] [QOL] Call Utility --- Cargo.lock | 1 + Cargo.toml | 1 + src/calls/call_group.rs | 7 +++ src/calls/call_util.rs | 91 ++++++++++++++++++++++++++---------- src/rho/client_connection.rs | 3 +- 5 files changed, 77 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1d9c439..c269643 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,6 +30,7 @@ dependencies = [ "json", "livekit", "livekit-api", + "livekit-protocol", "log", "loom", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index 7f08200..798d224 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,3 +88,4 @@ strum_macros = "0.27.2" livekit = "0.7.25" livekit-api = { version = "0.4.10", features = ["native-tls"] } hyper = { version = "1.8.1", features = ["http1", "http2"] } +livekit-protocol = "0.6.0" diff --git a/src/calls/call_group.rs b/src/calls/call_group.rs index 04208fe..474a90d 100644 --- a/src/calls/call_group.rs +++ b/src/calls/call_group.rs @@ -44,6 +44,12 @@ impl CallGroup { pub async fn set_anonymous_joining(&self, enable: bool) { *self.anonymous_joining.write().await = enable; + let _ = call_util::set_room_metadata( + self.call_id, + format!("{{\"anonymous_joining\": \"{}\"}}", enable), + ) + .await; + if self.short_link.read().await.is_none() { let long_link = format!( "https://app.tensamin.net/call/anonymous?call_id={}&omikron_id={}", @@ -88,6 +94,7 @@ impl CallGroup { } pub async fn remove_caller(&self, user_id: i64) { + let _ = call_util::remove_participant(self.call_id, user_id).await; self.members .write() .await diff --git a/src/calls/call_util.rs b/src/calls/call_util.rs index 105290e..4ab5f0c 100644 --- a/src/calls/call_util.rs +++ b/src/calls/call_util.rs @@ -2,6 +2,7 @@ use livekit_api::{ access_token::{self}, services::room::RoomClient, }; +use livekit_protocol::Room; use std::env; use std::str::FromStr; use std::time::Duration; @@ -9,7 +10,14 @@ use uuid::Uuid; use crate::{calls::call_manager::CALL_GROUPS, log, log_err, util::logger::PrintType}; -pub fn create_token(user_id: i64, call_id: Uuid, has_admin: bool) -> Result { +pub fn get_livekit() -> Result<(String, String, String), ()> { + let hostname = match env::var("LIVEKI_HOSTNAME") { + Ok(secret) => secret, + Err(_) => { + log_err!(PrintType::General, "LIVEKI_HOSTNAME not set!"); + return Err(()); + } + }; let api_key = match env::var("LIVEKIT_API_KEY") { Ok(key) => key, Err(_) => { @@ -24,11 +32,15 @@ pub fn create_token(user_id: i64, call_id: Uuid, has_admin: bool) -> Result Result { + let (_, api_key, api_secret) = get_livekit()?; let token = access_token::AccessToken::with_api_key(&api_key, &api_secret) .with_identity(&user_id.to_string()) .with_grants(access_token::VideoGrants { - can_update_own_metadata: true, room_join: true, room_admin: has_admin, room: call_id.to_string(), @@ -42,33 +54,62 @@ pub fn create_token(user_id: i64, call_id: Uuid, has_admin: bool) -> Result Result<(RoomClient, Room), ()> { + if let Ok((hostname, api_key, api_secret)) = get_livekit() { + let room_service = RoomClient::with_api_key(&hostname, &api_key, &api_secret); + let rooms = room_service.list_rooms(Vec::new()).await; + if let Ok(rooms) = rooms { + for room in rooms { + if room.name == call_id.to_string() { + return Ok((room_service, room)); + } + } + } + } + return Err(()); +} + +pub async fn remove_participant(call_id: Uuid, user_id: i64) -> Result<(), ()> { + if let Ok((hostname, api_key, api_secret)) = get_livekit() { + let room_service = RoomClient::with_api_key(&hostname, &api_key, &api_secret); + if let Ok(_) = room_service + .remove_participant(&call_id.to_string(), &user_id.to_string()) + .await + { + return Ok(()); + } + } + return Err(()); +} + +pub async fn get_room_metadata(call_id: Uuid) -> Result { + if let Ok((_, room)) = get_room(call_id).await { + Ok(room.metadata) + } else { + Err(()) + } +} + +pub async fn set_room_metadata(call_id: Uuid, metadata: String) -> Result<(), ()> { + if let Ok((hostname, api_key, api_secret)) = get_livekit() { + let room_service = RoomClient::with_api_key(&hostname, &api_key, &api_secret); + if let Ok(_) = room_service + .update_room_metadata(&call_id.to_string(), &metadata) + .await + { + return Ok(()); + } + } + return Err(()); +} pub fn garbage_collect_calls() { tokio::spawn(async move { - let api_key = match env::var("LIVEKIT_API_KEY") { - Ok(key) => key, - Err(_) => { - log_err!(PrintType::General, "LIVEKIT_API_KEY not set!"); - return; - } - }; - let api_secret = match env::var("LIVEKIT_API_SECRET") { - Ok(secret) => secret, - Err(_) => { - log_err!(PrintType::General, "LIVEKIT_API_SECRET not set!"); - return; - } - }; - let hostname = match env::var("LIVEKI_HOSTNAME") { - Ok(secret) => secret, - Err(_) => { - log_err!(PrintType::General, "LIVEKI_HOSTNAME not set!"); - return; - } - }; loop { - let room_service = RoomClient::with_api_key(&hostname, &api_key, &api_secret); - clean_calls(room_service).await; + if let Ok((hostname, api_key, api_secret)) = get_livekit() { + let room_service = RoomClient::with_api_key(&hostname, &api_key, &api_secret); + clean_calls(room_service).await; + } tokio::time::sleep(Duration::from_secs(2)).await; } }); diff --git a/src/rho/client_connection.rs b/src/rho/client_connection.rs index 7ebdf77..c384bec 100644 --- a/src/rho/client_connection.rs +++ b/src/rho/client_connection.rs @@ -14,7 +14,7 @@ use uuid::Uuid; use super::{rho_connection::RhoConnection, rho_manager}; use crate::anonymous_clients::anonymous_manager; -use crate::calls::call_manager; +use crate::calls::{call_manager, call_util}; use crate::omega::omega_connection::{WAITING_TASKS, get_omega_connection}; use crate::util::crypto_helper::{load_public_key, public_key_to_base64}; use crate::util::crypto_util::{DataFormat, SecurePayload}; @@ -532,6 +532,7 @@ impl ClientConnection { .unwrap() .has_admin() { + let _ = call_util::remove_participant(call_id, user_id).await; call.get_caller(user_id) .await .unwrap()