1use super::defs::{Entry, Gap, PtsInfo, NO_PTS, NO_SEQ};
9use super::ChatHashCache;
10use grammers_tl_types as tl;
11use log::info;
12
13pub(super) fn updates(updates: tl::types::Updates) -> tl::types::UpdatesCombined {
23 tl::types::UpdatesCombined {
24 updates: updates.updates,
25 users: updates.users,
26 chats: updates.chats,
27 date: updates.date,
28 seq_start: updates.seq,
29 seq: updates.seq,
30 }
31}
32
33pub(super) fn update_short(short: tl::types::UpdateShort) -> tl::types::UpdatesCombined {
34 tl::types::UpdatesCombined {
35 updates: vec![short.update],
36 users: Vec::new(),
37 chats: Vec::new(),
38 date: short.date,
39 seq_start: NO_SEQ,
40 seq: NO_SEQ,
41 }
42}
43
44pub(super) fn update_short_message(
45 short: tl::types::UpdateShortMessage,
46 self_id: i64,
47) -> tl::types::UpdatesCombined {
48 update_short(tl::types::UpdateShort {
49 update: tl::types::UpdateNewMessage {
50 message: tl::types::Message {
51 out: short.out,
52 mentioned: short.mentioned,
53 media_unread: short.media_unread,
54 silent: short.silent,
55 post: false,
56 from_scheduled: false,
57 legacy: false,
58 edit_hide: false,
59 pinned: false,
60 noforwards: false,
61 invert_media: false,
62 reactions: None,
63 id: short.id,
64 from_id: Some(
65 tl::types::PeerUser {
66 user_id: if short.out { self_id } else { short.user_id },
67 }
68 .into(),
69 ),
70 from_boosts_applied: None,
71 peer_id: tl::types::PeerChat {
72 chat_id: short.user_id,
73 }
74 .into(),
75 saved_peer_id: None,
76 fwd_from: short.fwd_from,
77 via_bot_id: short.via_bot_id,
78 reply_to: short.reply_to,
79 date: short.date,
80 message: short.message,
81 media: None,
82 reply_markup: None,
83 entities: short.entities,
84 views: None,
85 forwards: None,
86 replies: None,
87 edit_date: None,
88 post_author: None,
89 grouped_id: None,
90 restriction_reason: None,
91 ttl_period: short.ttl_period,
92 quick_reply_shortcut_id: None,
93 offline: false,
94 via_business_bot_id: None,
95 effect: None,
96 factcheck: None,
97 }
98 .into(),
99 pts: short.pts,
100 pts_count: short.pts_count,
101 }
102 .into(),
103 date: short.date,
104 })
105}
106
107pub(super) fn update_short_chat_message(
108 short: tl::types::UpdateShortChatMessage,
109) -> tl::types::UpdatesCombined {
110 update_short(tl::types::UpdateShort {
111 update: tl::types::UpdateNewMessage {
112 message: tl::types::Message {
113 out: short.out,
114 mentioned: short.mentioned,
115 media_unread: short.media_unread,
116 silent: short.silent,
117 post: false,
118 from_scheduled: false,
119 legacy: false,
120 edit_hide: false,
121 pinned: false,
122 noforwards: false,
123 invert_media: false,
124 reactions: None,
125 id: short.id,
126 from_id: Some(
127 tl::types::PeerUser {
128 user_id: short.from_id,
129 }
130 .into(),
131 ),
132 from_boosts_applied: None,
133 peer_id: tl::types::PeerChat {
134 chat_id: short.chat_id,
135 }
136 .into(),
137 saved_peer_id: None,
138 fwd_from: short.fwd_from,
139 via_bot_id: short.via_bot_id,
140 reply_to: short.reply_to,
141 date: short.date,
142 message: short.message,
143 media: None,
144 reply_markup: None,
145 entities: short.entities,
146 views: None,
147 forwards: None,
148 replies: None,
149 edit_date: None,
150 post_author: None,
151 grouped_id: None,
152 restriction_reason: None,
153 ttl_period: short.ttl_period,
154 quick_reply_shortcut_id: None,
155 offline: false,
156 via_business_bot_id: None,
157 effect: None,
158 factcheck: None,
159 }
160 .into(),
161 pts: short.pts,
162 pts_count: short.pts_count,
163 }
164 .into(),
165 date: short.date,
166 })
167}
168
169pub(super) fn update_short_sent_message(
170 short: tl::types::UpdateShortSentMessage,
171) -> tl::types::UpdatesCombined {
172 update_short(tl::types::UpdateShort {
173 update: tl::types::UpdateNewMessage {
174 message: tl::types::MessageEmpty {
175 id: short.id,
176 peer_id: None,
177 }
178 .into(),
179 pts: short.pts,
180 pts_count: short.pts_count,
181 }
182 .into(),
183 date: short.date,
184 })
185}
186
187pub(super) fn adapt(
188 updates: tl::enums::Updates,
189 chat_hashes: &ChatHashCache,
190) -> Result<tl::types::UpdatesCombined, Gap> {
191 Ok(match updates {
192 tl::enums::Updates::TooLong => {
195 info!("received updatesTooLong, treating as gap");
196 return Err(Gap);
197 }
198 tl::enums::Updates::UpdateShortMessage(short) => {
201 update_short_message(short, chat_hashes.self_id())
211 }
212 tl::enums::Updates::UpdateShortChatMessage(short) => {
213 update_short_chat_message(short)
216 }
217 tl::enums::Updates::UpdateShort(short) => update_short(short),
224 tl::enums::Updates::Combined(combined) => combined,
228 tl::enums::Updates::Updates(updates) => self::updates(updates),
231 tl::enums::Updates::UpdateShortSentMessage(short) => update_short_sent_message(short),
234 })
235}
236
237fn message_peer(message: &tl::enums::Message) -> Option<tl::enums::Peer> {
238 match message {
239 tl::enums::Message::Empty(_) => None,
240 tl::enums::Message::Message(m) => Some(m.peer_id.clone()),
241 tl::enums::Message::Service(m) => Some(m.peer_id.clone()),
242 }
243}
244
245fn message_channel_id(message: &tl::enums::Message) -> Option<i64> {
246 match message {
247 tl::enums::Message::Empty(_) => None,
248 tl::enums::Message::Message(m) => match &m.peer_id {
249 tl::enums::Peer::Channel(c) => Some(c.channel_id),
250 _ => None,
251 },
252 tl::enums::Message::Service(m) => match &m.peer_id {
253 tl::enums::Peer::Channel(c) => Some(c.channel_id),
254 _ => None,
255 },
256 }
257}
258
259impl PtsInfo {
260 pub(super) fn from_update(update: &tl::enums::Update) -> Option<Self> {
261 use tl::enums::Update::*;
262 match update {
263 NewMessage(u) => {
264 assert!(!matches!(
265 message_peer(&u.message),
266 Some(tl::enums::Peer::Channel(_))
267 ));
268 Some(Self {
269 pts: u.pts,
270 pts_count: u.pts_count,
271 entry: Entry::AccountWide,
272 })
273 }
274 MessageId(_) => None,
275 DeleteMessages(u) => Some(Self {
276 pts: u.pts,
277 pts_count: u.pts_count,
278 entry: Entry::AccountWide,
279 }),
280 UserTyping(_) => None,
281 ChatUserTyping(_) => None,
282 ChatParticipants(_) => None,
283 UserStatus(_) => None,
284 UserName(_) => None,
285 NewAuthorization(_) => None,
286 NewEncryptedMessage(u) => Some(Self {
287 pts: u.qts,
288 pts_count: 1,
289 entry: Entry::SecretChats,
290 }),
291 EncryptedChatTyping(_) => None,
292 Encryption(_) => None,
293 EncryptedMessagesRead(_) => None,
294 ChatParticipantAdd(_) => None,
295 ChatParticipantDelete(_) => None,
296 DcOptions(_) => None,
297 NotifySettings(_) => None,
298 ServiceNotification(_) => None,
299 Privacy(_) => None,
300 UserPhone(_) => None,
301 ReadHistoryInbox(u) => {
302 assert!(!matches!(u.peer, tl::enums::Peer::Channel(_)));
303 Some(Self {
304 pts: u.pts,
305 pts_count: u.pts_count,
306 entry: Entry::AccountWide,
307 })
308 }
309 ReadHistoryOutbox(u) => {
310 assert!(!matches!(u.peer, tl::enums::Peer::Channel(_)));
311 Some(Self {
312 pts: u.pts,
313 pts_count: u.pts_count,
314 entry: Entry::AccountWide,
315 })
316 }
317 WebPage(u) => Some(Self {
318 pts: u.pts,
319 pts_count: u.pts_count,
320 entry: Entry::AccountWide,
321 }),
322 ReadMessagesContents(u) => Some(Self {
323 pts: u.pts,
324 pts_count: u.pts_count,
325 entry: Entry::AccountWide,
326 }),
327 ChannelTooLong(u) => u.pts.map(|pts| Self {
328 pts,
329 pts_count: 0,
330 entry: Entry::Channel(u.channel_id),
331 }),
332 Channel(_) => None,
333 NewChannelMessage(u) => message_channel_id(&u.message).map(|channel_id| Self {
339 pts: u.pts,
340 pts_count: u.pts_count,
341 entry: Entry::Channel(channel_id),
342 }),
343 ReadChannelInbox(u) => Some(Self {
344 pts: u.pts,
345 pts_count: 0,
346 entry: Entry::Channel(u.channel_id),
347 }),
348 DeleteChannelMessages(u) => Some(Self {
349 pts: u.pts,
350 pts_count: u.pts_count,
351 entry: Entry::Channel(u.channel_id),
352 }),
353 ChannelMessageViews(_) => None,
354 ChatParticipantAdmin(_) => None,
355 NewStickerSet(_) => None,
356 StickerSetsOrder(_) => None,
357 StickerSets(_) => None,
358 SavedGifs => None,
359 BotInlineQuery(_) => None,
360 BotInlineSend(_) => None,
361 EditChannelMessage(u) => message_channel_id(&u.message).map(|channel_id| Self {
362 pts: u.pts,
363 pts_count: u.pts_count,
364 entry: Entry::Channel(channel_id),
365 }),
366 BotCallbackQuery(_) => None,
367 EditMessage(u) => {
368 assert!(!matches!(
369 message_peer(&u.message),
370 Some(tl::enums::Peer::Channel(_))
371 ));
372 Some(Self {
373 pts: u.pts,
374 pts_count: u.pts_count,
375 entry: Entry::AccountWide,
376 })
377 }
378 InlineBotCallbackQuery(_) => None,
379 ReadChannelOutbox(_) => None,
380 DraftMessage(_) => None,
381 ReadFeaturedStickers => None,
382 RecentStickers => None,
383 Config => None,
384 PtsChanged => None,
385 ChannelWebPage(u) => Some(Self {
386 pts: u.pts,
387 pts_count: u.pts_count,
388 entry: Entry::Channel(u.channel_id),
389 }),
390 DialogPinned(_) => None,
391 PinnedDialogs(_) => None,
392 BotWebhookJson(_) => None,
393 BotWebhookJsonquery(_) => None,
394 BotShippingQuery(_) => None,
395 BotPrecheckoutQuery(_) => None,
396 PhoneCall(_) => None,
397 LangPackTooLong(_) => None,
398 LangPack(_) => None,
399 FavedStickers => None,
400 ChannelReadMessagesContents(_) => None,
401 ContactsReset => None,
402 ChannelAvailableMessages(_) => None,
403 DialogUnreadMark(_) => None,
404 MessagePoll(_) => None,
405 ChatDefaultBannedRights(_) => None,
406 FolderPeers(u) => Some(Self {
407 pts: u.pts,
408 pts_count: u.pts_count,
409 entry: Entry::AccountWide,
410 }),
411 PeerSettings(_) => None,
412 PeerLocated(_) => None,
413 NewScheduledMessage(_) => None,
414 DeleteScheduledMessages(_) => None,
415 Theme(_) => None,
416 GeoLiveViewed(_) => None,
417 LoginToken => None,
418 MessagePollVote(_) => None,
419 DialogFilter(_) => None,
420 DialogFilterOrder(_) => None,
421 DialogFilters => None,
422 PhoneCallSignalingData(_) => None,
423 ChannelMessageForwards(_) => None,
424 ReadChannelDiscussionInbox(_) => None,
425 ReadChannelDiscussionOutbox(_) => None,
426 PeerBlocked(_) => None,
427 ChannelUserTyping(_) => None,
428 PinnedMessages(u) => {
429 assert!(!matches!(u.peer, tl::enums::Peer::Channel(_)));
430 Some(Self {
431 pts: u.pts,
432 pts_count: u.pts_count,
433 entry: Entry::AccountWide,
434 })
435 }
436 PinnedChannelMessages(u) => Some(Self {
437 pts: u.pts,
438 pts_count: u.pts_count,
439 entry: Entry::Channel(u.channel_id),
440 }),
441 Chat(_) => None,
442 GroupCallParticipants(_) => None,
443 GroupCall(_) => None,
444 PeerHistoryTtl(_) => None,
445 ChatParticipant(u) => Some(Self {
446 pts: u.qts,
447 pts_count: 1,
448 entry: Entry::SecretChats,
449 }),
450 ChannelParticipant(u) => Some(Self {
451 pts: u.qts,
452 pts_count: 1,
453 entry: Entry::SecretChats,
454 }),
455 BotStopped(u) => Some(Self {
456 pts: u.qts,
457 pts_count: 1,
458 entry: Entry::SecretChats,
459 }),
460 GroupCallConnection(_) => None,
461 BotCommands(_) => None,
462 PendingJoinRequests(_) => None,
463 BotChatInviteRequester(u) => Some(Self {
464 pts: u.qts,
465 pts_count: 1,
466 entry: Entry::SecretChats,
467 }),
468 MessageReactions(_) => None,
469 AttachMenuBots => None,
470 WebViewResultSent(_) => None,
471 BotMenuButton(_) => None,
472 SavedRingtones => None,
473 TranscribedAudio(_) => None,
474 ReadFeaturedEmojiStickers => None,
475 UserEmojiStatus(_) => None,
476 RecentEmojiStatuses => None,
477 RecentReactions => None,
478 MoveStickerSetToTop(_) => None,
479 MessageExtendedMedia(_) => None,
480 ChannelPinnedTopic(_) => None,
481 ChannelPinnedTopics(_) => None,
482 User(_) => None,
483 AutoSaveSettings => None,
484 Story(_) => None,
485 NewStoryReaction(_) => None,
486 ReadStories(_) => None,
487 StoryId(_) => None,
488 StoriesStealthMode(_) => None,
489 SentStoryReaction(_) => None,
490 BotChatBoost(u) => Some(Self {
491 pts: u.qts,
492 pts_count: 1,
493 entry: Entry::SecretChats,
494 }),
495 ChannelViewForumAsMessages(_) => None,
496 PeerWallpaper(_) => None,
497 BotMessageReaction(u) => Some(Self {
498 pts: u.qts,
499 pts_count: 1,
500 entry: Entry::SecretChats,
501 }),
502 BotMessageReactions(u) => Some(Self {
503 pts: u.qts,
504 pts_count: 1,
505 entry: Entry::SecretChats,
506 }),
507 SavedDialogPinned(_) => None,
508 PinnedSavedDialogs(_) => None,
509 SavedReactionTags => None,
510 SmsJob(_) => None,
511 QuickReplies(_) => None,
512 NewQuickReply(_) => None,
513 DeleteQuickReply(_) => None,
514 QuickReplyMessage(_) => None,
515 DeleteQuickReplyMessages(_) => None,
516 BotBusinessConnect(_) => None,
517 BotNewBusinessMessage(u) => Some(Self {
518 pts: u.qts,
519 pts_count: 1,
520 entry: Entry::SecretChats,
521 }),
522 BotEditBusinessMessage(u) => Some(Self {
523 pts: u.qts,
524 pts_count: 1,
525 entry: Entry::SecretChats,
526 }),
527 BotDeleteBusinessMessage(u) => Some(Self {
528 pts: u.qts,
529 pts_count: u.messages.len() as i32,
530 entry: Entry::SecretChats,
531 }),
532 BroadcastRevenueTransactions(_) => None,
533 StarsBalance(_) => None,
534 BusinessBotCallbackQuery(_) => None,
535 StarsRevenueStatus(_) => None,
536 }
537 .filter(|info| info.pts != NO_PTS)
538 }
539}