tgbot/types/file/voice/
mod.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        TextEntities,
16        TextEntity,
17        TextEntityError,
18    },
19};
20
21#[cfg(test)]
22mod tests;
23
24/// Represents a voice file.
25#[serde_with::skip_serializing_none]
26#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
27pub struct Voice {
28    /// Duration in seconds as defined by sender.
29    pub duration: Integer,
30    /// Identifier of the file.
31    ///
32    /// Can be used to download or reuse the file.
33    pub file_id: String,
34    /// Unique identifier of the file.
35    ///
36    /// It is supposed to be the same over time and for different bots.
37    /// Can't be used to download or reuse the file.
38    pub file_unique_id: String,
39    /// File size in bytes.
40    pub file_size: Option<Integer>,
41    /// MIME type as defined by sender.
42    pub mime_type: Option<String>,
43}
44
45impl Voice {
46    /// Creates a new `Voice`.
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    pub fn new<A, B>(duration: Integer, file_id: A, file_unique_id: B) -> Self
54    where
55        A: Into<String>,
56        B: Into<String>,
57    {
58        Self {
59            duration,
60            file_id: file_id.into(),
61            file_unique_id: file_unique_id.into(),
62            file_size: None,
63            mime_type: None,
64        }
65    }
66
67    /// Sets a new size of the file.
68    ///
69    /// # Arguments
70    ///
71    /// * `value` - The size of the file in bytes.
72    pub fn with_file_size(mut self, value: Integer) -> Self {
73        self.file_size = Some(value);
74        self
75    }
76
77    /// Sets a new MIME type.
78    ///
79    /// # Arguments
80    ///
81    /// * `value` - MIME type.
82    pub fn with_mime_type<T>(mut self, value: T) -> Self
83    where
84        T: Into<String>,
85    {
86        self.mime_type = Some(value.into());
87        self
88    }
89}
90
91/// Sends a voice message.
92///
93/// Audio must be in an .ogg file encoded with OPUS, or in .MP3 format, or in .M4A format.
94/// Other formats may be sent as Audio or Document.
95/// Bots can currently send voice messages of up to 50 MB in size,
96/// this limit may be changed in the future.
97#[derive(Debug)]
98pub struct SendVoice {
99    form: Form,
100}
101
102impl SendVoice {
103    /// Creates a new `SendVoice`.
104    ///
105    /// # Arguments
106    ///
107    /// * `chat_id` - Unique identifier of the target chat.
108    /// * `voice` - Audio file to send.
109    pub fn new<A, B>(chat_id: A, voice: B) -> Self
110    where
111        A: Into<ChatId>,
112        B: Into<InputFile>,
113    {
114        Self {
115            form: Form::from([("chat_id", chat_id.into().into()), ("voice", voice.into().into())]),
116        }
117    }
118
119    /// Sets a new value for the `allow_paid_broadcast` flag.
120    ///
121    /// # Arguments
122    ///
123    /// * `value` - Whether to allow up to 1000 messages per second, ignoring broadcasting limits
124    ///   for a fee of 0.1 Telegram Stars per message.
125    ///   The relevant Stars will be withdrawn from the bot's balance.
126    pub fn with_allow_paid_broadcast(mut self, value: bool) -> Self {
127        self.form.insert_field("allow_paid_broadcast", value);
128        self
129    }
130
131    /// Sets a new business connection ID.
132    ///
133    /// # Arguments
134    ///
135    /// * `value` - Unique identifier of the business connection.
136    pub fn with_business_connection_id<T>(mut self, value: T) -> Self
137    where
138        T: Into<String>,
139    {
140        self.form.insert_field("business_connection_id", value.into());
141        self
142    }
143
144    /// Sets a new caption.
145    ///
146    /// # Arguments
147    ///
148    /// * `value` - Caption; 0-1024 characters.
149    ///
150    /// May also be used when resending documents by `file_id`.
151    pub fn with_caption<T>(mut self, value: T) -> Self
152    where
153        T: Into<String>,
154    {
155        self.form.insert_field("caption", value.into());
156        self
157    }
158
159    /// Sets a new list of caption entities.
160    ///
161    /// # Arguments
162    ///
163    /// * `value` - The list of special entities that appear in the caption.
164    ///
165    /// Caption parse mode will be set to [`None`] when this method is called.
166    pub fn with_caption_entities<T>(mut self, value: T) -> Result<Self, TextEntityError>
167    where
168        T: IntoIterator<Item = TextEntity>,
169    {
170        let value: TextEntities = value.into_iter().collect();
171        self.form.insert_field("caption_entities", value.serialize()?);
172        self.form.remove_field("parse_mode");
173        Ok(self)
174    }
175
176    /// Sets a new caption parse mode.
177    ///
178    /// # Arguments
179    ///
180    /// * `value` - Parse mode.
181    ///
182    /// Caption entities will be set to [`None`] when this method is called.
183    pub fn with_caption_parse_mode(mut self, value: ParseMode) -> Self {
184        self.form.insert_field("parse_mode", value);
185        self.form.remove_field("caption_entities");
186        self
187    }
188
189    /// Sets a new value for the `disable_notification` flag.
190    ///
191    /// # Arguments
192    ///
193    /// * `value` - Indicates whether to send the message silently or not;
194    ///   a user will receive a notification without sound.
195    pub fn with_disable_notification(mut self, value: bool) -> Self {
196        self.form.insert_field("disable_notification", value);
197        self
198    }
199
200    /// Sets a new duration.
201    ///
202    /// # Arguments
203    ///
204    /// * `value` - Duration in seconds.
205    pub fn with_duration(mut self, value: Integer) -> Self {
206        self.form.insert_field("duration", value);
207        self
208    }
209
210    /// Sets a new message effect ID.
211    ///
212    /// # Arguments
213    ///
214    /// * `value` - Unique identifier of the message effect to be added to the message; for private chats only.
215    pub fn with_message_effect_id<T>(mut self, value: T) -> Self
216    where
217        T: Into<String>,
218    {
219        self.form.insert_field("message_effect_id", value.into());
220        self
221    }
222
223    /// Sets a new message thread ID.
224    ///
225    /// # Arguments
226    ///
227    /// * `value` - Unique identifier of the target message thread;
228    ///   supergroups only.
229    pub fn with_message_thread_id(mut self, value: Integer) -> Self {
230        self.form.insert_field("message_thread_id", value);
231        self
232    }
233
234    /// Sets a new value for the `protect_content` flag.
235    ///
236    /// # Arguments
237    ///
238    /// * `value` - Indicates whether to protect the contents
239    ///   of the sent message from forwarding and saving.
240    pub fn with_protect_content(mut self, value: bool) -> Self {
241        self.form.insert_field("protect_content", value.to_string());
242        self
243    }
244
245    /// Sets a new reply markup.
246    ///
247    /// # Arguments
248    ///
249    /// * `value` - Reply markup.
250    pub fn with_reply_markup<T>(mut self, value: T) -> Result<Self, ReplyMarkupError>
251    where
252        T: Into<ReplyMarkup>,
253    {
254        let value = value.into();
255        self.form.insert_field("reply_markup", value.serialize()?);
256        Ok(self)
257    }
258
259    /// Sets new reply parameters.
260    ///
261    /// # Arguments
262    ///
263    /// * `value` - Description of the message to reply to.
264    pub fn with_reply_parameters(mut self, value: ReplyParameters) -> Result<Self, ReplyParametersError> {
265        self.form.insert_field("reply_parameters", value.serialize()?);
266        Ok(self)
267    }
268}
269
270impl Method for SendVoice {
271    type Response = Message;
272
273    fn into_payload(self) -> Payload {
274        Payload::form("sendVoice", self.form)
275    }
276}