ruma_client_api/delayed_events/delayed_message_event.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
//! `PUT /_matrix/client/*/rooms/{roomId}/send/{eventType}/{txnId}`
//!
//! Send a delayed event (a scheduled message) to a room. [MSC4140](https://github.com/matrix-org/matrix-spec-proposals/pull/4140)
pub mod unstable {
//! `msc4140` ([MSC])
//!
//! [MSC]: https://github.com/matrix-org/matrix-spec-proposals/pull/4140
use ruma_common::{
api::{request, response, Metadata},
metadata,
serde::Raw,
OwnedRoomId, OwnedTransactionId,
};
use ruma_events::{AnyMessageLikeEventContent, MessageLikeEventContent, MessageLikeEventType};
use serde_json::value::to_raw_value as to_raw_json_value;
use crate::delayed_events::DelayParameters;
const METADATA: Metadata = metadata! {
method: PUT,
rate_limited: false,
authentication: AccessToken,
history: {
// We use the unstable prefix for the delay query parameter but the stable v3 endpoint.
unstable => "/_matrix/client/v3/rooms/:room_id/send/:event_type/:txn_id",
}
};
/// Request type for the [`delayed_message_event`](crate::delayed_events::delayed_message_event)
/// endpoint.
#[request(error = crate::Error)]
pub struct Request {
/// The room to send the event to.
#[ruma_api(path)]
pub room_id: OwnedRoomId,
/// The type of event to send.
#[ruma_api(path)]
pub event_type: MessageLikeEventType,
/// The transaction ID for this event.
///
/// Clients should generate a unique ID across requests within the
/// same session. A session is identified by an access token, and
/// persists when the [access token is refreshed].
///
/// It will be used by the server to ensure idempotency of requests.
///
/// [access token is refreshed]: https://spec.matrix.org/latest/client-server-api/#refreshing-access-tokens
#[ruma_api(path)]
pub txn_id: OwnedTransactionId,
/// The timeout duration for this delayed event.
#[ruma_api(query_all)]
pub delay_parameters: DelayParameters,
/// The event content to send.
#[ruma_api(body)]
pub body: Raw<AnyMessageLikeEventContent>,
}
/// Response type for the
/// [`delayed_message_event`](crate::delayed_events::delayed_message_event) endpoint.
#[response(error = crate::Error)]
pub struct Response {
/// The `delay_id` generated for this delayed event. Used to interact with delayed events.
pub delay_id: String,
}
impl Request {
/// Creates a new `Request` with the given room id, transaction id, `delay_parameters` and
/// event content.
///
/// # Errors
///
/// Since `Request` stores the request body in serialized form, this function can fail if
/// `T`s [`::serde::Serialize`] implementation can fail.
pub fn new<T>(
room_id: OwnedRoomId,
txn_id: OwnedTransactionId,
delay_parameters: DelayParameters,
content: &T,
) -> serde_json::Result<Self>
where
T: MessageLikeEventContent,
{
Ok(Self {
room_id,
txn_id,
event_type: content.event_type(),
delay_parameters,
body: Raw::from_json(to_raw_json_value(content)?),
})
}
/// Creates a new `Request` with the given room id, transaction id, event type,
/// `delay_parameters` and raw event content.
pub fn new_raw(
room_id: OwnedRoomId,
txn_id: OwnedTransactionId,
event_type: MessageLikeEventType,
delay_parameters: DelayParameters,
body: Raw<AnyMessageLikeEventContent>,
) -> Self {
Self { room_id, event_type, txn_id, delay_parameters, body }
}
}
impl Response {
/// Creates a new `Response` with the tokens required to control the delayed event using the
/// [`crate::delayed_events::update_delayed_event::unstable::Request`] request.
pub fn new(delay_id: String) -> Self {
Self { delay_id }
}
}
#[cfg(all(test, feature = "client"))]
mod tests {
use ruma_common::{
api::{MatrixVersion, OutgoingRequest, SendAccessToken},
owned_room_id,
};
use ruma_events::room::message::RoomMessageEventContent;
use serde_json::{json, Value as JsonValue};
use web_time::Duration;
use super::Request;
use crate::delayed_events::delayed_message_event::unstable::DelayParameters;
#[test]
fn serialize_delayed_message_request() {
let room_id = owned_room_id!("!roomid:example.org");
let req = Request::new(
room_id,
"1234".into(),
DelayParameters::Timeout { timeout: Duration::from_millis(103) },
&RoomMessageEventContent::text_plain("test"),
)
.unwrap();
let request: http::Request<Vec<u8>> = req
.try_into_http_request(
"https://homeserver.tld",
SendAccessToken::IfRequired("auth_tok"),
&[MatrixVersion::V1_1],
)
.unwrap();
let (parts, body) = request.into_parts();
assert_eq!(
"https://homeserver.tld/_matrix/client/v3/rooms/!roomid:example.org/send/m.room.message/1234?org.matrix.msc4140.delay=103",
parts.uri.to_string()
);
assert_eq!("PUT", parts.method.to_string());
assert_eq!(
json!({"msgtype":"m.text","body":"test"}),
serde_json::from_str::<JsonValue>(std::str::from_utf8(&body).unwrap()).unwrap()
);
}
}
}