tuwunel_api/client/
appservice.rs1use axum::extract::State;
2use ruma::api::{appservice::ping, client::appservice::request_ping};
3use tuwunel_core::{Err, Result, err};
4
5use crate::Ruma;
6
7pub(crate) async fn appservice_ping(
12 State(services): State<crate::State>,
13 body: Ruma<request_ping::v1::Request>,
14) -> Result<request_ping::v1::Response> {
15 let appservice_info = body.appservice_info.as_ref().ok_or_else(|| {
16 err!(Request(Forbidden("This endpoint can only be called by appservices.")))
17 })?;
18
19 if body.appservice_id != appservice_info.registration.id {
20 return Err!(Request(Forbidden(
21 "Appservices can only ping themselves (wrong appservice ID)."
22 )));
23 }
24
25 if appservice_info.registration.url.is_none()
26 || appservice_info
27 .registration
28 .url
29 .as_ref()
30 .is_some_and(|url| url.is_empty() || url == "null")
31 {
32 return Err!(Request(UrlNotSet(
33 "Appservice does not have a URL set, there is nothing to ping."
34 )));
35 }
36
37 let timer = tokio::time::Instant::now();
38
39 let _response = services
40 .appservice
41 .send_request(appservice_info.registration.clone(), ping::send_ping::v1::Request {
42 transaction_id: body.transaction_id.clone(),
43 })
44 .await?
45 .expect("We already validated if an appservice URL exists above");
46
47 Ok(request_ping::v1::Response { duration: timer.elapsed() })
48}