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}