Skip to content

Commit

Permalink
WidgetDriver: Add interacting with delayed event to the matrix driver.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
toger5 committed Aug 1, 2024
1 parent 536e7fd commit 2fab821
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 10 deletions.
43 changes: 42 additions & 1 deletion crates/matrix-sdk/src/widget/machine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -48,6 +50,7 @@ use self::{
#[cfg(doc)]
use super::WidgetDriver;
use super::{
capabilities,
filter::{MatrixEventContent, MatrixEventFilterInput},
Capabilities, StateKeySelector,
};
Expand Down Expand Up @@ -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::<UpdateDelayedEventResponse>::into),
)]
});
request_action.map(|a| vec![a]).unwrap_or_default()
}
}
}

Expand Down Expand Up @@ -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"));
}
Expand Down
31 changes: 22 additions & 9 deletions crates/matrix-sdk/src/widget/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -113,39 +113,52 @@ impl MatrixDriver {
event_type: TimelineEventType,
state_key: Option<String>,
content: Box<RawJsonValue>,
future_event_parameters: Option<future::FutureParameters>,
delayed_event_parameters: Option<delayed_events::DelayParameters>,
) -> Result<SendEventResponse> {
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::<AnyMessageLikeEventContent>::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::<AnyStateEventContent>::from_json(content),
);
self.room.client.send(r, None).await.map(|r| r.into())?
}
})
}

/// 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<delayed_events::update_delayed_event::unstable::Response> {
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 {
Expand Down

0 comments on commit 2fab821

Please sign in to comment.