diff --git a/Cargo.lock b/Cargo.lock index 3c2bbb6aa53..a3b34741b8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5010,7 +5010,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.10.1" -source = "git+https://github.com/ruma/ruma?rev=e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0#e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0" +source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" dependencies = [ "assign", "js_int", @@ -5027,7 +5027,7 @@ dependencies = [ [[package]] name = "ruma-client-api" version = "0.18.0" -source = "git+https://github.com/ruma/ruma?rev=e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0#e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0" +source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" dependencies = [ "as_variant", "assign", @@ -5050,7 +5050,7 @@ dependencies = [ [[package]] name = "ruma-common" version = "0.13.0" -source = "git+https://github.com/ruma/ruma?rev=e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0#e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0" +source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" dependencies = [ "as_variant", "base64 0.22.1", @@ -5082,7 +5082,7 @@ dependencies = [ [[package]] name = "ruma-events" version = "0.28.1" -source = "git+https://github.com/ruma/ruma?rev=e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0#e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0" +source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" dependencies = [ "as_variant", "indexmap 2.2.6", @@ -5106,7 +5106,7 @@ dependencies = [ [[package]] name = "ruma-federation-api" version = "0.9.0" -source = "git+https://github.com/ruma/ruma?rev=e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0#e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0" +source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" dependencies = [ "js_int", "ruma-common", @@ -5118,7 +5118,7 @@ dependencies = [ [[package]] name = "ruma-html" version = "0.2.0" -source = "git+https://github.com/ruma/ruma?rev=e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0#e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0" +source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" dependencies = [ "as_variant", "html5ever", @@ -5130,7 +5130,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" version = "0.9.5" -source = "git+https://github.com/ruma/ruma?rev=e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0#e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0" +source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" dependencies = [ "js_int", "thiserror", @@ -5139,7 +5139,7 @@ dependencies = [ [[package]] name = "ruma-macros" version = "0.13.0" -source = "git+https://github.com/ruma/ruma?rev=e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0#e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0" +source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" dependencies = [ "once_cell", "proc-macro-crate", @@ -5154,7 +5154,7 @@ dependencies = [ [[package]] name = "ruma-push-gateway-api" version = "0.9.0" -source = "git+https://github.com/ruma/ruma?rev=e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0#e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0" +source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" dependencies = [ "js_int", "ruma-common", diff --git a/Cargo.toml b/Cargo.toml index 5d37a6fa407..4c4cbb444d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,7 +44,7 @@ once_cell = "1.16.0" pin-project-lite = "0.2.9" rand = "0.8.5" reqwest = { version = "0.12.4", default-features = false } -ruma = { git = "https://github.com/ruma/ruma", rev = "e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0", features = [ +ruma = { git = "https://github.com/ruma/ruma", rev = "c37843e9be619ffac8c4d33ad3a6a175cc32610c", features = [ "client-api-c", "compat-upload-signatures", "compat-user-id", @@ -53,9 +53,10 @@ ruma = { git = "https://github.com/ruma/ruma", rev = "e5a370f7e5fcebb0da6e4945e5 "compat-encrypted-stickers", "unstable-msc3401", "unstable-msc3266", - "unstable-msc4075" + "unstable-msc4075", + "unstable-msc4140", ] } -ruma-common = { git = "https://github.com/ruma/ruma", rev = "e5a370f7e5fcebb0da6e4945e51c5fafba9aa5f0" } +ruma-common = { git = "https://github.com/ruma/ruma", rev = "c37843e9be619ffac8c4d33ad3a6a175cc32610c" } serde = "1.0.151" serde_html_form = "0.2.0" serde_json = "1.0.91" diff --git a/crates/matrix-sdk/src/widget/machine/driver_req.rs b/crates/matrix-sdk/src/widget/machine/driver_req.rs index a4c2550ca81..2a4c436898d 100644 --- a/crates/matrix-sdk/src/widget/machine/driver_req.rs +++ b/crates/matrix-sdk/src/widget/machine/driver_req.rs @@ -17,16 +17,18 @@ use std::marker::PhantomData; use ruma::{ - api::client::account::request_openid_token, + api::client::{account::request_openid_token, future::FutureParameters}, events::{AnyTimelineEvent, MessageLikeEventType, StateEventType, TimelineEventType}, serde::Raw, - OwnedEventId, }; use serde::Deserialize; use serde_json::value::RawValue as RawJsonValue; use tracing::error; -use super::{incoming::MatrixDriverResponse, Action, MatrixDriverRequestMeta, WidgetMachine}; +use super::{ + from_widget::SendEventResponse, incoming::MatrixDriverResponse, Action, + MatrixDriverRequestMeta, WidgetMachine, +}; use crate::widget::{Capabilities, StateKeySelector}; #[derive(Clone, Debug)] @@ -217,6 +219,8 @@ pub(crate) struct SendEventRequest { pub(crate) state_key: Option, /// Raw content of an event. pub(crate) content: Box, + /// Addition send event parameters to send a future + pub(crate) future_parameters: Option, } impl From for MatrixDriverRequestData { @@ -226,10 +230,10 @@ impl From for MatrixDriverRequestData { } impl MatrixDriverRequest for SendEventRequest { - type Response = OwnedEventId; + type Response = SendEventResponse; } -impl FromMatrixDriverResponse for OwnedEventId { +impl FromMatrixDriverResponse for SendEventResponse { fn from_response(ev: MatrixDriverResponse) -> Option { match ev { MatrixDriverResponse::MatrixEventSent(response) => Some(response), diff --git a/crates/matrix-sdk/src/widget/machine/from_widget.rs b/crates/matrix-sdk/src/widget/machine/from_widget.rs index 2094bbbeb3f..b2efbb92600 100644 --- a/crates/matrix-sdk/src/widget/machine/from_widget.rs +++ b/crates/matrix-sdk/src/widget/machine/from_widget.rs @@ -15,9 +15,10 @@ use std::fmt; use ruma::{ + api::client::future, events::{AnyTimelineEvent, MessageLikeEventType, StateEventType}, serde::Raw, - OwnedEventId, RoomId, + OwnedEventId, OwnedRoomId, }; use serde::{Deserialize, Serialize}; @@ -132,8 +133,65 @@ pub(super) struct ReadEventResponse { pub(super) events: Vec>, } -#[derive(Serialize)] -pub(super) struct SendEventResponse<'a> { - pub(super) room_id: &'a RoomId, - pub(super) event_id: OwnedEventId, +#[derive(Serialize, Debug)] +pub struct SendEventResponse { + /// The room id for the send event. + pub room_id: Option, + /// The event id of the send event. Its optional because if its a future one does not get + /// the event_id at this point. + pub event_id: Option, + /// A token to send/insert the future into the DAG. + pub send_token: Option, + /// A token to cancel this future. It will never be send if this is called. + pub cancel_token: Option, + /// The `future_group_id` generated for this future. Used to connect multiple futures + /// only one of the connected futures will be sent and inserted into the DAG. + pub future_group_id: Option, + /// A token used to refresh the timer of the future. This allows + /// to implement heartbeat like capabilities. An event is only sent once + /// a refresh in the timeout interval is missed. + /// + /// If the future does not have a timeout this will be `None`. + pub refresh_token: Option, +} + +impl SendEventResponse { + pub fn from_event_id(event_id: OwnedEventId) -> Self { + SendEventResponse { + room_id: None, + event_id: Some(event_id), + send_token: None, + cancel_token: None, + future_group_id: None, + refresh_token: None, + } + } + pub fn set_room_id(&mut self, room_id: OwnedRoomId) { + self.room_id = Some(room_id); + } +} +impl Into for future::send_future_message_event::unstable::Response { + fn into(self) -> SendEventResponse { + SendEventResponse { + room_id: None, + event_id: None, + send_token: Some(self.send_token), + cancel_token: Some(self.cancel_token), + future_group_id: Some(self.future_group_id), + refresh_token: self.refresh_token, + } + } +} + +impl Into for future::send_future_state_event::unstable::Response { + fn into(self) -> SendEventResponse { + SendEventResponse { + room_id: None, + event_id: None, + send_token: Some(self.send_token), + cancel_token: Some(self.cancel_token), + future_group_id: Some(self.future_group_id), + refresh_token: self.refresh_token, + } + } } diff --git a/crates/matrix-sdk/src/widget/machine/incoming.rs b/crates/matrix-sdk/src/widget/machine/incoming.rs index 4d365fefefc..661efae29a2 100644 --- a/crates/matrix-sdk/src/widget/machine/incoming.rs +++ b/crates/matrix-sdk/src/widget/machine/incoming.rs @@ -12,14 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -use ruma::{ - api::client::account::request_openid_token, events::AnyTimelineEvent, serde::Raw, OwnedEventId, -}; +use ruma::{api::client::account::request_openid_token, events::AnyTimelineEvent, serde::Raw}; use serde::{de, Deserialize, Deserializer}; use serde_json::value::RawValue as RawJsonValue; use uuid::Uuid; -use super::{from_widget::FromWidgetRequest, to_widget::ToWidgetResponse}; +use super::{ + from_widget::{FromWidgetRequest, SendEventResponse}, + to_widget::ToWidgetResponse, +}; use crate::widget::Capabilities; /// Incoming event that the client API must process. @@ -56,7 +57,7 @@ pub(crate) enum MatrixDriverResponse { MatrixEventRead(Vec>), /// Client sent some matrix event. The response contains the event ID. /// A response to an `Action::SendMatrixEvent` command. - MatrixEventSent(OwnedEventId), + MatrixEventSent(SendEventResponse), } pub(super) struct IncomingWidgetMessage { diff --git a/crates/matrix-sdk/src/widget/machine/mod.rs b/crates/matrix-sdk/src/widget/machine/mod.rs index 17c93fa5c9f..c371a2dbb6c 100644 --- a/crates/matrix-sdk/src/widget/machine/mod.rs +++ b/crates/matrix-sdk/src/widget/machine/mod.rs @@ -35,7 +35,7 @@ use self::{ }, from_widget::{ FromWidgetErrorResponse, FromWidgetRequest, ReadEventRequest, ReadEventResponse, - SendEventResponse, SupportedApiVersionsResponse, + SupportedApiVersionsResponse, }, incoming::{IncomingWidgetMessage, IncomingWidgetMessageKind}, openid::{OpenIdResponse, OpenIdState}, @@ -64,6 +64,7 @@ mod to_widget; pub(crate) use self::{ driver_req::{MatrixDriverRequestData, ReadStateEventRequest, SendEventRequest}, + from_widget::SendEventResponse, incoming::{IncomingMessage, MatrixDriverResponse}, }; @@ -343,10 +344,11 @@ impl WidgetMachine { } let (request, action) = self.send_matrix_driver_request(request); - request.then(|result, machine| { - let room_id = &machine.room_id; - let response = result.map(|event_id| SendEventResponse { event_id, room_id }); - vec![machine.send_from_widget_result_response(raw_request, response)] + request.then(|mut result, machine| { + if let Ok(r) = result.as_mut() { + r.set_room_id(machine.room_id.clone().to_owned()); + } + vec![machine.send_from_widget_result_response(raw_request, result)] }); action } diff --git a/crates/matrix-sdk/src/widget/matrix.rs b/crates/matrix-sdk/src/widget/matrix.rs index 7c2ea7ddb6f..647d58d2dfb 100644 --- a/crates/matrix-sdk/src/widget/matrix.rs +++ b/crates/matrix-sdk/src/widget/matrix.rs @@ -22,20 +22,21 @@ use ruma::{ api::client::{ account::request_openid_token::v3::{Request as OpenIdRequest, Response as OpenIdResponse}, filter::RoomEventFilter, + future, }, assign, events::{ - AnySyncTimelineEvent, AnyTimelineEvent, MessageLikeEventType, StateEventType, - TimelineEventType, + AnyMessageLikeEventContent, AnyStateEventContent, AnySyncTimelineEvent, AnyTimelineEvent, + MessageLikeEventType, StateEventType, TimelineEventType, }, serde::Raw, - OwnedEventId, RoomId, + RoomId, TransactionId, }; use serde_json::value::RawValue as RawJsonValue; use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver}; use tracing::error; -use super::StateKeySelector; +use super::{machine::SendEventResponse, StateKeySelector}; use crate::{ event_handler::EventHandlerDropGuard, room::MessagesOptions, HttpResult, Result, Room, }; @@ -112,11 +113,36 @@ impl MatrixDriver { event_type: TimelineEventType, state_key: Option, content: Box, - ) -> Result { + future: Option, + ) -> Result { let type_str = event_type.to_string(); - Ok(match state_key { - Some(key) => self.room.send_state_event_raw(&type_str, &key, content).await?.event_id, - None => self.room.send_raw(&type_str, content).await?.event_id, + Ok(match (state_key, future) { + (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)) => { + let r = future::send_future_message_event::unstable::Request::new_raw( + self.room.room_id().to_owned(), + TransactionId::new().to_owned(), + MessageLikeEventType::from(type_str), + future, + Raw::::from_json(content), + ); + self.room.client.send(r, None).await.map(|r| r.into())? + } + (Some(key), Some(future)) => { + let r = future::send_future_state_event::unstable::Request::new_raw( + self.room.room_id().to_owned(), + key, + StateEventType::from(type_str), + future, + Raw::::from_json(content), + ); + self.room.client.send(r, None).await.map(|r| r.into())? + } }) } diff --git a/crates/matrix-sdk/src/widget/mod.rs b/crates/matrix-sdk/src/widget/mod.rs index db0ac1f0b02..b3bc49e93b7 100644 --- a/crates/matrix-sdk/src/widget/mod.rs +++ b/crates/matrix-sdk/src/widget/mod.rs @@ -225,9 +225,10 @@ impl ProcessingContext { .map_err(|e| e.to_string()), MatrixDriverRequestData::SendMatrixEvent(req) => { - let SendEventRequest { event_type, state_key, content } = req; + let SendEventRequest { event_type, state_key, content, future_parameters } = + req; self.matrix_driver - .send(event_type, state_key, content) + .send(event_type, state_key, content, future_parameters) .await .map(MatrixDriverResponse::MatrixEventSent) .map_err(|e| e.to_string())