tgbot/types/definitions/
forum.rs

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