Skip to main content

tgbot/types/definitions/message/
mod.rs

1use serde::{Deserialize, Deserializer, Serialize};
2
3pub use self::{command::*, data::*, guest::*, methods::*, origin::*, quote::*, reply::*, sender::*};
4use crate::types::{Chat, InlineKeyboardMarkup, Integer, LinkPreviewOptions, SuggestedPostInfo, Text, User};
5
6mod command;
7mod data;
8mod guest;
9mod methods;
10mod origin;
11mod quote;
12mod reply;
13mod sender;
14
15/// Represents a result of `EditMessage*` requests.
16#[derive(Clone, Debug, Deserialize, Serialize)]
17#[serde(untagged)]
18pub enum EditMessageResult {
19    /// Returned if edited message is sent by the bot.
20    Message(Box<Message>),
21    /// Returned if edited message is NOT sent by the bot.
22    Bool(bool),
23}
24
25/// Describes a message that was deleted or is otherwise inaccessible to the bot.
26#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
27pub struct InaccessibleMessage {
28    /// Chat the message belonged to.
29    pub chat: Chat,
30    /// Unique message identifier inside the chat
31    pub message_id: Integer,
32}
33
34/// Describes a message that can be inaccessible to the bot.
35#[derive(Clone, Debug, derive_more::From, Serialize)]
36#[serde(untagged)]
37pub enum MaybeInaccessibleMessage {
38    /// Describes a message that was deleted or is otherwise inaccessible to the bot.
39    InaccessibleMessage(InaccessibleMessage),
40    /// Describes a regular message.
41    Message(Box<Message>),
42}
43
44impl<'de> Deserialize<'de> for MaybeInaccessibleMessage {
45    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
46    where
47        D: Deserializer<'de>,
48    {
49        Message::deserialize(deserializer).map(|x| {
50            if x.date == 0 {
51                Self::InaccessibleMessage(InaccessibleMessage {
52                    chat: x.chat,
53                    message_id: x.id,
54                })
55            } else {
56                Self::Message(Box::new(x))
57            }
58        })
59    }
60}
61
62/// Represents a message.
63#[serde_with::skip_serializing_none]
64#[derive(Clone, Debug, Deserialize, Serialize)]
65pub struct Message {
66    /// Chat the message belongs to.
67    pub chat: Chat,
68    /// Date the message was sent in Unix time.
69    pub date: Integer,
70    /// Date the message was last edited in Unix time.
71    pub edit_date: Option<Integer>,
72    /// Indicates whether the message can't be forwarded.
73    #[serde(default)]
74    pub has_protected_content: bool,
75    /// Unique message identifier inside the chat.
76    #[serde(rename = "message_id")]
77    pub id: Integer,
78    /// Indicates whether the message is a channel post that
79    /// was automatically forwarded
80    /// to the connected discussion group.
81    #[serde(default)]
82    pub is_automatic_forward: bool,
83    /// Sender of the message.
84    #[serde(flatten)]
85    pub sender: MessageSender,
86    /// Author signature.
87    pub author_signature: Option<String>,
88    /// Unique identifier of the business connection from which the message was received.
89    ///
90    /// If non-empty, the message belongs to a chat of the corresponding business account
91    /// that is independent from any potential bot chat which might share the same identifier.
92    pub business_connection_id: Option<String>,
93    /// Information about the direct messages chat topic that contains the message.
94    pub direct_messages_topic: Option<DirectMessagesTopic>,
95    /// Unique identifier of the message effect added to the message.
96    pub effect_id: Option<String>,
97    /// Information about the message that is being replied to, which may come from another chat or forum topic.
98    pub external_reply: Option<ExternalReplyInfo>,
99    /// formation about the original message for forwarded messages.
100    pub forward_origin: Option<MessageOrigin>,
101    /// For a message sent by a guest bot, this is the information about the user and chat.
102    #[serde(flatten)]
103    pub guest_bot: Option<MessageGuestBot>,
104    /// The unique identifier for the guest query.
105    ///
106    /// Use this identifier with the method [`crate::types::AnswerGuestQuery`]
107    /// to send a response message.
108    ///
109    /// If non-empty, the message belongs to the chat where the guest bot was summoned,
110    /// which may not coincide with other existing bot chats sharing the same identifier.
111    pub guest_query_id: Option<String>,
112    /// Indicates whether the message media is covered by a spoiler animation.
113    pub has_media_spoiler: Option<bool>,
114    /// Whether the message was sent by an implicit action.
115    ///
116    /// For example, as an away or a greeting business message, or as a scheduled message.
117    pub is_from_offline: Option<bool>,
118    /// Whether the message is a paid post.
119    ///
120    /// Note that such posts must not be deleted for 24 hours to receive the payment and can't be edited.
121    pub is_paid_post: Option<bool>,
122    /// Indicates whether the message is sent to a topic in a forum supergroup or a private chat with the bot.
123    pub is_topic_message: Option<bool>,
124    /// Options used for link preview generation for the message,
125    /// if it is a text message and link preview options were changed.
126    pub link_preview_options: Option<LinkPreviewOptions>,
127    /// Unique identifier of a media message group this message belongs to.
128    pub media_group_id: Option<String>,
129    /// Unique identifier of a message thread to which the message belongs;
130    /// for supergroups and private chats only.
131    pub message_thread_id: Option<Integer>,
132    /// The number of Telegram Stars that were paid by the sender of the message to send it.
133    pub paid_star_count: Option<Integer>,
134    /// For replies that quote part of the original message, the quoted part of the message.
135    pub quote: Option<TextQuote>,
136    /// Inline keyboard attached to the message.
137    pub reply_markup: Option<InlineKeyboardMarkup>,
138    /// For replies, the original message or story.
139    #[serde(flatten)]
140    pub reply_to: Option<ReplyTo>,
141    /// Identifier of the specific checklist task that is being replied to.
142    pub reply_to_checklist_task_id: Option<Integer>,
143    /// Persistent identifier of the specific poll option that is being replied to.
144    pub reply_to_poll_option_id: Option<String>,
145    /// Number of boosts added by the user.
146    ///
147    /// Contains a value only if the sender of the message boosted the chat.
148    pub sender_boost_count: Option<Integer>,
149    /// The bot that actually sent the message on behalf of the business account.
150    ///
151    /// Available only for outgoing messages sent on behalf of the connected business account.
152    pub sender_business_bot: Option<User>,
153    /// Tag or custom title of the sender of the message; for supergroups only.
154    pub sender_tag: Option<String>,
155    /// Whether the caption must be shown above the message media.
156    pub show_caption_above_media: Option<bool>,
157    /// Information about suggested post parameters if the message is a suggested post in a channel direct messages chat.
158    ///
159    /// If the message is an approved or declined suggested post, then it can't be edited.
160    pub suggested_post_info: Option<SuggestedPostInfo>,
161    /// Bot through which the message was sent.
162    pub via_bot: Option<User>,
163
164    /// Contains message data.
165    #[serde(flatten)]
166    pub data: MessageData,
167}
168
169impl Message {
170    /// Creates a new `Message`.
171    ///
172    /// # Arguments
173    ///
174    /// * `id` - Unique message identifier inside the chat.
175    /// * `date` - Date the message was sent in Unix time.
176    /// * `chat` - Chat the message belongs to.
177    /// * `data` - Data of the message.
178    /// * `sender` - Sender of the message.
179    pub fn new<A, B>(id: Integer, date: Integer, chat: A, data: MessageData, sender: B) -> Self
180    where
181        A: Into<Chat>,
182        B: Into<MessageSender>,
183    {
184        Self {
185            chat: chat.into(),
186            data,
187            date,
188            edit_date: None,
189            has_protected_content: false,
190            id,
191            is_automatic_forward: false,
192            sender: sender.into(),
193            author_signature: None,
194            business_connection_id: None,
195            direct_messages_topic: None,
196            effect_id: None,
197            external_reply: None,
198            forward_origin: None,
199            guest_bot: None,
200            guest_query_id: None,
201            has_media_spoiler: None,
202            is_from_offline: None,
203            is_paid_post: None,
204            is_topic_message: None,
205            link_preview_options: None,
206            media_group_id: None,
207            message_thread_id: None,
208            paid_star_count: None,
209            quote: None,
210            reply_markup: None,
211            reply_to: None,
212            reply_to_checklist_task_id: None,
213            reply_to_poll_option_id: None,
214            sender_boost_count: None,
215            sender_business_bot: None,
216            sender_tag: None,
217            show_caption_above_media: None,
218            suggested_post_info: None,
219            via_bot: None,
220        }
221    }
222
223    /// Returns `true` if the message has edited and `false` otherwise.
224    pub fn is_edited(&self) -> bool {
225        self.edit_date.is_some()
226    }
227
228    /// Returns a text of the message (includes caption).
229    pub fn get_text(&self) -> Option<&Text> {
230        match &self.data {
231            MessageData::Text(text) => Some(text),
232            MessageData::Audio(audio) => audio.caption.as_ref(),
233            MessageData::Document(doc) => doc.caption.as_ref(),
234            MessageData::Photo(photo) => photo.caption.as_ref(),
235            MessageData::Video(video) => video.caption.as_ref(),
236            MessageData::Voice(voice) => voice.caption.as_ref(),
237            _ => None,
238        }
239    }
240
241    /// Sets a new chat.
242    ///
243    /// # Arguments
244    ///
245    /// * `value` - Chat.
246    pub fn with_chat<T>(mut self, value: T) -> Self
247    where
248        T: Into<Chat>,
249    {
250        self.chat = value.into();
251        self
252    }
253
254    /// Sets a new data.
255    ///
256    /// # Arguments
257    ///
258    /// * `value` - Data of the message.
259    pub fn with_data<T>(mut self, value: T) -> Self
260    where
261        T: Into<MessageData>,
262    {
263        self.data = value.into();
264        self
265    }
266
267    /// Sets a new date.
268    ///
269    /// # Arguments
270    ///
271    /// * `value` - Date; Unix timestamp.
272    pub fn with_date(mut self, value: Integer) -> Self {
273        self.date = value;
274        self
275    }
276
277    /// Sets a new direct messages topic.
278    ///
279    /// # Arguments
280    ///
281    /// * `value` - Information about the direct messages chat topic that contains the message.
282    pub fn with_direct_messages_topic(mut self, value: DirectMessagesTopic) -> Self {
283        self.direct_messages_topic = Some(value);
284        self
285    }
286
287    /// Sets a new edit date.
288    ///
289    /// # Arguments
290    ///
291    /// * `value` - Edit date; Unix timestamp.
292    pub fn with_edit_date(mut self, value: Integer) -> Self {
293        self.edit_date = Some(value);
294        self
295    }
296
297    /// Sets a new effect ID.
298    ///
299    /// # Arguments
300    ///
301    /// * `value` - Unique identifier of the message effect.
302    pub fn with_effect_id<T>(mut self, value: T) -> Self
303    where
304        T: Into<String>,
305    {
306        self.effect_id = Some(value.into());
307        self
308    }
309
310    /// Sets a new value for the `has_protected_content` flag.
311    ///
312    /// # Arguments
313    ///
314    /// * `value` - Indicates whether messages from the chat can't be forwarded to other chats.
315    pub fn with_has_protected_content(mut self, value: bool) -> Self {
316        self.has_protected_content = value;
317        self
318    }
319
320    /// Sets a new ID.
321    ///
322    /// # Arguments
323    ///
324    /// * `value` - Unique identifier inside a chat.
325    pub fn with_id(mut self, value: Integer) -> Self {
326        self.id = value;
327        self
328    }
329
330    /// Sets a new value for the `is_automatic_forward` flag.
331    ///
332    /// # Arguments
333    ///
334    /// * `value` - Indicates whether the message was automatically forwarded.
335    pub fn with_is_automatic_forward(mut self, value: bool) -> Self {
336        self.is_automatic_forward = value;
337        self
338    }
339
340    /// Sets a new sender.
341    ///
342    /// # Arguments
343    ///
344    /// * `value` - Sender.
345    pub fn with_sender<T>(mut self, value: T) -> Self
346    where
347        T: Into<MessageSender>,
348    {
349        self.sender = value.into();
350        self
351    }
352
353    /// Sets a new author signature.
354    ///
355    /// # Arguments
356    ///
357    /// * `value` - Author signature.
358    pub fn with_author_signature<T>(mut self, value: T) -> Self
359    where
360        T: Into<String>,
361    {
362        self.author_signature = Some(value.into());
363        self
364    }
365
366    /// Sets a new business connection ID.
367    ///
368    /// # Arguments
369    ///
370    /// * `value` - Unique identifier of the business connection from which the message was received.
371    pub fn with_business_connection_id<T>(mut self, value: T) -> Self
372    where
373        T: Into<String>,
374    {
375        self.business_connection_id = Some(value.into());
376        self
377    }
378
379    /// Sets a new external reply.
380    ///
381    /// # Arguments
382    ///
383    /// * `value` - Information about the message that is being replied to,
384    ///   which may come from another chat or forum topic.
385    pub fn with_external_reply(mut self, value: ExternalReplyInfo) -> Self {
386        self.external_reply = Some(value);
387        self
388    }
389
390    /// Sets a new forward origin.
391    ///
392    /// # Arguments
393    ///
394    /// * `value` - Information about the message origin.
395    pub fn with_forward_origin(mut self, value: MessageOrigin) -> Self {
396        self.forward_origin = Some(value);
397        self
398    }
399
400    /// Sets a new guest bot.
401    ///
402    /// # Arguments
403    ///
404    /// * `value` - Information for a message sent by a guest bot.
405    pub fn with_guest_bot(mut self, value: MessageGuestBot) -> Self {
406        self.guest_bot = Some(value);
407        self
408    }
409
410    /// Sets a new guest query ID.
411    ///
412    /// # Arguments
413    ///
414    /// * `value` - The unique identifier for the guest query.
415    pub fn with_guest_query_id<T>(mut self, value: T) -> Self
416    where
417        T: Into<String>,
418    {
419        self.guest_query_id = Some(value.into());
420        self
421    }
422
423    /// Sets a new value for the `has_media_spoiler` flag.
424    ///
425    /// # Arguments
426    ///
427    /// * `value` - Indicates whether the message has a media spoiler.
428    pub fn with_has_media_spoiler(mut self, value: bool) -> Self {
429        self.has_media_spoiler = Some(value);
430        self
431    }
432
433    /// Sets a new value for the `is_from_offline` flag.
434    ///
435    /// # Arguments
436    ///
437    /// * `value` - Indicates whether the message was sent by an implicit action.
438    pub fn with_is_from_offline(mut self, value: bool) -> Self {
439        self.is_from_offline = Some(value);
440        self
441    }
442
443    /// Sets a new value for the `is_paid_post` flag.
444    ///
445    /// # Arguments
446    ///
447    /// * `value` - Whether the message is a paid post.
448    pub fn with_is_paid_post(mut self, value: bool) -> Self {
449        self.is_paid_post = Some(value);
450        self
451    }
452
453    /// Sets a new value for the `is_topic_message` flag.
454    ///
455    /// # Arguments
456    ///
457    /// * `value` - Indicates whether the message is a topic message.
458    pub fn with_is_topic_message(mut self, value: bool) -> Self {
459        self.is_topic_message = Some(value);
460        self
461    }
462
463    /// Sets a new link preview options.
464    ///
465    /// # Arguments
466    ///
467    /// * `value` - New options.
468    pub fn with_link_preview_options(mut self, value: LinkPreviewOptions) -> Self {
469        self.link_preview_options = Some(value);
470        self
471    }
472
473    /// Sets a new media group ID.
474    ///
475    /// # Arguments
476    ///
477    /// * `value` - Media group ID.
478    pub fn with_media_group_id<T>(mut self, value: T) -> Self
479    where
480        T: Into<String>,
481    {
482        self.media_group_id = Some(value.into());
483        self
484    }
485
486    /// Sets a new message thread ID.
487    ///
488    /// # Arguments
489    ///
490    /// * `value` - Unique identifier of the target message thread;
491    ///   for forum supergroups and private chats of bots with forum topic mode enabled only.
492    pub fn with_message_thread_id(mut self, value: Integer) -> Self {
493        self.message_thread_id = Some(value);
494        self
495    }
496
497    /// Sets a new paid star count
498    ///
499    /// # Arguments
500    ///
501    /// * `value` - The number of Telegram Stars that were paid by the sender of the message to send it.
502    pub fn with_paid_star_count(mut self, value: Integer) -> Self {
503        self.paid_star_count = Some(value);
504        self
505    }
506
507    /// Sets a new quote
508    ///
509    /// # Arguments
510    ///
511    /// * `value` - The quoted part of the original message.
512    pub fn with_quote(mut self, value: TextQuote) -> Self {
513        self.quote = Some(value);
514        self
515    }
516
517    /// Sets a new reply markup.
518    ///
519    /// # Arguments
520    ///
521    /// * `value` - Reply markup.
522    pub fn with_reply_markup<T>(mut self, value: T) -> Self
523    where
524        T: Into<InlineKeyboardMarkup>,
525    {
526        self.reply_markup = Some(value.into());
527        self
528    }
529
530    /// Sets a new original message or story for the reply.
531    ///
532    /// # Arguments
533    ///
534    /// * `value` - For replies, the original message or story.
535    pub fn with_reply_to<T>(mut self, value: T) -> Self
536    where
537        T: Into<ReplyTo>,
538    {
539        self.reply_to = Some(value.into());
540        self
541    }
542
543    /// Sets a new reply checklist task ID.
544    ///
545    /// # Arguments
546    ///
547    /// * `value` - Identifier of the specific checklist task that is being replied to.
548    pub fn with_reply_to_checklist_task_id(mut self, value: Integer) -> Self {
549        self.reply_to_checklist_task_id = Some(value);
550        self
551    }
552
553    /// Sets a new reply poll option ID.
554    ///
555    /// # Arguments
556    ///
557    /// * `value` - Persistent ID of the option
558    pub fn with_reply_to_poll_option_id<T>(mut self, value: T) -> Self
559    where
560        T: Into<String>,
561    {
562        self.reply_to_poll_option_id = Some(value.into());
563        self
564    }
565
566    /// Sets a new sender boost count.
567    ///
568    /// # Arguments
569    ///
570    /// * `value` - Number of boosts added by the user.
571    pub fn with_sender_boost_count(mut self, value: Integer) -> Self {
572        self.sender_boost_count = Some(value);
573        self
574    }
575
576    /// Sets a new bot.
577    ///
578    /// # Arguments
579    ///
580    /// * `value` - The bot that actually sent the message on behalf of the business account.
581    pub fn with_sender_business_bot(mut self, value: User) -> Self {
582        self.sender_business_bot = Some(value);
583        self
584    }
585
586    /// Sets a new sender tag.
587    ///
588    /// # Arguments
589    ///
590    /// * `value` - Tag or custom title of the sender of the message.
591    pub fn with_sender_tag<T>(mut self, value: T) -> Self
592    where
593        T: Into<String>,
594    {
595        self.sender_tag = Some(value.into());
596        self
597    }
598
599    /// Sets a new value for the `show_caption_above_media` flag.
600    ///
601    /// # Arguments
602    ///
603    /// * `value` - Whether the caption must be shown above the message media.
604    pub fn with_show_caption_above_media(mut self, value: bool) -> Self {
605        self.show_caption_above_media = Some(value);
606        self
607    }
608
609    /// Sets a new suggested post info.
610    ///
611    /// # Arguments
612    ///
613    /// * `value` - Information about suggested post parameters.
614    pub fn with_suggested_post_info(mut self, value: SuggestedPostInfo) -> Self {
615        self.suggested_post_info = Some(value);
616        self
617    }
618
619    /// Sets a new bot.
620    ///
621    /// # Arguments
622    ///
623    /// * `value` - Bot through which the message was sent.
624    pub fn with_via_bot(mut self, value: User) -> Self {
625        self.via_bot = Some(value);
626        self
627    }
628}
629
630/// Describes a topic of a direct messages chat.
631#[serde_with::skip_serializing_none]
632#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
633pub struct DirectMessagesTopic {
634    /// Unique identifier of the topic.
635    pub topic_id: Integer,
636    /// Information about the user that created the topic.
637    pub user: Option<User>,
638}
639
640impl DirectMessagesTopic {
641    /// Creates a new `DirectMessagesTopic`.
642    ///
643    /// # Arguments
644    ///
645    /// * `topic_id` - Unique identifier of the topic.
646    pub fn new(topic_id: Integer) -> Self {
647        Self { topic_id, user: None }
648    }
649
650    /// Sets a new user.
651    ///
652    /// # Arguments
653    ///
654    /// * `value` - Information about the user that created the topic.
655    pub fn with_user(mut self, value: User) -> Self {
656        self.user = Some(value);
657        self
658    }
659}
660
661/// Represents an unique message identifier.
662#[derive(Copy, Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
663pub struct MessageId {
664    /// The unique message identifier.
665    pub message_id: Integer,
666}