tgbot/types/definitions/file/video_note.rs
1use std::{error::Error, fmt};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6 api::{Form, Method, Payload},
7 types::{
8 ChatId,
9 InputFile,
10 Integer,
11 Message,
12 PhotoSize,
13 ReplyMarkup,
14 ReplyMarkupError,
15 ReplyParameters,
16 ReplyParametersError,
17 SuggestedPostParameters,
18 SuggestedPostParametersError,
19 },
20};
21
22/// Represents a video message.
23#[serde_with::skip_serializing_none]
24#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
25pub struct VideoNote {
26 /// Duration in seconds.
27 pub duration: Integer,
28 /// Identifier of the file.
29 ///
30 /// Can be used to download or reuse the file.
31 pub file_id: String,
32 /// Unique identifier of the file.
33 ///
34 /// It is supposed to be the same over time and for different bots.
35 /// Can't be used to download or reuse the file.
36 pub file_unique_id: String,
37 /// Width and height (diameter).
38 pub length: Integer,
39 /// File size in bytes.
40 pub file_size: Option<Integer>,
41 /// Thumbnail.
42 pub thumbnail: Option<PhotoSize>,
43}
44
45impl VideoNote {
46 /// Creates a new `VideoNote`.
47 ///
48 /// # Arguments
49 ///
50 /// * `duration` - Duration in seconds.
51 /// * `file_id` - Identifier of the file.
52 /// * `file_unique_id` - Unique identifier of the file.
53 /// * `length` - Width and height (diameter).
54 pub fn new<A, B>(duration: Integer, file_id: A, file_unique_id: B, length: Integer) -> Self
55 where
56 A: Into<String>,
57 B: Into<String>,
58 {
59 Self {
60 duration,
61 file_id: file_id.into(),
62 file_unique_id: file_unique_id.into(),
63 length,
64 file_size: None,
65 thumbnail: None,
66 }
67 }
68
69 /// Sets a new size of the file.
70 ///
71 /// # Arguments
72 ///
73 /// * `value` - The size of the file in bytes.
74 pub fn with_file_size(mut self, value: Integer) -> Self {
75 self.file_size = Some(value);
76 self
77 }
78
79 /// Sets a new thumbnail.
80 ///
81 /// # Arguments
82 ///
83 /// * `value` - Thumbnail.
84 pub fn with_thumbnail(mut self, value: PhotoSize) -> Self {
85 self.thumbnail = Some(value);
86 self
87 }
88}
89
90/// Sends a video message.
91///
92/// As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 minute long.
93#[derive(Debug)]
94pub struct SendVideoNote {
95 form: Form,
96}
97
98impl SendVideoNote {
99 /// Creates a new `SendVideoNote`.
100 ///
101 /// # Arguments
102 ///
103 /// * `chat_id` - Unique identifier of the target chat.
104 /// * `video_note` - Video note to send.
105 pub fn new<A, B>(chat_id: A, video_note: B) -> Self
106 where
107 A: Into<ChatId>,
108 B: Into<InputFile>,
109 {
110 Self {
111 form: Form::from([
112 ("chat_id", chat_id.into().into()),
113 ("video_note", video_note.into().into()),
114 ]),
115 }
116 }
117
118 /// Sets a new value for the `allow_paid_broadcast` flag.
119 ///
120 /// # Arguments
121 ///
122 /// * `value` - Whether to allow up to 1000 messages per second, ignoring broadcasting limits
123 /// for a fee of 0.1 Telegram Stars per message.
124 /// The relevant Stars will be withdrawn from the bot's balance.
125 pub fn with_allow_paid_broadcast(mut self, value: bool) -> Self {
126 self.form.insert_field("allow_paid_broadcast", value);
127 self
128 }
129
130 /// Sets a new business connection ID.
131 ///
132 /// # Arguments
133 ///
134 /// * `value` - Unique identifier of the business connection.
135 pub fn with_business_connection_id<T>(mut self, value: T) -> Self
136 where
137 T: Into<String>,
138 {
139 self.form.insert_field("business_connection_id", value.into());
140 self
141 }
142
143 /// Sets a new direct messages topic ID
144 ///
145 /// * `value` - Identifier of the direct messages topic to which the message will be sent.
146 ///
147 /// Required if the message is sent to a direct messages chat.
148 pub fn with_direct_messages_topic_id(mut self, value: Integer) -> Self {
149 self.form.insert_field("direct_messages_topic_id", value);
150 self
151 }
152
153 /// Sets a new value for the `disable_notification` flag.
154 ///
155 /// # Arguments
156 ///
157 /// * `value` - Indicates whether to send the message silently or not;
158 /// a user will receive a notification without sound.
159 pub fn with_disable_notification(mut self, value: bool) -> Self {
160 self.form.insert_field("disable_notification", value);
161 self
162 }
163
164 /// Sets a new duration.
165 ///
166 /// # Arguments
167 ///
168 /// * `value` - Duration in seconds.
169 pub fn with_duration(mut self, value: Integer) -> Self {
170 self.form.insert_field("duration", value);
171 self
172 }
173
174 /// Sets a new length.
175 ///
176 /// # Arguments
177 ///
178 /// * `value` - Video width and height, i.e. diameter of the video message.
179 pub fn with_length(mut self, value: Integer) -> Self {
180 self.form.insert_field("length", value);
181 self
182 }
183
184 /// Sets a new message effect ID.
185 ///
186 /// # Arguments
187 ///
188 /// * `value` - Unique identifier of the message effect to be added to the message; for private chats only.
189 pub fn with_message_effect_id<T>(mut self, value: T) -> Self
190 where
191 T: Into<String>,
192 {
193 self.form.insert_field("message_effect_id", value.into());
194 self
195 }
196
197 /// Sets a new message thread ID.
198 ///
199 /// # Arguments
200 ///
201 /// * `value` - Unique identifier of the target message thread;
202 /// supergroups only.
203 pub fn with_message_thread_id(mut self, value: Integer) -> Self {
204 self.form.insert_field("message_thread_id", value);
205 self
206 }
207
208 /// Sets a new value for the `protect_content` flag.
209 ///
210 /// # Arguments
211 ///
212 /// * `value` - Indicates whether to protect the contents
213 /// of the sent message from forwarding and saving.
214 pub fn with_protect_content(mut self, value: bool) -> Self {
215 self.form.insert_field("protect_content", value.to_string());
216 self
217 }
218
219 /// Sets a new reply markup.
220 ///
221 /// # Arguments
222 ///
223 /// * `value` - Reply markup.
224 pub fn with_reply_markup<T>(mut self, value: T) -> Result<Self, ReplyMarkupError>
225 where
226 T: Into<ReplyMarkup>,
227 {
228 let value = value.into();
229 self.form.insert_field("reply_markup", value.serialize()?);
230 Ok(self)
231 }
232
233 /// Sets new reply parameters.
234 ///
235 /// # Arguments
236 ///
237 /// * `value` - Description of the message to reply to.
238 pub fn with_reply_parameters(mut self, value: ReplyParameters) -> Result<Self, ReplyParametersError> {
239 self.form.insert_field("reply_parameters", value.serialize()?);
240 Ok(self)
241 }
242
243 /// Sets a new suggested post parameters.
244 ///
245 /// # Arguments
246 ///
247 /// * `value` - An object containing the parameters of the suggested post to send.
248 ///
249 /// For direct messages chats only.
250 ///
251 /// If the message is sent as a reply to another suggested post, then that suggested post is automatically declined.
252 pub fn with_suggested_post_parameters(
253 mut self,
254 value: &SuggestedPostParameters,
255 ) -> Result<Self, SuggestedPostParametersError> {
256 let value = serde_json::to_string(value).map_err(SuggestedPostParametersError::Serialize)?;
257 self.form.insert_field("suggested_post_parameters", value);
258 Ok(self)
259 }
260
261 /// Sets a new thumbnail.
262 ///
263 /// # Arguments
264 ///
265 /// * `value` - Thumbnail.
266 ///
267 /// The thumbnail should be in JPEG format and less than 200 kB in size.
268 /// A thumbnail‘s width and height should not exceed 320.
269 /// Ignored if the file is not uploaded using `multipart/form-data`.
270 /// Thumbnails can’t be reused and can be only uploaded as a new file.
271 pub fn with_thumbnail<T>(mut self, value: T) -> Result<Self, SendVideoNoteError>
272 where
273 T: Into<InputFile>,
274 {
275 let value = value.into();
276 if matches!(value, InputFile::Id(_)) {
277 return Err(SendVideoNoteError::InvalidThumbnail);
278 }
279 self.form.insert_field("thumbnail", value);
280 Ok(self)
281 }
282}
283
284impl Method for SendVideoNote {
285 type Response = Message;
286
287 fn into_payload(self) -> Payload {
288 Payload::form("sendVideoNote", self.form)
289 }
290}
291
292/// Represents an error when sending a video note.
293#[derive(Debug)]
294pub enum SendVideoNoteError {
295 /// Thumbnails can not be reused.
296 InvalidThumbnail,
297}
298
299impl fmt::Display for SendVideoNoteError {
300 fn fmt(&self, out: &mut fmt::Formatter<'_>) -> fmt::Result {
301 match self {
302 Self::InvalidThumbnail => write!(out, "thumbnails can’t be reused and can be only uploaded as a new file"),
303 }
304 }
305}
306
307impl Error for SendVideoNoteError {}