tuwunel_api/client/appservice/
ping.rs1use axum::extract::State;
2use ruma::api::{
3 appservice::ping::send_ping::v1::Request as SendPing,
4 client::appservice::request_ping::v1::{Request, Response},
5};
6use tuwunel_core::{Err, Result, err, utils::result::LogErr};
7
8use crate::Ruma;
9
10pub(crate) async fn appservice_ping(
15 State(services): State<crate::State>,
16 body: Ruma<Request>,
17) -> Result<Response> {
18 let appservice_info = body.appservice_info.as_ref().ok_or_else(|| {
19 err!(Request(Forbidden("This endpoint can only be called by appservices.")))
20 })?;
21
22 if body.appservice_id != appservice_info.registration.id {
23 return Err!(Request(Forbidden(
24 "Appservices can only ping themselves (wrong appservice ID)."
25 )));
26 }
27
28 if appservice_info.registration.url.is_none()
29 || appservice_info
30 .registration
31 .url
32 .as_ref()
33 .is_some_and(|url| url.is_empty() || url == "null")
34 {
35 return Err!(Request(UrlNotSet(
36 "Appservice does not have a URL set, there is nothing to ping."
37 )));
38 }
39
40 let timer = tokio::time::Instant::now();
41
42 services
43 .appservice
44 .ping(appservice_info.registration.clone(), SendPing {
45 transaction_id: body.transaction_id.clone(),
46 })
47 .await?;
48
49 let duration = timer.elapsed();
50
51 services
52 .sending
53 .flush_appservice(appservice_info.registration.id.clone())
54 .log_err()
55 .ok();
56
57 Ok(Response { duration })
58}