tuwunel_api/client/
to_device.rs1use std::collections::BTreeMap;
2
3use axum::extract::State;
4use ruma::{
5 api::{
6 client::to_device::send_event_to_device,
7 error::ErrorKind,
8 federation::{self, transactions::edu::DirectDeviceContent},
9 },
10 to_device::DeviceIdOrAllDevices,
11};
12use tuwunel_core::{Error, Result, utils::ReadyExt};
13use tuwunel_service::sending::EduBuf;
14
15use crate::Ruma;
16
17pub(crate) async fn send_event_to_device_route(
21 State(services): State<crate::State>,
22 body: Ruma<send_event_to_device::v3::Request>,
23) -> Result<send_event_to_device::v3::Response> {
24 let sender_user = body.sender_user();
25 let sender_device = body.sender_device.as_deref();
26
27 if services
29 .transaction_ids
30 .existing_txnid(sender_user, sender_device, &body.txn_id)
31 .await
32 .is_ok()
33 {
34 return Ok(send_event_to_device::v3::Response {});
35 }
36
37 for (target_user_id, map) in &body.messages {
38 for (target_device_id_maybe, event) in map {
39 if !services.globals.user_is_local(target_user_id) {
40 let mut map = BTreeMap::new();
41 map.insert(target_device_id_maybe.clone(), event.clone());
42 let mut messages = BTreeMap::new();
43 messages.insert(target_user_id.clone(), map);
44
45 let mut buf = EduBuf::new();
46 serde_json::to_writer(
47 &mut buf,
48 &federation::transactions::edu::Edu::DirectToDevice(DirectDeviceContent {
49 sender: sender_user.to_owned(),
50 ev_type: body.event_type.clone(),
51 message_id: services.globals.next_count().to_string().into(),
52 messages,
53 }),
54 )
55 .expect("DirectToDevice EDU can be serialized");
56
57 services
58 .sending
59 .send_edu_server(target_user_id.server_name(), buf)?;
60
61 continue;
62 }
63
64 let event_type = &body.event_type.to_string();
65
66 let event = event
67 .deserialize_as()
68 .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Event is invalid"))?;
69
70 match target_device_id_maybe {
71 | DeviceIdOrAllDevices::DeviceId(target_device_id) => {
72 services.users.add_to_device_event(
73 sender_user,
74 target_user_id,
75 target_device_id,
76 event_type,
77 &event,
78 );
79 },
80
81 | DeviceIdOrAllDevices::AllDevices => {
82 services
83 .users
84 .all_device_ids(target_user_id)
85 .ready_for_each(|target_device_id| {
86 services.users.add_to_device_event(
87 sender_user,
88 target_user_id,
89 target_device_id,
90 event_type,
91 &event,
92 );
93 })
94 .await;
95 },
96 }
97 }
98 }
99
100 services
102 .transaction_ids
103 .add_txnid(sender_user, sender_device, &body.txn_id, &[]);
104
105 Ok(send_event_to_device::v3::Response {})
106}