From ca14dfe7ad2cc704b6c63d54c556a3a17e0aa2fe Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 30 Dec 2021 11:45:38 +0300 Subject: [PATCH 1/6] Update tdweb version to 1.8.0. --- example/web/tdweb/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/web/tdweb/package.json b/example/web/tdweb/package.json index 2894319c5..9b56089a9 100644 --- a/example/web/tdweb/package.json +++ b/example/web/tdweb/package.json @@ -1,6 +1,6 @@ { "name": "tdweb", - "version": "1.7.0", + "version": "1.8.0", "description": "JavaScript interface for TDLib (Telegram library)", "main": "dist/tdweb.js", "repository": { From 20a460aeb33dfb9cb88d853cc48b2d73f163766d Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 28 Dec 2021 17:19:18 +0300 Subject: [PATCH 2/6] Update layer to 136. --- td/generate/scheme/telegram_api.tl | 38 +++++++++++++++++++------ td/telegram/DialogEventLog.cpp | 2 ++ td/telegram/MessageEntity.cpp | 2 ++ td/telegram/MessagesManager.cpp | 20 ++++++------- td/telegram/SponsoredMessageManager.cpp | 4 +++ td/telegram/UpdatesManager.cpp | 9 ++++-- td/telegram/UpdatesManager.h | 2 ++ td/telegram/Version.h | 2 +- 8 files changed, 57 insertions(+), 22 deletions(-) diff --git a/td/generate/scheme/telegram_api.tl b/td/generate/scheme/telegram_api.tl index 9dec906d2..b869d6a28 100644 --- a/td/generate/scheme/telegram_api.tl +++ b/td/generate/scheme/telegram_api.tl @@ -118,8 +118,8 @@ chatForbidden#6592a1a7 id:long title:string = Chat; channel#8261ac61 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat; channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat; -chatFull#46a6ffb4 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector = ChatFull; -channelFull#56662e2e flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector default_send_as:flags.29?Peer = ChatFull; +chatFull#d18ee226 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector available_reactions:flags.18?Vector = ChatFull; +channelFull#e13c3d20 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector default_send_as:flags.29?Peer available_reactions:flags.30?Vector = ChatFull; chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant; chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant; @@ -132,7 +132,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto; chatPhoto#1c6e1c11 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = ChatPhoto; messageEmpty#90a6ca84 flags:# id:int peer_id:flags.0?Peer = Message; -message#85d6cbe2 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true id:int from_id:flags.8?Peer peer_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long restriction_reason:flags.22?Vector ttl_period:flags.25?int = Message; +message#38116ee0 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true id:int from_id:flags.8?Peer peer_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long reactions:flags.20?MessageReactions restriction_reason:flags.22?Vector ttl_period:flags.25?int = Message; messageService#2b085862 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?Peer peer_id:Peer reply_to:flags.3?MessageReplyHeader date:int action:MessageAction ttl_period:flags.25?int = Message; messageMediaEmpty#3ded6320 = MessageMedia; @@ -371,6 +371,7 @@ updateGroupCallConnection#b783982 flags:# presentation:flags.0?true params:DataJ updateBotCommands#4d712f2e peer:Peer bot_id:long commands:Vector = Update; updatePendingJoinRequests#7063c3db peer:Peer requests_pending:int recent_requesters:Vector = Update; updateBotChatInviteRequester#11dfa986 peer:Peer date:int user_id:long about:string invite:ExportedChatInvite qts:int = Update; +updateMessageReactions#154798c3 peer:Peer msg_id:int reactions:MessageReactions = Update; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; @@ -604,6 +605,7 @@ messageEntityUnderline#9c4e7e8b offset:int length:int = MessageEntity; messageEntityStrike#bf0693d4 offset:int length:int = MessageEntity; messageEntityBlockquote#20df5d0 offset:int length:int = MessageEntity; messageEntityBankCard#761e6af4 offset:int length:int = MessageEntity; +messageEntitySpoiler#32ca960f offset:int length:int = MessageEntity; inputChannelEmpty#ee8c1e86 = InputChannel; inputChannel#f35aec28 channel_id:long access_hash:long = InputChannel; @@ -909,6 +911,7 @@ channelAdminLogEventActionChangeHistoryTTL#6e941a38 prev_value:int new_value:int channelAdminLogEventActionParticipantJoinByRequest#afb6144a invite:ExportedChatInvite approved_by:long = ChannelAdminLogEventAction; channelAdminLogEventActionToggleNoForwards#cb2ac766 new_value:Bool = ChannelAdminLogEventAction; channelAdminLogEventActionSendMessage#278f2868 message:Message = ChannelAdminLogEventAction; +channelAdminLogEventActionChangeAvailableReactions#9cf7f76a prev_value:Vector new_value:Vector = ChannelAdminLogEventAction; channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent; @@ -1272,7 +1275,7 @@ account.resetPasswordFailedWait#e3779861 retry_date:int = account.ResetPasswordR account.resetPasswordRequestedWait#e9effc7d until_date:int = account.ResetPasswordResult; account.resetPasswordOk#e926d63e = account.ResetPasswordResult; -sponsoredMessage#d151e19a flags:# random_id:bytes from_id:Peer channel_post:flags.2?int start_param:flags.0?string message:string entities:flags.1?Vector = SponsoredMessage; +sponsoredMessage#3a836df8 flags:# random_id:bytes from_id:flags.3?Peer chat_invite:flags.4?ChatInvite chat_invite_hash:flags.4?string channel_post:flags.2?int start_param:flags.0?string message:string entities:flags.1?Vector = SponsoredMessage; messages.sponsoredMessages#65a4c7d5 messages:Vector chats:Vector users:Vector = messages.SponsoredMessages; @@ -1292,6 +1295,19 @@ messages.peerSettings#6880b94d settings:PeerSettings chats:Vector users:Ve auth.loggedOut#c3a2835f flags:# future_auth_token:flags.0?bytes = auth.LoggedOut; +reactionCount#6fb250d1 flags:# chosen:flags.0?true reaction:string count:int = ReactionCount; + +messageReactions#87b6e36 flags:# min:flags.0?true can_see_list:flags.2?true results:Vector recent_reactons:flags.1?Vector = MessageReactions; + +messageUserReaction#932844fa user_id:long reaction:string = MessageUserReaction; + +messages.messageReactionsList#a366923c flags:# count:int reactions:Vector users:Vector next_offset:flags.0?string = messages.MessageReactionsList; + +availableReaction#21d7c4b flags:# inactive:flags.0?true reaction:string title:string static_icon:Document appear_animation:Document select_animation:Document activate_animation:Document effect_animation:Document = AvailableReaction; + +messages.availableReactionsNotModified#9f071957 = messages.AvailableReactions; +messages.availableReactions#768e3aad hash:int reactions:Vector = messages.AvailableReactions; + ---functions--- invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; @@ -1430,9 +1446,9 @@ messages.deleteHistory#b08f922a flags:# just_clear:flags.0?true revoke:flags.1?t messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector = messages.AffectedMessages; messages.receivedMessages#5a954c0 max_id:int = Vector; messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool; -messages.sendMessage#d9d75a4 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; -messages.sendMedia#e25ff8e0 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; -messages.forwardMessages#cc30290b flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true from_peer:InputPeer id:Vector random_id:Vector to_peer:InputPeer schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; +messages.sendMessage#d9d75a4 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; +messages.sendMedia#e25ff8e0 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; +messages.forwardMessages#cc30290b flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true from_peer:InputPeer id:Vector random_id:Vector to_peer:InputPeer schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; messages.reportSpam#cf1592db peer:InputPeer = Bool; messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings; messages.report#8953ab4e peer:InputPeer id:Vector reason:ReportReason message:string = Bool; @@ -1511,7 +1527,7 @@ messages.faveSticker#b9ffc55b id:InputDocument unfave:Bool = Bool; messages.getUnreadMentions#46578472 peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages; messages.readMentions#f0189d3 peer:InputPeer = messages.AffectedHistory; messages.getRecentLocations#702a40e0 peer:InputPeer limit:int hash:long = messages.Messages; -messages.sendMultiMedia#f803138f flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; +messages.sendMultiMedia#f803138f flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; messages.uploadEncryptedFile#5057c497 peer:InputEncryptedChat file:InputEncryptedFile = EncryptedFile; messages.searchStickerSets#35705b8a flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets; messages.getSplitRanges#1cff7e08 = Vector; @@ -1570,6 +1586,12 @@ messages.hideChatJoinRequest#7fe7e815 flags:# approved:flags.0?true peer:InputPe messages.hideAllChatJoinRequests#e085f4ea flags:# approved:flags.0?true peer:InputPeer link:flags.1?string = Updates; messages.toggleNoForwards#b11eafa2 peer:InputPeer enabled:Bool = Updates; messages.saveDefaultSendAs#ccfddf96 peer:InputPeer send_as:InputPeer = Bool; +messages.sendReaction#25690ce4 flags:# peer:InputPeer msg_id:int reaction:flags.0?string = Updates; +messages.getMessagesReactions#8bba90e6 peer:InputPeer id:Vector = Updates; +messages.getMessageReactionsList#e0ee6b77 flags:# peer:InputPeer id:int reaction:flags.0?string offset:flags.1?string limit:int = messages.MessageReactionsList; +messages.setChatAvailableReactions#14050ea6 peer:InputPeer available_reactions:Vector = Updates; +messages.getAvailableReactions#18dea0ac hash:int = messages.AvailableReactions; +messages.setDefaultReaction#d960c4d4 reaction:string = Bool; updates.getState#edd4882a = updates.State; updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference; diff --git a/td/telegram/DialogEventLog.cpp b/td/telegram/DialogEventLog.cpp index 26cf9b4cc..d6d322212 100644 --- a/td/telegram/DialogEventLog.cpp +++ b/td/telegram/DialogEventLog.cpp @@ -340,6 +340,8 @@ static td_api::object_ptr get_chat_event_action_object( auto action = move_tl_object_as(action_ptr); return td_api::make_object(action->new_value_); } + case telegram_api::channelAdminLogEventActionChangeAvailableReactions::ID: + return nullptr; default: UNREACHABLE(); return nullptr; diff --git a/td/telegram/MessageEntity.cpp b/td/telegram/MessageEntity.cpp index 9b528c3ba..39e5f04cf 100644 --- a/td/telegram/MessageEntity.cpp +++ b/td/telegram/MessageEntity.cpp @@ -3319,6 +3319,8 @@ vector get_message_entities(const ContactsManager *contacts_manag entities.emplace_back(MessageEntity::Type::Strikethrough, entity->offset_, entity->length_); break; } + case telegram_api::messageEntitySpoiler::ID: + break; case telegram_api::messageEntityBlockquote::ID: { auto entity = static_cast(server_entity.get()); entities.emplace_back(MessageEntity::Type::BlockQuote, entity->offset_, entity->length_); diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 81995d80b..1c406f18a 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -3066,9 +3066,9 @@ class SendMessageActor final : public NetActorOnce { } auto query = G()->net_query_creator().create(telegram_api::messages_sendMessage( - flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, std::move(input_peer), - reply_to_message_id.get_server_message_id().get(), text, random_id, std::move(reply_markup), - std::move(entities), schedule_date, std::move(as_input_peer))); + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + std::move(input_peer), reply_to_message_id.get_server_message_id().get(), text, random_id, + std::move(reply_markup), std::move(entities), schedule_date, std::move(as_input_peer))); if (G()->shared_config().get_option_boolean("use_quick_ack")) { query->quick_ack_promise_ = PromiseCreator::lambda( [random_id](Unit) { @@ -3257,10 +3257,10 @@ class SendMultiMediaActor final : public NetActorOnce { flags |= MessagesManager::SEND_MESSAGE_FLAG_HAS_SEND_AS; } - auto query = G()->net_query_creator().create( - telegram_api::messages_sendMultiMedia(flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, - std::move(input_peer), reply_to_message_id.get_server_message_id().get(), - std::move(input_single_media), schedule_date, std::move(as_input_peer))); + auto query = G()->net_query_creator().create(telegram_api::messages_sendMultiMedia( + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, std::move(input_peer), + reply_to_message_id.get_server_message_id().get(), std::move(input_single_media), schedule_date, + std::move(as_input_peer))); // no quick ack, because file reference errors are very likely to happen query->debug("send to MessagesManager::MultiSequenceDispatcher"); send_closure(td_->messages_manager_->sequence_dispatcher_, &MultiSequenceDispatcher::send_with_callback, @@ -3377,7 +3377,7 @@ class SendMediaActor final : public NetActorOnce { } auto query = G()->net_query_creator().create(telegram_api::messages_sendMedia( - flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, std::move(input_peer), + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, std::move(input_peer), reply_to_message_id.get_server_message_id().get(), std::move(input_media), text, random_id, std::move(reply_markup), std::move(entities), schedule_date, std::move(as_input_peer))); if (G()->shared_config().get_option_boolean("use_quick_ack") && was_uploaded_) { @@ -3756,8 +3756,8 @@ class ForwardMessagesActor final : public NetActorOnce { auto query = G()->net_query_creator().create(telegram_api::messages_forwardMessages( flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, - std::move(from_input_peer), MessagesManager::get_server_message_ids(message_ids), std::move(random_ids), - std::move(to_input_peer), schedule_date, std::move(as_input_peer))); + false /*ignored*/, std::move(from_input_peer), MessagesManager::get_server_message_ids(message_ids), + std::move(random_ids), std::move(to_input_peer), schedule_date, std::move(as_input_peer))); if (G()->shared_config().get_option_boolean("use_quick_ack")) { query->quick_ack_promise_ = PromiseCreator::lambda( [random_ids = random_ids_](Unit) { diff --git a/td/telegram/SponsoredMessageManager.cpp b/td/telegram/SponsoredMessageManager.cpp index 09c92b768..5e52e9c86 100644 --- a/td/telegram/SponsoredMessageManager.cpp +++ b/td/telegram/SponsoredMessageManager.cpp @@ -243,6 +243,10 @@ void SponsoredMessageManager::on_get_dialog_sponsored_messages( td_->contacts_manager_->on_get_chats(std::move(sponsored_messages->chats_), "on_get_dialog_sponsored_messages"); for (auto &sponsored_message : sponsored_messages->messages_) { + if (sponsored_message->from_id_ == nullptr) { + continue; + } + DialogId sponsor_dialog_id(sponsored_message->from_id_); if (!sponsor_dialog_id.is_valid() || !td_->messages_manager_->have_dialog_info_force(sponsor_dialog_id)) { LOG(ERROR) << "Receive unknown sponsor " << sponsor_dialog_id; diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 44eefac95..ad7639f17 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -893,8 +893,8 @@ void UpdatesManager::on_get_updates(tl_object_ptr &&updat false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, update->id_, make_tl_object(from_id), make_tl_object(update->user_id_), std::move(update->fwd_from_), update->via_bot_id_, std::move(update->reply_to_), update->date_, - update->message_, nullptr, nullptr, std::move(update->entities_), 0, 0, nullptr, 0, string(), 0, Auto(), - update->ttl_period_); + update->message_, nullptr, nullptr, std::move(update->entities_), 0, 0, nullptr, 0, string(), 0, nullptr, + Auto(), update->ttl_period_); on_pending_update( make_tl_object(std::move(message), update->pts_, update->pts_count_), 0, std::move(promise), "telegram_api::updatesShortMessage"); @@ -918,7 +918,7 @@ void UpdatesManager::on_get_updates(tl_object_ptr &&updat make_tl_object(update->from_id_), make_tl_object(update->chat_id_), std::move(update->fwd_from_), update->via_bot_id_, std::move(update->reply_to_), update->date_, update->message_, nullptr, nullptr, std::move(update->entities_), - 0, 0, nullptr, 0, string(), 0, Auto(), update->ttl_period_); + 0, 0, nullptr, 0, string(), 0, nullptr, Auto(), update->ttl_period_); on_pending_update( make_tl_object(std::move(message), update->pts_, update->pts_count_), 0, std::move(promise), "telegram_api::updatesShortChatMessage"); @@ -3280,4 +3280,7 @@ void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { +} + } // namespace td diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index 5e7b7ee20..86357f525 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -504,6 +504,8 @@ class UpdatesManager final : public Actor { void on_update(tl_object_ptr update, Promise &&promise); // unsupported updates + + void on_update(tl_object_ptr update, Promise &&promise); }; } // namespace td diff --git a/td/telegram/Version.h b/td/telegram/Version.h index 545040dc8..4350187dd 100644 --- a/td/telegram/Version.h +++ b/td/telegram/Version.h @@ -10,7 +10,7 @@ namespace td { -constexpr int32 MTPROTO_LAYER = 135; +constexpr int32 MTPROTO_LAYER = 136; enum class Version : int32 { Initial, // 0 From ed766a4d2fff6e95759e8b12267b2c517b6f356b Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 28 Dec 2021 18:19:19 +0300 Subject: [PATCH 3/6] Add flag messageSendOptions.protect_content. --- td/generate/scheme/td_api.tl | 3 ++- td/telegram/MessagesManager.cpp | 14 +++++++++++++- td/telegram/MessagesManager.h | 9 +++++++-- td/telegram/cli.cpp | 5 +++-- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index d973c2be5..2b7fb44e2 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1951,8 +1951,9 @@ messageSchedulingStateSendWhenOnline = MessageSchedulingState; //@description Options to be used when a message is sent //@disable_notification Pass true to disable notification for the message //@from_background Pass true if the message is sent from the background +//@protect_content Pass true if the content of the message must be protected from forwarding and saving; for bots only //@scheduling_state Message scheduling state; pass null to send message immediately. Messages sent to a secret chat, live location messages and self-destructing messages can't be scheduled -messageSendOptions disable_notification:Bool from_background:Bool scheduling_state:MessageSchedulingState = MessageSendOptions; +messageSendOptions disable_notification:Bool from_background:Bool protect_content:Bool scheduling_state:MessageSchedulingState = MessageSendOptions; //@description Options to be used when a message content is copied without reference to the original sender. Service messages and messageInvoice can't be copied //@send_copy True, if content of the message needs to be copied without reference to the original sender. Always true if the message is forwarded to a secret chat or is local diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 1c406f18a..77c3389d9 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -23799,6 +23799,7 @@ unique_ptr MessagesManager::create_message_to_send( m->is_channel_post = is_channel_post; m->is_outgoing = is_scheduled || dialog_id != DialogId(my_id); m->from_background = options.from_background; + m->noforwards = options.protect_content; m->view_count = is_channel_post && !is_scheduled ? 1 : 0; m->forward_count = 0; if ([&] { @@ -24433,6 +24434,7 @@ Result MessagesManager::process_message_sen if (options != nullptr) { result.disable_notification = options->disable_notification_; result.from_background = options->from_background_; + result.protect_content = options->protect_content_; TRY_RESULT_ASSIGN(result.schedule_date, get_message_schedule_date(std::move(options->scheduling_state_))); } @@ -24454,6 +24456,10 @@ Result MessagesManager::process_message_sen } } + if (result.protect_content && !td_->auth_manager_->is_bot()) { + result.protect_content = false; + } + return result; } @@ -26581,6 +26587,9 @@ int32 MessagesManager::get_message_flags(const Message *m) { if (m->message_id.is_scheduled()) { flags |= SEND_MESSAGE_FLAG_HAS_SCHEDULE_DATE; } + if (m->noforwards) { + flags |= SEND_MESSAGE_FLAG_NOFORWARDS; + } return flags; } @@ -26890,6 +26899,9 @@ void MessagesManager::do_forward_messages(DialogId to_dialog_id, DialogId from_d if (messages[0]->has_explicit_sender) { flags |= SEND_MESSAGE_FLAG_HAS_SEND_AS; } + if (messages[0]->noforwards) { + flags |= SEND_MESSAGE_FLAG_NOFORWARDS; + } vector random_ids = transform(messages, [this, to_dialog_id](const Message *m) { return begin_send_message(to_dialog_id, m); }); @@ -27399,7 +27411,7 @@ Result> MessagesManager::resend_messages(DialogId dialog_id, v auto need_another_sender = message->send_error_code == 400 && message->send_error_message == CSlice("SEND_AS_PEER_INVALID"); - MessageSendOptions options(message->disable_notification, message->from_background, + MessageSendOptions options(message->disable_notification, message->from_background, message->noforwards, get_message_schedule_date(message.get())); Message *m = get_message_to_send( d, message->top_thread_message_id, diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 2058200e0..f1a1a4521 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -135,6 +135,7 @@ class MessagesManager final : public Actor { static constexpr int32 SEND_MESSAGE_FLAG_HAS_SCHEDULE_DATE = 1 << 10; static constexpr int32 SEND_MESSAGE_FLAG_HAS_MESSAGE = 1 << 11; static constexpr int32 SEND_MESSAGE_FLAG_HAS_SEND_AS = 1 << 13; + static constexpr int32 SEND_MESSAGE_FLAG_NOFORWARDS = 1 << 14; static constexpr int32 ONLINE_MEMBER_COUNT_CACHE_EXPIRE_TIME = 30 * 60; @@ -1651,11 +1652,15 @@ class MessagesManager final : public Actor { struct MessageSendOptions { bool disable_notification = false; bool from_background = false; + bool protect_content = false; int32 schedule_date = 0; MessageSendOptions() = default; - MessageSendOptions(bool disable_notification, bool from_background, int32 schedule_date) - : disable_notification(disable_notification), from_background(from_background), schedule_date(schedule_date) { + MessageSendOptions(bool disable_notification, bool from_background, bool protect_content, int32 schedule_date) + : disable_notification(disable_notification) + , from_background(from_background) + , protect_content(protect_content) + , schedule_date(schedule_date) { } }; diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 5809a5d12..ed0d2c37c 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -1618,14 +1618,15 @@ class CliClient final : public Actor { auto chat = as_chat_id(chat_id); auto id = send_request(td_api::make_object( chat, as_message_thread_id(message_thread_id_), reply_to_message_id, - td_api::make_object(disable_notification, from_background, + td_api::make_object(disable_notification, from_background, true, as_message_scheduling_state(schedule_date_)), nullptr, std::move(input_message_content))); query_id_to_send_message_info_[id].start_time = Time::now(); } td_api::object_ptr default_message_send_options() const { - return td_api::make_object(false, false, as_message_scheduling_state(schedule_date_)); + return td_api::make_object(false, false, false, + as_message_scheduling_state(schedule_date_)); } void send_get_background_url(td_api::object_ptr &&background_type) { From 68539fe8468e296ab4e8c91734aeabc03b3a6ad3 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 28 Dec 2021 20:41:37 +0300 Subject: [PATCH 4/6] Add textEntityTypeSpoiler. --- td/generate/scheme/td_api.tl | 11 +-- td/telegram/MessageEntity.cpp | 88 +++++++++++++++++++---- td/telegram/MessageEntity.h | 1 + test/message_entities.cpp | 130 +++++++++++++++++++++++----------- 4 files changed, 173 insertions(+), 57 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 2b7fb44e2..3582fe5dd 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -73,7 +73,7 @@ textEntity offset:int32 length:int32 type:TextEntityType = TextEntity; textEntities entities:vector = TextEntities; //@description A text with some entities @text The text @entities Entities contained in the text. Entities can be nested, but must not mutually intersect with each other. -//-Pre, Code and PreCode entities can't contain other entities. Bold, Italic, Underline and Strikethrough entities can contain and to be contained in all other entities. All other entities can't contain each other +//-Pre, Code and PreCode entities can't contain other entities. Bold, Italic, Underline, Strikethrough, and Spoiler entities can contain and to be contained in all other entities. All other entities can't contain each other formattedText text:string entities:vector = FormattedText; @@ -1913,6 +1913,9 @@ textEntityTypeUnderline = TextEntityType; //@description A strikethrough text textEntityTypeStrikethrough = TextEntityType; +//@description A spoiler text. Not supported in secret chats +textEntityTypeSpoiler = TextEntityType; + //@description Text that must be formatted as if inside a code HTML tag textEntityTypeCode = TextEntityType; @@ -1964,7 +1967,7 @@ messageCopyOptions send_copy:Bool replace_caption:Bool new_caption:formattedText //@class InputMessageContent @description The content of a message to send -//@description A text message @text Formatted text to be sent; 1-GetOption("message_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Code, Pre, PreCode, TextUrl and MentionName entities are allowed to be specified manually +//@description A text message @text Formatted text to be sent; 1-GetOption("message_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, Code, Pre, PreCode, TextUrl and MentionName entities are allowed to be specified manually //@disable_web_page_preview True, if rich web page previews for URLs in the message text must be disabled @clear_draft True, if a chat message draft must be deleted inputMessageText text:formattedText disable_web_page_preview:Bool clear_draft:Bool = InputMessageContent; @@ -4539,11 +4542,11 @@ editMessageSchedulingState chat_id:int53 message_id:int53 scheduling_state:Messa //@description Returns all entities (mentions, hashtags, cashtags, bot commands, bank card numbers, URLs, and email addresses) contained in the text. Can be called synchronously @text The text in which to look for entites getTextEntities text:string = TextEntities; -//@description Parses Bold, Italic, Underline, Strikethrough, Code, Pre, PreCode, TextUrl and MentionName entities contained in the text. Can be called synchronously @text The text to parse @parse_mode Text parse mode +//@description Parses Bold, Italic, Underline, Strikethrough, Spoiler, Code, Pre, PreCode, TextUrl and MentionName entities contained in the text. Can be called synchronously @text The text to parse @parse_mode Text parse mode parseTextEntities text:string parse_mode:TextParseMode = FormattedText; //@description Parses Markdown entities in a human-friendly format, ignoring markup errors. Can be called synchronously -//@text The text to parse. For example, "__italic__ ~~strikethrough~~ **bold** `code` ```pre``` __[italic__ text_url](telegram.org) __italic**bold italic__bold**" +//@text The text to parse. For example, "__italic__ ~~strikethrough~~ ||spoiler|| **bold** `code` ```pre``` __[italic__ text_url](telegram.org) __italic**bold italic__bold**" parseMarkdown text:formattedText = FormattedText; //@description Replaces text entities with Markdown formatting in a human-friendly format. Entities that can't be represented in Markdown unambiguously are kept as is. Can be called synchronously @text The text diff --git a/td/telegram/MessageEntity.cpp b/td/telegram/MessageEntity.cpp index 39e5f04cf..c27527c1a 100644 --- a/td/telegram/MessageEntity.cpp +++ b/td/telegram/MessageEntity.cpp @@ -29,7 +29,7 @@ namespace td { int MessageEntity::get_type_priority(Type type) { - static const int types[] = {50, 50, 50, 50, 50, 90, 91, 20, 11, 10, 49, 49, 50, 50, 92, 93, 0, 50, 50}; + static const int types[] = {50, 50, 50, 50, 50, 90, 91, 20, 11, 10, 49, 49, 50, 50, 92, 93, 0, 50, 50, 94}; static_assert(sizeof(types) / sizeof(types[0]) == static_cast(MessageEntity::Type::Size), ""); return types[static_cast(type)]; } @@ -74,6 +74,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, const MessageEntity::Ty return string_builder << "BankCardNumber"; case MessageEntity::Type::MediaTimestamp: return string_builder << "MediaTimestamp"; + case MessageEntity::Type::Spoiler: + return string_builder << "Spoiler"; default: UNREACHABLE(); return string_builder << "Impossible"; @@ -137,6 +139,8 @@ tl_object_ptr MessageEntity::get_text_entity_type_object return make_tl_object(); case MessageEntity::Type::MediaTimestamp: return make_tl_object(media_timestamp); + case MessageEntity::Type::Spoiler: + return make_tl_object(); default: UNREACHABLE(); return nullptr; @@ -1395,7 +1399,7 @@ static constexpr int32 get_entity_type_mask(MessageEntity::Type type) { static constexpr int32 get_splittable_entities_mask() { return get_entity_type_mask(MessageEntity::Type::Bold) | get_entity_type_mask(MessageEntity::Type::Italic) | get_entity_type_mask(MessageEntity::Type::Underline) | - get_entity_type_mask(MessageEntity::Type::Strikethrough); + get_entity_type_mask(MessageEntity::Type::Strikethrough) | get_entity_type_mask(MessageEntity::Type::Spoiler); } static constexpr int32 get_blockquote_entities_mask() { @@ -1449,15 +1453,18 @@ static int32 is_hidden_data_entity(MessageEntity::Type type) { get_pre_entities_mask())) != 0; } -static constexpr size_t SPLITTABLE_ENTITY_TYPE_COUNT = 4; +static constexpr size_t SPLITTABLE_ENTITY_TYPE_COUNT = 5; static size_t get_splittable_entity_type_index(MessageEntity::Type type) { if (static_cast(type) <= static_cast(MessageEntity::Type::Bold) + 1) { // Bold or Italic return static_cast(type) - static_cast(MessageEntity::Type::Bold); - } else { + } else if (static_cast(type) <= static_cast(MessageEntity::Type::Underline) + 1) { // Underline or Strikethrough return static_cast(type) - static_cast(MessageEntity::Type::Underline) + 2; + } else { + CHECK(type == MessageEntity::Type::Spoiler); + return 4; } } @@ -1765,6 +1772,8 @@ string get_first_url(Slice text, const vector &entities) { break; case MessageEntity::Type::MediaTimestamp: break; + case MessageEntity::Type::Spoiler: + break; default: UNREACHABLE(); } @@ -1963,6 +1972,8 @@ static Result> do_parse_markdown_v2(CSlice text, string &r return c == '_' && text[i + 1] == '_'; case MessageEntity::Type::Strikethrough: return c == '~'; + case MessageEntity::Type::Spoiler: + return c == '|' && text[i + 1] == '|'; default: UNREACHABLE(); return false; @@ -1990,6 +2001,15 @@ static Result> do_parse_markdown_v2(CSlice text, string &r case '~': type = MessageEntity::Type::Strikethrough; break; + case '|': + if (text[i + 1] == '|') { + i++; + type = MessageEntity::Type::Spoiler; + } else { + return Status::Error(400, PSLICE() << "Character '" << text[i] + << "' is reserved and must be escaped with the preceding '\\'"); + } + break; case '[': type = MessageEntity::Type::TextUrl; break; @@ -2038,6 +2058,7 @@ static Result> do_parse_markdown_v2(CSlice text, string &r case MessageEntity::Type::Strikethrough: break; case MessageEntity::Type::Underline: + case MessageEntity::Type::Spoiler: i++; break; case MessageEntity::Type::Pre: @@ -2364,14 +2385,28 @@ static vector find_splittable_entities_v3(Slice text, const vecto if (is_utf8_character_first_code_unit(c)) { utf16_offset += 1 + (c >= 0xf0); // >= 4 bytes in symbol => surrogate pair } - if ((c == '_' || c == '*' || c == '~') && text[i] == text[i + 1] && unallowed_boundaries.count(utf16_offset) == 0) { + if ((c == '_' || c == '*' || c == '~' || c == '|') && text[i] == text[i + 1] && + unallowed_boundaries.count(utf16_offset) == 0) { auto j = i + 2; while (j != text.size() && text[j] == text[i] && unallowed_boundaries.count(utf16_offset + j - i - 1) == 0) { j++; } if (j == i + 2) { - auto type = c == '_' ? MessageEntity::Type::Italic - : (c == '*' ? MessageEntity::Type::Bold : MessageEntity::Type::Strikethrough); + auto type = [c] { + switch (c) { + case '_': + return MessageEntity::Type::Italic; + case '*': + return MessageEntity::Type::Bold; + case '~': + return MessageEntity::Type::Strikethrough; + case '|': + return MessageEntity::Type::Spoiler; + default: + UNREACHABLE(); + return MessageEntity::Type::Size; + } + }(); auto index = get_splittable_entity_type_index(type); if (splittable_entity_offset[index] != 0) { auto length = utf16_offset - splittable_entity_offset[index] - 1; @@ -2391,7 +2426,7 @@ static vector find_splittable_entities_v3(Slice text, const vecto } // entities must be valid and can contain only splittable and continuous entities -// __italic__ ~~strikethrough~~ **bold** and [text_url](telegram.org) entities are left to be parsed +// __italic__ ~~strikethrough~~ **bold** ||spoiler|| and [text_url](telegram.org) entities are left to be parsed static FormattedText parse_markdown_v3_without_pre(Slice text, vector entities) { check_is_sorted(entities); @@ -2405,7 +2440,7 @@ static FormattedText parse_markdown_v3_without_pre(Slice text, vectorargument; @@ -2757,6 +2796,10 @@ FormattedText get_markdown_v3(FormattedText text) { result.text += "~~"; utf16_added += 2; break; + case MessageEntity::Type::Spoiler: + result.text += "||"; + utf16_added += 2; + break; case MessageEntity::Type::TextUrl: result.text += '['; utf16_added++; @@ -2895,7 +2938,7 @@ static Result> do_parse_html(CSlice text, string &result) string tag_name = to_lower(text.substr(begin_pos + 1, i - begin_pos - 1)); if (tag_name != "a" && tag_name != "b" && tag_name != "strong" && tag_name != "i" && tag_name != "em" && tag_name != "s" && tag_name != "strike" && tag_name != "del" && tag_name != "u" && tag_name != "ins" && - tag_name != "pre" && tag_name != "code") { + tag_name != "span" && tag_name != "pre" && tag_name != "code") { return Status::Error(400, PSLICE() << "Unsupported start tag \"" << tag_name << "\" at byte offset " << begin_pos); } @@ -2971,9 +3014,16 @@ static Result> do_parse_html(CSlice text, string &result) } else if (tag_name == "code" && attribute_name == Slice("class") && begins_with(attribute_value, "language-")) { argument = attribute_value.substr(9); + } else if (tag_name == "span" && attribute_name == Slice("class") && begins_with(attribute_value, "tg-")) { + argument = attribute_value.substr(3); } } + if (tag_name == "span" && argument != "spoiler") { + return Status::Error(400, PSLICE() + << "Tag \"span\" must have class \"tg-spoiler\" at byte offset " << begin_pos); + } + nested_entities.emplace_back(std::move(tag_name), std::move(argument), utf16_offset, result.size()); } else { // end of an entity @@ -3009,6 +3059,9 @@ static Result> do_parse_html(CSlice text, string &result) entities.emplace_back(MessageEntity::Type::Strikethrough, entity_offset, entity_length); } else if (tag_name == "u" || tag_name == "ins") { entities.emplace_back(MessageEntity::Type::Underline, entity_offset, entity_length); + } else if (tag_name == "span") { + CHECK(nested_entities.back().argument == "spoiler"); + entities.emplace_back(MessageEntity::Type::Spoiler, entity_offset, entity_length); } else if (tag_name == "a") { auto url = std::move(nested_entities.back().argument); if (url.empty()) { @@ -3139,6 +3192,8 @@ vector> get_input_secret_message_entiti break; case MessageEntity::Type::MediaTimestamp: break; + case MessageEntity::Type::Spoiler: + break; default: UNREACHABLE(); } @@ -3239,6 +3294,9 @@ Result> get_message_entities(const ContactsManager *contac entities.emplace_back(MessageEntity::Type::MediaTimestamp, offset, length, entity->media_timestamp_); break; } + case td_api::textEntityTypeSpoiler::ID: + entities.emplace_back(MessageEntity::Type::Spoiler, offset, length); + break; default: UNREACHABLE(); } @@ -3319,8 +3377,11 @@ vector get_message_entities(const ContactsManager *contacts_manag entities.emplace_back(MessageEntity::Type::Strikethrough, entity->offset_, entity->length_); break; } - case telegram_api::messageEntitySpoiler::ID: + case telegram_api::messageEntitySpoiler::ID: { + auto entity = static_cast(server_entity.get()); + entities.emplace_back(MessageEntity::Type::Spoiler, entity->offset_, entity->length_); break; + } case telegram_api::messageEntityBlockquote::ID: { auto entity = static_cast(server_entity.get()); entities.emplace_back(MessageEntity::Type::BlockQuote, entity->offset_, entity->length_); @@ -3736,7 +3797,7 @@ static void split_entities(vector &entities, const vector> get_input_message_entities(co case MessageEntity::Type::Strikethrough: result.push_back(make_tl_object(entity.offset, entity.length)); break; + case MessageEntity::Type::Spoiler: + result.push_back(make_tl_object(entity.offset, entity.length)); + break; default: UNREACHABLE(); } diff --git a/td/telegram/MessageEntity.h b/td/telegram/MessageEntity.h index 9d5944394..adacd831c 100644 --- a/td/telegram/MessageEntity.h +++ b/td/telegram/MessageEntity.h @@ -48,6 +48,7 @@ class MessageEntity { BlockQuote, BankCardNumber, MediaTimestamp, + Spoiler, Size }; Type type = Type::Size; diff --git a/test/message_entities.cpp b/test/message_entities.cpp index de37c75db..ac3006a1a 100644 --- a/test/message_entities.cpp +++ b/test/message_entities.cpp @@ -979,7 +979,7 @@ TEST(MessageEntities, fix_formatted_text) { {td::MessageEntity::Type::Mention, 7, 6}, {td::MessageEntity::Type::Italic, 7, 6}}); - // _a*b*_ + // __a~b~__ check_fix_formatted_text( "ab", {{td::MessageEntity::Type::Underline, 0, 2}, {td::MessageEntity::Type::Strikethrough, 1, 1}}, "ab", {{td::MessageEntity::Type::Underline, 0, 1}, @@ -1007,41 +1007,41 @@ TEST(MessageEntities, fix_formatted_text) { {td::MessageEntity::Type::Underline, 1, 1}, {td::MessageEntity::Type::Strikethrough, 1, 1}}); - // _*a*b_ - check_fix_formatted_text( - "ab", {{td::MessageEntity::Type::Underline, 0, 2}, {td::MessageEntity::Type::Strikethrough, 0, 1}}, "ab", - {{td::MessageEntity::Type::Underline, 0, 2}, {td::MessageEntity::Type::Strikethrough, 0, 1}}); - check_fix_formatted_text( - "ab", - {{td::MessageEntity::Type::Underline, 0, 1}, - {td::MessageEntity::Type::Underline, 1, 1}, - {td::MessageEntity::Type::Strikethrough, 0, 1}}, - "ab", {{td::MessageEntity::Type::Underline, 0, 2}, {td::MessageEntity::Type::Strikethrough, 0, 1}}); + // __||a||b__ + check_fix_formatted_text("ab", {{td::MessageEntity::Type::Underline, 0, 2}, {td::MessageEntity::Type::Spoiler, 0, 1}}, + "ab", + {{td::MessageEntity::Type::Underline, 0, 2}, {td::MessageEntity::Type::Spoiler, 0, 1}}); + check_fix_formatted_text("ab", + {{td::MessageEntity::Type::Underline, 0, 1}, + {td::MessageEntity::Type::Underline, 1, 1}, + {td::MessageEntity::Type::Spoiler, 0, 1}}, + "ab", + {{td::MessageEntity::Type::Underline, 0, 2}, {td::MessageEntity::Type::Spoiler, 0, 1}}); // _*a*_\r_*b*_ check_fix_formatted_text("a\rb", {{td::MessageEntity::Type::Bold, 0, 1}, - {td::MessageEntity::Type::Strikethrough, 0, 1}, + {td::MessageEntity::Type::Italic, 0, 1}, {td::MessageEntity::Type::Bold, 2, 1}, - {td::MessageEntity::Type::Strikethrough, 2, 1}}, - "ab", - {{td::MessageEntity::Type::Bold, 0, 2}, {td::MessageEntity::Type::Strikethrough, 0, 2}}); + {td::MessageEntity::Type::Italic, 2, 1}}, + "ab", {{td::MessageEntity::Type::Bold, 0, 2}, {td::MessageEntity::Type::Italic, 0, 2}}); check_fix_formatted_text("a\nb", {{td::MessageEntity::Type::Bold, 0, 1}, - {td::MessageEntity::Type::Strikethrough, 0, 1}, + {td::MessageEntity::Type::Italic, 0, 1}, {td::MessageEntity::Type::Bold, 2, 1}, - {td::MessageEntity::Type::Strikethrough, 2, 1}}, + {td::MessageEntity::Type::Italic, 2, 1}}, "a\nb", {{td::MessageEntity::Type::Bold, 0, 1}, - {td::MessageEntity::Type::Strikethrough, 0, 1}, + {td::MessageEntity::Type::Italic, 0, 1}, {td::MessageEntity::Type::Bold, 2, 1}, - {td::MessageEntity::Type::Strikethrough, 2, 1}}); + {td::MessageEntity::Type::Italic, 2, 1}}); + + // ||`a`|| + check_fix_formatted_text("a", {{td::MessageEntity::Type::Pre, 0, 1}, {td::MessageEntity::Type::Spoiler, 0, 1}}, "a", + {{td::MessageEntity::Type::Pre, 0, 1}}); + check_fix_formatted_text("a", {{td::MessageEntity::Type::Spoiler, 0, 1}, {td::MessageEntity::Type::Pre, 0, 1}}, "a", + {{td::MessageEntity::Type::Pre, 0, 1}}); - // _`a`_ - check_fix_formatted_text("a", {{td::MessageEntity::Type::Pre, 0, 1}, {td::MessageEntity::Type::Strikethrough, 0, 1}}, - "a", {{td::MessageEntity::Type::Pre, 0, 1}}); - check_fix_formatted_text("a", {{td::MessageEntity::Type::Strikethrough, 0, 1}, {td::MessageEntity::Type::Pre, 0, 1}}, - "a", {{td::MessageEntity::Type::Pre, 0, 1}}); check_fix_formatted_text("abc", {{td::MessageEntity::Type::Pre, 0, 3}, {td::MessageEntity::Type::Strikethrough, 1, 1}}, "abc", {{td::MessageEntity::Type::Pre, 0, 3}}); @@ -1259,6 +1259,14 @@ TEST(MessageEntities, parse_html) { check_parse_html("\t", "\t", {{td::MessageEntity::Type::Italic, 0, 1}}); check_parse_html("\r", "\r", {{td::MessageEntity::Type::Italic, 0, 1}}); check_parse_html("\n", "\n", {{td::MessageEntity::Type::Italic, 0, 1}}); + check_parse_html("➡️ ➡️➡️ ➡️➡️ ➡️", + "➡️ ➡️➡️ ➡️➡️ ➡️", + {{td::MessageEntity::Type::Spoiler, 5, 5}, {td::MessageEntity::Type::Bold, 10, 5}}); + check_parse_html("🏟 🏟🏟 <🏟", "🏟 🏟🏟 <🏟", + {{td::MessageEntity::Type::Spoiler, 5, 6}}); + check_parse_html("🏟 🏟🏟 ><🏟", + "🏟 🏟🏟 ><🏟", + {{td::MessageEntity::Type::Spoiler, 5, 7}, {td::MessageEntity::Type::Bold, 9, 3}}); check_parse_html("\t", "\t", {{td::MessageEntity::Type::TextUrl, 0, 1, "http://telegram.org/"}}); check_parse_html("\r", "\r", @@ -1360,6 +1368,7 @@ TEST(MessageEntities, parse_markdown) { check_parse_markdown("[telegram\\.org](asd", "Can't find end of a URL at byte offset 16"); check_parse_markdown("🏟 🏟__🏟 _🏟___", "Can't find end of Italic entity at byte offset 23"); check_parse_markdown("🏟 🏟__", "Can't find end of Underline entity at byte offset 9"); + check_parse_markdown("🏟 🏟||test\\|", "Can't find end of Spoiler entity at byte offset 9"); check_parse_markdown("", "", {}); check_parse_markdown("\\\\", "\\", {}); @@ -1401,6 +1410,7 @@ TEST(MessageEntities, parse_markdown) { check_parse_markdown("🏟 🏟```🏟 \\\\\\`🏟```", "🏟 🏟 \\`🏟", {{td::MessageEntity::Type::PreCode, 5, 5, "🏟"}}); check_parse_markdown("🏟 🏟**", "🏟 🏟", {}); + check_parse_markdown("||test||", "test", {{td::MessageEntity::Type::Spoiler, 0, 4}}); check_parse_markdown("🏟 🏟``", "🏟 🏟", {}); check_parse_markdown("🏟 🏟``````", "🏟 🏟", {}); check_parse_markdown("🏟 🏟____", "🏟 🏟", {}); @@ -1569,6 +1579,9 @@ TEST(MessageEntities, parse_markdown_v3) { "[text](example.com)", {{td::MessageEntity::Type::Strikethrough, 0, 1}, {td::MessageEntity::Type::Strikethrough, 5, 14}}, "text", {{td::MessageEntity::Type::TextUrl, 0, 4, "http://example.com/"}}); + check_parse_markdown_v3("[text](example.com)", + {{td::MessageEntity::Type::Spoiler, 0, 1}, {td::MessageEntity::Type::Spoiler, 5, 14}}, "text", + {{td::MessageEntity::Type::TextUrl, 0, 4, "http://example.com/"}}); check_parse_markdown_v3("🏟[🏟](t.me) `🏟` [🏟](t.me) `a`", "🏟🏟 🏟 🏟 a", {{td::MessageEntity::Type::TextUrl, 2, 2, "http://t.me/"}, @@ -1580,14 +1593,16 @@ TEST(MessageEntities, parse_markdown_v3) { check_parse_markdown_v3("__\n__", "\n", {{td::MessageEntity::Type::Italic, 0, 1}}); check_parse_markdown_v3("__ __a", " a", {}, true); check_parse_markdown_v3("__\n__a", "\na", {}, true); - check_parse_markdown_v3("**** __a__ **b** ~~c~~", "**** a b c", + check_parse_markdown_v3("**** __a__ **b** ~~c~~ ||d||", "**** a b c d", {{td::MessageEntity::Type::Italic, 5, 1}, {td::MessageEntity::Type::Bold, 7, 1}, - {td::MessageEntity::Type::Strikethrough, 9, 1}}); - check_parse_markdown_v3("тест __аааа__ **бббб** ~~вввв~~", "тест аааа бббб вввв", + {td::MessageEntity::Type::Strikethrough, 9, 1}, + {td::MessageEntity::Type::Spoiler, 11, 1}}); + check_parse_markdown_v3("тест __аааа__ **бббб** ~~вввв~~ ||гггг||", "тест аааа бббб вввв гггг", {{td::MessageEntity::Type::Italic, 5, 4}, {td::MessageEntity::Type::Bold, 10, 4}, - {td::MessageEntity::Type::Strikethrough, 15, 4}}); + {td::MessageEntity::Type::Strikethrough, 15, 4}, + {td::MessageEntity::Type::Spoiler, 20, 4}}); check_parse_markdown_v3("___a___ ***b** ~c~~", "___a___ ***b** ~c~~", {}); check_parse_markdown_v3( "__asd[ab__cd](t.me)", "asdabcd", @@ -1614,6 +1629,18 @@ TEST(MessageEntities, parse_markdown_v3) { check_parse_markdown_v3("__#test__test", {{td::MessageEntity::Type::Strikethrough, 0, 2}}, "#testtest", {{td::MessageEntity::Type::Italic, 0, 5}}); + check_parse_markdown_v3( + "~~**~~||**a||", {{td::MessageEntity::Type::Strikethrough, 2, 1}, {td::MessageEntity::Type::Bold, 6, 1}}, + "**||**a||", {{td::MessageEntity::Type::Strikethrough, 0, 2}, {td::MessageEntity::Type::Bold, 2, 1}}, true); + check_parse_markdown_v3("**||**a||", + {{td::MessageEntity::Type::Strikethrough, 0, 2}, {td::MessageEntity::Type::Bold, 2, 1}}, + "||a||", {{td::MessageEntity::Type::Bold, 0, 2}}, true); + check_parse_markdown_v3("||a||", {{td::MessageEntity::Type::Bold, 0, 2}}, "a", + {{td::MessageEntity::Type::Spoiler, 0, 1}}, true); + check_parse_markdown_v3("~~||~~#test||test", "#testtest", {{td::MessageEntity::Type::Spoiler, 0, 5}}); + check_parse_markdown_v3("||#test||test", {{td::MessageEntity::Type::Strikethrough, 0, 2}}, "#testtest", + {{td::MessageEntity::Type::Spoiler, 0, 5}}); + check_parse_markdown_v3("__[ab_](t.me)_", "__ab__", {{td::MessageEntity::Type::TextUrl, 2, 3, "http://t.me/"}}); check_parse_markdown_v3( "__[ab__](t.me)_", "ab_", @@ -1628,6 +1655,20 @@ TEST(MessageEntities, parse_markdown_v3) { check_parse_markdown_v3("`a` __ab__", {{td::MessageEntity::Type::Underline, 5, 1}}, "a __ab__", {{td::MessageEntity::Type::Code, 0, 1}, {td::MessageEntity::Type::Underline, 3, 1}}); + check_parse_markdown_v3("||[ab|](t.me)|", "||ab||", {{td::MessageEntity::Type::TextUrl, 2, 3, "http://t.me/"}}); + check_parse_markdown_v3( + "||[ab||](t.me)|", "ab|", + {{td::MessageEntity::Type::TextUrl, 0, 2, "http://t.me/"}, {td::MessageEntity::Type::Spoiler, 0, 2}}); + check_parse_markdown_v3("||[||ab||](t.me)||", "||||ab||||", + {{td::MessageEntity::Type::TextUrl, 2, 6, "http://t.me/"}}); + check_parse_markdown_v3( + "||[||ab||](t.me)a||", "||||aba", + {{td::MessageEntity::Type::TextUrl, 2, 4, "http://t.me/"}, {td::MessageEntity::Type::Spoiler, 6, 1}}); + check_parse_markdown_v3("`a` ||ab||", {{td::MessageEntity::Type::Bold, 6, 3}}, "a ||ab||", + {{td::MessageEntity::Type::Code, 0, 1}, {td::MessageEntity::Type::Bold, 4, 3}}); + check_parse_markdown_v3("`a` ||ab||", {{td::MessageEntity::Type::Underline, 5, 1}}, "a ||ab||", + {{td::MessageEntity::Type::Code, 0, 1}, {td::MessageEntity::Type::Underline, 3, 1}}); + check_parse_markdown_v3("`a` @test__test__test", "a @test__test__test", {{td::MessageEntity::Type::Code, 0, 1}}); check_parse_markdown_v3("`a` #test__test__test", "a #test__test__test", {{td::MessageEntity::Type::Code, 0, 1}}); check_parse_markdown_v3("`a` __@test_test_test__", "a @test_test_test", @@ -1652,13 +1693,17 @@ TEST(MessageEntities, parse_markdown_v3) { {{td::MessageEntity::Type::Italic, 0, 6}, {td::MessageEntity::Type::Bold, 2, 6}, {td::MessageEntity::Type::Strikethrough, 4, 6}}); - check_parse_markdown_v3("__ab**cd~~ef__gh**ij~~", "abcdefghij", + check_parse_markdown_v3("__ab**cd~~ef||gh__ij**kl~~mn||", "abcdefghijklmn", {{td::MessageEntity::Type::Italic, 0, 2}, {td::MessageEntity::Type::Bold, 2, 2}, {td::MessageEntity::Type::Italic, 2, 2}, - {td::MessageEntity::Type::Strikethrough, 4, 6}, - {td::MessageEntity::Type::Bold, 4, 4}, - {td::MessageEntity::Type::Italic, 4, 2}}, + {td::MessageEntity::Type::Bold, 4, 2}, + {td::MessageEntity::Type::Italic, 4, 2}, + {td::MessageEntity::Type::Strikethrough, 4, 2}, + {td::MessageEntity::Type::Spoiler, 6, 8}, + {td::MessageEntity::Type::Strikethrough, 6, 6}, + {td::MessageEntity::Type::Bold, 6, 4}, + {td::MessageEntity::Type::Italic, 6, 2}}, true); check_parse_markdown_v3("__ab**[cd~~ef__](t.me)gh**ij~~", "abcdefghij", {{td::MessageEntity::Type::Italic, 0, 6}, @@ -1682,9 +1727,9 @@ TEST(MessageEntities, parse_markdown_v3) { check_parse_markdown_v3( "__italic__ ~~strikethrough~~ **bold** `code` ```pre``` __[italic__ text_url](telegram.org) __italic**bold " "italic__bold**__italic__ ~~strikethrough~~ **bold** `code` ```pre``` __[italic__ text_url](telegram.org) " - "__italic**bold italic__bold**", + "__italic**bold italic__bold** ||spoiler||", "italic strikethrough bold code pre italic text_url italicbold italicbolditalic strikethrough bold code pre " - "italic text_url italicbold italicbold", + "italic text_url italicbold italicbold spoiler", {{td::MessageEntity::Type::Italic, 0, 6}, {td::MessageEntity::Type::Strikethrough, 7, 13}, {td::MessageEntity::Type::Bold, 21, 4}, @@ -1702,14 +1747,15 @@ TEST(MessageEntities, parse_markdown_v3) { {td::MessageEntity::Type::TextUrl, 107, 15, "http://telegram.org/"}, {td::MessageEntity::Type::Italic, 107, 6}, {td::MessageEntity::Type::Italic, 123, 17}, - {td::MessageEntity::Type::Bold, 129, 15}}); + {td::MessageEntity::Type::Bold, 129, 15}, + {td::MessageEntity::Type::Spoiler, 145, 7}}); - td::vector parts{"a", " #test__a", "__", "**", "~~", "[", "](t.me)", "`"}; + td::vector parts{"a", " #test__a", "__", "**", "~~", "||", "[", "](t.me)", "`"}; td::vector types{ td::MessageEntity::Type::Bold, td::MessageEntity::Type::Italic, td::MessageEntity::Type::Underline, - td::MessageEntity::Type::Strikethrough, td::MessageEntity::Type::Code, td::MessageEntity::Type::Pre, - td::MessageEntity::Type::PreCode, td::MessageEntity::Type::TextUrl, td::MessageEntity::Type::MentionName, - td::MessageEntity::Type::Cashtag}; + td::MessageEntity::Type::Strikethrough, td::MessageEntity::Type::Spoiler, td::MessageEntity::Type::Code, + td::MessageEntity::Type::Pre, td::MessageEntity::Type::PreCode, td::MessageEntity::Type::TextUrl, + td::MessageEntity::Type::MentionName, td::MessageEntity::Type::Cashtag}; for (size_t test_n = 0; test_n < 1000; test_n++) { td::string str; int part_n = td::Random::fast(1, 200); @@ -1767,11 +1813,13 @@ TEST(MessageEntities, get_markdown_v3) { check_get_markdown_v3("__ __", {}, " ", {{td::MessageEntity::Type::Italic, 0, 1}}); check_get_markdown_v3("** **", {}, " ", {{td::MessageEntity::Type::Bold, 0, 1}}); check_get_markdown_v3("~~ ~~", {}, " ", {{td::MessageEntity::Type::Strikethrough, 0, 1}}); - check_get_markdown_v3("__a__ **b** ~~c~~ d", {{td::MessageEntity::Type::PreCode, 18, 1, "C++"}}, "a b c d", + check_get_markdown_v3("|| ||", {}, " ", {{td::MessageEntity::Type::Spoiler, 0, 1}}); + check_get_markdown_v3("__a__ **b** ~~c~~ ||d|| e", {{td::MessageEntity::Type::PreCode, 24, 1, "C++"}}, "a b c d e", {{td::MessageEntity::Type::Italic, 0, 1}, {td::MessageEntity::Type::Bold, 2, 1}, {td::MessageEntity::Type::Strikethrough, 4, 1}, - {td::MessageEntity::Type::PreCode, 6, 1, "C++"}}); + {td::MessageEntity::Type::Spoiler, 6, 1}, + {td::MessageEntity::Type::PreCode, 8, 1, "C++"}}); check_get_markdown_v3("`ab` ```cd``` ef", {{td::MessageEntity::Type::PreCode, 14, 2, "C++"}}, "ab cd ef", {{td::MessageEntity::Type::Code, 0, 2}, {td::MessageEntity::Type::Pre, 3, 2}, From fce20df018a8ec23e440637e3557694ab36b44f4 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 30 Dec 2021 14:15:04 +0300 Subject: [PATCH 5/6] Add support for sponsored chats with an invite link. --- td/generate/scheme/td_api.tl | 5 +- td/telegram/LinkManager.cpp | 11 ++++ td/telegram/LinkManager.h | 2 + td/telegram/SponsoredMessageManager.cpp | 68 +++++++++++++++++++------ 4 files changed, 68 insertions(+), 18 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 3582fe5dd..f1bb3f809 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -831,10 +831,11 @@ messageCalendar total_count:int32 days:vector = MessageCalen //@description Describes a sponsored message //@message_id Message identifier; unique for the chat to which the sponsored message belongs among both ordinary and sponsored messages -//@sponsor_chat_id Chat identifier +//@sponsor_chat_id Sponsor chat identifier; 0 if the sponsor chat is accessible through an invite link +//@sponsor_chat_info Information about the sponsor chat; may be null unless sponsor_chat_id == 0 //@link An internal link to be opened when the sponsored message is clicked; may be null. If null, the sponsor chat needs to be opened instead //@content Content of the message. Currently, can be only of the type messageText -sponsoredMessage message_id:int53 sponsor_chat_id:int53 link:InternalLinkType content:MessageContent = SponsoredMessage; +sponsoredMessage message_id:int53 sponsor_chat_id:int53 sponsor_chat_info:chatInviteLinkInfo link:InternalLinkType content:MessageContent = SponsoredMessage; //@class NotificationSettingsScope @description Describes the types of chats to which notification settings are relevant diff --git a/td/telegram/LinkManager.cpp b/td/telegram/LinkManager.cpp index a4481c77e..1749facc3 100644 --- a/td/telegram/LinkManager.cpp +++ b/td/telegram/LinkManager.cpp @@ -1235,6 +1235,17 @@ string LinkManager::get_dialog_invite_link_hash(Slice invite_link) { return get_url_query_hash(link_info.is_tg_, url_query); } +string LinkManager::get_dialog_invite_link(Slice hash, bool is_internal) { + if (!is_base64url_characters(hash)) { + return string(); + } + if (is_internal) { + return PSTRING() << "tg:join?invite=" << hash; + } else { + return PSTRING() << G()->shared_config().get_option_string("t_me_url", "https://t.me/") << '+' << hash; + } +} + UserId LinkManager::get_link_user_id(Slice url) { string lower_cased_url = to_lower(url); url = lower_cased_url; diff --git a/td/telegram/LinkManager.h b/td/telegram/LinkManager.h index 2bc65a72b..6749ad3af 100644 --- a/td/telegram/LinkManager.h +++ b/td/telegram/LinkManager.h @@ -70,6 +70,8 @@ class LinkManager final : public Actor { static string get_dialog_invite_link_hash(Slice invite_link); + static string get_dialog_invite_link(Slice hash, bool is_internal); + static UserId get_link_user_id(Slice url); static Result get_message_link_info(Slice url); diff --git a/td/telegram/SponsoredMessageManager.cpp b/td/telegram/SponsoredMessageManager.cpp index 5e52e9c86..930b47ef9 100644 --- a/td/telegram/SponsoredMessageManager.cpp +++ b/td/telegram/SponsoredMessageManager.cpp @@ -10,6 +10,7 @@ #include "td/telegram/ConfigShared.h" #include "td/telegram/ContactsManager.h" #include "td/telegram/Global.h" +#include "td/telegram/LinkManager.h" #include "td/telegram/MessageContent.h" #include "td/telegram/MessageEntity.h" #include "td/telegram/MessagesManager.h" @@ -94,15 +95,17 @@ struct SponsoredMessageManager::SponsoredMessage { DialogId sponsor_dialog_id; ServerMessageId server_message_id; string start_param; + string invite_hash; unique_ptr content; SponsoredMessage() = default; SponsoredMessage(int64 local_id, DialogId sponsor_dialog_id, ServerMessageId server_message_id, string start_param, - unique_ptr content) + string invite_hash, unique_ptr content) : local_id(local_id) , sponsor_dialog_id(sponsor_dialog_id) , server_message_id(server_message_id) , start_param(std::move(start_param)) + , invite_hash(std::move(invite_hash)) , content(std::move(content)) { } }; @@ -148,6 +151,7 @@ void SponsoredMessageManager::delete_cached_sponsored_messages(DialogId dialog_i td_api::object_ptr SponsoredMessageManager::get_sponsored_message_object( DialogId dialog_id, const SponsoredMessage &sponsored_message) const { + td_api::object_ptr chat_invite_link_info; td_api::object_ptr link; switch (sponsored_message.sponsor_dialog_id.get_type()) { case DialogType::User: { @@ -170,12 +174,23 @@ td_api::object_ptr SponsoredMessageManager::get_sponso PSTRING() << t_me << "c/" << channel_id.get() << '/' << sponsored_message.server_message_id.get()); } break; + case DialogType::None: { + CHECK(!sponsored_message.invite_hash.empty()); + auto invite_link = LinkManager::get_dialog_invite_link(sponsored_message.invite_hash, false); + chat_invite_link_info = td_->contacts_manager_->get_chat_invite_link_info_object(invite_link); + if (chat_invite_link_info == nullptr) { + LOG(ERROR) << "Failed to get invite link info for " << invite_link; + return nullptr; + } + link = td_api::make_object( + LinkManager::get_dialog_invite_link(sponsored_message.invite_hash, true)); + } default: break; } return td_api::make_object( - sponsored_message.local_id, sponsored_message.sponsor_dialog_id.get(), std::move(link), - get_message_content_object(sponsored_message.content.get(), td_, dialog_id, 0, false, true, -1)); + sponsored_message.local_id, sponsored_message.sponsor_dialog_id.get(), std::move(chat_invite_link_info), + std::move(link), get_message_content_object(sponsored_message.content.get(), td_, dialog_id, 0, false, true, -1)); } td_api::object_ptr SponsoredMessageManager::get_sponsored_message_object( @@ -243,21 +258,41 @@ void SponsoredMessageManager::on_get_dialog_sponsored_messages( td_->contacts_manager_->on_get_chats(std::move(sponsored_messages->chats_), "on_get_dialog_sponsored_messages"); for (auto &sponsored_message : sponsored_messages->messages_) { - if (sponsored_message->from_id_ == nullptr) { + DialogId sponsor_dialog_id; + ServerMessageId server_message_id; + string invite_hash; + if (sponsored_message->from_id_ != nullptr) { + sponsor_dialog_id = DialogId(sponsored_message->from_id_); + if (!sponsor_dialog_id.is_valid() || !td_->messages_manager_->have_dialog_info_force(sponsor_dialog_id)) { + LOG(ERROR) << "Receive unknown sponsor " << sponsor_dialog_id; + continue; + } + server_message_id = ServerMessageId(sponsored_message->channel_post_); + if (!server_message_id.is_valid() && server_message_id != ServerMessageId()) { + LOG(ERROR) << "Receive invalid channel post in " << to_string(sponsored_message); + server_message_id = ServerMessageId(); + } + td_->messages_manager_->force_create_dialog(sponsor_dialog_id, "on_get_dialog_sponsored_messages"); + } else if (sponsored_message->chat_invite_ != nullptr && !sponsored_message->chat_invite_hash_.empty()) { + auto invite_link = LinkManager::get_dialog_invite_link(sponsored_message->chat_invite_hash_, false); + if (invite_link.empty()) { + LOG(ERROR) << "Receive invalid invite link hash in " << to_string(sponsored_message); + continue; + } + auto chat_invite = to_string(sponsored_message->chat_invite_); + td_->contacts_manager_->on_get_dialog_invite_link_info(invite_link, std::move(sponsored_message->chat_invite_), + Promise()); + auto chat_invite_link_info = td_->contacts_manager_->get_chat_invite_link_info_object(invite_link); + if (chat_invite_link_info == nullptr) { + LOG(ERROR) << "Failed to get invite link info from " << chat_invite << " for " << to_string(sponsored_message); + continue; + } + invite_hash = std::move(sponsored_message->chat_invite_hash_); + } else { + LOG(ERROR) << "Receive " << to_string(sponsored_message); continue; } - DialogId sponsor_dialog_id(sponsored_message->from_id_); - if (!sponsor_dialog_id.is_valid() || !td_->messages_manager_->have_dialog_info_force(sponsor_dialog_id)) { - LOG(ERROR) << "Receive unknown sponsor " << sponsor_dialog_id; - continue; - } - auto server_message_id = ServerMessageId(sponsored_message->channel_post_); - if (!server_message_id.is_valid() && server_message_id != ServerMessageId()) { - LOG(ERROR) << "Receive invalid channel post in " << to_string(sponsored_message); - server_message_id = ServerMessageId(); - } - td_->messages_manager_->force_create_dialog(sponsor_dialog_id, "on_get_dialog_sponsored_messages"); auto message_text = get_message_text(td_->contacts_manager_.get(), std::move(sponsored_message->message_), std::move(sponsored_message->entities_), true, true, 0, false, "on_get_dialog_sponsored_messages"); @@ -283,7 +318,8 @@ void SponsoredMessageManager::on_get_dialog_sponsored_messages( CHECK(messages->message_random_ids.count(local_id) == 0); messages->message_random_ids[local_id] = sponsored_message->random_id_.as_slice().str(); messages->messages.emplace_back(local_id, sponsor_dialog_id, server_message_id, - std::move(sponsored_message->start_param_), std::move(content)); + std::move(sponsored_message->start_param_), std::move(invite_hash), + std::move(content)); } for (auto &promise : promises) { From 20278192975d44a139ce50f7581bfbeddafc32e4 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 30 Dec 2021 15:28:10 +0300 Subject: [PATCH 6/6] Fix ContactsManager::get_input_user. --- td/telegram/ContactsManager.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 13cd3c0e0..549bddf1d 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -4366,14 +4366,15 @@ Result> ContactsManager::get_input_user(U } const User *u = get_user(user_id); - if (u == nullptr) { - return Status::Error(400, "User not found"); - } - if (u->access_hash == -1 || u->is_min_access_hash) { + if (u == nullptr || u->access_hash == -1 || u->is_min_access_hash) { if (td_->auth_manager_->is_bot() && user_id.is_valid()) { return make_tl_object(user_id.get(), 0); } - return Status::Error(400, "Have no access to the user"); + if (u == nullptr) { + return Status::Error(400, "User not found"); + } else { + return Status::Error(400, "Have no access to the user"); + } } return make_tl_object(user_id.get(), u->access_hash);