tgbot/types/sticker/set/mod.rs
1use serde::{Deserialize, Serialize};
2
3use crate::{
4 api::{Form, Method, Payload},
5 types::{
6 InputFile,
7 InputSticker,
8 InputStickerError,
9 InputStickers,
10 Integer,
11 PhotoSize,
12 Sticker,
13 StickerFormat,
14 StickerType,
15 },
16};
17
18#[cfg(test)]
19mod tests;
20
21/// Represents a sticker set.
22#[serde_with::skip_serializing_none]
23#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
24pub struct StickerSet {
25 /// Name of the sticker set.
26 pub name: String,
27 /// Type of stickers.
28 pub sticker_type: StickerType,
29 /// List of stickers.
30 pub stickers: Vec<Sticker>,
31 /// Title of the sticker set.
32 pub title: String,
33 /// Sticker set thumbnail in the WEBP or TGS format.
34 pub thumbnail: Option<PhotoSize>,
35}
36
37impl StickerSet {
38 /// Creates a new `StickerSet`.
39 ///
40 /// # Arguments
41 ///
42 /// * `name` - Name of the sticker set.
43 /// * `sticker_type` - Type of stickers.
44 /// * `stickers` - List of stickers.
45 /// * `title` - Title of the sticker set.
46 pub fn new<A, B, C>(name: A, sticker_type: StickerType, stickers: C, title: B) -> Self
47 where
48 A: Into<String>,
49 B: Into<String>,
50 C: IntoIterator<Item = Sticker>,
51 {
52 Self {
53 name: name.into(),
54 sticker_type,
55 stickers: stickers.into_iter().collect(),
56 title: title.into(),
57 thumbnail: None,
58 }
59 }
60
61 /// Sets a new thumbnail.
62 ///
63 /// # Arguments
64 ///
65 /// * `value` - Thumbnail.
66 pub fn with_thumbnail(mut self, value: PhotoSize) -> Self {
67 self.thumbnail = Some(value);
68 self
69 }
70}
71
72/// Adds a new sticker to a set created by the bot.
73///
74/// The format of the added sticker must match the format of the other stickers in the set.
75/// Emoji sticker sets can have up to 200 stickers.
76/// Animated and video sticker sets can have up to 50 stickers.
77/// Static sticker sets can have up to 120 stickers.
78#[derive(Debug)]
79pub struct AddStickerToSet {
80 form: Form,
81}
82
83impl AddStickerToSet {
84 /// Creates a new `AddStickerToSet`.
85 ///
86 /// # Arguments
87 ///
88 /// * `user_id` - User identifier of sticker set owner.
89 /// * `name` - Sticker set name.
90 /// * `sticker` - Sticker file.
91 pub fn new<T>(user_id: Integer, name: T, sticker: InputSticker) -> Result<Self, InputStickerError>
92 where
93 T: Into<String>,
94 {
95 let mut form: Form = sticker.try_into()?;
96 form.insert_field("user_id", user_id);
97 form.insert_field("name", name.into());
98 Ok(Self { form })
99 }
100}
101
102impl Method for AddStickerToSet {
103 type Response = bool;
104
105 fn into_payload(self) -> Payload {
106 Payload::form("addStickerToSet", self.form)
107 }
108}
109
110/// Creates a new sticker set owned by a user.
111///
112/// The bot will be able to edit the created sticker set.
113#[derive(Debug)]
114pub struct CreateNewStickerSet {
115 form: Form,
116}
117
118impl CreateNewStickerSet {
119 /// Creates a new `CreateNewStickerSet`.
120 ///
121 /// # Arguments
122 ///
123 /// * `user_id` - User identifier of created sticker set owner.
124 /// * `name` - Short name of sticker set, to be used in t.me/addstickers/ URLs (e.g., animals);
125 /// can contain only english letters, digits and underscores;
126 /// must begin with a letter, can't contain consecutive underscores
127 /// and must end in `_by_<bot username>`;
128 /// <bot_username> is case insensitive;
129 /// 1-64 characters.
130 /// * `title` - Sticker set title; 1-64 characters.
131 /// * `stickers` - A list of 1-50 initial stickers to be added to the sticker set.
132 pub fn new<A, B>(user_id: Integer, name: A, title: B, stickers: InputStickers) -> Result<Self, InputStickerError>
133 where
134 A: Into<String>,
135 B: Into<String>,
136 {
137 let mut form: Form = stickers.try_into()?;
138 form.insert_field("user_id", user_id);
139 form.insert_field("name", name.into());
140 form.insert_field("title", title.into());
141 Ok(Self { form })
142 }
143
144 /// Sets a new value for the `needs_repainting` flag.
145 ///
146 /// # Arguments
147 ///
148 /// * `value` - Indicates whether stickers in the sticker set must be repainted to the color
149 /// of text when used in messages, the accent color if used as emoji status,
150 /// white on chat photos, or another appropriate color based on context;
151 /// for custom emoji sticker sets only.
152 pub fn with_needs_repainting(mut self, value: bool) -> Self {
153 self.form.insert_field("needs_repainting", value);
154 self
155 }
156
157 /// Sets a new sticker type.
158 ///
159 /// # Arguments
160 ///
161 /// * `value` - Type of stickers in the set.
162 ///
163 /// By default, a regular sticker set is created.
164 pub fn with_sticker_type(mut self, value: StickerType) -> Self {
165 self.form.insert_field("sticker_type", value.as_ref());
166 self
167 }
168}
169
170impl Method for CreateNewStickerSet {
171 type Response = bool;
172
173 fn into_payload(self) -> Payload {
174 Payload::form("createNewStickerSet", self.form)
175 }
176}
177
178/// Deletes a sticker from a set created by the bot.
179#[derive(Clone, Debug, Serialize)]
180pub struct DeleteStickerFromSet {
181 sticker: String,
182}
183
184impl DeleteStickerFromSet {
185 /// Creates a new `DeleteStickerFromSet`.
186 ///
187 /// # Arguments
188 ///
189 /// * `sticker` - File identifier of the sticker.
190 pub fn new<T>(sticker: T) -> Self
191 where
192 T: Into<String>,
193 {
194 Self {
195 sticker: sticker.into(),
196 }
197 }
198}
199
200impl Method for DeleteStickerFromSet {
201 type Response = bool;
202
203 fn into_payload(self) -> Payload {
204 Payload::json("deleteStickerFromSet", self)
205 }
206}
207
208/// Deletes a sticker set that was created by the bot.
209#[derive(Clone, Debug, Serialize)]
210pub struct DeleteStickerSet {
211 name: String,
212}
213
214impl DeleteStickerSet {
215 /// Creates a new `DeleteStickerSet`.
216 ///
217 /// # Arguments
218 ///
219 /// * `name` - Sticker set name.
220 pub fn new<T>(name: T) -> Self
221 where
222 T: Into<String>,
223 {
224 Self { name: name.into() }
225 }
226}
227
228impl Method for DeleteStickerSet {
229 type Response = bool;
230
231 fn into_payload(self) -> Payload {
232 Payload::json("deleteStickerSet", self)
233 }
234}
235
236/// Returns a sticker set.
237#[derive(Clone, Debug, Serialize)]
238pub struct GetStickerSet {
239 name: String,
240}
241
242impl GetStickerSet {
243 /// Creates a new `GetStickerSet`.
244 ///
245 /// # Arguments
246 ///
247 /// * `name` - Name of the sticker set.
248 pub fn new<T>(name: T) -> Self
249 where
250 T: Into<String>,
251 {
252 Self { name: name.into() }
253 }
254}
255
256impl Method for GetStickerSet {
257 type Response = StickerSet;
258
259 fn into_payload(self) -> Payload {
260 Payload::json("getStickerSet", self)
261 }
262}
263
264/// Replaces an existing sticker in a sticker set with a new one.
265///
266/// The method is equivalent to calling [`crate::types::DeleteStickerFromSet`],
267/// then [`crate::types::AddStickerToSet`],
268/// then [`crate::types::SetStickerPositionInSet`].
269#[derive(Debug)]
270pub struct ReplaceStickerInSet {
271 form: Form,
272}
273
274impl ReplaceStickerInSet {
275 /// Creates a new `ReplaceStickerInSet`.
276 ///
277 /// # Arguments
278 ///
279 /// * `name` - Sticker set name.
280 /// * `old_sticker` - File identifier of the replaced sticker.
281 /// * `sticker` - Information about the added sticker;
282 /// if exactly the same sticker had already been added to the set, then the set remains unchanged.
283 /// * `user_id` - User identifier of the sticker set owner.
284 pub fn new<A, B>(
285 name: A,
286 old_sticker: B,
287 sticker: InputSticker,
288 user_id: Integer,
289 ) -> Result<Self, InputStickerError>
290 where
291 A: Into<String>,
292 B: Into<String>,
293 {
294 let mut form: Form = sticker.try_into()?;
295 form.insert_field("name", name.into());
296 form.insert_field("old_sticker", old_sticker.into());
297 form.insert_field("user_id", user_id);
298 Ok(Self { form })
299 }
300}
301
302impl Method for ReplaceStickerInSet {
303 type Response = bool;
304
305 fn into_payload(self) -> Payload {
306 Payload::form("replaceStickerInSet", self.form)
307 }
308}
309
310/// Sets the thumbnail of a custom emoji sticker set.
311#[serde_with::skip_serializing_none]
312#[derive(Clone, Debug, Serialize)]
313pub struct SetCustomEmojiStickerSetThumbnail {
314 name: String,
315 custom_emoji_id: Option<String>,
316}
317
318impl SetCustomEmojiStickerSetThumbnail {
319 /// Creates a new `SetCustomEmojiStickerSetThumbnail`.
320 ///
321 /// # Arguments
322 ///
323 /// * `name` - Sticker set name.
324 pub fn new<T>(name: T) -> Self
325 where
326 T: Into<String>,
327 {
328 Self {
329 name: name.into(),
330 custom_emoji_id: None,
331 }
332 }
333
334 /// Sets a new custom emoji ID.
335 ///
336 /// # Arguments
337 ///
338 /// * `value` - Custom emoji identifier of a sticker from the sticker set.
339 ///
340 /// Pass an empty string to drop the thumbnail and use the first sticker as the thumbnail.
341 pub fn with_custom_emoji_id<T>(mut self, value: T) -> Self
342 where
343 T: Into<String>,
344 {
345 self.custom_emoji_id = Some(value.into());
346 self
347 }
348}
349
350impl Method for SetCustomEmojiStickerSetThumbnail {
351 type Response = bool;
352
353 fn into_payload(self) -> Payload {
354 Payload::json("setCustomEmojiStickerSetThumbnail", self)
355 }
356}
357
358/// Moves a sticker in a set created by the bot to a specific position.
359#[derive(Clone, Debug, Serialize)]
360pub struct SetStickerPositionInSet {
361 position: Integer,
362 sticker: String,
363}
364
365impl SetStickerPositionInSet {
366 /// Creates a new `SetStickerPositionInSet`.
367 ///
368 /// # Arguments
369 ///
370 /// * `position` - New sticker position in the set, zero-based.
371 /// * `sticker` - File identifier of the sticker.
372 pub fn new<T>(position: Integer, sticker: T) -> Self
373 where
374 T: Into<String>,
375 {
376 Self {
377 position,
378 sticker: sticker.into(),
379 }
380 }
381}
382
383impl Method for SetStickerPositionInSet {
384 type Response = bool;
385
386 fn into_payload(self) -> Payload {
387 Payload::json("setStickerPositionInSet", self)
388 }
389}
390
391/// Sets a title of a created sticker set.
392#[derive(Clone, Debug, Serialize)]
393pub struct SetStickerSetTitle {
394 name: String,
395 title: String,
396}
397
398impl SetStickerSetTitle {
399 /// Creates a new `SetStickerSetTitle`.
400 ///
401 /// # Arguments
402 ///
403 /// * `name` - Sticker set name.
404 /// * `title` - Sticker set title; 1-64 characters.
405 pub fn new<A, B>(name: A, title: B) -> Self
406 where
407 A: Into<String>,
408 B: Into<String>,
409 {
410 Self {
411 name: name.into(),
412 title: title.into(),
413 }
414 }
415}
416
417impl Method for SetStickerSetTitle {
418 type Response = bool;
419
420 fn into_payload(self) -> Payload {
421 Payload::json("setStickerSetTitle", self)
422 }
423}
424
425/// Sets a thumbnail of a sticker set.
426#[derive(Debug)]
427pub struct SetStickerSetThumbnail {
428 form: Form,
429}
430
431impl SetStickerSetThumbnail {
432 /// Creates a new `SetStickerSetThumbnail`.
433 ///
434 /// # Arguments
435 ///
436 /// * `name` - Sticker set name.
437 /// * `user_id` - User identifier of the sticker set owner.
438 /// * `format` - Format of the thumbnail.
439 pub fn new<N>(name: N, user_id: Integer, format: StickerFormat) -> Self
440 where
441 N: Into<String>,
442 {
443 Self {
444 form: Form::from([
445 ("name", name.into().into()),
446 ("user_id", user_id.into()),
447 ("format", format.as_ref().into()),
448 ]),
449 }
450 }
451
452 /// Sets a new thumbnail.
453 ///
454 /// # Arguments
455 ///
456 /// * `value` - A WEBP or PNG image with the thumbnail.
457 ///
458 /// Must be up to 128 kilobytes in size and have a width and height of exactly 100px,
459 /// or a .TGS animation with a thumbnail up to 32 kilobytes in size
460 /// (see <https://core.telegram.org/stickers#animated-sticker-requirements> for animated sticker
461 /// technical requirements), or a WEBM video with the thumbnail up to 32 kilobytes in size;
462 /// see <https://core.telegram.org/stickers#video-sticker-requirements> for video sticker
463 /// technical requirements.
464 ///
465 /// Animated and video sticker set thumbnails can't be uploaded via HTTP URL.
466 /// If omitted, then the thumbnail is dropped and the first sticker is used as the thumbnail.
467 pub fn with_thumbnail<T>(mut self, value: T) -> Self
468 where
469 T: Into<InputFile>,
470 {
471 self.form.insert_field("thumbnail", value.into());
472 self
473 }
474}
475
476impl Method for SetStickerSetThumbnail {
477 type Response = bool;
478
479 fn into_payload(self) -> Payload {
480 Payload::form("setStickerSetThumbnail", self.form)
481 }
482}