tgbot/types/forum/mod.rs
1use serde::{Deserialize, Serialize};
2
3use crate::{
4 api::{Method, Payload},
5 types::{ChatId, ForumTopicIconColor, Integer, Sticker},
6};
7
8#[cfg(test)]
9mod tests;
10
11/// Represents a forum topic.
12#[serde_with::skip_serializing_none]
13#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
14pub struct ForumTopic {
15 /// Color of the icon.
16 pub icon_color: ForumTopicIconColor,
17 /// Unique identifier.
18 pub message_thread_id: Integer,
19 /// Name.
20 pub name: String,
21 /// Unique identifier of the custom emoji shown as the topic icon.
22 pub icon_custom_emoji_id: Option<String>,
23}
24
25impl ForumTopic {
26 /// Creates a new `ForumTopic`.
27 ///
28 /// # Arguments
29 ///
30 /// * `icon_color` - Color of the icon.
31 /// * `message_thread_id` - Unique identifier of the topic.
32 /// * `name` - Name of the topic.
33 pub fn new<A, B>(icon_color: A, message_thread_id: Integer, name: B) -> Self
34 where
35 A: Into<ForumTopicIconColor>,
36 B: Into<String>,
37 {
38 Self {
39 icon_color: icon_color.into(),
40 message_thread_id,
41 name: name.into(),
42 icon_custom_emoji_id: None,
43 }
44 }
45
46 /// Sets a new icon custom emoji ID.
47 ///
48 /// # Arguments
49 ///
50 /// * `value` - Emoji ID.
51 pub fn with_icon_custom_emoji_id<T>(mut self, value: T) -> Self
52 where
53 T: Into<String>,
54 {
55 self.icon_custom_emoji_id = Some(value.into());
56 self
57 }
58}
59
60/// Closes an open topic in a forum supergroup chat.
61///
62/// The bot must be an administrator in the chat for this to work
63/// and must have the `can_manage_topics` administrator rights,
64/// unless it is the creator of the topic.
65#[derive(Clone, Debug, Serialize)]
66pub struct CloseForumTopic {
67 chat_id: ChatId,
68 message_thread_id: Integer,
69}
70
71impl CloseForumTopic {
72 /// Creates a new `CloseForumTopic`.
73 ///
74 /// # Arguments
75 ///
76 /// * `chat_id` - Unique identifier of the target chat.
77 /// * `message_thread_id` - Unique identifier of the target message thread of the forum topic.
78 pub fn new<T>(chat_id: T, message_thread_id: Integer) -> Self
79 where
80 T: Into<ChatId>,
81 {
82 Self {
83 chat_id: chat_id.into(),
84 message_thread_id,
85 }
86 }
87}
88
89impl Method for CloseForumTopic {
90 type Response = bool;
91
92 fn into_payload(self) -> Payload {
93 Payload::json("closeForumTopic", self)
94 }
95}
96
97/// Creates a topic in a forum supergroup chat.
98///
99/// The bot must be an administrator in the chat for this to work
100/// and must have the can_manage_topics administrator rights.
101#[serde_with::skip_serializing_none]
102#[derive(Clone, Debug, Serialize)]
103pub struct CreateForumTopic {
104 chat_id: ChatId,
105 name: String,
106 icon_color: Option<ForumTopicIconColor>,
107 icon_custom_emoji_id: Option<String>,
108}
109
110impl CreateForumTopic {
111 /// Creates a new `CreateForumTopic`.
112 ///
113 /// # Arguments
114 ///
115 /// * `chat_id` - Unique identifier of the target chat.
116 /// * `name` - Topic name; 1 - 128 characters.
117 pub fn new<A, B>(chat_id: A, name: B) -> Self
118 where
119 A: Into<ChatId>,
120 B: Into<String>,
121 {
122 Self {
123 chat_id: chat_id.into(),
124 name: name.into(),
125 icon_color: None,
126 icon_custom_emoji_id: None,
127 }
128 }
129
130 /// Sets a new color of the topic icon.
131 ///
132 /// # Arguments
133 ///
134 /// * `value` - Color of the topic icon.
135 pub fn with_icon_color(mut self, value: ForumTopicIconColor) -> Self {
136 self.icon_color = Some(value);
137 self
138 }
139
140 /// Sets a new icon custom emoji ID.
141 ///
142 /// # Arguments
143 ///
144 /// * `value` - Unique identifier of the custom emoji shown as the topic icon.
145 ///
146 /// Use [`GetForumTopicIconStickers`] to get all allowed custom emoji identifiers.
147 pub fn with_icon_custom_emoji_id<T>(mut self, value: T) -> Self
148 where
149 T: Into<String>,
150 {
151 self.icon_custom_emoji_id = Some(value.into());
152 self
153 }
154}
155
156impl Method for CreateForumTopic {
157 type Response = ForumTopic;
158
159 fn into_payload(self) -> Payload {
160 Payload::json("createForumTopic", self)
161 }
162}
163
164/// Closes an opened 'General' topic in a forum supergroup chat.
165///
166/// The bot must be an administrator in the chat for this to work
167/// and must have the can_manage_topics administrator rights.
168#[derive(Clone, Debug, Serialize)]
169pub struct CloseGeneralForumTopic {
170 chat_id: ChatId,
171}
172
173impl CloseGeneralForumTopic {
174 /// Creates a new `CloseGeneralForumTopic`.
175 ///
176 /// # Arguments
177 ///
178 /// * `chat_id` - Unique identifier of the target chat.
179 pub fn new<T>(chat_id: T) -> Self
180 where
181 T: Into<ChatId>,
182 {
183 Self {
184 chat_id: chat_id.into(),
185 }
186 }
187}
188
189impl Method for CloseGeneralForumTopic {
190 type Response = bool;
191
192 fn into_payload(self) -> Payload {
193 Payload::json("closeGeneralForumTopic", self)
194 }
195}
196
197/// Deletes a forum topic along with all its messages in a forum supergroup chat.
198///
199/// The bot must be an administrator in the chat for this to work
200/// and must have the can_delete_messages administrator rights.
201#[derive(Clone, Debug, Serialize)]
202pub struct DeleteForumTopic {
203 chat_id: ChatId,
204 message_thread_id: Integer,
205}
206
207impl DeleteForumTopic {
208 /// Creates a new `DeleteForumTopic`.
209 ///
210 /// # Arguments
211 ///
212 /// * `chat_id` - Unique identifier of the target chat.
213 /// * `message_thread_id` - Unique identifier of the target message thread of the forum topic.
214 pub fn new<T>(chat_id: T, message_thread_id: Integer) -> Self
215 where
216 T: Into<ChatId>,
217 {
218 Self {
219 chat_id: chat_id.into(),
220 message_thread_id,
221 }
222 }
223}
224
225impl Method for DeleteForumTopic {
226 type Response = bool;
227
228 fn into_payload(self) -> Payload {
229 Payload::json("deleteForumTopic", self)
230 }
231}
232
233/// Changes name and icon of a topic in a forum supergroup chat.
234///
235/// The bot must be an administrator in the chat for this to work
236/// and must have can_manage_topics administrator rights,
237/// unless it is the creator of the topic.
238#[serde_with::skip_serializing_none]
239#[derive(Clone, Debug, Serialize)]
240pub struct EditForumTopic {
241 chat_id: ChatId,
242 message_thread_id: Integer,
243 icon_custom_emoji_id: Option<String>,
244 name: Option<String>,
245}
246
247impl EditForumTopic {
248 /// Creates a new `EditForumTopic`.
249 ///
250 /// # Arguments
251 ///
252 /// * `chat_id` - Unique identifier of the target.
253 /// * `message_thread_id` - Unique identifier of the target message thread of the forum topic.
254 pub fn new<C>(chat_id: C, message_thread_id: Integer) -> Self
255 where
256 C: Into<ChatId>,
257 {
258 Self {
259 chat_id: chat_id.into(),
260 message_thread_id,
261 icon_custom_emoji_id: None,
262 name: None,
263 }
264 }
265
266 /// Sets a new icon custom emoji ID.
267 ///
268 /// # Arguments
269 ///
270 /// * `value` - New unique identifier of the custom emoji shown as the topic icon.
271 ///
272 /// Use [`GetForumTopicIconStickers`] to get all allowed custom emoji identifiers.
273 /// Pass an empty string to remove the icon.
274 /// If not specified, the current icon will be kept.
275 pub fn with_icon_custom_emoji_id<T>(mut self, value: T) -> Self
276 where
277 T: Into<String>,
278 {
279 self.icon_custom_emoji_id = Some(value.into());
280 self
281 }
282
283 /// Sets a new name.
284 ///
285 /// # Arguments
286 ///
287 /// * `value` - New topic name; 0-128 characters.
288 ///
289 /// If not specified or empty, the current name of the topic will be kept.
290 pub fn with_name<T>(mut self, value: T) -> Self
291 where
292 T: Into<String>,
293 {
294 self.name = Some(value.into());
295 self
296 }
297}
298
299impl Method for EditForumTopic {
300 type Response = bool;
301
302 fn into_payload(self) -> Payload {
303 Payload::json("editForumTopic", self)
304 }
305}
306
307/// Changes the name of the 'General' topic in a forum supergroup chat.
308///
309/// The bot must be an administrator in the chat for this to work
310/// and must have `can_manage_topics` administrator rights.
311#[derive(Clone, Debug, Serialize)]
312pub struct EditGeneralForumTopic {
313 chat_id: ChatId,
314 name: String,
315}
316
317impl EditGeneralForumTopic {
318 /// Creates a new `EditGeneralForumTopic`.
319 ///
320 /// # Arguments
321 ///
322 /// * `chat_id` - Unique identifier for the target chat.
323 /// * `name` - New topic name, 1-128 characters.
324 pub fn new<A, B>(chat_id: A, name: B) -> Self
325 where
326 A: Into<ChatId>,
327 B: Into<String>,
328 {
329 Self {
330 chat_id: chat_id.into(),
331 name: name.into(),
332 }
333 }
334}
335
336impl Method for EditGeneralForumTopic {
337 type Response = bool;
338
339 fn into_payload(self) -> Payload {
340 Payload::json("editGeneralForumTopic", self)
341 }
342}
343
344/// Returns custom emoji stickers, which can be used as a forum topic icon by any user.
345#[derive(Clone, Copy, Debug)]
346pub struct GetForumTopicIconStickers;
347
348impl Method for GetForumTopicIconStickers {
349 type Response = Vec<Sticker>;
350
351 fn into_payload(self) -> Payload {
352 Payload::empty("getForumTopicIconStickers")
353 }
354}
355
356/// Hides the 'General' topic in a forum supergroup chat.
357///
358/// The bot must be an administrator in the chat for this to work
359/// and must have the `can_manage_topics` administrator rights.
360/// The topic will be automatically closed if it was open.
361#[derive(Clone, Debug, Serialize)]
362pub struct HideGeneralForumTopic {
363 chat_id: ChatId,
364}
365
366impl HideGeneralForumTopic {
367 /// Creates a new `HideGeneralForumTopic`.
368 ///
369 /// # Arguments
370 ///
371 /// * `chat_id` - Unique identifier for the target chat.
372 pub fn new<T>(chat_id: T) -> Self
373 where
374 T: Into<ChatId>,
375 {
376 Self {
377 chat_id: chat_id.into(),
378 }
379 }
380}
381
382impl Method for HideGeneralForumTopic {
383 type Response = bool;
384
385 fn into_payload(self) -> Payload {
386 Payload::json("hideGeneralForumTopic", self)
387 }
388}
389
390/// Reopens a closed topic in a forum supergroup chat.
391///
392/// The bot must be an administrator in the chat for this to work
393/// and must have the `can_manage_topics` administrator rights,
394/// unless it is the creator of the topic.
395#[derive(Clone, Debug, Serialize)]
396pub struct ReopenForumTopic {
397 chat_id: ChatId,
398 message_thread_id: Integer,
399}
400
401impl ReopenForumTopic {
402 /// Creates a new `ReopenForumTopic`.
403 ///
404 /// # Arguments
405 ///
406 /// * `chat_id` - Unique identifier of the target chat.
407 /// * `message_thread_id` - Unique identifier of the target message thread of the forum topic.
408 pub fn new<T>(chat_id: T, message_thread_id: Integer) -> Self
409 where
410 T: Into<ChatId>,
411 {
412 Self {
413 chat_id: chat_id.into(),
414 message_thread_id,
415 }
416 }
417}
418
419impl Method for ReopenForumTopic {
420 type Response = bool;
421
422 fn into_payload(self) -> Payload {
423 Payload::json("reopenForumTopic", self)
424 }
425}
426
427/// Reopens a closed 'General' topic in a forum supergroup chat.
428///
429/// The bot must be an administrator in the chat for this to work
430/// and must have the `can_manage_topics` administrator rights.
431/// The topic will be automatically unhidden if it was hidden.
432#[derive(Clone, Debug, Serialize)]
433pub struct ReopenGeneralForumTopic {
434 chat_id: ChatId,
435}
436
437impl ReopenGeneralForumTopic {
438 /// Creates a new `ReopenGeneralForumTopic`.
439 ///
440 /// # Arguments
441 ///
442 /// * `chat_id` - Unique identifier of the target chat.
443 pub fn new<T>(chat_id: T) -> Self
444 where
445 T: Into<ChatId>,
446 {
447 Self {
448 chat_id: chat_id.into(),
449 }
450 }
451}
452
453impl Method for ReopenGeneralForumTopic {
454 type Response = bool;
455
456 fn into_payload(self) -> Payload {
457 Payload::json("reopenGeneralForumTopic", self)
458 }
459}
460
461/// Reveals the 'General' topic in a forum supergroup chat.
462///
463/// The bot must be an administrator in the chat for this to work
464/// and must have the `can_manage_topics` administrator rights.
465#[derive(Clone, Debug, Serialize)]
466pub struct UnhideGeneralForumTopic {
467 chat_id: ChatId,
468}
469
470impl UnhideGeneralForumTopic {
471 /// Creates a new `UnhideGeneralForumTopic`.
472 ///
473 /// # Arguments
474 ///
475 /// * `chat_id` - Unique identifier of the target chat.
476 pub fn new<T>(chat_id: T) -> Self
477 where
478 T: Into<ChatId>,
479 {
480 Self {
481 chat_id: chat_id.into(),
482 }
483 }
484}
485
486impl Method for UnhideGeneralForumTopic {
487 type Response = bool;
488
489 fn into_payload(self) -> Payload {
490 Payload::json("unhideGeneralForumTopic", self)
491 }
492}
493
494/// Clears the list of pinned messages in a forum topic.
495///
496/// The bot must be an administrator in the chat for this to work
497/// and must have the `can_pin_messages` administrator right in the supergroup.
498#[derive(Clone, Debug, Serialize)]
499pub struct UnpinAllForumTopicMessages {
500 chat_id: ChatId,
501 message_thread_id: Integer,
502}
503
504impl UnpinAllForumTopicMessages {
505 /// Creates a new `UnpinAllForumTopicMessages`.
506 ///
507 /// # Arguments
508 ///
509 /// * `chat_id` - Unique identifier of the target chat.
510 /// * `message_thread_id` - Unique identifier of the target message thread of the forum topic.
511 pub fn new<T>(chat_id: T, message_thread_id: Integer) -> Self
512 where
513 T: Into<ChatId>,
514 {
515 Self {
516 chat_id: chat_id.into(),
517 message_thread_id,
518 }
519 }
520}
521
522impl Method for UnpinAllForumTopicMessages {
523 type Response = bool;
524
525 fn into_payload(self) -> Payload {
526 Payload::json("unpinAllForumTopicMessages", self)
527 }
528}
529
530/// Clears the list of pinned messages in a General forum topic.
531///
532/// The bot must be an administrator in the chat for this to work
533/// and must have the `can_pin_messages` administrator right in the supergroup.
534#[derive(Clone, Debug, Serialize)]
535pub struct UnpinAllGeneralForumTopicMessages {
536 chat_id: ChatId,
537}
538
539impl UnpinAllGeneralForumTopicMessages {
540 /// Creates a new `UnpinAllGeneralForumTopicMessages`.
541 ///
542 /// # Arguments
543 ///
544 /// * `chat_id` - Unique identifier of the target chat.
545 pub fn new<T>(chat_id: T) -> Self
546 where
547 T: Into<ChatId>,
548 {
549 Self {
550 chat_id: chat_id.into(),
551 }
552 }
553}
554
555impl Method for UnpinAllGeneralForumTopicMessages {
556 type Response = bool;
557
558 fn into_payload(self) -> Payload {
559 Payload::json("unpinAllGeneralForumTopicMessages", self)
560 }
561}