tgbot/types/definitions/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, SuggestedPostInfo, Text, User};
5
6mod command;
7mod data;
8mod methods;
9mod origin;
10mod quote;
11mod reply;
12mod sender;
13
14/// Represents a result of `EditMessage*` requests.
15#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
16#[allow(clippy::large_enum_variant)]
17#[serde(untagged)]
18pub enum EditMessageResult {
19 /// Returned if edited message is sent by the bot.
20 Message(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, PartialEq, 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, PartialEq, 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 /// Indicates whether the message media is covered by a spoiler animation.
102 pub has_media_spoiler: Option<bool>,
103 /// Whether the message was sent by an implicit action.
104 ///
105 /// For example, as an away or a greeting business message, or as a scheduled message.
106 pub is_from_offline: Option<bool>,
107 /// Whether the message is a paid post.
108 ///
109 /// Note that such posts must not be deleted for 24 hours to receive the payment and can't be edited.
110 pub is_paid_post: Option<bool>,
111 /// Indicates whether the message is sent to a forum topic.
112 pub is_topic_message: Option<bool>,
113 /// Options used for link preview generation for the message,
114 /// if it is a text message and link preview options were changed.
115 pub link_preview_options: Option<LinkPreviewOptions>,
116 /// Unique identifier of a media message group this message belongs to.
117 pub media_group_id: Option<String>,
118 /// Unique identifier of a message thread to which the message belongs;
119 /// for supergroups only.
120 pub message_thread_id: Option<Integer>,
121 /// The number of Telegram Stars that were paid by the sender of the message to send it.
122 pub paid_star_count: Option<Integer>,
123 /// For replies that quote part of the original message, the quoted part of the message.
124 pub quote: Option<TextQuote>,
125 /// Inline keyboard attached to the message.
126 pub reply_markup: Option<InlineKeyboardMarkup>,
127 /// For replies, the original message or story.
128 #[serde(flatten)]
129 pub reply_to: Option<ReplyTo>,
130 /// Identifier of the specific checklist task that is being replied to.
131 pub reply_to_checklist_task_id: Option<Integer>,
132 /// Number of boosts added by the user.
133 ///
134 /// Contains a value only if the sender of the message boosted the chat.
135 pub sender_boost_count: Option<Integer>,
136 /// The bot that actually sent the message on behalf of the business account.
137 ///
138 /// Available only for outgoing messages sent on behalf of the connected business account.
139 pub sender_business_bot: Option<User>,
140 /// Whether the caption must be shown above the message media.
141 pub show_caption_above_media: Option<bool>,
142 /// Information about suggested post parameters if the message is a suggested post in a channel direct messages chat.
143 ///
144 /// If the message is an approved or declined suggested post, then it can't be edited.
145 pub suggested_post_info: Option<SuggestedPostInfo>,
146 /// Bot through which the message was sent.
147 pub via_bot: Option<User>,
148
149 /// Contains message data.
150 #[serde(flatten)]
151 pub data: MessageData,
152}
153
154impl Message {
155 /// Creates a new `Message`.
156 ///
157 /// # Arguments
158 ///
159 /// * `id` - Unique message identifier inside the chat.
160 /// * `date` - Date the message was sent in Unix time.
161 /// * `chat` - Chat the message belongs to.
162 /// * `data` - Data of the message.
163 /// * `sender` - Sender of the message.
164 pub fn new<A, B>(id: Integer, date: Integer, chat: A, data: MessageData, sender: B) -> Self
165 where
166 A: Into<Chat>,
167 B: Into<MessageSender>,
168 {
169 Self {
170 chat: chat.into(),
171 data,
172 date,
173 edit_date: None,
174 has_protected_content: false,
175 id,
176 is_automatic_forward: false,
177 sender: sender.into(),
178 author_signature: None,
179 business_connection_id: None,
180 direct_messages_topic: None,
181 effect_id: None,
182 external_reply: None,
183 forward_origin: None,
184 has_media_spoiler: None,
185 is_from_offline: None,
186 is_paid_post: None,
187 is_topic_message: None,
188 link_preview_options: None,
189 media_group_id: None,
190 message_thread_id: None,
191 paid_star_count: None,
192 quote: None,
193 reply_markup: None,
194 reply_to: None,
195 reply_to_checklist_task_id: None,
196 sender_boost_count: None,
197 sender_business_bot: None,
198 show_caption_above_media: None,
199 suggested_post_info: None,
200 via_bot: None,
201 }
202 }
203
204 /// Returns `true` if the message has edited and `false` otherwise.
205 pub fn is_edited(&self) -> bool {
206 self.edit_date.is_some()
207 }
208
209 /// Returns a text of the message (includes caption).
210 pub fn get_text(&self) -> Option<&Text> {
211 match self.data {
212 MessageData::Text(ref text)
213 | MessageData::Audio(MessageDataAudio {
214 caption: Some(ref text),
215 ..
216 })
217 | MessageData::Document(MessageDataDocument {
218 caption: Some(ref text),
219 ..
220 })
221 | MessageData::Photo(MessageDataPhoto {
222 caption: Some(ref text),
223 ..
224 })
225 | MessageData::Video(MessageDataVideo {
226 caption: Some(ref text),
227 ..
228 })
229 | MessageData::Voice(MessageDataVoice {
230 caption: Some(ref text),
231 ..
232 }) => Some(text),
233 _ => None,
234 }
235 }
236
237 /// Sets a new chat.
238 ///
239 /// # Arguments
240 ///
241 /// * `value` - Chat.
242 pub fn with_chat<T>(mut self, value: T) -> Self
243 where
244 T: Into<Chat>,
245 {
246 self.chat = value.into();
247 self
248 }
249
250 /// Sets a new data.
251 ///
252 /// # Arguments
253 ///
254 /// * `value` - Data of the message.
255 pub fn with_data(mut self, value: MessageData) -> Self {
256 self.data = value;
257 self
258 }
259
260 /// Sets a new date.
261 ///
262 /// # Arguments
263 ///
264 /// * `value` - Date; Unix timestamp.
265 pub fn with_date(mut self, value: Integer) -> Self {
266 self.date = value;
267 self
268 }
269
270 /// Sets a new direct messages topic.
271 ///
272 /// # Arguments
273 ///
274 /// * `value` - Information about the direct messages chat topic that contains the message.
275 pub fn with_direct_messages_topic(mut self, value: DirectMessagesTopic) -> Self {
276 self.direct_messages_topic = Some(value);
277 self
278 }
279
280 /// Sets a new edit date.
281 ///
282 /// # Arguments
283 ///
284 /// * `value` - Edit date; Unix timestamp.
285 pub fn with_edit_date(mut self, value: Integer) -> Self {
286 self.edit_date = Some(value);
287 self
288 }
289
290 /// Sets a new effect ID.
291 ///
292 /// # Arguments
293 ///
294 /// * `value` - Unique identifier of the message effect.
295 pub fn with_effect_id<T>(mut self, value: T) -> Self
296 where
297 T: Into<String>,
298 {
299 self.effect_id = Some(value.into());
300 self
301 }
302
303 /// Sets a new value for the `has_protected_content` flag.
304 ///
305 /// # Arguments
306 ///
307 /// * `value` - Indicates whether messages from the chat can't be forwarded to other chats.
308 pub fn with_has_protected_content(mut self, value: bool) -> Self {
309 self.has_protected_content = value;
310 self
311 }
312
313 /// Sets a new ID.
314 ///
315 /// # Arguments
316 ///
317 /// * `value` - Unique identifier inside a chat.
318 pub fn with_id(mut self, value: Integer) -> Self {
319 self.id = value;
320 self
321 }
322
323 /// Sets a new value for the `is_automatic_forward` flag.
324 ///
325 /// # Arguments
326 ///
327 /// * `value` - Indicates whether the message was automatically forwarded.
328 pub fn with_is_automatic_forward(mut self, value: bool) -> Self {
329 self.is_automatic_forward = value;
330 self
331 }
332
333 /// Sets a new sender.
334 ///
335 /// # Arguments
336 ///
337 /// * `value` - Sender.
338 pub fn with_sender<T>(mut self, value: T) -> Self
339 where
340 T: Into<MessageSender>,
341 {
342 self.sender = value.into();
343 self
344 }
345
346 /// Sets a new author signature.
347 ///
348 /// # Arguments
349 ///
350 /// * `value` - Author signature.
351 pub fn with_author_signature<T>(mut self, value: T) -> Self
352 where
353 T: Into<String>,
354 {
355 self.author_signature = Some(value.into());
356 self
357 }
358
359 /// Sets a new business connection ID.
360 ///
361 /// # Arguments
362 ///
363 /// * `value` - Unique identifier of the business connection from which the message was received.
364 pub fn with_business_connection_id<T>(mut self, value: T) -> Self
365 where
366 T: Into<String>,
367 {
368 self.business_connection_id = Some(value.into());
369 self
370 }
371
372 /// Sets a new external reply.
373 ///
374 /// # Arguments
375 ///
376 /// * `value` - Information about the message that is being replied to,
377 /// which may come from another chat or forum topic.
378 pub fn with_external_reply(mut self, value: ExternalReplyInfo) -> Self {
379 self.external_reply = Some(value);
380 self
381 }
382
383 /// Sets a new forward origin.
384 ///
385 /// # Arguments
386 ///
387 /// * `value` - Information about the message origin.
388 pub fn with_forward_origin(mut self, value: MessageOrigin) -> Self {
389 self.forward_origin = Some(value);
390 self
391 }
392
393 /// Sets a new value for the `has_media_spoiler` flag.
394 ///
395 /// # Arguments
396 ///
397 /// * `value` - Indicates whether the message has a media spoiler.
398 pub fn with_has_media_spoiler(mut self, value: bool) -> Self {
399 self.has_media_spoiler = Some(value);
400 self
401 }
402
403 /// Sets a new value for the `is_from_offline` flag.
404 ///
405 /// # Arguments
406 ///
407 /// * `value` - Indicates whether the message was sent by an implicit action.
408 pub fn with_is_from_offline(mut self, value: bool) -> Self {
409 self.is_from_offline = Some(value);
410 self
411 }
412
413 /// Sets a new value for the `is_paid_post` flag.
414 ///
415 /// # Arguments
416 ///
417 /// * `value` - Whether the message is a paid post.
418 pub fn with_is_paid_post(mut self, value: bool) -> Self {
419 self.is_paid_post = Some(value);
420 self
421 }
422
423 /// Sets a new value for the `is_topic_message` flag.
424 ///
425 /// # Arguments
426 ///
427 /// * `value` - Indicates whether the message is a topic message.
428 pub fn with_is_topic_message(mut self, value: bool) -> Self {
429 self.is_topic_message = Some(value);
430 self
431 }
432
433 /// Sets a new link preview options.
434 ///
435 /// # Arguments
436 ///
437 /// * `value` - New options.
438 pub fn with_link_preview_options(mut self, value: LinkPreviewOptions) -> Self {
439 self.link_preview_options = Some(value);
440 self
441 }
442
443 /// Sets a new media group ID.
444 ///
445 /// # Arguments
446 ///
447 /// * `value` - Media group ID.
448 pub fn with_media_group_id<T>(mut self, value: T) -> Self
449 where
450 T: Into<String>,
451 {
452 self.media_group_id = Some(value.into());
453 self
454 }
455
456 /// Sets a new message thread ID.
457 ///
458 /// # Arguments
459 ///
460 /// * `value` - Unique identifier of the target message thread;
461 /// supergroups only.
462 pub fn with_message_thread_id(mut self, value: Integer) -> Self {
463 self.message_thread_id = Some(value);
464 self
465 }
466
467 /// Sets a new paid star count
468 ///
469 /// # Arguments
470 ///
471 /// * `value` - The number of Telegram Stars that were paid by the sender of the message to send it.
472 pub fn with_paid_star_count(mut self, value: Integer) -> Self {
473 self.paid_star_count = Some(value);
474 self
475 }
476
477 /// Sets a new quote
478 ///
479 /// # Arguments
480 ///
481 /// * `value` - The quoted part of the original message.
482 pub fn with_quote(mut self, value: TextQuote) -> Self {
483 self.quote = Some(value);
484 self
485 }
486
487 /// Sets a new reply markup.
488 ///
489 /// # Arguments
490 ///
491 /// * `value` - Reply markup.
492 pub fn with_reply_markup<T>(mut self, value: T) -> Self
493 where
494 T: Into<InlineKeyboardMarkup>,
495 {
496 self.reply_markup = Some(value.into());
497 self
498 }
499
500 /// Sets a new original message or story for the reply.
501 ///
502 /// # Arguments
503 ///
504 /// * `value` - For replies, the original message or story.
505 pub fn with_reply_to<T>(mut self, value: T) -> Self
506 where
507 T: Into<ReplyTo>,
508 {
509 self.reply_to = Some(value.into());
510 self
511 }
512
513 /// Sets a new reply checklist task ID.
514 ///
515 /// # Arguments
516 ///
517 /// * `value` - Identifier of the specific checklist task that is being replied to.
518 pub fn with_reply_to_checklist_task_id(mut self, value: Integer) -> Self {
519 self.reply_to_checklist_task_id = Some(value);
520 self
521 }
522
523 /// Sets a new sender boost count.
524 ///
525 /// # Arguments
526 ///
527 /// * `value` - Number of boosts added by the user.
528 pub fn with_sender_boost_count(mut self, value: Integer) -> Self {
529 self.sender_boost_count = Some(value);
530 self
531 }
532
533 /// Sets a new bot.
534 ///
535 /// # Arguments
536 ///
537 /// * `value` - The bot that actually sent the message on behalf of the business account.
538 pub fn with_sender_business_bot(mut self, value: User) -> Self {
539 self.sender_business_bot = Some(value);
540 self
541 }
542
543 /// Sets a new value for the `show_caption_above_media` flag.
544 ///
545 /// # Arguments
546 ///
547 /// * `value` - Whether the caption must be shown above the message media.
548 pub fn with_show_caption_above_media(mut self, value: bool) -> Self {
549 self.show_caption_above_media = Some(value);
550 self
551 }
552
553 /// Sets a new suggested post info.
554 ///
555 /// # Arguments
556 ///
557 /// * `value` - Information about suggested post parameters.
558 pub fn with_suggested_post_info(mut self, value: SuggestedPostInfo) -> Self {
559 self.suggested_post_info = Some(value);
560 self
561 }
562
563 /// Sets a new bot.
564 ///
565 /// # Arguments
566 ///
567 /// * `value` - Bot through which the message was sent.
568 pub fn with_via_bot(mut self, value: User) -> Self {
569 self.via_bot = Some(value);
570 self
571 }
572}
573
574/// Describes a topic of a direct messages chat.
575#[serde_with::skip_serializing_none]
576#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
577pub struct DirectMessagesTopic {
578 /// Unique identifier of the topic.
579 pub topic_id: Integer,
580 /// Information about the user that created the topic.
581 pub user: Option<User>,
582}
583
584impl DirectMessagesTopic {
585 /// Creates a new `DirectMessagesTopic`.
586 ///
587 /// # Arguments
588 ///
589 /// * `topic_id` - Unique identifier of the topic.
590 pub fn new(topic_id: Integer) -> Self {
591 Self { topic_id, user: None }
592 }
593
594 /// Sets a new user.
595 ///
596 /// # Arguments
597 ///
598 /// * `value` - Information about the user that created the topic.
599 pub fn with_user(mut self, value: User) -> Self {
600 self.user = Some(value);
601 self
602 }
603}
604
605/// Represents an unique message identifier.
606#[derive(Copy, Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
607pub struct MessageId {
608 /// The unique message identifier.
609 pub message_id: Integer,
610}