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}