tgbot/types/definitions/file/
voice.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        ReplyMarkup,
12        ReplyMarkupError,
13        ReplyParameters,
14        ReplyParametersError,
15        SuggestedPostParameters,
16        SuggestedPostParametersError,
17        TextEntities,
18        TextEntity,
19        TextEntityError,
20    },
21};
22
23/// Represents a voice file.
24#[serde_with::skip_serializing_none]
25#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
26pub struct Voice {
27    /// Duration in seconds as defined by sender.
28    pub duration: Integer,
29    /// Identifier of the file.
30    ///
31    /// Can be used to download or reuse the file.
32    pub file_id: String,
33    /// Unique identifier of the file.
34    ///
35    /// It is supposed to be the same over time and for different bots.
36    /// Can't be used to download or reuse the file.
37    pub file_unique_id: String,
38    /// File size in bytes.
39    pub file_size: Option<Integer>,
40    /// MIME type as defined by sender.
41    pub mime_type: Option<String>,
42}
43
44impl Voice {
45    /// Creates a new `Voice`.
46    ///
47    /// # Arguments
48    ///
49    /// * `duration` - Duration in seconds.
50    /// * `file_id` - Identifier of the file.
51    /// * `file_unique_id` - Unique identifier of the file.
52    pub fn new<A, B>(duration: Integer, file_id: A, file_unique_id: B) -> Self
53    where
54        A: Into<String>,
55        B: Into<String>,
56    {
57        Self {
58            duration,
59            file_id: file_id.into(),
60            file_unique_id: file_unique_id.into(),
61            file_size: None,
62            mime_type: None,
63        }
64    }
65
66    /// Sets a new size of the file.
67    ///
68    /// # Arguments
69    ///
70    /// * `value` - The size of the file in bytes.
71    pub fn with_file_size(mut self, value: Integer) -> Self {
72        self.file_size = Some(value);
73        self
74    }
75
76    /// Sets a new MIME type.
77    ///
78    /// # Arguments
79    ///
80    /// * `value` - MIME type.
81    pub fn with_mime_type<T>(mut self, value: T) -> Self
82    where
83        T: Into<String>,
84    {
85        self.mime_type = Some(value.into());
86        self
87    }
88}
89
90/// Sends a voice message.
91///
92/// Audio must be in an .ogg file encoded with OPUS, or in .MP3 format, or in .M4A format.
93/// Other formats may be sent as Audio or Document.
94/// Bots can currently send voice messages of up to 50 MB in size,
95/// this limit may be changed in the future.
96#[derive(Debug)]
97pub struct SendVoice {
98    form: Form,
99}
100
101impl SendVoice {
102    /// Creates a new `SendVoice`.
103    ///
104    /// # Arguments
105    ///
106    /// * `chat_id` - Unique identifier of the target chat.
107    /// * `voice` - Audio file to send.
108    pub fn new<A, B>(chat_id: A, voice: B) -> Self
109    where
110        A: Into<ChatId>,
111        B: Into<InputFile>,
112    {
113        Self {
114            form: Form::from([("chat_id", chat_id.into().into()), ("voice", voice.into().into())]),
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 caption.
144    ///
145    /// # Arguments
146    ///
147    /// * `value` - Caption; 0-1024 characters.
148    ///
149    /// May also be used when resending documents by `file_id`.
150    pub fn with_caption<T>(mut self, value: T) -> Self
151    where
152        T: Into<String>,
153    {
154        self.form.insert_field("caption", value.into());
155        self
156    }
157
158    /// Sets a new list of caption entities.
159    ///
160    /// # Arguments
161    ///
162    /// * `value` - The list of special entities that appear in the caption.
163    ///
164    /// Caption parse mode will be set to [`None`] when this method is called.
165    pub fn with_caption_entities<T>(mut self, value: T) -> Result<Self, TextEntityError>
166    where
167        T: IntoIterator<Item = TextEntity>,
168    {
169        let value: TextEntities = value.into_iter().collect();
170        self.form.insert_field("caption_entities", value.serialize()?);
171        self.form.remove_field("parse_mode");
172        Ok(self)
173    }
174
175    /// Sets a new caption parse mode.
176    ///
177    /// # Arguments
178    ///
179    /// * `value` - Parse mode.
180    ///
181    /// Caption entities will be set to [`None`] when this method is called.
182    pub fn with_caption_parse_mode(mut self, value: ParseMode) -> Self {
183        self.form.insert_field("parse_mode", value);
184        self.form.remove_field("caption_entities");
185        self
186    }
187
188    /// Sets a new direct messages topic ID
189    ///
190    /// * `value` - Identifier of the direct messages topic to which the message will be sent.
191    ///
192    /// Required if the message is sent to a direct messages chat.
193    pub fn with_direct_messages_topic_id(mut self, value: Integer) -> Self {
194        self.form.insert_field("direct_messages_topic_id", value);
195        self
196    }
197
198    /// Sets a new value for the `disable_notification` flag.
199    ///
200    /// # Arguments
201    ///
202    /// * `value` - Indicates whether to send the message silently or not;
203    ///   a user will receive a notification without sound.
204    pub fn with_disable_notification(mut self, value: bool) -> Self {
205        self.form.insert_field("disable_notification", value);
206        self
207    }
208
209    /// Sets a new duration.
210    ///
211    /// # Arguments
212    ///
213    /// * `value` - Duration in seconds.
214    pub fn with_duration(mut self, value: Integer) -> Self {
215        self.form.insert_field("duration", value);
216        self
217    }
218
219    /// Sets a new message effect ID.
220    ///
221    /// # Arguments
222    ///
223    /// * `value` - Unique identifier of the message effect to be added to the message; for private chats only.
224    pub fn with_message_effect_id<T>(mut self, value: T) -> Self
225    where
226        T: Into<String>,
227    {
228        self.form.insert_field("message_effect_id", value.into());
229        self
230    }
231
232    /// Sets a new message thread ID.
233    ///
234    /// # Arguments
235    ///
236    /// * `value` - Unique identifier of the target message thread;
237    ///   supergroups only.
238    pub fn with_message_thread_id(mut self, value: Integer) -> Self {
239        self.form.insert_field("message_thread_id", value);
240        self
241    }
242
243    /// Sets a new value for the `protect_content` flag.
244    ///
245    /// # Arguments
246    ///
247    /// * `value` - Indicates whether to protect the contents
248    ///   of the sent message from forwarding and saving.
249    pub fn with_protect_content(mut self, value: bool) -> Self {
250        self.form.insert_field("protect_content", value.to_string());
251        self
252    }
253
254    /// Sets a new reply markup.
255    ///
256    /// # Arguments
257    ///
258    /// * `value` - Reply markup.
259    pub fn with_reply_markup<T>(mut self, value: T) -> Result<Self, ReplyMarkupError>
260    where
261        T: Into<ReplyMarkup>,
262    {
263        let value = value.into();
264        self.form.insert_field("reply_markup", value.serialize()?);
265        Ok(self)
266    }
267
268    /// Sets new reply parameters.
269    ///
270    /// # Arguments
271    ///
272    /// * `value` - Description of the message to reply to.
273    pub fn with_reply_parameters(mut self, value: ReplyParameters) -> Result<Self, ReplyParametersError> {
274        self.form.insert_field("reply_parameters", value.serialize()?);
275        Ok(self)
276    }
277
278    /// Sets a new suggested post parameters.
279    ///
280    /// # Arguments
281    ///
282    /// * `value` - An object containing the parameters of the suggested post to send.
283    ///
284    /// For direct messages chats only.
285    ///
286    /// If the message is sent as a reply to another suggested post, then that suggested post is automatically declined.
287    pub fn with_suggested_post_parameters(
288        mut self,
289        value: &SuggestedPostParameters,
290    ) -> Result<Self, SuggestedPostParametersError> {
291        let value = serde_json::to_string(value).map_err(SuggestedPostParametersError::Serialize)?;
292        self.form.insert_field("suggested_post_parameters", value);
293        Ok(self)
294    }
295}
296
297impl Method for SendVoice {
298    type Response = Message;
299
300    fn into_payload(self) -> Payload {
301        Payload::form("sendVoice", self.form)
302    }
303}