tbot/event_loop/webhook/
http.rs

1use super::handle;
2use crate::{errors, event_loop::Webhook};
3use hyper::{
4    service::{make_service_fn, service_fn},
5    Server,
6};
7use std::{convert::Infallible, net::SocketAddr, sync::Arc};
8use tokio::time::timeout;
9use tracing::instrument;
10
11/// Configures the HTTP webhook server.
12#[must_use = "webhook server needs to be `start`ed to run the event loop"]
13pub struct Http<'a> {
14    webhook: Webhook<'a>,
15}
16
17impl<'a> Http<'a> {
18    pub(crate) const fn new(webhook: Webhook<'a>) -> Self {
19        Self { webhook }
20    }
21}
22
23impl<'a> Http<'a> {
24    /// Starts the server.
25    #[instrument(name = "http_webhook", skip(self))]
26    pub async fn start(self) -> Result<Infallible, errors::HttpWebhook> {
27        let Webhook {
28            event_loop,
29            ip,
30            port,
31            updates_url,
32            url,
33            certificate,
34            max_connections,
35            allowed_updates,
36            request_timeout,
37        } = self.webhook;
38
39        let set_webhook = event_loop
40            .bot
41            .set_webhook(url, certificate, max_connections, allowed_updates)
42            .call();
43
44        timeout(request_timeout, set_webhook).await??;
45
46        let bot = Arc::new(event_loop.bot.clone());
47        let event_loop = Arc::new(event_loop);
48        let addr = SocketAddr::new(ip, port);
49        let updates_url = Arc::new(updates_url);
50
51        Server::bind(&addr)
52            .serve(make_service_fn(move |_| {
53                let bot = Arc::clone(&bot);
54                let event_loop = Arc::clone(&event_loop);
55                let updates_url = Arc::clone(&updates_url);
56
57                async move {
58                    let service = service_fn(move |request| {
59                        handle(
60                            Arc::clone(&bot),
61                            Arc::clone(&event_loop),
62                            request,
63                            Arc::clone(&updates_url),
64                        )
65                    });
66
67                    Ok::<_, hyper::Error>(service)
68                }
69            }))
70            .await?;
71
72        unreachable!("[tbot] The webhook server unexpectedly returned.");
73    }
74}