From 2fab82183fcda8fd7d5533110ddf3783855045dc Mon Sep 17 00:00:00 2001 From: Timo Date: Wed, 31 Jul 2024 19:36:14 +0200 Subject: [PATCH] WidgetDriver: Add interacting with delayed event to the matrix driver. In `matrix.rs` we add methods to interact with the matrix homeserver. And in `machine/mod.rs` we implement the widgetMachine cases for handling (checking capabilities and using the matrixDriver) delayed events. --- crates/matrix-sdk/src/widget/machine/mod.rs | 43 ++++++++++++++++++++- crates/matrix-sdk/src/widget/matrix.rs | 31 ++++++++++----- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/crates/matrix-sdk/src/widget/machine/mod.rs b/crates/matrix-sdk/src/widget/machine/mod.rs index 85979e8311b..31e96fc7da9 100644 --- a/crates/matrix-sdk/src/widget/machine/mod.rs +++ b/crates/matrix-sdk/src/widget/machine/mod.rs @@ -18,6 +18,8 @@ use std::{fmt, iter, time::Duration}; +use driver_req::UpdateDelayedEventRequest; +use from_widget::UpdateDelayedEventResponse; use indexmap::IndexMap; use ruma::{ serde::{JsonObject, Raw}, @@ -48,6 +50,7 @@ use self::{ #[cfg(doc)] use super::WidgetDriver; use super::{ + capabilities, filter::{MatrixEventContent, MatrixEventFilterInput}, Capabilities, StateKeySelector, }; @@ -245,6 +248,36 @@ impl WidgetMachine { let response = self.send_from_widget_response(raw_request, OpenIdResponse::Pending); iter::once(response).chain(request_action).collect() } + FromWidgetRequest::DelayedEventUpdate(req) => { + let CapabilitiesState::Negotiated(capabilities) = &self.capabilities else { + let text = + "Received send update delayed event request before capabilities were negotiated"; + return vec![self.send_from_widget_error_response(raw_request, text)]; + }; + if !capabilities.update_delayed_event { + return vec![self.send_from_widget_error_response( + raw_request, + format!( + "Not allowed: missing the {} capability.", + capabilities::UPDATE_DELAYED_EVENT + ), + )]; + } + let (request, request_action) = + self.send_matrix_driver_request(UpdateDelayedEventRequest { + action: req.action, + delay_id: req.delay_id, + }); + request.then(|res, machine| { + vec![machine.send_from_widget_result_response( + raw_request, + // This is mapped to another type because the update_delay_event::Response + // does not impl Serialize + res.map(Into::::into), + )] + }); + request_action.map(|a| vec![a]).unwrap_or_default() + } } } @@ -338,7 +371,15 @@ impl WidgetMachine { Default::default() }), }; - + if !capabilities.send_delayed_event && request.delay.is_some() { + return Some(self.send_from_widget_error_response( + raw_request, + format!( + "Not allowed: missing the {} capability.", + capabilities::SEND_DELAYED_EVENT + ), + )); + } if !capabilities.send.iter().any(|filter| filter.matches(&filter_in)) { return Some(self.send_from_widget_error_response(raw_request, "Not allowed")); } diff --git a/crates/matrix-sdk/src/widget/matrix.rs b/crates/matrix-sdk/src/widget/matrix.rs index 7d6338c706e..b0d09b18ab7 100644 --- a/crates/matrix-sdk/src/widget/matrix.rs +++ b/crates/matrix-sdk/src/widget/matrix.rs @@ -21,8 +21,8 @@ use matrix_sdk_base::deserialized_responses::RawAnySyncOrStrippedState; use ruma::{ api::client::{ account::request_openid_token::v3::{Request as OpenIdRequest, Response as OpenIdResponse}, + delayed_events::{self, update_delayed_event::unstable::UpdateAction}, filter::RoomEventFilter, - future, }, assign, events::{ @@ -113,32 +113,32 @@ impl MatrixDriver { event_type: TimelineEventType, state_key: Option, content: Box, - future_event_parameters: Option, + delayed_event_parameters: Option, ) -> Result { let type_str = event_type.to_string(); - Ok(match (state_key, future_event_parameters) { + Ok(match (state_key, delayed_event_parameters) { (None, None) => SendEventResponse::from_event_id( self.room.send_raw(&type_str, content).await?.event_id, ), (Some(key), None) => SendEventResponse::from_event_id( self.room.send_state_event_raw(&type_str, &key, content).await?.event_id, ), - (None, Some(future_event_parameters)) => { - let r = future::send_future_message_event::unstable::Request::new_raw( + (None, Some(delayed_event_parameters)) => { + let r = delayed_events::delayed_message_event::unstable::Request::new_raw( self.room.room_id().to_owned(), TransactionId::new(), MessageLikeEventType::from(type_str), - future_event_parameters, + delayed_event_parameters, Raw::::from_json(content), ); self.room.client.send(r, None).await.map(|r| r.into())? } - (Some(key), Some(future_event_parameters)) => { - let r = future::send_future_state_event::unstable::Request::new_raw( + (Some(key), Some(delayed_event_parameters)) => { + let r = delayed_events::delayed_state_event::unstable::Request::new_raw( self.room.room_id().to_owned(), key, StateEventType::from(type_str), - future_event_parameters, + delayed_event_parameters, Raw::::from_json(content), ); self.room.client.send(r, None).await.map(|r| r.into())? @@ -146,6 +146,19 @@ impl MatrixDriver { }) } + /// Send a request to the `/delayed_events`` endpoint ([MSC4140](https://github.com/matrix-org/matrix-spec-proposals/pull/4140)) + /// This can be used to refresh cancel or send a Delayed Event (An Event + /// that is send ahead of time to the homeserver and gets distributed + /// once it times out.) + pub(crate) async fn update_delayed_event( + &self, + delay_id: String, + action: UpdateAction, + ) -> HttpResult { + let r = delayed_events::update_delayed_event::unstable::Request::new(delay_id, action); + self.room.client.send(r, None).await + } + /// Starts forwarding new room events. Once the returned `EventReceiver` /// is dropped, forwarding will be stopped. pub(crate) fn events(&self) -> EventReceiver {