From e1f89b69ea117f166be423f035a5a34f4c0e7366 Mon Sep 17 00:00:00 2001 From: tototomate123 Date: Tue, 28 Oct 2025 21:51:36 +0100 Subject: [PATCH] feat: Add Element Call / MatrixRTC support --- src/api/client/capabilities.rs | 11 +++++++ src/api/client/well_known.rs | 58 +++++++++++++++++++++++++++------- src/api/router.rs | 3 +- src/core/config/mod.rs | 20 ++++++++++++ tuwunel-example.toml | 20 ++++++++++++ 5 files changed, 100 insertions(+), 12 deletions(-) diff --git a/src/api/client/capabilities.rs b/src/api/client/capabilities.rs index 5cae8a1a..7983c168 100644 --- a/src/api/client/capabilities.rs +++ b/src/api/client/capabilities.rs @@ -51,5 +51,16 @@ pub(crate) async fn get_capabilities_route( json!({"enabled": services.config.forget_forced_upon_leave}), )?; + // MSC4143: MatrixRTC - advertise RTC transport support + if !services + .server + .config + .well_known + .rtc_transports + .is_empty() + { + capabilities.set("org.matrix.msc4143.rtc_foci", json!({"supported": true}))?; + } + Ok(get_capabilities::v3::Response { capabilities }) } diff --git a/src/api/client/well_known.rs b/src/api/client/well_known.rs index 4dff3b3e..8ab1c0e0 100644 --- a/src/api/client/well_known.rs +++ b/src/api/client/well_known.rs @@ -1,8 +1,6 @@ use axum::{Json, extract::State, response::IntoResponse}; -use ruma::api::client::discovery::{ - discover_homeserver::{self, HomeserverInfo}, - discover_support::{self, Contact}, -}; +use ruma::api::client::discovery::discover_support::{self, Contact}; +use serde_json::{Value, json}; use tuwunel_core::{Err, Result}; use crate::Ruma; @@ -10,20 +8,58 @@ use crate::Ruma; /// # `GET /.well-known/matrix/client` /// /// Returns the .well-known URL if it is configured, otherwise returns 404. +/// Also includes RTC transport configuration for Element Call (MSC4143). pub(crate) async fn well_known_client( State(services): State, - _body: Ruma, -) -> Result { +) -> Result> { let client_url = match services.server.config.well_known.client.as_ref() { | Some(url) => url.to_string(), | None => return Err!(Request(NotFound("Not found."))), }; - Ok(discover_homeserver::Response { - homeserver: HomeserverInfo { base_url: client_url }, - identity_server: None, - tile_server: None, - }) + let mut response = json!({ + "m.homeserver": { + "base_url": client_url + } + }); + + // Add RTC transport configuration if available (MSC4143 / Element Call) + // Element Call has evolved through several versions with different field + // expectations + if !services + .server + .config + .well_known + .rtc_transports + .is_empty() + { + if let Some(obj) = response.as_object_mut() { + // Element Call expects "org.matrix.msc4143.rtc_foci" (not rtc_foci_preferred) + // with an array of transport objects + obj.insert( + "org.matrix.msc4143.rtc_foci".to_owned(), + json!(services.server.config.well_known.rtc_transports), + ); + + // Also add the LiveKit URL directly for backward compatibility + if let Some(first_transport) = services + .server + .config + .well_known + .rtc_transports + .first() + { + if let Some(livekit_url) = first_transport.get("livekit_service_url") { + obj.insert( + "org.matrix.msc4143.livekit_service_url".to_owned(), + livekit_url.clone(), + ); + } + } + } + } + + Ok(Json(response)) } /// # `GET /.well-known/matrix/support` diff --git a/src/api/router.rs b/src/api/router.rs index 05eb0530..196192a9 100644 --- a/src/api/router.rs +++ b/src/api/router.rs @@ -190,7 +190,8 @@ pub fn build(router: Router, server: &Server) -> Router { get(client::get_room_summary_legacy) ) .ruma_route(&client::well_known_support) - .ruma_route(&client::well_known_client) + // this is the only thing currently needed to support Element Video Rooms / Calls. + .route("/.well-known/matrix/client", get(client::well_known_client)) .route("/_tuwunel/server_version", get(client::tuwunel_server_version)) .ruma_route(&client::room_initial_sync_route) .route("/client/server.json", get(client::syncv3_client_server_json)); diff --git a/src/core/config/mod.rs b/src/core/config/mod.rs index 0bb2da4e..9dc1fd80 100644 --- a/src/core/config/mod.rs +++ b/src/core/config/mod.rs @@ -2146,6 +2146,26 @@ pub struct WellKnownConfig { /// /// example "@admin:example.com" pub support_mxid: Option, + + /// Element Call / MatrixRTC configuration (MSC4143). + /// Configures the LiveKit SFU server for voice/video calls. + /// + /// Requires a LiveKit server with JWT authentication. + /// The `livekit_service_url` should point to your LiveKit JWT endpoint. + /// + /// Note: You must also set `client` above to your homeserver URL. + /// + /// Example: + /// ```toml + /// [global.well_known] + /// client = "https://matrix.yourdomain.com" + /// + /// [[global.well_known.rtc_transports]] + /// type = "livekit" + /// livekit_service_url = "https://livekit.yourdomain.com" + /// ``` + #[serde(default)] + pub rtc_transports: Vec, } #[derive(Clone, Copy, Debug, Deserialize, Default)] diff --git a/tuwunel-example.toml b/tuwunel-example.toml index 7e323e99..efe5fad7 100644 --- a/tuwunel-example.toml +++ b/tuwunel-example.toml @@ -1832,6 +1832,26 @@ # #support_mxid = +# Element Call / MatrixRTC configuration (MSC4143). +# Configures the LiveKit SFU server for voice/video calls. +# +# Requires a LiveKit server with JWT authentication. +# The `livekit_service_url` should point to your LiveKit JWT endpoint. +# +# Note: You must also set `client` above to your homeserver URL. +# +# Example: +# ```toml +# [global.well_known] +# client = "https://matrix.yourdomain.com" +# +# [[global.well_known.rtc_transports]] +# type = "livekit" +# livekit_service_url = "https://livekit.yourdomain.com" +# ``` +# +#rtc_transports = false + #[global.blurhashing] # blurhashing x component, 4 is recommended by https://blurha.sh/