tgbot/types/webhook/
mod.rs

1use std::collections::HashSet;
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6    api::{Method, Payload},
7    types::{AllowedUpdate, Integer},
8};
9
10#[cfg(test)]
11mod tests;
12
13/// Represents a current status of a webhook.
14#[serde_with::skip_serializing_none]
15#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
16pub struct WebhookInfo {
17    /// Indicates whether a custom certificate was provided for webhook certificate checks.
18    pub has_custom_certificate: bool,
19    /// Number of updates awaiting delivery.
20    pub pending_update_count: Integer,
21    /// Webhook URL, may be empty if webhook is not set up.
22    pub url: String,
23    /// A list of update types the bot is subscribed to.
24    ///
25    /// Defaults to all update types.
26    pub allowed_updates: Option<Vec<AllowedUpdate>>,
27    /// Currently used webhook IP address.
28    pub ip_address: Option<String>,
29    /// Unix time for the most recent error that happened
30    /// when trying to deliver an update via webhook.
31    pub last_error_date: Option<Integer>,
32    /// Error message in human-readable format for the most recent error
33    /// that happened when trying to deliver an update via webhook.
34    pub last_error_message: Option<String>,
35    /// Unix time of the most recent error that happened
36    /// when trying to synchronize available updates with Telegram datacenters.
37    pub last_synchronization_error_date: Option<Integer>,
38    /// Maximum allowed number of simultaneous HTTPS connections
39    /// to the webhook for update delivery.
40    pub max_connections: Option<Integer>,
41}
42
43impl WebhookInfo {
44    /// Creates a new `WebhookInfo`.
45    ///
46    /// # Arguments
47    ///
48    /// * `url` - Webhook URL.
49    /// * `has_custom_certificate` - Indicates whether a custom certificate was provided.
50    /// * `pending_update_count` - Number of updates awaiting delivery.
51    pub fn new<T>(url: T, has_custom_certificate: bool, pending_update_count: Integer) -> Self
52    where
53        T: Into<String>,
54    {
55        Self {
56            has_custom_certificate,
57            pending_update_count,
58            url: url.into(),
59            allowed_updates: None,
60            ip_address: None,
61            last_error_date: None,
62            last_error_message: None,
63            last_synchronization_error_date: None,
64            max_connections: None,
65        }
66    }
67
68    /// Sets a new list of allowed updates.
69    ///
70    /// # Arguments
71    ///
72    /// * `value` - List of allowed updates.
73    pub fn with_allowed_updates<T>(mut self, value: T) -> Self
74    where
75        T: IntoIterator<Item = AllowedUpdate>,
76    {
77        self.allowed_updates = Some(value.into_iter().collect());
78        self
79    }
80
81    /// Sets a new IP address.
82    ///
83    /// # Arguments
84    ///
85    /// * `value` - IP address.
86    pub fn with_ip_address<T>(mut self, value: T) -> Self
87    where
88        T: Into<String>,
89    {
90        self.ip_address = Some(value.into());
91        self
92    }
93
94    /// Sets a new last error date.
95    ///
96    /// # Arguments
97    ///
98    /// * `value` - Last error date.
99    pub fn with_last_error_date(mut self, value: Integer) -> Self {
100        self.last_error_date = Some(value);
101        self
102    }
103
104    /// Sets a new last error message.
105    ///
106    /// # Arguments
107    ///
108    /// * `value` - Last error message.
109    pub fn with_last_error_message<T>(mut self, value: T) -> Self
110    where
111        T: Into<String>,
112    {
113        self.last_error_message = Some(value.into());
114        self
115    }
116
117    /// Sets a new last synchronization error date.
118    ///
119    /// # Arguments
120    ///
121    /// * `value` - Last synchronization error date.
122    pub fn with_last_synchronization_error_date(mut self, value: Integer) -> Self {
123        self.last_synchronization_error_date = Some(value);
124        self
125    }
126
127    /// Sets a new number of max connections.
128    ///
129    /// # Arguments
130    ///
131    /// * `value` - Number of max connections.
132    pub fn with_max_connections(mut self, value: Integer) -> Self {
133        self.max_connections = Some(value);
134        self
135    }
136}
137
138/// Removes a webhook integration if you decide to switch back to [`crate::types::GetUpdates`].
139#[derive(Clone, Copy, Debug, Default, Serialize)]
140pub struct DeleteWebhook {
141    drop_pending_updates: Option<bool>,
142}
143
144impl DeleteWebhook {
145    /// Sets a new value for the `drop_pending_updates` flag.
146    ///
147    /// # Arguments
148    ///
149    /// * `value` - Indicates whether to drop all pending updates.
150    pub fn with_drop_pending_updates(mut self, value: bool) -> Self {
151        self.drop_pending_updates = Some(value);
152        self
153    }
154}
155
156impl Method for DeleteWebhook {
157    type Response = bool;
158
159    fn into_payload(self) -> Payload {
160        if self.drop_pending_updates.is_some() {
161            Payload::json("deleteWebhook", self)
162        } else {
163            Payload::empty("deleteWebhook")
164        }
165    }
166}
167
168/// Returns current webhook status.
169#[derive(Clone, Copy, Debug)]
170pub struct GetWebhookInfo;
171
172impl Method for GetWebhookInfo {
173    type Response = WebhookInfo;
174
175    fn into_payload(self) -> Payload {
176        Payload::empty("getWebhookInfo")
177    }
178}
179
180/// Specifies an url and returns incoming updates via an outgoing webhook.
181///
182/// Whenever there is an update for the bot, we will send an HTTPS POST request
183/// to the specified url, containing a JSON-serialized Update.
184/// In case of an unsuccessful request, we will give up after a reasonable amount of attempts.
185///
186/// If you'd like to make sure that the Webhook request comes from Telegram,
187/// we recommend using a secret path in the URL, e.g. `https://www.example.com/<token>`
188/// Since nobody else knows your bot‘s token, you can be pretty sure it’s us.
189#[serde_with::skip_serializing_none]
190#[derive(Clone, Debug, Serialize)]
191pub struct SetWebhook {
192    url: String,
193    allowed_updates: Option<HashSet<AllowedUpdate>>,
194    certificate: Option<String>,
195    drop_pending_updates: Option<bool>,
196    ip_address: Option<String>,
197    max_connections: Option<Integer>,
198    secret_token: Option<String>,
199}
200
201impl SetWebhook {
202    /// Creates a new `SetWebhook`.
203    ///
204    /// # Arguments
205    ///
206    /// * `url` - HTTPS url to send updates to; use an empty string to remove webhook integration.
207    pub fn new<T>(url: T) -> Self
208    where
209        T: Into<String>,
210    {
211        Self {
212            url: url.into(),
213            allowed_updates: None,
214            certificate: None,
215            drop_pending_updates: None,
216            ip_address: None,
217            max_connections: None,
218            secret_token: None,
219        }
220    }
221
222    /// Adds a type of update you want your bot to receive.
223    ///
224    /// # Arguments
225    ///
226    /// * `value` - A type to add.
227    pub fn add_allowed_update(mut self, value: AllowedUpdate) -> Self {
228        match self.allowed_updates {
229            Some(ref mut updates) => {
230                updates.insert(value);
231            }
232            None => {
233                let mut updates = HashSet::new();
234                updates.insert(value);
235                self.allowed_updates = Some(updates);
236            }
237        };
238        self
239    }
240
241    /// Sets a new list of allowed update types.
242    ///
243    /// # Arguments
244    ///
245    /// * `value` - List of types you want your bot to receive.
246    ///
247    /// For example, specify `[AllowedUpdate::Message]`
248    /// to only receive updates of these types.
249    /// See [`AllowedUpdate`] for a complete list of available update types.
250    /// Specify an empty list to receive all updates regardless of type (default).
251    /// If not specified, the previous setting will be used.
252    /// Please note that this parameter doesn't affect
253    /// updates created before the call to the [`SetWebhook`],
254    /// so unwanted updates may be received for a short period of time.
255    pub fn with_allowed_updates(mut self, value: HashSet<AllowedUpdate>) -> Self {
256        self.allowed_updates = Some(value);
257        self
258    }
259
260    /// Sets a new certificate.
261    ///
262    /// # Arguments
263    ///
264    /// * `value` - Public key certificate; so that the root certificate in use can be checked.
265    pub fn with_certificate<T>(mut self, value: T) -> Self
266    where
267        T: Into<String>,
268    {
269        self.certificate = Some(value.into());
270        self
271    }
272
273    /// Sets a new value for the `drop_pending_updates` flag.
274    ///
275    /// # Arguments
276    ///
277    /// * `value` - Indicates whether to drop all pending updates.
278    pub fn with_drop_pending_updates(mut self, value: bool) -> Self {
279        self.drop_pending_updates = Some(value);
280        self
281    }
282
283    /// Sets a new IP address.
284    ///
285    /// # Arguments
286    ///
287    /// * `value` - The fixed IP address which will be used to send webhook requests
288    ///   instead of the IP address resolved through DNS.
289    pub fn with_ip_address<T>(mut self, value: T) -> Self
290    where
291        T: Into<String>,
292    {
293        self.ip_address = Some(value.into());
294        self
295    }
296
297    /// Sets a new number of max connections.
298    ///
299    /// # Arguments
300    ///
301    /// * `value` - Maximum allowed number of simultaneous HTTPS connections
302    ///   to the webhook for update delivery; 1-100; default - 40.
303    ///
304    /// Use lower values to limit the load on your bot‘s server,
305    /// and higher values to increase your bot’s throughput.
306    pub fn with_max_connections(mut self, value: Integer) -> Self {
307        self.max_connections = Some(value);
308        self
309    }
310
311    /// Sets a new secret token.
312    ///
313    /// # Arguments
314    ///
315    /// * `value` - A secret token to be sent in a header.
316    ///
317    /// “X-Telegram-Bot-Api-Secret-Token” in every webhook request; 1-256 characters
318    ///
319    /// Only characters A-Z, a-z, 0-9, _ and - are allowed.
320    /// The header is useful to ensure that the request comes from a webhook set by you.
321    pub fn with_secret_token<T>(mut self, value: T) -> Self
322    where
323        T: Into<String>,
324    {
325        self.secret_token = Some(value.into());
326        self
327    }
328}
329
330impl Method for SetWebhook {
331    type Response = bool;
332
333    fn into_payload(self) -> Payload {
334        Payload::json("setWebhook", self)
335    }
336}