1use layer_tl_types as tl;
8use layer_tl_types::{Cursor, Deserializable};
9
10use crate::{Client, InvocationError as Error};
11
12#[derive(Debug, Clone)]
16pub struct IncomingMessage {
17 pub raw: tl::enums::Message,
19}
20
21impl IncomingMessage {
22 pub(crate) fn from_raw(raw: tl::enums::Message) -> Self {
23 Self { raw }
24 }
25
26 pub fn text(&self) -> Option<&str> {
28 match &self.raw {
29 tl::enums::Message::Message(m) => {
30 if m.message.is_empty() { None } else { Some(&m.message) }
31 }
32 _ => None,
33 }
34 }
35
36 pub fn id(&self) -> i32 {
38 match &self.raw {
39 tl::enums::Message::Message(m) => m.id,
40 tl::enums::Message::Service(m) => m.id,
41 tl::enums::Message::Empty(m) => m.id,
42 }
43 }
44
45 pub fn peer_id(&self) -> Option<&tl::enums::Peer> {
47 match &self.raw {
48 tl::enums::Message::Message(m) => Some(&m.peer_id),
49 tl::enums::Message::Service(m) => Some(&m.peer_id),
50 _ => None,
51 }
52 }
53
54 pub fn sender_id(&self) -> Option<&tl::enums::Peer> {
56 match &self.raw {
57 tl::enums::Message::Message(m) => m.from_id.as_ref(),
58 tl::enums::Message::Service(m) => m.from_id.as_ref(),
59 _ => None,
60 }
61 }
62
63 pub fn outgoing(&self) -> bool {
65 match &self.raw {
66 tl::enums::Message::Message(m) => m.out,
67 tl::enums::Message::Service(m) => m.out,
68 _ => false,
69 }
70 }
71
72 pub fn date(&self) -> i32 {
74 match &self.raw {
75 tl::enums::Message::Message(m) => m.date,
76 tl::enums::Message::Service(m) => m.date,
77 _ => 0,
78 }
79 }
80
81 pub fn edit_date(&self) -> Option<i32> {
83 match &self.raw {
84 tl::enums::Message::Message(m) => m.edit_date,
85 _ => None,
86 }
87 }
88
89 pub fn mentioned(&self) -> bool {
91 match &self.raw {
92 tl::enums::Message::Message(m) => m.mentioned,
93 tl::enums::Message::Service(m) => m.mentioned,
94 _ => false,
95 }
96 }
97
98 pub fn silent(&self) -> bool {
100 match &self.raw {
101 tl::enums::Message::Message(m) => m.silent,
102 tl::enums::Message::Service(m) => m.silent,
103 _ => false,
104 }
105 }
106
107 pub fn post(&self) -> bool {
109 match &self.raw {
110 tl::enums::Message::Message(m) => m.post,
111 _ => false,
112 }
113 }
114
115 pub fn pinned(&self) -> bool {
117 match &self.raw {
118 tl::enums::Message::Message(m) => m.pinned,
119 _ => false,
120 }
121 }
122
123 pub fn forward_count(&self) -> Option<i32> {
125 match &self.raw {
126 tl::enums::Message::Message(m) => m.forwards,
127 _ => None,
128 }
129 }
130
131 pub fn view_count(&self) -> Option<i32> {
133 match &self.raw {
134 tl::enums::Message::Message(m) => m.views,
135 _ => None,
136 }
137 }
138
139 pub fn reply_count(&self) -> Option<i32> {
141 match &self.raw {
142 tl::enums::Message::Message(m) => {
143 m.replies.as_ref().map(|r| match r {
144 tl::enums::MessageReplies::MessageReplies(x) => x.replies,
145 })
146 }
147 _ => None,
148 }
149 }
150
151 pub fn reply_to_message_id(&self) -> Option<i32> {
153 match &self.raw {
154 tl::enums::Message::Message(m) => {
155 m.reply_to.as_ref().and_then(|r| match r {
156 tl::enums::MessageReplyHeader::MessageReplyHeader(h) => h.reply_to_msg_id,
157 _ => None,
158 })
159 }
160 _ => None,
161 }
162 }
163
164 pub async fn reply_to_message(
172 &self,
173 client: &Client,
174 ) -> Result<Option<IncomingMessage>, Error> {
175 let reply_id = match self.reply_to_message_id() {
176 Some(id) => id,
177 None => return Ok(None),
178 };
179 let peer = match self.peer_id() {
180 Some(p) => p.clone(),
181 None => return Ok(None),
182 };
183 let msgs = client.get_messages_by_id(peer, &[reply_id]).await?;
184 Ok(msgs.into_iter().next())
185 }
186
187 pub fn date_utc(&self) -> Option<chrono::DateTime<chrono::Utc>> {
191 use chrono::TimeZone;
192 let ts = self.date();
193 if ts == 0 { return None; }
194 chrono::Utc.timestamp_opt(ts as i64, 0).single()
195 }
196
197 pub fn edit_date_utc(&self) -> Option<chrono::DateTime<chrono::Utc>> {
199 use chrono::TimeZone;
200 self.edit_date().and_then(|ts| chrono::Utc.timestamp_opt(ts as i64, 0).single())
201 }
202
203 pub fn media(&self) -> Option<&tl::enums::MessageMedia> {
205 match &self.raw {
206 tl::enums::Message::Message(m) => m.media.as_ref(),
207 _ => None,
208 }
209 }
210
211 pub fn entities(&self) -> Option<&Vec<tl::enums::MessageEntity>> {
213 match &self.raw {
214 tl::enums::Message::Message(m) => m.entities.as_ref(),
215 _ => None,
216 }
217 }
218
219 pub fn grouped_id(&self) -> Option<i64> {
221 match &self.raw {
222 tl::enums::Message::Message(m) => m.grouped_id,
223 _ => None,
224 }
225 }
226
227 pub fn reply_markup(&self) -> Option<&tl::enums::ReplyMarkup> {
229 match &self.raw {
230 tl::enums::Message::Message(m) => m.reply_markup.as_ref(),
231 _ => None,
232 }
233 }
234
235 pub fn forward_header(&self) -> Option<&tl::enums::MessageFwdHeader> {
237 match &self.raw {
238 tl::enums::Message::Message(m) => m.fwd_from.as_ref(),
239 _ => None,
240 }
241 }
242
243 pub fn noforwards(&self) -> bool {
245 match &self.raw {
246 tl::enums::Message::Message(m) => m.noforwards,
247 _ => false,
248 }
249 }
250
251 pub async fn reply(&self, client: &mut Client, text: impl Into<String>) -> Result<(), Error> {
253 let peer = match self.peer_id() {
254 Some(p) => p.clone(),
255 None => return Err(Error::Deserialize("cannot reply: unknown peer".into())),
256 };
257 let msg_id = self.id();
258 client.send_message_to_peer_ex(peer, &crate::InputMessage::text(text.into())
259 .reply_to(Some(msg_id))).await
260 }
261}
262
263#[derive(Debug, Clone)]
267pub struct MessageDeletion {
268 pub message_ids: Vec<i32>,
270 pub channel_id: Option<i64>,
272}
273
274#[derive(Debug, Clone)]
278pub struct CallbackQuery {
279 pub query_id: i64,
280 pub user_id: i64,
281 pub message_id: Option<i32>,
282 pub chat_instance: i64,
283 pub data_raw: Option<Vec<u8>>,
285 pub game_short_name: Option<String>,
287}
288
289impl CallbackQuery {
290 pub fn data(&self) -> Option<&str> {
292 self.data_raw.as_ref().and_then(|d| std::str::from_utf8(d).ok())
293 }
294
295 pub async fn answer(
297 &self,
298 client: &mut Client,
299 text: Option<&str>,
300 ) -> Result<(), Error> {
301 client.answer_callback_query(self.query_id, text, false).await.map(|_| ())
302 }
303
304 pub async fn answer_alert(
306 &self,
307 client: &mut Client,
308 text: &str,
309 ) -> Result<(), Error> {
310 client.answer_callback_query(self.query_id, Some(text), true).await.map(|_| ())
311 }
312}
313
314#[derive(Debug, Clone)]
318pub struct InlineQuery {
319 pub query_id: i64,
320 pub user_id: i64,
321 pub query: String,
322 pub offset: String,
323 pub peer: Option<tl::enums::Peer>,
325}
326
327impl InlineQuery {
328 pub fn query(&self) -> &str { &self.query }
330}
331
332#[derive(Debug, Clone)]
336pub struct InlineSend {
337 pub user_id: i64,
338 pub query: String,
339 pub id: String,
340 pub msg_id: Option<tl::enums::InputBotInlineMessageId>,
342}
343
344#[derive(Debug, Clone)]
348pub struct RawUpdate {
349 pub constructor_id: u32,
351}
352
353#[non_exhaustive]
357#[derive(Debug, Clone)]
358pub enum Update {
359 NewMessage(IncomingMessage),
361 MessageEdited(IncomingMessage),
363 MessageDeleted(MessageDeletion),
365 CallbackQuery(CallbackQuery),
367 InlineQuery(InlineQuery),
369 InlineSend(InlineSend),
371 Raw(RawUpdate),
373}
374
375const ID_UPDATES_TOO_LONG: u32 = 0xe317af7e;
378const ID_UPDATE_SHORT_MESSAGE: u32 = 0x313bc7f8;
379const ID_UPDATE_SHORT_CHAT_MSG: u32 = 0x4d6deea5;
380const ID_UPDATE_SHORT: u32 = 0x78d4dec1;
381const ID_UPDATES: u32 = 0x74ae4240;
382const ID_UPDATES_COMBINED: u32 = 0x725b04c3;
383
384pub(crate) fn parse_updates(bytes: &[u8]) -> Vec<Update> {
388 if bytes.len() < 4 {
389 return vec![];
390 }
391 let cid = u32::from_le_bytes(bytes[..4].try_into().unwrap());
392
393 match cid {
394 ID_UPDATES_TOO_LONG => {
395 log::warn!("[layer] updatesTooLong — call client.get_difference() to recover missed updates");
396 vec![]
397 }
398
399 ID_UPDATE_SHORT_MESSAGE => {
400 let mut cur = Cursor::from_slice(&bytes[4..]); match tl::types::UpdateShortMessage::deserialize(&mut cur) {
402 Ok(m) => vec![Update::NewMessage(make_short_dm(m))],
403 Err(e) => { log::debug!("[layer] updateShortMessage parse error (unknown constructor or newer layer): {e}"); vec![] }
404 }
405 }
406
407 ID_UPDATE_SHORT_CHAT_MSG => {
408 let mut cur = Cursor::from_slice(&bytes[4..]); match tl::types::UpdateShortChatMessage::deserialize(&mut cur) {
410 Ok(m) => vec![Update::NewMessage(make_short_chat(m))],
411 Err(e) => { log::debug!("[layer] updateShortChatMessage parse error (unknown constructor or newer layer): {e}"); vec![] }
412 }
413 }
414
415 ID_UPDATE_SHORT => {
416 let mut cur = Cursor::from_slice(&bytes[4..]); match tl::types::UpdateShort::deserialize(&mut cur) {
418 Ok(m) => from_single_update(m.update),
419 Err(e) => { log::debug!("[layer] updateShort parse error (unknown constructor or newer layer): {e}"); vec![] }
420 }
421 }
422
423 ID_UPDATES => {
424 let mut cur = Cursor::from_slice(bytes);
425 match tl::enums::Updates::deserialize(&mut cur) {
426 Ok(tl::enums::Updates::Updates(u)) => {
427 u.updates.into_iter().flat_map(from_single_update).collect()
428 }
429 Err(e) => { log::debug!("[layer] Updates parse error (unknown constructor or newer layer): {e}"); vec![] }
430 _ => vec![],
431 }
432 }
433
434 ID_UPDATES_COMBINED => {
435 let mut cur = Cursor::from_slice(bytes);
436 match tl::enums::Updates::deserialize(&mut cur) {
437 Ok(tl::enums::Updates::Combined(u)) => {
438 u.updates.into_iter().flat_map(from_single_update).collect()
439 }
440 Err(e) => { log::debug!("[layer] UpdatesCombined parse error (unknown constructor or newer layer): {e}"); vec![] }
441 _ => vec![],
442 }
443 }
444
445 _ => vec![],
446 }
447}
448
449pub fn from_single_update_pub(upd: tl::enums::Update) -> Vec<Update> {
451 from_single_update(upd)
452}
453
454fn from_single_update(upd: tl::enums::Update) -> Vec<Update> {
456 use tl::enums::Update::*;
457 match upd {
458 NewMessage(u) => vec![Update::NewMessage(IncomingMessage::from_raw(u.message))],
459 NewChannelMessage(u) => vec![Update::NewMessage(IncomingMessage::from_raw(u.message))],
460 EditMessage(u) => vec![Update::MessageEdited(IncomingMessage::from_raw(u.message))],
461 EditChannelMessage(u) => vec![Update::MessageEdited(IncomingMessage::from_raw(u.message))],
462 DeleteMessages(u) => vec![Update::MessageDeleted(MessageDeletion {
463 message_ids: u.messages,
464 channel_id: None,
465 })],
466 DeleteChannelMessages(u) => vec![Update::MessageDeleted(MessageDeletion {
467 message_ids: u.messages,
468 channel_id: Some(u.channel_id),
469 })],
470 BotCallbackQuery(u) => vec![Update::CallbackQuery(CallbackQuery {
471 query_id: u.query_id,
472 user_id: u.user_id,
473 message_id: Some(u.msg_id),
474 chat_instance: u.chat_instance,
475 data_raw: u.data,
476 game_short_name: u.game_short_name,
477 })],
478 InlineBotCallbackQuery(u) => vec![Update::CallbackQuery(CallbackQuery {
479 query_id: u.query_id,
480 user_id: u.user_id,
481 message_id: None,
482 chat_instance: u.chat_instance,
483 data_raw: u.data,
484 game_short_name: u.game_short_name,
485 })],
486 BotInlineQuery(u) => vec![Update::InlineQuery(InlineQuery {
487 query_id: u.query_id,
488 user_id: u.user_id,
489 query: u.query,
490 offset: u.offset,
491 peer: None,
492 })],
493 BotInlineSend(u) => vec![Update::InlineSend(InlineSend {
494 user_id: u.user_id,
495 query: u.query,
496 id: u.id,
497 msg_id: u.msg_id,
498 })],
499 other => {
500 let cid = tl_constructor_id(&other);
501 vec![Update::Raw(RawUpdate { constructor_id: cid })]
502 }
503 }
504}
505
506fn tl_constructor_id(upd: &tl::enums::Update) -> u32 {
508 use tl::enums::Update::*;
509 match upd {
510 AttachMenuBots => 0x17b7a20b,
511 AutoSaveSettings => 0xec05b097,
512 BotBusinessConnect(_) => 0x8ae5c97a,
513 BotCallbackQuery(_) => 0xb9cfc48d,
514 BotChatBoost(_) => 0x904dd49c,
515 BotChatInviteRequester(_) => 0x11dfa986,
516 BotCommands(_) => 0x4d712f2e,
517 BotDeleteBusinessMessage(_) => 0xa02a982e,
518 BotEditBusinessMessage(_) => 0x7df587c,
519 BotInlineQuery(_) => 0x496f379c,
520 BotInlineSend(_) => 0x12f12a07,
521 BotMenuButton(_) => 0x14b85813,
522 BotMessageReaction(_) => 0xac21d3ce,
523 BotMessageReactions(_) => 0x9cb7759,
524 BotNewBusinessMessage(_) => 0x9ddb347c,
525 BotPrecheckoutQuery(_) => 0x8caa9a96,
526 BotPurchasedPaidMedia(_) => 0x283bd312,
527 BotShippingQuery(_) => 0xb5aefd7d,
528 BotStopped(_) => 0xc4870a49,
529 BotWebhookJson(_) => 0x8317c0c3,
530 BotWebhookJsonquery(_) => 0x9b9240a6,
531 BusinessBotCallbackQuery(_) => 0x1ea2fda7,
532 Channel(_) => 0x635b4c09,
533 ChannelAvailableMessages(_) => 0xb23fc698,
534 ChannelMessageForwards(_) => 0xd29a27f4,
535 ChannelMessageViews(_) => 0xf226ac08,
536 ChannelParticipant(_) => 0x985d3abb,
537 ChannelReadMessagesContents(_) => 0x25f324f7,
538 ChannelTooLong(_) => 0x108d941f,
539 ChannelUserTyping(_) => 0x8c88c923,
540 ChannelViewForumAsMessages(_) => 0x7b68920,
541 ChannelWebPage(_) => 0x2f2ba99f,
542 Chat(_) => 0xf89a6a4e,
543 ChatDefaultBannedRights(_) => 0x54c01850,
544 ChatParticipant(_) => 0xd087663a,
545 ChatParticipantAdd(_) => 0x3dda5451,
546 ChatParticipantAdmin(_) => 0xd7ca61a2,
547 ChatParticipantDelete(_) => 0xe32f3d77,
548 ChatParticipants(_) => 0x7761198,
549 ChatUserTyping(_) => 0x83487af0,
550 Config => 0xa229dd06,
551 ContactsReset => 0x7084a7be,
552 DcOptions(_) => 0x8e5e9873,
553 DeleteChannelMessages(_) => 0xc32d5b12,
554 DeleteGroupCallMessages(_) => 0x3e85e92c,
555 DeleteMessages(_) => 0xa20db0e5,
556 DeleteQuickReply(_) => 0x53e6f1ec,
557 DeleteQuickReplyMessages(_) => 0x566fe7cd,
558 DeleteScheduledMessages(_) => 0xf2a71983,
559 DialogFilter(_) => 0x26ffde7d,
560 DialogFilterOrder(_) => 0xa5d72105,
561 DialogFilters => 0x3504914f,
562 DialogPinned(_) => 0x6e6fe51c,
563 DialogUnreadMark(_) => 0xb658f23e,
564 DraftMessage(_) => 0xedfc111e,
565 EditChannelMessage(_) => 0x1b3f4df7,
566 EditMessage(_) => 0xe40370a3,
567 EmojiGameInfo(_) => 0xfb9c547a,
568 EncryptedChatTyping(_) => 0x1710f156,
569 EncryptedMessagesRead(_) => 0x38fe25b7,
570 Encryption(_) => 0xb4a2e88d,
571 FavedStickers => 0xe511996d,
572 FolderPeers(_) => 0x19360dc0,
573 GeoLiveViewed(_) => 0x871fb939,
574 GroupCall(_) => 0x9d2216e0,
575 GroupCallChainBlocks(_) => 0xa477288f,
576 GroupCallConnection(_) => 0xb783982,
577 GroupCallEncryptedMessage(_) => 0xc957a766,
578 GroupCallMessage(_) => 0xd8326f0d,
579 GroupCallParticipants(_) => 0xf2ebdb4e,
580 InlineBotCallbackQuery(_) => 0x691e9052,
581 LangPack(_) => 0x56022f4d,
582 LangPackTooLong(_) => 0x46560264,
583 LoginToken => 0x564fe691,
584 MessageExtendedMedia(_) => 0xd5a41724,
585 MessageId(_) => 0x4e90bfd6,
586 MessagePoll(_) => 0xaca1657b,
587 MessagePollVote(_) => 0x24f40e77,
588 MessageReactions(_) => 0x1e297bfa,
589 MonoForumNoPaidException(_) => 0x9f812b08,
590 MoveStickerSetToTop(_) => 0x86fccf85,
591 NewAuthorization(_) => 0x8951abef,
592 NewChannelMessage(_) => 0x62ba04d9,
593 NewEncryptedMessage(_) => 0x12bcbd9a,
594 NewMessage(_) => 0x1f2b0afd,
595 NewQuickReply(_) => 0xf53da717,
596 NewScheduledMessage(_) => 0x39a51dfb,
597 NewStickerSet(_) => 0x688a30aa,
598 NewStoryReaction(_) => 0x1824e40b,
599 NotifySettings(_) => 0xbec268ef,
600 PaidReactionPrivacy(_) => 0x8b725fce,
601 PeerBlocked(_) => 0xebe07752,
602 PeerHistoryTtl(_) => 0xbb9bb9a5,
603 PeerLocated(_) => 0xb4afcfb0,
604 PeerSettings(_) => 0x6a7e7366,
605 PeerWallpaper(_) => 0xae3f101d,
606 PendingJoinRequests(_) => 0x7063c3db,
607 PhoneCall(_) => 0xab0f6b1e,
608 PhoneCallSignalingData(_) => 0x2661bf09,
609 PinnedChannelMessages(_) => 0x5bb98608,
610 PinnedDialogs(_) => 0xfa0f3ca2,
611 PinnedForumTopic(_) => 0x683b2c52,
612 PinnedForumTopics(_) => 0xdef143d0,
613 PinnedMessages(_) => 0xed85eab5,
614 PinnedSavedDialogs(_) => 0x686c85a6,
615 Privacy(_) => 0xee3b272a,
616 PtsChanged => 0x3354678f,
617 QuickReplies(_) => 0xf9470ab2,
618 QuickReplyMessage(_) => 0x3e050d0f,
619 ReadChannelDiscussionInbox(_) => 0xd6b19546,
620 ReadChannelDiscussionOutbox(_) => 0x695c9e7c,
621 ReadChannelInbox(_) => 0x922e6e10,
622 ReadChannelOutbox(_) => 0xb75f99a9,
623 ReadFeaturedEmojiStickers => 0xfb4c496c,
624 ReadFeaturedStickers => 0x571d2742,
625 ReadHistoryInbox(_) => 0x9e84bc99,
626 ReadHistoryOutbox(_) => 0x2f2f21bf,
627 ReadMessagesContents(_) => 0xf8227181,
628 ReadMonoForumInbox(_) => 0x77b0e372,
629 ReadMonoForumOutbox(_) => 0xa4a79376,
630 ReadStories(_) => 0xf74e932b,
631 RecentEmojiStatuses => 0x30f443db,
632 RecentReactions => 0x6f7863f4,
633 RecentStickers => 0x9a422c20,
634 SavedDialogPinned(_) => 0xaeaf9e74,
635 SavedGifs => 0x9375341e,
636 SavedReactionTags => 0x39c67432,
637 SavedRingtones => 0x74d8be99,
638 SentPhoneCode(_) => 0x504aa18f,
639 SentStoryReaction(_) => 0x7d627683,
640 ServiceNotification(_) => 0xebe46819,
641 SmsJob(_) => 0xf16269d4,
642 StarGiftAuctionState(_) => 0x48e246c2,
643 StarGiftAuctionUserState(_) => 0xdc58f31e,
644 StarGiftCraftFail => 0xac072444,
645 StarsBalance(_) => 0x4e80a379,
646 StarsRevenueStatus(_) => 0xa584b019,
647 StickerSets(_) => 0x31c24808,
648 StickerSetsOrder(_) => 0xbb2d201,
649 StoriesStealthMode(_) => 0x2c084dc1,
650 Story(_) => 0x75b3b798,
651 StoryId(_) => 0x1bf335b9,
652 Theme(_) => 0x8216fba3,
653 TranscribedAudio(_) => 0x84cd5a,
654 User(_) => 0x20529438,
655 UserEmojiStatus(_) => 0x28373599,
656 UserName(_) => 0xa7848924,
657 UserPhone(_) => 0x5492a13,
658 UserStatus(_) => 0xe5bdf8de,
659 UserTyping(_) => 0x2a17bf5c,
660 WebPage(_) => 0x7f891213,
661 WebViewResultSent(_) => 0x1592b79d,
662 ChatParticipantRank(_) => 0xbd8367b9,
663 }
664}
665
666fn make_short_dm(m: tl::types::UpdateShortMessage) -> IncomingMessage {
669 let msg = tl::types::Message {
670 out: m.out,
671 mentioned: m.mentioned,
672 media_unread: m.media_unread,
673 silent: m.silent,
674 post: false,
675 from_scheduled: false,
676 legacy: false,
677 edit_hide: false,
678 pinned: false,
679 noforwards: false,
680 invert_media: false,
681 offline: false,
682 video_processing_pending: false,
683 id: m.id,
684 from_id: Some(tl::enums::Peer::User(tl::types::PeerUser { user_id: m.user_id })),
685 peer_id: tl::enums::Peer::User(tl::types::PeerUser { user_id: m.user_id }),
686 saved_peer_id: None,
687 fwd_from: m.fwd_from,
688 via_bot_id: m.via_bot_id,
689 via_business_bot_id: None,
690 reply_to: m.reply_to,
691 date: m.date,
692 message: m.message,
693 media: None,
694 reply_markup: None,
695 entities: m.entities,
696 views: None,
697 forwards: None,
698 replies: None,
699 edit_date: None,
700 post_author: None,
701 grouped_id: None,
702 reactions: None,
703 restriction_reason: None,
704 ttl_period: None,
705 quick_reply_shortcut_id: None,
706 effect: None,
707 factcheck: None,
708 report_delivery_until_date: None,
709 paid_message_stars: None,
710 suggested_post: None,
711 from_rank: None,
712 from_boosts_applied: None,
713 paid_suggested_post_stars: false,
714 paid_suggested_post_ton: false,
715 schedule_repeat_period: None,
716 summary_from_language: None,
717 };
718 IncomingMessage { raw: tl::enums::Message::Message(msg) }
719}
720
721fn make_short_chat(m: tl::types::UpdateShortChatMessage) -> IncomingMessage {
722 let msg = tl::types::Message {
723 out: m.out,
724 mentioned: m.mentioned,
725 media_unread: m.media_unread,
726 silent: m.silent,
727 post: false,
728 from_scheduled: false,
729 legacy: false,
730 edit_hide: false,
731 pinned: false,
732 noforwards: false,
733 invert_media: false,
734 offline: false,
735 video_processing_pending: false,
736 id: m.id,
737 from_id: Some(tl::enums::Peer::User(tl::types::PeerUser { user_id: m.from_id })),
738 peer_id: tl::enums::Peer::Chat(tl::types::PeerChat { chat_id: m.chat_id }),
739 saved_peer_id: None,
740 fwd_from: m.fwd_from,
741 via_bot_id: m.via_bot_id,
742 via_business_bot_id: None,
743 reply_to: m.reply_to,
744 date: m.date,
745 message: m.message,
746 media: None,
747 reply_markup: None,
748 entities: m.entities,
749 views: None,
750 forwards: None,
751 replies: None,
752 edit_date: None,
753 post_author: None,
754 grouped_id: None,
755 reactions: None,
756 restriction_reason: None,
757 ttl_period: None,
758 quick_reply_shortcut_id: None,
759 effect: None,
760 factcheck: None,
761 report_delivery_until_date: None,
762 paid_message_stars: None,
763 suggested_post: None,
764 from_rank: None,
765 from_boosts_applied: None,
766 paid_suggested_post_stars: false,
767 paid_suggested_post_ton: false,
768 schedule_repeat_period: None,
769 summary_from_language: None,
770 };
771 IncomingMessage { raw: tl::enums::Message::Message(msg) }
772}