tgbot/types/message/
mod.rs

1use serde::{Deserialize, Deserializer, Serialize};
2
3pub use self::{command::*, data::*, methods::*, origin::*, quote::*, reply::*, sender::*};
4use crate::types::{Chat, InlineKeyboardMarkup, Integer, LinkPreviewOptions, Text, User};
5
6#[cfg(test)]
7mod tests;
8
9mod command;
10mod data;
11mod methods;
12mod origin;
13mod quote;
14mod reply;
15mod sender;
16
17/// Represents a result of `EditMessage*` requests.
18#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
19#[allow(clippy::large_enum_variant)]
20#[serde(untagged)]
21pub enum EditMessageResult {
22    /// Returned if edited message is sent by the bot.
23    Message(Message),
24    /// Returned if edited message is NOT sent by the bot.
25    Bool(bool),
26}
27
28/// Describes a message that was deleted or is otherwise inaccessible to the bot.
29#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
30pub struct InaccessibleMessage {
31    /// Chat the message belonged to.
32    pub chat: Chat,
33    /// Unique message identifier inside the chat
34    pub message_id: Integer,
35}
36
37/// Describes a message that can be inaccessible to the bot.
38#[derive(Clone, Debug, derive_more::From, PartialEq, Serialize)]
39#[serde(untagged)]
40pub enum MaybeInaccessibleMessage {
41    /// Describes a message that was deleted or is otherwise inaccessible to the bot.
42    InaccessibleMessage(InaccessibleMessage),
43    /// Describes a regular message.
44    Message(Box<Message>),
45}
46
47impl<'de> Deserialize<'de> for MaybeInaccessibleMessage {
48    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
49    where
50        D: Deserializer<'de>,
51    {
52        Message::deserialize(deserializer).map(|x| {
53            if x.date == 0 {
54                Self::InaccessibleMessage(InaccessibleMessage {
55                    chat: x.chat,
56                    message_id: x.id,
57                })
58            } else {
59                Self::Message(Box::new(x))
60            }
61        })
62    }
63}
64
65/// Represents a message.
66#[serde_with::skip_serializing_none]
67#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
68pub struct Message {
69    /// Chat the message belongs to.
70    pub chat: Chat,
71    /// Date the message was sent in Unix time.
72    pub date: Integer,
73    /// Date the message was last edited in Unix time.
74    pub edit_date: Option<Integer>,
75    /// Indicates whether the message can't be forwarded.
76    #[serde(default)]
77    pub has_protected_content: bool,
78    /// Unique message identifier inside the chat.
79    #[serde(rename = "message_id")]
80    pub id: Integer,
81    /// Indicates whether the message is a channel post that
82    /// was automatically forwarded
83    /// to the connected discussion group.
84    #[serde(default)]
85    pub is_automatic_forward: bool,
86    /// Sender of the message.
87    #[serde(flatten)]
88    pub sender: MessageSender,
89    /// Author signature.
90    pub author_signature: Option<String>,
91    /// Unique identifier of the business connection from which the message was received.
92    ///
93    /// If non-empty, the message belongs to a chat of the corresponding business account
94    /// that is independent from any potential bot chat which might share the same identifier.
95    pub business_connection_id: Option<String>,
96    /// Unique identifier of the message effect added to the message.
97    pub effect_id: Option<String>,
98    /// Information about the message that is being replied to, which may come from another chat or forum topic.
99    pub external_reply: Option<ExternalReplyInfo>,
100    /// formation about the original message for forwarded messages.
101    pub forward_origin: Option<MessageOrigin>,
102    /// Indicates whether the message media is covered by a spoiler animation.
103    pub has_media_spoiler: Option<bool>,
104    /// Whether the message was sent by an implicit action.
105    ///
106    /// For example, as an away or a greeting business message, or as a scheduled message.
107    pub is_from_offline: Option<bool>,
108    /// Indicates whether the message is sent to a forum topic.
109    pub is_topic_message: Option<bool>,
110    /// Options used for link preview generation for the message,
111    /// if it is a text message and link preview options were changed.
112    pub link_preview_options: Option<LinkPreviewOptions>,
113    /// Unique identifier of a media message group this message belongs to.
114    pub media_group_id: Option<String>,
115    /// Unique identifier of a message thread to which the message belongs;
116    /// for supergroups only.
117    pub message_thread_id: Option<Integer>,
118    /// The number of Telegram Stars that were paid by the sender of the message to send it.
119    pub paid_star_count: Option<Integer>,
120    /// For replies that quote part of the original message, the quoted part of the message.
121    pub quote: Option<TextQuote>,
122    /// Inline keyboard attached to the message.
123    pub reply_markup: Option<InlineKeyboardMarkup>,
124    /// For replies, the original message or story.
125    #[serde(flatten)]
126    pub reply_to: Option<ReplyTo>,
127    /// Number of boosts added by the user.
128    ///
129    /// Contains a value only if the sender of the message boosted the chat.
130    pub sender_boost_count: Option<Integer>,
131    /// The bot that actually sent the message on behalf of the business account.
132    ///
133    /// Available only for outgoing messages sent on behalf of the connected business account.
134    pub sender_business_bot: Option<User>,
135    /// Whether the caption must be shown above the message media.
136    pub show_caption_above_media: Option<bool>,
137    /// Bot through which the message was sent.
138    pub via_bot: Option<User>,
139
140    /// Contains message data.
141    #[serde(flatten)]
142    pub data: MessageData,
143}
144
145impl Message {
146    /// Creates a new `Message`.
147    ///
148    /// # Arguments
149    ///
150    /// * `id` - Unique message identifier inside the chat.
151    /// * `date` - Date the message was sent in Unix time.
152    /// * `chat` - Chat the message belongs to.
153    /// * `data` - Data of the message.
154    /// * `sender` - Sender of the message.
155    pub fn new<A, B>(id: Integer, date: Integer, chat: A, data: MessageData, sender: B) -> Self
156    where
157        A: Into<Chat>,
158        B: Into<MessageSender>,
159    {
160        Self {
161            chat: chat.into(),
162            data,
163            date,
164            edit_date: None,
165            has_protected_content: false,
166            id,
167            is_automatic_forward: false,
168            sender: sender.into(),
169            author_signature: None,
170            business_connection_id: None,
171            effect_id: None,
172            external_reply: None,
173            forward_origin: None,
174            has_media_spoiler: None,
175            is_from_offline: None,
176            is_topic_message: None,
177            link_preview_options: None,
178            media_group_id: None,
179            message_thread_id: None,
180            paid_star_count: None,
181            quote: None,
182            reply_markup: None,
183            reply_to: None,
184            sender_boost_count: None,
185            sender_business_bot: None,
186            show_caption_above_media: None,
187            via_bot: None,
188        }
189    }
190
191    /// Returns `true` if the message has edited and `false` otherwise.
192    pub fn is_edited(&self) -> bool {
193        self.edit_date.is_some()
194    }
195
196    /// Returns a text of the message (includes caption).
197    pub fn get_text(&self) -> Option<&Text> {
198        match self.data {
199            MessageData::Text(ref text)
200            | MessageData::Audio(MessageDataAudio {
201                caption: Some(ref text),
202                ..
203            })
204            | MessageData::Document(MessageDataDocument {
205                caption: Some(ref text),
206                ..
207            })
208            | MessageData::Photo(MessageDataPhoto {
209                caption: Some(ref text),
210                ..
211            })
212            | MessageData::Video(MessageDataVideo {
213                caption: Some(ref text),
214                ..
215            })
216            | MessageData::Voice(MessageDataVoice {
217                caption: Some(ref text),
218                ..
219            }) => Some(text),
220            _ => None,
221        }
222    }
223
224    /// Sets a new chat.
225    ///
226    /// # Arguments
227    ///
228    /// * `value` - Chat.
229    pub fn with_chat<T>(mut self, value: T) -> Self
230    where
231        T: Into<Chat>,
232    {
233        self.chat = value.into();
234        self
235    }
236
237    /// Sets a new data.
238    ///
239    /// # Arguments
240    ///
241    /// * `value` - Data of the message.
242    pub fn with_data(mut self, value: MessageData) -> Self {
243        self.data = value;
244        self
245    }
246
247    /// Sets a new date.
248    ///
249    /// # Arguments
250    ///
251    /// * `value` - Date; Unix timestamp.
252    pub fn with_date(mut self, value: Integer) -> Self {
253        self.date = value;
254        self
255    }
256
257    /// Sets a new edit date.
258    ///
259    /// # Arguments
260    ///
261    /// * `value` - Edit date; Unix timestamp.
262    pub fn with_edit_date(mut self, value: Integer) -> Self {
263        self.edit_date = Some(value);
264        self
265    }
266
267    /// Sets a new effect ID.
268    ///
269    /// # Arguments
270    ///
271    /// * `value` - Unique identifier of the message effect.
272    pub fn with_effect_id<T>(mut self, value: T) -> Self
273    where
274        T: Into<String>,
275    {
276        self.effect_id = Some(value.into());
277        self
278    }
279
280    /// Sets a new value for the `has_protected_content` flag.
281    ///
282    /// # Arguments
283    ///
284    /// * `value` - Indicates whether messages from the chat can't be forwarded to other chats.
285    pub fn with_has_protected_content(mut self, value: bool) -> Self {
286        self.has_protected_content = value;
287        self
288    }
289
290    /// Sets a new ID.
291    ///
292    /// # Arguments
293    ///
294    /// * `value` - Unique identifier inside a chat.
295    pub fn with_id(mut self, value: Integer) -> Self {
296        self.id = value;
297        self
298    }
299
300    /// Sets a new value for the `is_automatic_forward` flag.
301    ///
302    /// # Arguments
303    ///
304    /// * `value` - Indicates whether the message was automatically forwarded.
305    pub fn with_is_automatic_forward(mut self, value: bool) -> Self {
306        self.is_automatic_forward = value;
307        self
308    }
309
310    /// Sets a new sender.
311    ///
312    /// # Arguments
313    ///
314    /// * `value` - Sender.
315    pub fn with_sender<T>(mut self, value: T) -> Self
316    where
317        T: Into<MessageSender>,
318    {
319        self.sender = value.into();
320        self
321    }
322
323    /// Sets a new author signature.
324    ///
325    /// # Arguments
326    ///
327    /// * `value` - Author signature.
328    pub fn with_author_signature<T>(mut self, value: T) -> Self
329    where
330        T: Into<String>,
331    {
332        self.author_signature = Some(value.into());
333        self
334    }
335
336    /// Sets a new business connection ID.
337    ///
338    /// # Arguments
339    ///
340    /// * `value` - Unique identifier of the business connection from which the message was received.
341    pub fn with_business_connection_id<T>(mut self, value: T) -> Self
342    where
343        T: Into<String>,
344    {
345        self.business_connection_id = Some(value.into());
346        self
347    }
348
349    /// Sets a new external reply.
350    ///
351    /// # Arguments
352    ///
353    /// * `value` - Information about the message that is being replied to,
354    ///   which may come from another chat or forum topic.
355    pub fn with_external_reply(mut self, value: ExternalReplyInfo) -> Self {
356        self.external_reply = Some(value);
357        self
358    }
359
360    /// Sets a new forward origin.
361    ///
362    /// # Arguments
363    ///
364    /// * `value` - Information about the message origin.
365    pub fn with_forward_origin(mut self, value: MessageOrigin) -> Self {
366        self.forward_origin = Some(value);
367        self
368    }
369
370    /// Sets a new value for the `has_media_spoiler` flag.
371    ///
372    /// # Arguments
373    ///
374    /// * `value` - Indicates whether the message has a media spoiler.
375    pub fn with_has_media_spoiler(mut self, value: bool) -> Self {
376        self.has_media_spoiler = Some(value);
377        self
378    }
379
380    /// Sets a new value for the `is_from_offline` flag.
381    ///
382    /// # Arguments
383    ///
384    /// * `value` - Indicates whether the message was sent by an implicit action.
385    pub fn with_is_from_offline(mut self, value: bool) -> Self {
386        self.is_from_offline = Some(value);
387        self
388    }
389
390    /// Sets a new value for the `is_topic_message` flag.
391    ///
392    /// # Arguments
393    ///
394    /// * `value` - Indicates whether the message is a topic message.
395    pub fn with_is_topic_message(mut self, value: bool) -> Self {
396        self.is_topic_message = Some(value);
397        self
398    }
399
400    /// Sets a new link preview options.
401    ///
402    /// # Arguments
403    ///
404    /// * `value` - New options.
405    pub fn with_link_preview_options(mut self, value: LinkPreviewOptions) -> Self {
406        self.link_preview_options = Some(value);
407        self
408    }
409
410    /// Sets a new media group ID.
411    ///
412    /// # Arguments
413    ///
414    /// * `value` - Media group ID.
415    pub fn with_media_group_id<T>(mut self, value: T) -> Self
416    where
417        T: Into<String>,
418    {
419        self.media_group_id = Some(value.into());
420        self
421    }
422
423    /// Sets a new message thread ID.
424    ///
425    /// # Arguments
426    ///
427    /// * `value` - Unique identifier of the target message thread;
428    ///   supergroups only.
429    pub fn with_message_thread_id(mut self, value: Integer) -> Self {
430        self.message_thread_id = Some(value);
431        self
432    }
433
434    /// Sets a new paid star count
435    ///
436    /// # Arguments
437    ///
438    /// * `value` - The number of Telegram Stars that were paid by the sender of the message to send it.
439    pub fn with_paid_star_count(mut self, value: Integer) -> Self {
440        self.paid_star_count = Some(value);
441        self
442    }
443
444    /// Sets a new quote
445    ///
446    /// # Arguments
447    ///
448    /// * `value` - The quoted part of the original message.
449    pub fn with_quote(mut self, value: TextQuote) -> Self {
450        self.quote = Some(value);
451        self
452    }
453
454    /// Sets a new reply markup.
455    ///
456    /// # Arguments
457    ///
458    /// * `value` - Reply markup.
459    pub fn with_reply_markup<T>(mut self, value: T) -> Self
460    where
461        T: Into<InlineKeyboardMarkup>,
462    {
463        self.reply_markup = Some(value.into());
464        self
465    }
466
467    /// Sets a new original message or story for the reply.
468    ///
469    /// # Arguments
470    ///
471    /// * `value` - For replies, the original message or story.
472    pub fn with_reply_to<T>(mut self, value: T) -> Self
473    where
474        T: Into<ReplyTo>,
475    {
476        self.reply_to = Some(value.into());
477        self
478    }
479
480    /// Sets a new sender boost count.
481    ///
482    /// # Arguments
483    ///
484    /// * `value` - Number of boosts added by the user.
485    pub fn with_sender_boost_count(mut self, value: Integer) -> Self {
486        self.sender_boost_count = Some(value);
487        self
488    }
489
490    /// Sets a new bot.
491    ///
492    /// # Arguments
493    ///
494    /// * `value` - The bot that actually sent the message on behalf of the business account.
495    pub fn with_sender_business_bot(mut self, value: User) -> Self {
496        self.sender_business_bot = Some(value);
497        self
498    }
499
500    /// Sets a new value for the `show_caption_above_media` flag.
501    ///
502    /// # Arguments
503    ///
504    /// * `value` - Whether the caption must be shown above the message media.
505    pub fn with_show_caption_above_media(mut self, value: bool) -> Self {
506        self.show_caption_above_media = Some(value);
507        self
508    }
509
510    /// Sets a new bot.
511    ///
512    /// # Arguments
513    ///
514    /// * `value` - Bot through which the message was sent.
515    pub fn with_via_bot(mut self, value: User) -> Self {
516        self.via_bot = Some(value);
517        self
518    }
519}
520
521/// Represents an unique message identifier.
522#[derive(Copy, Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
523pub struct MessageId {
524    /// The unique message identifier.
525    pub message_id: Integer,
526}