Get latest message for a room

This commit is contained in:
2025-11-24 11:20:20 +01:00
parent d23190f9d2
commit 7562a7fc61
3 changed files with 67 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
use futures_util::{StreamExt, stream};
use matrix_sdk::Room;
use matrix_sdk::deserialized_responses::{TimelineEvent, TimelineEventKind};
use matrix_sdk::room::MessagesOptions;
use matrix_sdk::ruma::{MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedUserId, RoomId, UInt};
use serde::Serialize;
use serde_json::value::RawValue;
#[derive(Serialize)]
pub struct APIEvent {
id: OwnedEventId,
time: MilliSecondsSinceUnixEpoch,
sender: OwnedUserId,
data: Box<RawValue>,
}
impl APIEvent {
pub async fn from_evt(msg: TimelineEvent, room_id: &RoomId) -> anyhow::Result<Self> {
let (event, raw) = match &msg.kind {
TimelineEventKind::Decrypted(d) => (d.event.deserialize()?, d.event.json()),
TimelineEventKind::UnableToDecrypt { event, .. }
| TimelineEventKind::PlainText { event } => (
event.deserialize()?.into_full_event(room_id.to_owned()),
event.json(),
),
};
Ok(Self {
id: event.event_id().to_owned(),
time: event.origin_server_ts(),
sender: event.sender().to_owned(),
data: raw.to_owned(),
})
}
}
#[derive(Serialize)]
pub struct APIEventsList {
pub start: String,
pub end: Option<String>,
pub messages: Vec<APIEvent>,
}
/// Get messages for a given room
pub(super) async fn get_events(room: &Room, limit: u32) -> anyhow::Result<APIEventsList> {
let mut msg_opts = MessagesOptions::backward();
msg_opts.limit = UInt::from(limit);
let messages = room.messages(msg_opts).await?;
Ok(APIEventsList {
start: messages.start,
end: messages.end,
messages: stream::iter(messages.chunk)
.then(async |msg| APIEvent::from_evt(msg, room.room_id()).await)
.collect::<Vec<_>>()
.await
.into_iter()
.collect::<Result<Vec<_>, _>>()?,
})
}

View File

@@ -1,4 +1,5 @@
use crate::controllers::HttpResult; use crate::controllers::HttpResult;
use crate::controllers::matrix::matrix_event_controller::{APIEvent, get_events};
use crate::controllers::matrix::matrix_media_controller; use crate::controllers::matrix::matrix_media_controller;
use crate::extractors::matrix_client_extractor::MatrixClientExtractor; use crate::extractors::matrix_client_extractor::MatrixClientExtractor;
use actix_web::{HttpRequest, HttpResponse, web}; use actix_web::{HttpRequest, HttpResponse, web};
@@ -15,10 +16,13 @@ pub struct APIRoomInfo {
avatar: Option<OwnedMxcUri>, avatar: Option<OwnedMxcUri>,
is_space: bool, is_space: bool,
parents: Vec<OwnedRoomId>, parents: Vec<OwnedRoomId>,
number_unread_messages: u64,
latest_event: Option<APIEvent>,
} }
impl APIRoomInfo { impl APIRoomInfo {
async fn from_room(r: &Room) -> anyhow::Result<Self> { async fn from_room(r: &Room) -> anyhow::Result<Self> {
// Get parent spaces
let parent_spaces = r let parent_spaces = r
.parent_spaces() .parent_spaces()
.await? .await?
@@ -47,6 +51,8 @@ impl APIRoomInfo {
avatar: r.avatar_url(), avatar: r.avatar_url(),
is_space: r.is_space(), is_space: r.is_space(),
parents: parent_spaces, parents: parent_spaces,
number_unread_messages: r.num_unread_messages(),
latest_event: get_events(r, 1).await?.messages.into_iter().next(),
}) })
} }
} }

View File

@@ -1,3 +1,4 @@
pub mod matrix_event_controller;
pub mod matrix_media_controller; pub mod matrix_media_controller;
pub mod matrix_profile_controller; pub mod matrix_profile_controller;
pub mod matrix_room_controller; pub mod matrix_room_controller;