matrix_sdk_crypto/types/requests/
to_device.rs

1// Copyright 2020 The Matrix.org Foundation C.I.C.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::{collections::BTreeMap, iter};
16
17use ruma::{
18    events::{AnyToDeviceEventContent, EventContent, ToDeviceEventType},
19    serde::Raw,
20    to_device::DeviceIdOrAllDevices,
21    OwnedDeviceId, OwnedTransactionId, OwnedUserId, TransactionId, UserId,
22};
23use serde::{Deserialize, Serialize};
24
25/// Customized version of
26/// `ruma_client_api::to_device::send_event_to_device::v3::Request`
27#[derive(Clone, Debug, Deserialize, Serialize)]
28pub struct ToDeviceRequest {
29    /// Type of event being sent to each device.
30    pub event_type: ToDeviceEventType,
31
32    /// A request identifier unique to the access token used to send the
33    /// request.
34    pub txn_id: OwnedTransactionId,
35
36    /// A map of users to devices to a content for a message event to be
37    /// sent to the user's device. Individual message events can be sent
38    /// to devices, but all events must be of the same type.
39    /// The content's type for this field will be updated in a future
40    /// release, until then you can create a value using
41    /// `serde_json::value::to_raw_value`.
42    pub messages:
43        BTreeMap<OwnedUserId, BTreeMap<DeviceIdOrAllDevices, Raw<AnyToDeviceEventContent>>>,
44}
45
46impl ToDeviceRequest {
47    /// Create a new owned to-device request
48    ///
49    /// # Arguments
50    ///
51    /// * `recipient` - The ID of the user that should receive this to-device
52    ///   event.
53    ///
54    /// * `recipient_device` - The device that should receive this to-device
55    ///   event, or all devices.
56    ///
57    /// * `event_type` - The type of the event content that is getting sent out.
58    ///
59    /// * `content` - The content of the to-device event.
60    pub fn new(
61        recipient: &UserId,
62        recipient_device: impl Into<DeviceIdOrAllDevices>,
63        event_type: &str,
64        content: Raw<AnyToDeviceEventContent>,
65    ) -> Self {
66        let event_type = ToDeviceEventType::from(event_type);
67        let user_messages = iter::once((recipient_device.into(), content)).collect();
68        let messages = iter::once((recipient.to_owned(), user_messages)).collect();
69
70        ToDeviceRequest { event_type, txn_id: TransactionId::new(), messages }
71    }
72
73    pub(crate) fn for_recipients(
74        recipient: &UserId,
75        recipient_devices: Vec<OwnedDeviceId>,
76        content: &AnyToDeviceEventContent,
77        txn_id: OwnedTransactionId,
78    ) -> Self {
79        let event_type = content.event_type();
80        let raw_content = Raw::new(content).expect("Failed to serialize to-device event");
81
82        if recipient_devices.is_empty() {
83            Self::new(
84                recipient,
85                DeviceIdOrAllDevices::AllDevices,
86                &event_type.to_string(),
87                raw_content,
88            )
89        } else {
90            let device_messages = recipient_devices
91                .into_iter()
92                .map(|d| (DeviceIdOrAllDevices::DeviceId(d), raw_content.clone()))
93                .collect();
94
95            let messages = iter::once((recipient.to_owned(), device_messages)).collect();
96
97            ToDeviceRequest { event_type, txn_id, messages }
98        }
99    }
100
101    pub(crate) fn with_id_raw(
102        recipient: &UserId,
103        recipient_device: impl Into<DeviceIdOrAllDevices>,
104        content: Raw<AnyToDeviceEventContent>,
105        event_type: ToDeviceEventType,
106        txn_id: OwnedTransactionId,
107    ) -> Self {
108        let user_messages = iter::once((recipient_device.into(), content)).collect();
109        let messages = iter::once((recipient.to_owned(), user_messages)).collect();
110
111        ToDeviceRequest { event_type, txn_id, messages }
112    }
113
114    pub(crate) fn with_id(
115        recipient: &UserId,
116        recipient_device: impl Into<DeviceIdOrAllDevices>,
117        content: &AnyToDeviceEventContent,
118        txn_id: OwnedTransactionId,
119    ) -> Self {
120        let event_type = content.event_type();
121        let raw_content = Raw::new(content).expect("Failed to serialize to-device event");
122
123        let user_messages = iter::once((recipient_device.into(), raw_content)).collect();
124        let messages = iter::once((recipient.to_owned(), user_messages)).collect();
125
126        ToDeviceRequest { event_type, txn_id, messages }
127    }
128
129    /// Get the number of unique messages this request contains.
130    ///
131    /// *Note*: A single message may be sent to multiple devices, so this may or
132    /// may not be the number of devices that will receive the messages as well.
133    pub fn message_count(&self) -> usize {
134        self.messages.values().map(|d| d.len()).sum()
135    }
136}