Skip to content

Commit

Permalink
Support for sending futures events through the widget api.
Browse files Browse the repository at this point in the history
  • Loading branch information
toger5 committed Jun 23, 2024
1 parent 4ee56fa commit c7c11e0
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 46 deletions.
26 changes: 13 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "c21817436979acbe66d43064498920a6d289b562", features = [
ruma = { git = "https://github.com/toger5/ruma", rev = "6a2ab00269093db46aa7c2b9e4a1437f40931bcb", features = [
"client-api-c",
"compat-upload-signatures",
"compat-user-id",
Expand All @@ -53,9 +53,10 @@ ruma = { git = "https://github.com/ruma/ruma", rev = "c21817436979acbe66d4306449
"compat-encrypted-stickers",
"unstable-msc3401",
"unstable-msc3266",
"unstable-msc4075"
"unstable-msc4075",
"unstable-msc4140",
] }
ruma-common = { git = "https://github.com/ruma/ruma", rev = "c21817436979acbe66d43064498920a6d289b562" }
ruma-common = { git = "https://github.com/toger5/ruma", rev = "6a2ab00269093db46aa7c2b9e4a1437f40931bcb" }
serde = "1.0.151"
serde_html_form = "0.2.0"
serde_json = "1.0.91"
Expand Down
14 changes: 9 additions & 5 deletions crates/matrix-sdk/src/widget/machine/driver_req.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -217,6 +219,8 @@ pub(crate) struct SendEventRequest {
pub(crate) state_key: Option<String>,
/// Raw content of an event.
pub(crate) content: Box<RawJsonValue>,
/// Addition send event parameters to send a future
pub(crate) future_parameters: Option<FutureParameters>,
}

impl From<SendEventRequest> for MatrixDriverRequestData {
Expand All @@ -226,10 +230,10 @@ impl From<SendEventRequest> 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<Self> {
match ev {
MatrixDriverResponse::MatrixEventSent(response) => Some(response),
Expand Down
68 changes: 63 additions & 5 deletions crates/matrix-sdk/src/widget/machine/from_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -132,8 +133,65 @@ pub(super) struct ReadEventResponse {
pub(super) events: Vec<Raw<AnyTimelineEvent>>,
}

#[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<OwnedRoomId>,
/// 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<OwnedEventId>,
/// A token to send/insert the future into the DAG.
pub send_token: Option<String>,
/// A token to cancel this future. It will never be send if this is called.
pub cancel_token: Option<String>,
/// 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<String>,
/// 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<String>,
}

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<SendEventResponse> 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<SendEventResponse> 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,
}
}
}
11 changes: 6 additions & 5 deletions crates/matrix-sdk/src/widget/machine/incoming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -56,7 +57,7 @@ pub(crate) enum MatrixDriverResponse {
MatrixEventRead(Vec<Raw<AnyTimelineEvent>>),
/// 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 {
Expand Down
12 changes: 7 additions & 5 deletions crates/matrix-sdk/src/widget/machine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use self::{
},
from_widget::{
FromWidgetErrorResponse, FromWidgetRequest, ReadEventRequest, ReadEventResponse,
SendEventResponse, SupportedApiVersionsResponse,
SupportedApiVersionsResponse,
},
incoming::{IncomingWidgetMessage, IncomingWidgetMessageKind},
openid::{OpenIdResponse, OpenIdState},
Expand Down Expand Up @@ -64,6 +64,7 @@ mod to_widget;

pub(crate) use self::{
driver_req::{MatrixDriverRequestData, ReadStateEventRequest, SendEventRequest},
from_widget::SendEventResponse,
incoming::{IncomingMessage, MatrixDriverResponse},
};

Expand Down Expand Up @@ -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
}
Expand Down
42 changes: 34 additions & 8 deletions crates/matrix-sdk/src/widget/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down Expand Up @@ -112,11 +113,36 @@ impl MatrixDriver {
event_type: TimelineEventType,
state_key: Option<String>,
content: Box<RawJsonValue>,
) -> Result<OwnedEventId> {
future: Option<future::FutureParameters>,
) -> Result<SendEventResponse> {
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::<AnyMessageLikeEventContent>::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::<AnyStateEventContent>::from_json(content),
);
self.room.client.send(r, None).await.map(|r| r.into())?
}
})
}

Expand Down
5 changes: 3 additions & 2 deletions crates/matrix-sdk/src/widget/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,10 @@ impl<T: CapabilitiesProvider> ProcessingContext<T> {
.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())
Expand Down

0 comments on commit c7c11e0

Please sign in to comment.