tgbot/types/definitions/live_photo.rs
1use serde::{Deserialize, Serialize};
2
3use crate::{
4 api::{Form, Method, Payload},
5 types::{
6 ChatId,
7 InputFile,
8 Integer,
9 Message,
10 ParseMode,
11 PhotoSize,
12 ReplyMarkup,
13 ReplyMarkupError,
14 ReplyParameters,
15 ReplyParametersError,
16 SuggestedPostParameters,
17 SuggestedPostParametersError,
18 TextEntities,
19 TextEntity,
20 TextEntityError,
21 },
22};
23
24/// Represents a live photo.
25#[serde_with::skip_serializing_none]
26#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
27pub struct LivePhoto {
28 /// Duration of the video in seconds as defined by the sender.
29 duration: Integer,
30 /// Identifier for the video file which can be used to download or reuse the file.
31 file_id: String,
32 /// Unique identifier for the video file which is supposed to be the same over time and for different bots.
33 ///
34 /// Can't be used to download or reuse the file.
35 file_unique_id: String,
36 /// Video height as defined by the sender.
37 height: Integer,
38 /// Video width as defined by the sender.
39 width: Integer,
40 /// File size in bytes.
41 file_size: Option<Integer>,
42 /// MIME type of the file as defined by the sender.
43 mime_type: Option<String>,
44 /// Available sizes of the corresponding static photo.
45 photo: Option<Vec<PhotoSize>>,
46}
47
48impl LivePhoto {
49 /// Creates a new `LivePhoto`.
50 ///
51 /// # Arguments
52 ///
53 /// * `duration` - Duration of the video in seconds.
54 /// * `file_id` - Identifier for the video file which can be used to download or reuse the file.
55 /// * `file_unique_id` - Unique identifier for the video file which is supposed to be the same over time for different bots.
56 /// * `height` - Video height.
57 /// * `width` -> Video width.
58 pub fn new<A, B>(duration: Integer, file_id: A, file_unique_id: B, height: Integer, width: Integer) -> Self
59 where
60 A: Into<String>,
61 B: Into<String>,
62 {
63 Self {
64 duration,
65 file_id: file_id.into(),
66 file_unique_id: file_unique_id.into(),
67 height,
68 width,
69 file_size: None,
70 mime_type: None,
71 photo: None,
72 }
73 }
74
75 /// Sets a new file size.
76 ///
77 /// # Arguments
78 ///
79 /// * `value` - File size in bytes.
80 pub fn with_file_size(mut self, value: Integer) -> Self {
81 self.file_size = Some(value);
82 self
83 }
84
85 /// Sets a new MIME type.
86 ///
87 /// # Arguments
88 ///
89 /// * `value` - MIME type of the file as defined by the sender.
90 pub fn with_mime_type<T>(mut self, value: T) -> Self
91 where
92 T: Into<String>,
93 {
94 self.mime_type = Some(value.into());
95 self
96 }
97
98 /// Sets a new photo.
99 ///
100 /// # Arguments
101 ///
102 /// * `value` - Available sizes of the corresponding static photo.
103 pub fn with_photo<T>(mut self, value: T) -> Self
104 where
105 T: IntoIterator<Item = PhotoSize>,
106 {
107 self.photo = Some(value.into_iter().collect());
108 self
109 }
110}
111
112/// Sends live photos.
113#[derive(Debug)]
114pub struct SendLivePhoto {
115 form: Form,
116}
117
118impl SendLivePhoto {
119 /// Creates a new `SendLivePhoto`.
120 ///
121 /// # Arguments
122 ///
123 /// * `chat_id` - Unique identifier of the target chat.
124 /// * `live_photo` -Live photo videi to send.
125 /// * `photo` - Static photo to send.
126 pub fn new<A, B, C>(chat_id: A, live_photo: B, photo: C) -> Self
127 where
128 A: Into<ChatId>,
129 B: Into<InputFile>,
130 C: Into<InputFile>,
131 {
132 let chat_id = chat_id.into();
133 let live_photo = live_photo.into();
134 let photo = photo.into();
135 Self {
136 form: Form::from([
137 ("chat_id", chat_id.into()),
138 ("live_photo", live_photo.into()),
139 ("photo", photo.into()),
140 ]),
141 }
142 }
143
144 /// Sets a new value for the `allow_paid_broadcast` flag.
145 ///
146 /// # Arguments
147 ///
148 /// * `value` - Whether to allow up to 1000 messages per second;
149 /// ignoring broadcasting limits for a fee of 0.1 Telegram Stars per message;
150 /// the relevant Stars will be withdrawn from the bot's balance.
151 pub fn with_allow_paid_broadcast(mut self, value: bool) -> Self {
152 self.form.insert_field("allow_paid_broadcast", value);
153 self
154 }
155
156 /// Sets a new business connection ID.
157 ///
158 /// # Arguments
159 ///
160 /// * `value` - Unique identifier of the business connection on behalf of which the message will be sent.
161 pub fn with_business_connection_id<T>(mut self, value: T) -> Self
162 where
163 T: Into<String>,
164 {
165 self.form.insert_field("business_connection_id", value.into());
166 self
167 }
168
169 /// Sets a new caption.
170 ///
171 /// # Arguments
172 ///
173 /// * `value` - Video caption (may also be used when resending videos by file_id);
174 /// 0-1024 characters after entities parsing.
175 pub fn with_caption<T>(mut self, value: T) -> Self
176 where
177 T: Into<String>,
178 {
179 self.form.insert_field("caption", value.into());
180 self
181 }
182
183 /// Sets a new list of caption entities.
184 ///
185 /// # Arguments
186 ///
187 /// * `value` - A list of special entities that appear in the caption;
188 /// parse mode will be removed when this method is called.
189 pub fn with_caption_entities<T>(mut self, value: T) -> Result<Self, TextEntityError>
190 where
191 T: IntoIterator<Item = TextEntity>,
192 {
193 let value = TextEntities::from_iter(value);
194 self.form.insert_field("caption_entities", value.serialize()?);
195 self.form.remove_field("parse_mode");
196 Ok(self)
197 }
198
199 /// Sets a new direct messages topic ID.
200 ///
201 /// # Arguments
202 ///
203 /// * `value` - Identifier of the direct messages topic to which the message will be sent;
204 /// required if the message is sent to a direct messages chat.
205 pub fn with_direct_messages_topic_id(mut self, value: Integer) -> Self {
206 self.form.insert_field("direct_messages_topic_id", value);
207 self
208 }
209
210 /// Sets a new value for the `disable_notification` flag.
211 ///
212 /// # Arguments
213 ///
214 /// * `value` - Sends the message silently;
215 /// users will receive a notification with no sound.
216 pub fn with_disable_notification(mut self, value: bool) -> Self {
217 self.form.insert_field("disable_notification", value);
218 self
219 }
220
221 /// Sets a new value for the `has_spoiler` flag.
222 ///
223 /// # Arguments
224 ///
225 /// * `value` - Pass True if the video needs to be covered with a spoiler animation
226 pub fn with_has_spoiler(mut self, value: bool) -> Self {
227 self.form.insert_field("has_spoiler", value);
228 self
229 }
230
231 /// Sets a new message effect ID.
232 ///
233 /// # Arguments
234 ///
235 /// * `value` - Unique identifier of the message effect to be added to the message;
236 /// for private chats only.
237 pub fn with_message_effect_id<T>(mut self, value: T) -> Self
238 where
239 T: Into<String>,
240 {
241 self.form.insert_field("message_effect_id", value.into());
242 self
243 }
244
245 /// Sets a new message thread ID.
246 ///
247 /// # Arguments
248 ///
249 /// * `value` - Unique identifier for the target message thread (topic) of a forum;
250 /// for forum supergroups and private chats of bots with forum topic mode enabled only.
251 pub fn with_message_thread_id(mut self, value: Integer) -> Self {
252 self.form.insert_field("message_thread_id", value);
253 self
254 }
255
256 /// Sets a new parse mode.
257 ///
258 /// # Arguments
259 ///
260 /// * `value` - Mode for parsing entities in the video caption.
261 /// Caption entities will be removed when this method is called.
262 pub fn with_parse_mode(mut self, value: ParseMode) -> Self {
263 self.form.insert_field("parse_mode", value);
264 self.form.remove_field("caption_entities");
265 self
266 }
267
268 /// Sets a new value for the `protect_content` flag.
269 ///
270 /// # Arguments
271 ///
272 /// * `value` - Protects the contents of the sent message from forwarding and saving.
273 pub fn with_protect_content(mut self, value: bool) -> Self {
274 self.form.insert_field("protect_content", value);
275 self
276 }
277
278 /// Sets a new reply markup.
279 ///
280 /// # Arguments
281 ///
282 /// * `value` - Additional interface options.
283 pub fn with_reply_markup<T>(mut self, value: T) -> Result<Self, ReplyMarkupError>
284 where
285 T: Into<ReplyMarkup>,
286 {
287 self.form.insert_field("reply_markup", value.into().serialize()?);
288 Ok(self)
289 }
290
291 /// Sets a new reply parameters.
292 ///
293 /// # Arguments
294 ///
295 /// * `value` - Description of the message to reply to.
296 pub fn with_reply_parameters(mut self, value: ReplyParameters) -> Result<Self, ReplyParametersError> {
297 self.form.insert_field("reply_parameters", value.serialize()?);
298 Ok(self)
299 }
300
301 /// Sets a new value for the `show_caption_above_media` flag.
302 ///
303 /// # Arguments
304 ///
305 /// * `value` - Whether the caption must be shown above the message media.
306 pub fn with_show_caption_above_media(mut self, value: bool) -> Self {
307 self.form.insert_field("show_caption_above_media", value);
308 self
309 }
310
311 /// Sets a new suggested post parameters.
312 ///
313 /// # Arguments
314 ///
315 /// * `value` - The parameters of the suggested post to send;
316 /// for direct messages chats only;
317 /// if the message is sent as a reply to another suggested post,
318 /// then that suggested post is automatically declined.
319 pub fn with_suggested_post_parameters(
320 mut self,
321 value: &SuggestedPostParameters,
322 ) -> Result<Self, SuggestedPostParametersError> {
323 self.form.insert_field("suggested_post_parameters", value.serialize()?);
324 Ok(self)
325 }
326}
327
328impl Method for SendLivePhoto {
329 type Response = Message;
330
331 fn into_payload(self) -> Payload {
332 Payload::form("sendLivePhoto", self.form)
333 }
334}