diff --git a/src/main.rs b/src/main.rs index 3463bdf..3c68652 100644 --- a/src/main.rs +++ b/src/main.rs @@ -57,11 +57,7 @@ async fn main() -> std::io::Result<()> { .route("/api", web::get().to(api::api_home)) .route("/api", web::post().to(api::api_home)) .route("/api/account/whoami", web::get().to(api::account::who_am_i)) - .route("/api/room/{room_id}/name", web::get().to(api::room::name)) - .route( - "/api/room/{room_id}/avatar", - web::get().to(api::room::avatar), - ) + .route("/api/room/{room_id}", web::get().to(api::room::info)) .route( "/api/media/{server_name}/{media_id}/download", web::get().to(api::media::download), diff --git a/src/server/api/room.rs b/src/server/api/room.rs index 47430cc..b1ee771 100644 --- a/src/server/api/room.rs +++ b/src/server/api/room.rs @@ -1,10 +1,11 @@ use crate::extractors::client_auth::APIClientAuth; -use crate::server::HttpResult; +use crate::server::{HttpFailure, HttpResult}; use crate::utils::matrix_utils::ApiMxcURI; use actix_web::{web, HttpResponse}; use ruma::api::client::state; use ruma::events::StateEventType; use ruma::{OwnedMxcUri, OwnedRoomId}; +use serde::de::DeserializeOwned; #[derive(serde::Deserialize)] pub struct RoomIDInPath { @@ -12,44 +13,53 @@ pub struct RoomIDInPath { } #[derive(serde::Serialize)] -struct GetRoomNameResponse { - name: String, +struct GetRoomInfoResponse { + name: Option, + avatar: Option, } -/// Get room name -pub async fn name(auth: APIClientAuth, path: web::Path) -> HttpResult { +/// Get a room information +async fn get_room_info( + auth: &APIClientAuth, + room_id: OwnedRoomId, + event_type: StateEventType, + field: &str, +) -> anyhow::Result, HttpFailure> { let res = auth .send_request(state::get_state_events_for_key::v3::Request::new( - path.room_id.clone(), - StateEventType::RoomName, + room_id, + event_type, String::default(), )) .await?; - Ok(HttpResponse::Ok().json(GetRoomNameResponse { - name: res.content.get_field("name")?.unwrap_or("").to_string(), + Ok(res.content.get_field(field)?) +} + +/// Get room information +pub async fn info(auth: APIClientAuth, path: web::Path) -> HttpResult { + let room_name: Option = get_room_info( + &auth, + path.room_id.clone(), + StateEventType::RoomName, + "name", + ) + .await + .ok() + .flatten(); + + let room_avatar: Option = get_room_info( + &auth, + path.room_id.clone(), + StateEventType::RoomAvatar, + "url", + ) + .await + .ok() + .flatten(); + + Ok(HttpResponse::Ok().json(GetRoomInfoResponse { + name: room_name, + avatar: room_avatar.map(ApiMxcURI), })) } - -#[derive(serde::Serialize)] -struct GetRoomAvatarResponse(ApiMxcURI); - -/// Get room avatar -pub async fn avatar(auth: APIClientAuth, path: web::Path) -> HttpResult { - let res = auth - .send_request(state::get_state_events_for_key::v3::Request::new( - path.room_id.clone(), - StateEventType::RoomAvatar, - String::default(), - )) - .await?; - - let avatar_url: Option = res.content.get_field("url")?; - - match avatar_url { - None => Ok(HttpResponse::NotFound().body("No avatar found for this room.")), - Some(avatar_url) => { - Ok(HttpResponse::Ok().json(GetRoomAvatarResponse(ApiMxcURI(avatar_url)))) - } - } -}