Merge remote-tracking branch 'td/master'
This commit is contained in:
commit
f42cce37a4
@ -136,12 +136,9 @@ if (IOS_DEPLOYMENT_TARGET)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
set (CMAKE_SHARED_LINKER_FLAGS_INIT "-fapplication-extension")
|
set (CMAKE_SHARED_LINKER_FLAGS_INIT "-fapplication-extension")
|
||||||
if (NOT SIMULATOR_FLAG)
|
set (CMAKE_C_FLAGS_INIT "${XCODE_IOS_PLATFORM_VERSION_FLAGS}")
|
||||||
set (BITCODE "-fembed-bitcode")
|
|
||||||
endif()
|
|
||||||
set (CMAKE_C_FLAGS_INIT "${XCODE_IOS_PLATFORM_VERSION_FLAGS} ${BITCODE}")
|
|
||||||
# Hidden visibilty is required for cxx on iOS
|
# Hidden visibilty is required for cxx on iOS
|
||||||
set (CMAKE_CXX_FLAGS_INIT "${XCODE_IOS_PLATFORM_VERSION_FLAGS} ${BITCODE} -fvisibility-inlines-hidden")
|
set (CMAKE_CXX_FLAGS_INIT "${XCODE_IOS_PLATFORM_VERSION_FLAGS} -fvisibility-inlines-hidden")
|
||||||
|
|
||||||
set (CMAKE_C_LINK_FLAGS "${XCODE_IOS_PLATFORM_VERSION_FLAGS} -fapplication-extension -Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}")
|
set (CMAKE_C_LINK_FLAGS "${XCODE_IOS_PLATFORM_VERSION_FLAGS} -fapplication-extension -Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}")
|
||||||
set (CMAKE_CXX_LINK_FLAGS "${XCODE_IOS_PLATFORM_VERSION_FLAGS} -fapplication-extension -Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}")
|
set (CMAKE_CXX_LINK_FLAGS "${XCODE_IOS_PLATFORM_VERSION_FLAGS} -fapplication-extension -Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}")
|
||||||
|
@ -6,7 +6,7 @@ if (POLICY CMP0065)
|
|||||||
cmake_policy(SET CMP0065 NEW)
|
cmake_policy(SET CMP0065 NEW)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
project(TDLib VERSION 1.8.6 LANGUAGES CXX C)
|
project(TDLib VERSION 1.8.8 LANGUAGES CXX C)
|
||||||
|
|
||||||
if (NOT DEFINED CMAKE_MODULE_PATH)
|
if (NOT DEFINED CMAKE_MODULE_PATH)
|
||||||
set(CMAKE_MODULE_PATH "")
|
set(CMAKE_MODULE_PATH "")
|
||||||
@ -324,6 +324,7 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/DialogId.cpp
|
td/telegram/DialogId.cpp
|
||||||
td/telegram/DialogInviteLink.cpp
|
td/telegram/DialogInviteLink.cpp
|
||||||
td/telegram/DialogLocation.cpp
|
td/telegram/DialogLocation.cpp
|
||||||
|
td/telegram/DialogNotificationSettings.cpp
|
||||||
td/telegram/DialogParticipant.cpp
|
td/telegram/DialogParticipant.cpp
|
||||||
td/telegram/DialogParticipantFilter.cpp
|
td/telegram/DialogParticipantFilter.cpp
|
||||||
td/telegram/DialogSource.cpp
|
td/telegram/DialogSource.cpp
|
||||||
@ -355,6 +356,11 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/files/FileUploader.cpp
|
td/telegram/files/FileUploader.cpp
|
||||||
td/telegram/files/PartsManager.cpp
|
td/telegram/files/PartsManager.cpp
|
||||||
td/telegram/files/ResourceManager.cpp
|
td/telegram/files/ResourceManager.cpp
|
||||||
|
td/telegram/ForumTopic.cpp
|
||||||
|
td/telegram/ForumTopicEditedData.cpp
|
||||||
|
td/telegram/ForumTopicIcon.cpp
|
||||||
|
td/telegram/ForumTopicInfo.cpp
|
||||||
|
td/telegram/ForumTopicManager.cpp
|
||||||
td/telegram/Game.cpp
|
td/telegram/Game.cpp
|
||||||
td/telegram/GameManager.cpp
|
td/telegram/GameManager.cpp
|
||||||
td/telegram/Global.cpp
|
td/telegram/Global.cpp
|
||||||
@ -366,6 +372,7 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/InlineQueriesManager.cpp
|
td/telegram/InlineQueriesManager.cpp
|
||||||
td/telegram/InputDialogId.cpp
|
td/telegram/InputDialogId.cpp
|
||||||
td/telegram/InputGroupCallId.cpp
|
td/telegram/InputGroupCallId.cpp
|
||||||
|
td/telegram/InputInvoice.cpp
|
||||||
td/telegram/InputMessageText.cpp
|
td/telegram/InputMessageText.cpp
|
||||||
td/telegram/JsonValue.cpp
|
td/telegram/JsonValue.cpp
|
||||||
td/telegram/LanguagePackManager.cpp
|
td/telegram/LanguagePackManager.cpp
|
||||||
@ -376,8 +383,10 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/MessageContent.cpp
|
td/telegram/MessageContent.cpp
|
||||||
td/telegram/MessageContentType.cpp
|
td/telegram/MessageContentType.cpp
|
||||||
td/telegram/MessageEntity.cpp
|
td/telegram/MessageEntity.cpp
|
||||||
|
td/telegram/MessageExtendedMedia.cpp
|
||||||
td/telegram/MessageId.cpp
|
td/telegram/MessageId.cpp
|
||||||
td/telegram/MessageReaction.cpp
|
td/telegram/MessageReaction.cpp
|
||||||
|
td/telegram/MessageReplyHeader.cpp
|
||||||
td/telegram/MessageReplyInfo.cpp
|
td/telegram/MessageReplyInfo.cpp
|
||||||
td/telegram/MessagesDb.cpp
|
td/telegram/MessagesDb.cpp
|
||||||
td/telegram/MessageSearchFilter.cpp
|
td/telegram/MessageSearchFilter.cpp
|
||||||
@ -405,11 +414,12 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/net/SessionMultiProxy.cpp
|
td/telegram/net/SessionMultiProxy.cpp
|
||||||
td/telegram/NewPasswordState.cpp
|
td/telegram/NewPasswordState.cpp
|
||||||
td/telegram/NotificationManager.cpp
|
td/telegram/NotificationManager.cpp
|
||||||
td/telegram/NotificationSettings.cpp
|
td/telegram/NotificationSettingsScope.cpp
|
||||||
td/telegram/NotificationSettingsManager.cpp
|
td/telegram/NotificationSettingsManager.cpp
|
||||||
td/telegram/NotificationSound.cpp
|
td/telegram/NotificationSound.cpp
|
||||||
td/telegram/NotificationType.cpp
|
td/telegram/NotificationType.cpp
|
||||||
td/telegram/OptionManager.cpp
|
td/telegram/OptionManager.cpp
|
||||||
|
td/telegram/OrderInfo.cpp
|
||||||
td/telegram/Payments.cpp
|
td/telegram/Payments.cpp
|
||||||
td/telegram/PasswordManager.cpp
|
td/telegram/PasswordManager.cpp
|
||||||
td/telegram/PhoneNumberManager.cpp
|
td/telegram/PhoneNumberManager.cpp
|
||||||
@ -425,6 +435,7 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/ReplyMarkup.cpp
|
td/telegram/ReplyMarkup.cpp
|
||||||
td/telegram/ReportReason.cpp
|
td/telegram/ReportReason.cpp
|
||||||
td/telegram/RestrictionReason.cpp
|
td/telegram/RestrictionReason.cpp
|
||||||
|
td/telegram/ScopeNotificationSettings.cpp
|
||||||
td/telegram/SecretChatActor.cpp
|
td/telegram/SecretChatActor.cpp
|
||||||
td/telegram/SecretChatDb.cpp
|
td/telegram/SecretChatDb.cpp
|
||||||
td/telegram/SecretChatsManager.cpp
|
td/telegram/SecretChatsManager.cpp
|
||||||
@ -451,7 +462,9 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/ThemeManager.cpp
|
td/telegram/ThemeManager.cpp
|
||||||
td/telegram/TopDialogCategory.cpp
|
td/telegram/TopDialogCategory.cpp
|
||||||
td/telegram/TopDialogManager.cpp
|
td/telegram/TopDialogManager.cpp
|
||||||
|
td/telegram/TranscriptionInfo.cpp
|
||||||
td/telegram/UpdatesManager.cpp
|
td/telegram/UpdatesManager.cpp
|
||||||
|
td/telegram/Usernames.cpp
|
||||||
td/telegram/Venue.cpp
|
td/telegram/Venue.cpp
|
||||||
td/telegram/VideoNotesManager.cpp
|
td/telegram/VideoNotesManager.cpp
|
||||||
td/telegram/VideosManager.cpp
|
td/telegram/VideosManager.cpp
|
||||||
@ -519,6 +532,7 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/Contact.h
|
td/telegram/Contact.h
|
||||||
td/telegram/ContactsManager.h
|
td/telegram/ContactsManager.h
|
||||||
td/telegram/CountryInfoManager.h
|
td/telegram/CountryInfoManager.h
|
||||||
|
td/telegram/CustomEmojiId.h
|
||||||
td/telegram/DelayDispatcher.h
|
td/telegram/DelayDispatcher.h
|
||||||
td/telegram/Dependencies.h
|
td/telegram/Dependencies.h
|
||||||
td/telegram/DeviceTokenManager.h
|
td/telegram/DeviceTokenManager.h
|
||||||
@ -536,6 +550,7 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/DialogInviteLink.h
|
td/telegram/DialogInviteLink.h
|
||||||
td/telegram/DialogListId.h
|
td/telegram/DialogListId.h
|
||||||
td/telegram/DialogLocation.h
|
td/telegram/DialogLocation.h
|
||||||
|
td/telegram/DialogNotificationSettings.h
|
||||||
td/telegram/DialogParticipant.h
|
td/telegram/DialogParticipant.h
|
||||||
td/telegram/DialogParticipantFilter.h
|
td/telegram/DialogParticipantFilter.h
|
||||||
td/telegram/DialogSource.h
|
td/telegram/DialogSource.h
|
||||||
@ -576,6 +591,11 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/files/ResourceManager.h
|
td/telegram/files/ResourceManager.h
|
||||||
td/telegram/files/ResourceState.h
|
td/telegram/files/ResourceState.h
|
||||||
td/telegram/FolderId.h
|
td/telegram/FolderId.h
|
||||||
|
td/telegram/ForumTopic.h
|
||||||
|
td/telegram/ForumTopicEditedData.h
|
||||||
|
td/telegram/ForumTopicIcon.h
|
||||||
|
td/telegram/ForumTopicInfo.h
|
||||||
|
td/telegram/ForumTopicManager.h
|
||||||
td/telegram/FullMessageId.h
|
td/telegram/FullMessageId.h
|
||||||
td/telegram/Game.h
|
td/telegram/Game.h
|
||||||
td/telegram/GameManager.h
|
td/telegram/GameManager.h
|
||||||
@ -590,8 +610,10 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/InlineQueriesManager.h
|
td/telegram/InlineQueriesManager.h
|
||||||
td/telegram/InputDialogId.h
|
td/telegram/InputDialogId.h
|
||||||
td/telegram/InputGroupCallId.h
|
td/telegram/InputGroupCallId.h
|
||||||
|
td/telegram/InputInvoice.h
|
||||||
td/telegram/InputMessageText.h
|
td/telegram/InputMessageText.h
|
||||||
td/telegram/JsonValue.h
|
td/telegram/JsonValue.h
|
||||||
|
td/telegram/LabeledPricePart.h
|
||||||
td/telegram/LanguagePackManager.h
|
td/telegram/LanguagePackManager.h
|
||||||
td/telegram/LinkManager.h
|
td/telegram/LinkManager.h
|
||||||
td/telegram/Location.h
|
td/telegram/Location.h
|
||||||
@ -603,9 +625,11 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/MessageContentType.h
|
td/telegram/MessageContentType.h
|
||||||
td/telegram/MessageCopyOptions.h
|
td/telegram/MessageCopyOptions.h
|
||||||
td/telegram/MessageEntity.h
|
td/telegram/MessageEntity.h
|
||||||
|
td/telegram/MessageExtendedMedia.h
|
||||||
td/telegram/MessageId.h
|
td/telegram/MessageId.h
|
||||||
td/telegram/MessageLinkInfo.h
|
td/telegram/MessageLinkInfo.h
|
||||||
td/telegram/MessageReaction.h
|
td/telegram/MessageReaction.h
|
||||||
|
td/telegram/MessageReplyHeader.h
|
||||||
td/telegram/MessageReplyInfo.h
|
td/telegram/MessageReplyInfo.h
|
||||||
td/telegram/MessageThreadInfo.h
|
td/telegram/MessageThreadInfo.h
|
||||||
td/telegram/MessagesDb.h
|
td/telegram/MessagesDb.h
|
||||||
@ -645,12 +669,13 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/NotificationGroupType.h
|
td/telegram/NotificationGroupType.h
|
||||||
td/telegram/NotificationId.h
|
td/telegram/NotificationId.h
|
||||||
td/telegram/NotificationManager.h
|
td/telegram/NotificationManager.h
|
||||||
td/telegram/NotificationSettings.h
|
td/telegram/NotificationSettingsScope.h
|
||||||
td/telegram/NotificationSettingsManager.h
|
td/telegram/NotificationSettingsManager.h
|
||||||
td/telegram/NotificationSound.h
|
td/telegram/NotificationSound.h
|
||||||
td/telegram/NotificationSoundType.h
|
td/telegram/NotificationSoundType.h
|
||||||
td/telegram/NotificationType.h
|
td/telegram/NotificationType.h
|
||||||
td/telegram/OptionManager.h
|
td/telegram/OptionManager.h
|
||||||
|
td/telegram/OrderInfo.h
|
||||||
td/telegram/PasswordManager.h
|
td/telegram/PasswordManager.h
|
||||||
td/telegram/Payments.h
|
td/telegram/Payments.h
|
||||||
td/telegram/PhoneNumberManager.h
|
td/telegram/PhoneNumberManager.h
|
||||||
@ -672,6 +697,7 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/RequestActor.h
|
td/telegram/RequestActor.h
|
||||||
td/telegram/RestrictionReason.h
|
td/telegram/RestrictionReason.h
|
||||||
td/telegram/ScheduledServerMessageId.h
|
td/telegram/ScheduledServerMessageId.h
|
||||||
|
td/telegram/ScopeNotificationSettings.h
|
||||||
td/telegram/SecretChatActor.h
|
td/telegram/SecretChatActor.h
|
||||||
td/telegram/SecretChatId.h
|
td/telegram/SecretChatId.h
|
||||||
td/telegram/SecretChatDb.h
|
td/telegram/SecretChatDb.h
|
||||||
@ -705,9 +731,11 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/ThemeManager.h
|
td/telegram/ThemeManager.h
|
||||||
td/telegram/TopDialogCategory.h
|
td/telegram/TopDialogCategory.h
|
||||||
td/telegram/TopDialogManager.h
|
td/telegram/TopDialogManager.h
|
||||||
|
td/telegram/TranscriptionInfo.h
|
||||||
td/telegram/UniqueId.h
|
td/telegram/UniqueId.h
|
||||||
td/telegram/UpdatesManager.h
|
td/telegram/UpdatesManager.h
|
||||||
td/telegram/UserId.h
|
td/telegram/UserId.h
|
||||||
|
td/telegram/Usernames.h
|
||||||
td/telegram/Venue.h
|
td/telegram/Venue.h
|
||||||
td/telegram/Version.h
|
td/telegram/Version.h
|
||||||
td/telegram/VideoNotesManager.h
|
td/telegram/VideoNotesManager.h
|
||||||
@ -721,6 +749,7 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/AudiosManager.hpp
|
td/telegram/AudiosManager.hpp
|
||||||
td/telegram/AuthManager.hpp
|
td/telegram/AuthManager.hpp
|
||||||
td/telegram/BackgroundType.hpp
|
td/telegram/BackgroundType.hpp
|
||||||
|
td/telegram/DialogNotificationSettings.hpp
|
||||||
td/telegram/DialogFilter.hpp
|
td/telegram/DialogFilter.hpp
|
||||||
td/telegram/Dimensions.hpp
|
td/telegram/Dimensions.hpp
|
||||||
td/telegram/Document.hpp
|
td/telegram/Document.hpp
|
||||||
@ -732,14 +761,17 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/files/FileLocation.hpp
|
td/telegram/files/FileLocation.hpp
|
||||||
td/telegram/files/FileManager.hpp
|
td/telegram/files/FileManager.hpp
|
||||||
td/telegram/files/FileSourceId.hpp
|
td/telegram/files/FileSourceId.hpp
|
||||||
|
td/telegram/ForumTopicEditedData.hpp
|
||||||
|
td/telegram/ForumTopicIcon.hpp
|
||||||
td/telegram/Game.hpp
|
td/telegram/Game.hpp
|
||||||
|
td/telegram/InputInvoice.hpp
|
||||||
td/telegram/InputMessageText.hpp
|
td/telegram/InputMessageText.hpp
|
||||||
td/telegram/MessageEntity.hpp
|
td/telegram/MessageEntity.hpp
|
||||||
|
td/telegram/MessageExtendedMedia.hpp
|
||||||
td/telegram/MessageReaction.hpp
|
td/telegram/MessageReaction.hpp
|
||||||
td/telegram/MessageReplyInfo.hpp
|
td/telegram/MessageReplyInfo.hpp
|
||||||
td/telegram/MinChannel.hpp
|
td/telegram/MinChannel.hpp
|
||||||
td/telegram/NotificationSettings.hpp
|
td/telegram/OrderInfo.hpp
|
||||||
td/telegram/Payments.hpp
|
|
||||||
td/telegram/Photo.hpp
|
td/telegram/Photo.hpp
|
||||||
td/telegram/PhotoSize.hpp
|
td/telegram/PhotoSize.hpp
|
||||||
td/telegram/PhotoSizeSource.hpp
|
td/telegram/PhotoSizeSource.hpp
|
||||||
@ -747,10 +779,12 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/PollManager.hpp
|
td/telegram/PollManager.hpp
|
||||||
td/telegram/PremiumGiftOption.hpp
|
td/telegram/PremiumGiftOption.hpp
|
||||||
td/telegram/ReplyMarkup.hpp
|
td/telegram/ReplyMarkup.hpp
|
||||||
|
td/telegram/ScopeNotificationSettings.hpp
|
||||||
td/telegram/SecureValue.hpp
|
td/telegram/SecureValue.hpp
|
||||||
td/telegram/SendCodeHelper.hpp
|
td/telegram/SendCodeHelper.hpp
|
||||||
td/telegram/StickerSetId.hpp
|
td/telegram/StickerSetId.hpp
|
||||||
td/telegram/StickersManager.hpp
|
td/telegram/StickersManager.hpp
|
||||||
|
td/telegram/TranscriptionInfo.hpp
|
||||||
td/telegram/VideoNotesManager.hpp
|
td/telegram/VideoNotesManager.hpp
|
||||||
td/telegram/VideosManager.hpp
|
td/telegram/VideosManager.hpp
|
||||||
td/telegram/VoiceNotesManager.hpp
|
td/telegram/VoiceNotesManager.hpp
|
||||||
|
@ -130,7 +130,7 @@ target_link_libraries(YourTarget PRIVATE Td::TdStatic)
|
|||||||
|
|
||||||
Or you could install `TDLib` and then reference it in your CMakeLists.txt like this:
|
Or you could install `TDLib` and then reference it in your CMakeLists.txt like this:
|
||||||
```
|
```
|
||||||
find_package(Td 1.8.6 REQUIRED)
|
find_package(Td 1.8.8 REQUIRED)
|
||||||
target_link_libraries(YourTarget PRIVATE Td::TdStatic)
|
target_link_libraries(YourTarget PRIVATE Td::TdStatic)
|
||||||
```
|
```
|
||||||
See [example/cpp/CMakeLists.txt](https://github.com/tdlight-team/tdlight/blob/master/example/cpp/CMakeLists.txt).
|
See [example/cpp/CMakeLists.txt](https://github.com/tdlight-team/tdlight/blob/master/example/cpp/CMakeLists.txt).
|
||||||
|
@ -66,7 +66,7 @@ function split_file($file, $chunks, $undo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!file_exists($cpp_name)) {
|
if (!file_exists($cpp_name)) {
|
||||||
echo "ERROR: skip unexisting file $cpp_name".PHP_EOL;
|
echo "ERROR: skip nonexistent file $cpp_name".PHP_EOL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,12 +286,13 @@ function split_file($file, $chunks, $undo) {
|
|||||||
'documents_manager[_(-][^.]|DocumentsManager' => "DocumentsManager",
|
'documents_manager[_(-][^.]|DocumentsManager' => "DocumentsManager",
|
||||||
'file_reference_manager[_(-][^.]|FileReferenceManager|file_references[)]' => 'FileReferenceManager',
|
'file_reference_manager[_(-][^.]|FileReferenceManager|file_references[)]' => 'FileReferenceManager',
|
||||||
'file_manager[_(-][^.]|FileManager([^ ;.]| [^*])|update_file[)]' => 'files/FileManager',
|
'file_manager[_(-][^.]|FileManager([^ ;.]| [^*])|update_file[)]' => 'files/FileManager',
|
||||||
|
'forum_topic_manager[_(-][^.]|ForumTopicManager' => 'ForumTopicManager',
|
||||||
'G[(][)]|Global[^A-Za-z]' => 'Global',
|
'G[(][)]|Global[^A-Za-z]' => 'Global',
|
||||||
'game_manager[_(-][^.]|GameManager' => 'GameManager',
|
'game_manager[_(-][^.]|GameManager' => 'GameManager',
|
||||||
'group_call_manager[_(-][^.]|GroupCallManager' => 'GroupCallManager',
|
'group_call_manager[_(-][^.]|GroupCallManager' => 'GroupCallManager',
|
||||||
'HashtagHints' => 'HashtagHints',
|
'HashtagHints' => 'HashtagHints',
|
||||||
'inline_queries_manager[_(-][^.]|InlineQueriesManager' => 'InlineQueriesManager',
|
'inline_queries_manager[_(-][^.]|InlineQueriesManager' => 'InlineQueriesManager',
|
||||||
'language_pack_manager[_(-][^.]|LanguagePackManager' => 'LanguagePackManager',
|
'language_pack_manager[_(-]|LanguagePackManager' => 'LanguagePackManager',
|
||||||
'link_manager[_(-][^.]|LinkManager' => 'LinkManager',
|
'link_manager[_(-][^.]|LinkManager' => 'LinkManager',
|
||||||
'LogeventIdWithGeneration|add_log_event|delete_log_event|get_erase_log_event_promise|parse_time|store_time' => 'logevent/LogEventHelper',
|
'LogeventIdWithGeneration|add_log_event|delete_log_event|get_erase_log_event_promise|parse_time|store_time' => 'logevent/LogEventHelper',
|
||||||
'MessageCopyOptions' => 'MessageCopyOptions',
|
'MessageCopyOptions' => 'MessageCopyOptions',
|
||||||
@ -303,7 +304,7 @@ function split_file($file, $chunks, $undo) {
|
|||||||
'poll_manager[_(-][^.]|PollManager' => "PollManager",
|
'poll_manager[_(-][^.]|PollManager' => "PollManager",
|
||||||
'PublicDialogType|get_public_dialog_type' => 'PublicDialogType',
|
'PublicDialogType|get_public_dialog_type' => 'PublicDialogType',
|
||||||
'SecretChatActor' => 'SecretChatActor',
|
'SecretChatActor' => 'SecretChatActor',
|
||||||
'secret_chats_manager[_(-][^.]|SecretChatsManager' => 'SecretChatsManager',
|
'secret_chats_manager[_(-]|SecretChatsManager' => 'SecretChatsManager',
|
||||||
'sponsored_message_manager[_(-][^.]|SponsoredMessageManager' => 'SponsoredMessageManager',
|
'sponsored_message_manager[_(-][^.]|SponsoredMessageManager' => 'SponsoredMessageManager',
|
||||||
'stickers_manager[_(-][^.]|StickersManager' => 'StickersManager',
|
'stickers_manager[_(-][^.]|StickersManager' => 'StickersManager',
|
||||||
'[>](td_db[(][)]|get_td_db_impl[(])|TdDb[^A-Za-z]' => 'TdDb',
|
'[>](td_db[(][)]|get_td_db_impl[(])|TdDb[^A-Za-z]' => 'TdDb',
|
||||||
|
@ -138,7 +138,7 @@ static void measure(td::StringBuilder &sb, td::Slice name, td::Slice key_name, t
|
|||||||
ht.emplace(key_generator.next(), value_generator.next());
|
ht.emplace(key_generator.next(), value_generator.next());
|
||||||
update();
|
update();
|
||||||
if ((i + 1) % p == 0) {
|
if ((i + 1) % p == 0) {
|
||||||
stat.emplace_back(Stat{pi, min_ratio, max_ratio});
|
stat.push_back(Stat{pi, min_ratio, max_ratio});
|
||||||
reset();
|
reset();
|
||||||
pi++;
|
pi++;
|
||||||
p *= 10;
|
p *= 10;
|
||||||
|
@ -134,7 +134,7 @@ See [example/cpp](https://github.com/tdlight-team/tdlight/tree/master/example/cp
|
|||||||
See also the source code of [Fernschreiber](https://github.com/Wunderfitz/harbour-fernschreiber) and [Depecher](https://github.com/blacksailer/depecher) – Telegram apps for Sailfish OS,
|
See also the source code of [Fernschreiber](https://github.com/Wunderfitz/harbour-fernschreiber) and [Depecher](https://github.com/blacksailer/depecher) – Telegram apps for Sailfish OS,
|
||||||
[TELEports](https://gitlab.com/ubports/development/apps/teleports) – a Qt-client for Ubuntu Touch, [tdlib-purple](https://github.com/ars3niy/tdlib-purple) - Telegram plugin for Pidgin,
|
[TELEports](https://gitlab.com/ubports/development/apps/teleports) – a Qt-client for Ubuntu Touch, [tdlib-purple](https://github.com/ars3niy/tdlib-purple) - Telegram plugin for Pidgin,
|
||||||
or [MeeGram](https://github.com/qtinsider/meegram2) - a Telegram client for Nokia N9,
|
or [MeeGram](https://github.com/qtinsider/meegram2) - a Telegram client for Nokia N9,
|
||||||
[TDLib Native Sciter Extension](https://github.com/RadRussianRus/TDLibNSE) - a Sciter native extension for TDLib's JSON interface, all of which are based on TDLib.
|
[TDLib Native Sciter Extension](https://github.com/EricKotato/TDLibNSE) - a Sciter native extension for TDLib's JSON interface, all of which are based on TDLib.
|
||||||
|
|
||||||
<a name="swift"></a>
|
<a name="swift"></a>
|
||||||
## Using TDLib in Swift projects
|
## Using TDLib in Swift projects
|
||||||
@ -182,7 +182,7 @@ See also [f-Telegram](https://github.com/evgfilim1/ftg) - Flutter Telegram clien
|
|||||||
|
|
||||||
TDLib can be used from the Rust programming language through the [JSON](https://github.com/tdlib/td#using-json) interface.
|
TDLib can be used from the Rust programming language through the [JSON](https://github.com/tdlib/td#using-json) interface.
|
||||||
|
|
||||||
See [rust-tdlib](https://github.com/aCLr/rust-tdlib), [tdlib](https://github.com/melix99/tdlib-rs), or [tdlib-rs](https://github.com/agnipau/tdlib-rs), which provide convenient TDLib clients with automatically generated and fully-documented classes for all TDLib API methods and objects.
|
See [rust-tdlib](https://github.com/aCLr/rust-tdlib), or [tdlib](https://github.com/melix99/tdlib-rs), which provide convenient TDLib clients with automatically generated and fully-documented classes for all TDLib API methods and objects.
|
||||||
|
|
||||||
See [rtdlib](https://github.com/fewensa/rtdlib), [tdlib-rs](https://github.com/d653/tdlib-rs), [tdlib-futures](https://github.com/yuri91/tdlib-futures),
|
See [rtdlib](https://github.com/fewensa/rtdlib), [tdlib-rs](https://github.com/d653/tdlib-rs), [tdlib-futures](https://github.com/yuri91/tdlib-futures),
|
||||||
[tdlib-sys](https://github.com/nuxeh/tdlib-sys), [tdjson-rs](https://github.com/mersinvald/tdjson-rs), [rust-tdlib](https://github.com/vhaoran/rust-tdlib), or [tdlib-json-sys](https://github.com/aykxt/tdlib-json-sys) for examples of TDLib Rust bindings.
|
[tdlib-sys](https://github.com/nuxeh/tdlib-sys), [tdjson-rs](https://github.com/mersinvald/tdjson-rs), [rust-tdlib](https://github.com/vhaoran/rust-tdlib), or [tdlib-json-sys](https://github.com/aykxt/tdlib-json-sys) for examples of TDLib Rust bindings.
|
||||||
|
26
example/android/Dockerfile
Normal file
26
example/android/Dockerfile
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
FROM --platform=linux/amd64 ubuntu:22.04 as build
|
||||||
|
|
||||||
|
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -yq default-jdk g++ git gperf make perl php-cli unzip wget && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /home
|
||||||
|
|
||||||
|
ARG ANDROID_NDK_VERSION=23.2.8568313
|
||||||
|
COPY ./check-environment.sh ./fetch-sdk.sh ./
|
||||||
|
RUN ./fetch-sdk.sh SDK "$ANDROID_NDK_VERSION"
|
||||||
|
|
||||||
|
ARG OPENSSL_VERSION=OpenSSL_1_1_1q
|
||||||
|
COPY ./build-openssl.sh ./
|
||||||
|
RUN ./build-openssl.sh SDK "$ANDROID_NDK_VERSION" openssl "$OPENSSL_VERSION"
|
||||||
|
|
||||||
|
ADD "https://api.github.com/repos/tdlib/td/git/refs/heads/master" version.json
|
||||||
|
ARG COMMIT_HASH=master
|
||||||
|
RUN git clone https://github.com/tdlib/td.git && cd td && git checkout "$COMMIT_HASH"
|
||||||
|
RUN cd td && git merge-base --is-ancestor bcd89728c3b93b67448b93b4863dc5bd4e122a4c "$COMMIT_HASH"
|
||||||
|
|
||||||
|
ARG ANDROID_STL=c++_static
|
||||||
|
RUN td/example/android/build-tdlib.sh SDK "$ANDROID_NDK_VERSION" openssl "$ANDROID_STL" && rm -rf td/example/android/build-*
|
||||||
|
|
||||||
|
|
||||||
|
FROM scratch
|
||||||
|
|
||||||
|
COPY --from=build /home/td/example/android/tdlib/tdlib* /
|
@ -17,6 +17,8 @@ If you already have prebuilt OpenSSL, you can skip the third step and specify pa
|
|||||||
|
|
||||||
If you want to update TDLib to a newer version, you need to run only the script `./build-tdlib.sh`.
|
If you want to update TDLib to a newer version, you need to run only the script `./build-tdlib.sh`.
|
||||||
|
|
||||||
You can specify different OpenSSL version as the fourth parameter to the script `./build-openssl.sh`. By default OpenSSL 1.1.1 is used because of much smaller binary footprint than newer OpenSSL versions.
|
You can specify different OpenSSL version as the fourth parameter to the script `./build-openssl.sh`. By default OpenSSL 1.1.1 is used because of much smaller binary footprint and better performance than newer OpenSSL versions.
|
||||||
|
|
||||||
You can build TDLib against shared standard C++ library by specifying "c++_shared" as the fourth parameter to the script `./build-tdlib.sh`. This can reduce total application size if you have a lot of other C++ code and want it to use the same shared library.
|
You can build TDLib against shared standard C++ library by specifying "c++_shared" as the fourth parameter to the script `./build-tdlib.sh`. This can reduce total application size if you have a lot of other C++ code and want it to use the same shared library.
|
||||||
|
|
||||||
|
Alternatively, you can use Docker to build TDLib for Android. Use `docker build --output tdlib .` to build the latest TDLib commit from Github, or `docker build --build-arg COMMIT_HASH=<commit-hash> --output tdlib .` to build specific commit. The output archives will be placed in the tdlib directory as specified.
|
||||||
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.4 FATAL_ERROR)
|
|||||||
|
|
||||||
project(TdExample VERSION 1.0 LANGUAGES CXX)
|
project(TdExample VERSION 1.0 LANGUAGES CXX)
|
||||||
|
|
||||||
find_package(Td 1.8.6 REQUIRED)
|
find_package(Td 1.8.8 REQUIRED)
|
||||||
|
|
||||||
add_executable(tdjson_example tdjson_example.cpp)
|
add_executable(tdjson_example tdjson_example.cpp)
|
||||||
target_link_libraries(tdjson_example PRIVATE Td::TdJson)
|
target_link_libraries(tdjson_example PRIVATE Td::TdJson)
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
diff --git a/Makefile b/Makefile
|
diff --git a/Makefile b/Makefile
|
||||||
index 695be54..4efe5e5 100644
|
index 695be54..eda7b0d 100644
|
||||||
--- a/Makefile
|
--- a/Makefile
|
||||||
+++ b/Makefile
|
+++ b/Makefile
|
||||||
@@ -5,10 +5,13 @@
|
@@ -7,8 +7,11 @@
|
||||||
# - iOS - build everything for iOS
|
|
||||||
# - tvOS - build everything for tvOS
|
|
||||||
# - watchOS - build everything for watchOS
|
# - watchOS - build everything for watchOS
|
||||||
# - OpenSSL-macOS - build OpenSSL for macOS
|
# - OpenSSL-macOS - build OpenSSL for macOS
|
||||||
# - OpenSSL-iOS - build OpenSSL for iOS
|
# - OpenSSL-iOS - build OpenSSL for iOS
|
||||||
@ -16,7 +14,14 @@ index 695be54..4efe5e5 100644
|
|||||||
# - BZip2-macOS - build BZip2 for macOS
|
# - BZip2-macOS - build BZip2 for macOS
|
||||||
# - BZip2-iOS - build BZip2 for iOS
|
# - BZip2-iOS - build BZip2 for iOS
|
||||||
# - BZip2-tvOS - build BZip2 for tvOS
|
# - BZip2-tvOS - build BZip2 for tvOS
|
||||||
@@ -36,31 +39,45 @@ OPENSSL_VERSION=$(OPENSSL_VERSION_NUMBER)$(OPENSSL_REVISION)
|
@@ -30,37 +33,51 @@ PYTHON_VERSION=2.7.14
|
||||||
|
PYTHON_VER=$(basename $(PYTHON_VERSION))
|
||||||
|
|
||||||
|
OPENSSL_VERSION_NUMBER=1.0.2
|
||||||
|
-OPENSSL_REVISION=n
|
||||||
|
+OPENSSL_REVISION=u
|
||||||
|
OPENSSL_VERSION=$(OPENSSL_VERSION_NUMBER)$(OPENSSL_REVISION)
|
||||||
|
|
||||||
BZIP2_VERSION=1.0.6
|
BZIP2_VERSION=1.0.6
|
||||||
|
|
||||||
# Supported OS
|
# Supported OS
|
||||||
@ -33,19 +38,23 @@ index 695be54..4efe5e5 100644
|
|||||||
-TARGETS-iOS=iphonesimulator.x86_64 iphonesimulator.i386 iphoneos.armv7 iphoneos.armv7s iphoneos.arm64
|
-TARGETS-iOS=iphonesimulator.x86_64 iphonesimulator.i386 iphoneos.armv7 iphoneos.armv7s iphoneos.arm64
|
||||||
+TARGETS-iOS=iphoneos.armv7 iphoneos.armv7s iphoneos.arm64
|
+TARGETS-iOS=iphoneos.armv7 iphoneos.armv7s iphoneos.arm64
|
||||||
CFLAGS-iOS=-mios-version-min=7.0
|
CFLAGS-iOS=-mios-version-min=7.0
|
||||||
CFLAGS-iphoneos.armv7=-fembed-bitcode
|
-CFLAGS-iphoneos.armv7=-fembed-bitcode
|
||||||
CFLAGS-iphoneos.armv7s=-fembed-bitcode
|
-CFLAGS-iphoneos.armv7s=-fembed-bitcode
|
||||||
CFLAGS-iphoneos.arm64=-fembed-bitcode
|
-CFLAGS-iphoneos.arm64=-fembed-bitcode
|
||||||
|
+CFLAGS-iphoneos.armv7=
|
||||||
|
+CFLAGS-iphoneos.armv7s=
|
||||||
|
+CFLAGS-iphoneos.arm64=
|
||||||
|
+
|
||||||
+# iOS-simulator targets
|
+# iOS-simulator targets
|
||||||
+TARGETS-iOS-simulator=iphonesimulator.x86_64 iphonesimulator.i386 iphonesimulator.arm64
|
+TARGETS-iOS-simulator=iphonesimulator.x86_64 iphonesimulator.i386 iphonesimulator.arm64
|
||||||
+CFLAGS-iOS-simulator=-mios-simulator-version-min=7.0
|
+CFLAGS-iOS-simulator=-mios-simulator-version-min=7.0
|
||||||
+
|
|
||||||
# tvOS targets
|
# tvOS targets
|
||||||
-TARGETS-tvOS=appletvsimulator.x86_64 appletvos.arm64
|
-TARGETS-tvOS=appletvsimulator.x86_64 appletvos.arm64
|
||||||
+TARGETS-tvOS=appletvos.arm64
|
+TARGETS-tvOS=appletvos.arm64
|
||||||
CFLAGS-tvOS=-mtvos-version-min=9.0
|
CFLAGS-tvOS=-mtvos-version-min=9.0
|
||||||
CFLAGS-appletvos.arm64=-fembed-bitcode
|
-CFLAGS-appletvos.arm64=-fembed-bitcode
|
||||||
|
+CFLAGS-appletvos.arm64=
|
||||||
PYTHON_CONFIGURE-tvOS=ac_cv_func_sigaltstack=no
|
PYTHON_CONFIGURE-tvOS=ac_cv_func_sigaltstack=no
|
||||||
|
|
||||||
+# tvOS-simulator targets
|
+# tvOS-simulator targets
|
||||||
@ -56,8 +65,9 @@ index 695be54..4efe5e5 100644
|
|||||||
-TARGETS-watchOS=watchsimulator.i386 watchos.armv7k
|
-TARGETS-watchOS=watchsimulator.i386 watchos.armv7k
|
||||||
+TARGETS-watchOS=watchos.armv7k watchos.arm64_32
|
+TARGETS-watchOS=watchos.armv7k watchos.arm64_32
|
||||||
CFLAGS-watchOS=-mwatchos-version-min=4.0
|
CFLAGS-watchOS=-mwatchos-version-min=4.0
|
||||||
CFLAGS-watchos.armv7k=-fembed-bitcode
|
-CFLAGS-watchos.armv7k=-fembed-bitcode
|
||||||
+CFLAGS-watchos.arm64_32=-fembed-bitcode
|
+CFLAGS-watchos.armv7k=
|
||||||
|
+CFLAGS-watchos.arm64_32=
|
||||||
PYTHON_CONFIGURE-watchOS=ac_cv_func_sigaltstack=no
|
PYTHON_CONFIGURE-watchOS=ac_cv_func_sigaltstack=no
|
||||||
|
|
||||||
+# watchOS-simulator targets
|
+# watchOS-simulator targets
|
||||||
@ -80,3 +90,15 @@ index 695be54..4efe5e5 100644
|
|||||||
else
|
else
|
||||||
cd $$(OPENSSL_DIR-$1) && \
|
cd $$(OPENSSL_DIR-$1) && \
|
||||||
CC="$$(CC-$1)" \
|
CC="$$(CC-$1)" \
|
||||||
|
@@ -216,7 +235,10 @@ $$(OPENSSL_DIR-$1)/libssl.a $$(OPENSSL_DIR-$1)/libcrypto.a: $$(OPENSSL_DIR-$1)/M
|
||||||
|
CC="$$(CC-$1)" \
|
||||||
|
CROSS_TOP="$$(dir $$(SDK_ROOT-$1)).." \
|
||||||
|
CROSS_SDK="$$(notdir $$(SDK_ROOT-$1))" \
|
||||||
|
- make all && make install
|
||||||
|
+ make build_libs && \
|
||||||
|
+ mkdir -p "$(PROJECT_DIR)/build/$2/openssl/lib" && \
|
||||||
|
+ cp libcrypto.a libssl.a "$(PROJECT_DIR)/build/$2/openssl/lib"
|
||||||
|
+ -cd $$(OPENSSL_DIR-$1) && make install_sw 2> /dev/null
|
||||||
|
|
||||||
|
# Unpack BZip2
|
||||||
|
$$(BZIP2_DIR-$1)/Makefile: downloads/bzip2-$(BZIP2_VERSION).tgz
|
||||||
|
@ -26,12 +26,12 @@ do
|
|||||||
echo $platform
|
echo $platform
|
||||||
cd Python-Apple-support
|
cd Python-Apple-support
|
||||||
#NB: -j will fail
|
#NB: -j will fail
|
||||||
make OpenSSL-$platform
|
make OpenSSL-$platform || exit 1
|
||||||
cd ..
|
cd ..
|
||||||
rm -rf third_party/openssl/$platform
|
rm -rf third_party/openssl/$platform || exit 1
|
||||||
mkdir -p third_party/openssl/$platform/lib
|
mkdir -p third_party/openssl/$platform/lib || exit 1
|
||||||
cp ./Python-Apple-support/build/$platform/libcrypto.a third_party/openssl/$platform/lib/
|
cp ./Python-Apple-support/build/$platform/libcrypto.a third_party/openssl/$platform/lib/ || exit 1
|
||||||
cp ./Python-Apple-support/build/$platform/libssl.a third_party/openssl/$platform/lib/
|
cp ./Python-Apple-support/build/$platform/libssl.a third_party/openssl/$platform/lib/ || exit 1
|
||||||
cp -r ./Python-Apple-support/build/$platform/Support/OpenSSL/Headers/ third_party/openssl/$platform/include
|
cp -r ./Python-Apple-support/build/$platform/openssl/include/ third_party/openssl/$platform/include || exit 1
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011">
|
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011">
|
||||||
<Metadata>
|
<Metadata>
|
||||||
<Identity Id="Telegram.Td.UWP" Version="1.8.6" Language="en-US" Publisher="Telegram LLC" />
|
<Identity Id="Telegram.Td.UWP" Version="1.8.8" Language="en-US" Publisher="Telegram LLC" />
|
||||||
<DisplayName>TDLib for Universal Windows Platform</DisplayName>
|
<DisplayName>TDLib for Universal Windows Platform</DisplayName>
|
||||||
<Description>TDLib is a library for building Telegram clients</Description>
|
<Description>TDLib is a library for building Telegram clients</Description>
|
||||||
<MoreInfo>https://core.telegram.org/tdlib</MoreInfo>
|
<MoreInfo>https://core.telegram.org/tdlib</MoreInfo>
|
||||||
|
15
sqlite/sqlite/sqlite3.c
vendored
15
sqlite/sqlite/sqlite3.c
vendored
@ -60743,17 +60743,24 @@ act_like_temp_file:
|
|||||||
pPager->memDb = (u8)memDb;
|
pPager->memDb = (u8)memDb;
|
||||||
pPager->readOnly = (u8)readOnly;
|
pPager->readOnly = (u8)readOnly;
|
||||||
assert( useJournal || pPager->tempFile );
|
assert( useJournal || pPager->tempFile );
|
||||||
pPager->noSync = pPager->tempFile;
|
int level = SQLITE_DEFAULT_SYNCHRONOUS + 1;
|
||||||
|
pPager->noSync = pPager->tempFile || level==PAGER_SYNCHRONOUS_OFF;
|
||||||
if( pPager->noSync ){
|
if( pPager->noSync ){
|
||||||
assert( pPager->fullSync==0 );
|
assert( pPager->fullSync==0 );
|
||||||
assert( pPager->extraSync==0 );
|
assert( pPager->extraSync==0 );
|
||||||
assert( pPager->syncFlags==0 );
|
assert( pPager->syncFlags==0 );
|
||||||
assert( pPager->walSyncFlags==0 );
|
assert( pPager->walSyncFlags==0 );
|
||||||
}else{
|
}else{
|
||||||
pPager->fullSync = 1;
|
pPager->fullSync = level>=PAGER_SYNCHRONOUS_FULL ?1:0;
|
||||||
pPager->extraSync = 0;
|
pPager->extraSync = level==PAGER_SYNCHRONOUS_EXTRA ?1:0;
|
||||||
pPager->syncFlags = SQLITE_SYNC_NORMAL;
|
pPager->syncFlags = SQLITE_SYNC_NORMAL;
|
||||||
pPager->walSyncFlags = SQLITE_SYNC_NORMAL | (SQLITE_SYNC_NORMAL<<2);
|
pPager->walSyncFlags = (pPager->syncFlags<<2);
|
||||||
|
if( pPager->fullSync ){
|
||||||
|
pPager->walSyncFlags |= pPager->syncFlags;
|
||||||
|
}
|
||||||
|
#if SQLITE_DEFAULT_CKPTFULLFSYNC
|
||||||
|
pPager->walSyncFlags |= (SQLITE_SYNC_FULL<<2);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* pPager->pFirst = 0; */
|
/* pPager->pFirst = 0; */
|
||||||
/* pPager->pFirstSynced = 0; */
|
/* pPager->pFirstSynced = 0; */
|
||||||
|
@ -212,14 +212,14 @@ abstract class TlDocumentationGenerator
|
|||||||
$known_fields[$field_name] = $field_type;
|
$known_fields[$field_name] = $field_type;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$this->printError("Have no info about field `$field_name`");
|
$this->printError("Have no documentation for field `$field_name`");
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($info as $name => $value) {
|
foreach ($info as $name => $value) {
|
||||||
if (!$value) {
|
if (!$value) {
|
||||||
$this->printError("info[$name] for $class_name is empty");
|
$this->printError("Documentation for field $name of $class_name is empty");
|
||||||
} elseif (($value[0] < 'A' || $value[0] > 'Z') && ($value[0] < '0' || $value[0] > '9')) {
|
} elseif (($value[0] < 'A' || $value[0] > 'Z') && ($value[0] < '0' || $value[0] > '9')) {
|
||||||
$this->printError("info[$name] for $class_name doesn't begins with capital letter");
|
$this->printError("Documentation for field $name of $class_name doesn't begin with a capital letter");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +235,7 @@ abstract class TlDocumentationGenerator
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach (array_diff_key($info, $known_fields) as $field_name => $field_info) {
|
foreach (array_diff_key($info, $known_fields) as $field_name => $field_info) {
|
||||||
$this->printError("Have info about unexisted field `$field_name`");
|
$this->printError("Have info about nonexistent field `$field_name`");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_keys($info) !== array_keys($known_fields)) {
|
if (array_keys($info) !== array_keys($known_fields)) {
|
||||||
|
@ -15,12 +15,12 @@ vector {t:Type} # [ t ] = Vector t;
|
|||||||
decryptedMessage8#1f814f1f random_id:long random_bytes:bytes message:string media:DecryptedMessageMedia = DecryptedMessage;
|
decryptedMessage8#1f814f1f random_id:long random_bytes:bytes message:string media:DecryptedMessageMedia = DecryptedMessage;
|
||||||
decryptedMessageService8#aa48327d random_id:long random_bytes:bytes action:DecryptedMessageAction = DecryptedMessage;
|
decryptedMessageService8#aa48327d random_id:long random_bytes:bytes action:DecryptedMessageAction = DecryptedMessage;
|
||||||
decryptedMessageMediaEmpty#89f5c4a = DecryptedMessageMedia;
|
decryptedMessageMediaEmpty#89f5c4a = DecryptedMessageMedia;
|
||||||
decryptedMessageMediaPhoto23#32798a8c thumb:bytes thumb_w:int thumb_h:int w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
|
decryptedMessageMediaPhoto8#32798a8c thumb:bytes thumb_w:int thumb_h:int w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
|
||||||
decryptedMessageMediaVideo8#4cee6ef3 thumb:bytes thumb_w:int thumb_h:int duration:int w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
|
decryptedMessageMediaVideo8#4cee6ef3 thumb:bytes thumb_w:int thumb_h:int duration:int w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
|
||||||
decryptedMessageMediaGeoPoint#35480a59 lat:double long:double = DecryptedMessageMedia;
|
decryptedMessageMediaGeoPoint#35480a59 lat:double long:double = DecryptedMessageMedia;
|
||||||
decryptedMessageMediaContact#588a0a97 phone_number:string first_name:string last_name:string user_id:int = DecryptedMessageMedia;
|
decryptedMessageMediaContact#588a0a97 phone_number:string first_name:string last_name:string user_id:int = DecryptedMessageMedia;
|
||||||
decryptedMessageActionSetMessageTTL#a1733aec ttl_seconds:int = DecryptedMessageAction;
|
decryptedMessageActionSetMessageTTL#a1733aec ttl_seconds:int = DecryptedMessageAction;
|
||||||
decryptedMessageMediaDocument23#b095434b thumb:bytes thumb_w:int thumb_h:int file_name:string mime_type:string size:int key:bytes iv:bytes = DecryptedMessageMedia;
|
decryptedMessageMediaDocument8#b095434b thumb:bytes thumb_w:int thumb_h:int file_name:string mime_type:string size:int key:bytes iv:bytes = DecryptedMessageMedia;
|
||||||
decryptedMessageMediaAudio8#6080758f duration:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
|
decryptedMessageMediaAudio8#6080758f duration:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
|
||||||
decryptedMessageActionReadMessages#c4f40be random_ids:Vector<long> = DecryptedMessageAction;
|
decryptedMessageActionReadMessages#c4f40be random_ids:Vector<long> = DecryptedMessageAction;
|
||||||
decryptedMessageActionDeleteMessages#65614304 random_ids:Vector<long> = DecryptedMessageAction;
|
decryptedMessageActionDeleteMessages#65614304 random_ids:Vector<long> = DecryptedMessageAction;
|
||||||
@ -59,7 +59,7 @@ decryptedMessageActionNoop#a82fdd63 = DecryptedMessageAction;
|
|||||||
documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute;
|
documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute;
|
||||||
documentAttributeAnimated#11b58939 = DocumentAttribute;
|
documentAttributeAnimated#11b58939 = DocumentAttribute;
|
||||||
documentAttributeSticker23#fb0a5727 = DocumentAttribute;
|
documentAttributeSticker23#fb0a5727 = DocumentAttribute;
|
||||||
documentAttributeVideo#5910cccb duration:int w:int h:int = DocumentAttribute;
|
documentAttributeVideo23#5910cccb duration:int w:int h:int = DocumentAttribute;
|
||||||
documentAttributeAudio23#51448e5 duration:int = DocumentAttribute;
|
documentAttributeAudio23#51448e5 duration:int = DocumentAttribute;
|
||||||
documentAttributeFilename#15590068 file_name:string = DocumentAttribute;
|
documentAttributeFilename#15590068 file_name:string = DocumentAttribute;
|
||||||
photoSizeEmpty#e17e23c type:string = PhotoSize;
|
photoSizeEmpty#e17e23c type:string = PhotoSize;
|
||||||
@ -105,7 +105,7 @@ decryptedMessageMediaWebPage#e50511d8 url:string = DecryptedMessageMedia;
|
|||||||
|
|
||||||
sendMessageRecordRoundAction#88f27fbc = SendMessageAction;
|
sendMessageRecordRoundAction#88f27fbc = SendMessageAction;
|
||||||
sendMessageUploadRoundAction#bb718624 = SendMessageAction;
|
sendMessageUploadRoundAction#bb718624 = SendMessageAction;
|
||||||
documentAttributeVideo66#ef02ce6 flags:# round_message:flags.0?true duration:int w:int h:int = DocumentAttribute;
|
documentAttributeVideo#ef02ce6 flags:# round_message:flags.0?true duration:int w:int h:int = DocumentAttribute;
|
||||||
|
|
||||||
// layer 73
|
// layer 73
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ textEntity offset:int32 length:int32 type:TextEntityType = TextEntity;
|
|||||||
textEntities entities:vector<textEntity> = TextEntities;
|
textEntities entities:vector<textEntity> = 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.
|
//@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, Strikethrough, and Spoiler 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 can be part of any other entities. All other entities can't contain each other
|
||||||
formattedText text:string entities:vector<textEntity> = FormattedText;
|
formattedText text:string entities:vector<textEntity> = FormattedText;
|
||||||
|
|
||||||
|
|
||||||
@ -163,9 +163,6 @@ remoteFile id:string unique_id:string is_uploading_active:Bool is_uploading_comp
|
|||||||
//@remote Information about the remote copy of the file
|
//@remote Information about the remote copy of the file
|
||||||
file id:int32 size:int53 expected_size:int53 local:localFile remote:remoteFile = File;
|
file id:int32 size:int53 expected_size:int53 local:localFile remote:remoteFile = File;
|
||||||
|
|
||||||
//@description Represents a list of files @files List of files
|
|
||||||
files files:vector<file> = Files;
|
|
||||||
|
|
||||||
|
|
||||||
//@class InputFile @description Points to a file
|
//@class InputFile @description Points to a file
|
||||||
|
|
||||||
@ -323,9 +320,9 @@ sticker set_id:int64 width:int32 height:int32 emoji:string format:StickerFormat
|
|||||||
video duration:int32 width:int32 height:int32 file_name:string mime_type:string has_stickers:Bool supports_streaming:Bool minithumbnail:minithumbnail thumbnail:thumbnail video:file = Video;
|
video duration:int32 width:int32 height:int32 file_name:string mime_type:string has_stickers:Bool supports_streaming:Bool minithumbnail:minithumbnail thumbnail:thumbnail video:file = Video;
|
||||||
|
|
||||||
//@description Describes a video note. The video must be equal in width and height, cropped to a circle, and stored in MPEG4 format @duration Duration of the video, in seconds; as defined by the sender
|
//@description Describes a video note. The video must be equal in width and height, cropped to a circle, and stored in MPEG4 format @duration Duration of the video, in seconds; as defined by the sender
|
||||||
//@length Video width and height; as defined by the sender @minithumbnail Video minithumbnail; may be null
|
//@waveform A waveform representation of the video note's audio in 5-bit format; may be empty if unknown @length Video width and height; as defined by the sender @minithumbnail Video minithumbnail; may be null
|
||||||
//@thumbnail Video thumbnail in JPEG format; as defined by the sender; may be null @video File containing the video
|
//@thumbnail Video thumbnail in JPEG format; as defined by the sender; may be null @speech_recognition_result Result of speech recognition in the video note; may be null @video File containing the video
|
||||||
videoNote duration:int32 length:int32 minithumbnail:minithumbnail thumbnail:thumbnail video:file = VideoNote;
|
videoNote duration:int32 waveform:bytes length:int32 minithumbnail:minithumbnail thumbnail:thumbnail speech_recognition_result:SpeechRecognitionResult video:file = VideoNote;
|
||||||
|
|
||||||
//@description Describes a voice note. The voice note must be encoded with the Opus codec, and stored inside an OGG container. Voice notes can have only a single audio channel
|
//@description Describes a voice note. The voice note must be encoded with the Opus codec, and stored inside an OGG container. Voice notes can have only a single audio channel
|
||||||
//@duration Duration of the voice note, in seconds; as defined by the sender @waveform A waveform representation of the voice note in 5-bit format
|
//@duration Duration of the voice note, in seconds; as defined by the sender @waveform A waveform representation of the voice note in 5-bit format
|
||||||
@ -334,9 +331,11 @@ voiceNote duration:int32 waveform:bytes mime_type:string speech_recognition_resu
|
|||||||
|
|
||||||
//@description Describes an animated or custom representation of an emoji
|
//@description Describes an animated or custom representation of an emoji
|
||||||
//@sticker Sticker for the emoji; may be null if yet unknown for a custom emoji. If the sticker is a custom emoji, it can have arbitrary format different from stickerFormatTgs
|
//@sticker Sticker for the emoji; may be null if yet unknown for a custom emoji. If the sticker is a custom emoji, it can have arbitrary format different from stickerFormatTgs
|
||||||
|
//@sticker_width Expected width of the sticker, which can be used if the sticker is null
|
||||||
|
//@sticker_height Expected height of the sticker, which can be used if the sticker is null
|
||||||
//@fitzpatrick_type Emoji modifier fitzpatrick type; 0-6; 0 if none
|
//@fitzpatrick_type Emoji modifier fitzpatrick type; 0-6; 0 if none
|
||||||
//@sound File containing the sound to be played when the sticker is clicked; may be null. The sound is encoded with the Opus codec, and stored inside an OGG container
|
//@sound File containing the sound to be played when the sticker is clicked; may be null. The sound is encoded with the Opus codec, and stored inside an OGG container
|
||||||
animatedEmoji sticker:sticker fitzpatrick_type:int32 sound:file = AnimatedEmoji;
|
animatedEmoji sticker:sticker sticker_width:int32 sticker_height:int32 fitzpatrick_type:int32 sound:file = AnimatedEmoji;
|
||||||
|
|
||||||
//@description Describes a user contact @phone_number Phone number of the user @first_name First name of the user; 1-255 characters in length @last_name Last name of the user @vcard Additional data about the user in a form of vCard; 0-2048 bytes in length @user_id Identifier of the user, if known; otherwise 0
|
//@description Describes a user contact @phone_number Phone number of the user @first_name First name of the user; 1-255 characters in length @last_name Last name of the user @vcard Additional data about the user in a form of vCard; 0-2048 bytes in length @user_id Identifier of the user, if known; otherwise 0
|
||||||
contact phone_number:string first_name:string last_name:string vcard:string user_id:int53 = Contact;
|
contact phone_number:string first_name:string last_name:string vcard:string user_id:int53 = Contact;
|
||||||
@ -467,7 +466,8 @@ inputChatPhotoAnimation animation:InputFile main_frame_timestamp:double = InputC
|
|||||||
//@can_change_info True, if the user can change the chat title, photo, and other settings
|
//@can_change_info True, if the user can change the chat title, photo, and other settings
|
||||||
//@can_invite_users True, if the user can invite new users to the chat
|
//@can_invite_users True, if the user can invite new users to the chat
|
||||||
//@can_pin_messages True, if the user can pin messages
|
//@can_pin_messages True, if the user can pin messages
|
||||||
chatPermissions can_send_messages:Bool can_send_media_messages:Bool can_send_polls:Bool can_send_other_messages:Bool can_add_web_page_previews:Bool can_change_info:Bool can_invite_users:Bool can_pin_messages:Bool = ChatPermissions;
|
//@can_manage_topics True, if the user can manage topics
|
||||||
|
chatPermissions can_send_messages:Bool can_send_media_messages:Bool can_send_polls:Bool can_send_other_messages:Bool can_add_web_page_previews:Bool can_change_info:Bool can_invite_users:Bool can_pin_messages:Bool can_manage_topics:Bool = ChatPermissions;
|
||||||
|
|
||||||
//@description Describes rights of the administrator
|
//@description Describes rights of the administrator
|
||||||
//@can_manage_chat True, if the administrator can get chat event log, get chat statistics, get message statistics in channels, get channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other privilege; applicable to supergroups and channels only
|
//@can_manage_chat True, if the administrator can get chat event log, get chat statistics, get message statistics in channels, get channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other privilege; applicable to supergroups and channels only
|
||||||
@ -478,10 +478,11 @@ chatPermissions can_send_messages:Bool can_send_media_messages:Bool can_send_pol
|
|||||||
//@can_invite_users True, if the administrator can invite new users to the chat
|
//@can_invite_users True, if the administrator can invite new users to the chat
|
||||||
//@can_restrict_members True, if the administrator can restrict, ban, or unban chat members; always true for channels
|
//@can_restrict_members True, if the administrator can restrict, ban, or unban chat members; always true for channels
|
||||||
//@can_pin_messages True, if the administrator can pin messages; applicable to basic groups and supergroups only
|
//@can_pin_messages True, if the administrator can pin messages; applicable to basic groups and supergroups only
|
||||||
|
//@can_manage_topics True, if the administrator can manage topics; applicable to forum supergroups only
|
||||||
//@can_promote_members True, if the administrator can add new administrators with a subset of their own privileges or demote administrators that were directly or indirectly promoted by them
|
//@can_promote_members True, if the administrator can add new administrators with a subset of their own privileges or demote administrators that were directly or indirectly promoted by them
|
||||||
//@can_manage_video_chats True, if the administrator can manage video chats
|
//@can_manage_video_chats True, if the administrator can manage video chats
|
||||||
//@is_anonymous True, if the administrator isn't shown in the chat member list and sends messages anonymously; applicable to supergroups only
|
//@is_anonymous True, if the administrator isn't shown in the chat member list and sends messages anonymously; applicable to supergroups only
|
||||||
chatAdministratorRights can_manage_chat:Bool can_change_info:Bool can_post_messages:Bool can_edit_messages:Bool can_delete_messages:Bool can_invite_users:Bool can_restrict_members:Bool can_pin_messages:Bool can_promote_members:Bool can_manage_video_chats:Bool is_anonymous:Bool = ChatAdministratorRights;
|
chatAdministratorRights can_manage_chat:Bool can_change_info:Bool can_post_messages:Bool can_edit_messages:Bool can_delete_messages:Bool can_invite_users:Bool can_restrict_members:Bool can_pin_messages:Bool can_manage_topics:Bool can_promote_members:Bool can_manage_video_chats:Bool is_anonymous:Bool = ChatAdministratorRights;
|
||||||
|
|
||||||
|
|
||||||
//@description Describes an option for buying Telegram Premium to a user
|
//@description Describes an option for buying Telegram Premium to a user
|
||||||
@ -493,6 +494,7 @@ chatAdministratorRights can_manage_chat:Bool can_change_info:Bool can_post_messa
|
|||||||
//@payment_link An internal link to be opened for buying Telegram Premium to the user if store payment isn't possible; may be null if direct payment isn't available
|
//@payment_link An internal link to be opened for buying Telegram Premium to the user if store payment isn't possible; may be null if direct payment isn't available
|
||||||
premiumPaymentOption currency:string amount:int53 discount_percentage:int32 month_count:int32 store_product_id:string payment_link:InternalLinkType = PremiumPaymentOption;
|
premiumPaymentOption currency:string amount:int53 discount_percentage:int32 month_count:int32 store_product_id:string payment_link:InternalLinkType = PremiumPaymentOption;
|
||||||
|
|
||||||
|
|
||||||
//@description Describes a custom emoji to be shown instead of the Telegram Premium badge @custom_emoji_id Identifier of the custom emoji in stickerFormatTgs format. If the custom emoji belongs to the sticker set GetOption("themed_emoji_statuses_sticker_set_id"), then it's color must be changed to the color of the Telegram Premium badge
|
//@description Describes a custom emoji to be shown instead of the Telegram Premium badge @custom_emoji_id Identifier of the custom emoji in stickerFormatTgs format. If the custom emoji belongs to the sticker set GetOption("themed_emoji_statuses_sticker_set_id"), then it's color must be changed to the color of the Telegram Premium badge
|
||||||
emojiStatus custom_emoji_id:int64 = EmojiStatus;
|
emojiStatus custom_emoji_id:int64 = EmojiStatus;
|
||||||
|
|
||||||
@ -500,11 +502,18 @@ emojiStatus custom_emoji_id:int64 = EmojiStatus;
|
|||||||
emojiStatuses emoji_statuses:vector<emojiStatus> = EmojiStatuses;
|
emojiStatuses emoji_statuses:vector<emojiStatus> = EmojiStatuses;
|
||||||
|
|
||||||
|
|
||||||
|
//@description Describes usernames assigned to a user, a supergroup, or a channel
|
||||||
|
//@active_usernames List of active usernames; the first one must be shown as the primary username. The order of active usernames can be changed with reorderActiveUsernames or reorderSupergroupActiveUsernames
|
||||||
|
//@disabled_usernames List of currently disabled usernames; the username can be activated with toggleUsernameIsActive/toggleSupergroupUsernameIsActive
|
||||||
|
//@editable_username The active username, which can be changed with setUsername/setSupergroupUsername
|
||||||
|
usernames active_usernames:vector<string> disabled_usernames:vector<string> editable_username:string = Usernames;
|
||||||
|
|
||||||
|
|
||||||
//@description Represents a user
|
//@description Represents a user
|
||||||
//@id User identifier
|
//@id User identifier
|
||||||
//@first_name First name of the user
|
//@first_name First name of the user
|
||||||
//@last_name Last name of the user
|
//@last_name Last name of the user
|
||||||
//@username Username of the user
|
//@usernames Usernames of the user; may be null
|
||||||
//@phone_number Phone number of the user
|
//@phone_number Phone number of the user
|
||||||
//@status Current online status of the user
|
//@status Current online status of the user
|
||||||
//@profile_photo Profile photo of the user; may be null
|
//@profile_photo Profile photo of the user; may be null
|
||||||
@ -521,7 +530,7 @@ emojiStatuses emoji_statuses:vector<emojiStatus> = EmojiStatuses;
|
|||||||
//@type Type of the user
|
//@type Type of the user
|
||||||
//@language_code IETF language tag of the user's language; only available to bots
|
//@language_code IETF language tag of the user's language; only available to bots
|
||||||
//@added_to_attachment_menu True, if the user added the current bot to attachment menu; only available to bots
|
//@added_to_attachment_menu True, if the user added the current bot to attachment menu; only available to bots
|
||||||
user id:int53 first_name:string last_name:string username:string phone_number:string status:UserStatus profile_photo:profilePhoto emoji_status:emojiStatus is_contact:Bool is_mutual_contact:Bool is_verified:Bool is_premium:Bool is_support:Bool restriction_reason:string is_scam:Bool is_fake:Bool have_access:Bool type:UserType language_code:string added_to_attachment_menu:Bool = User;
|
user id:int53 first_name:string last_name:string usernames:usernames phone_number:string status:UserStatus profile_photo:profilePhoto emoji_status:emojiStatus is_contact:Bool is_mutual_contact:Bool is_verified:Bool is_premium:Bool is_support:Bool restriction_reason:string is_scam:Bool is_fake:Bool have_access:Bool type:UserType language_code:string added_to_attachment_menu:Bool = User;
|
||||||
|
|
||||||
|
|
||||||
//@description Contains information about a bot
|
//@description Contains information about a bot
|
||||||
@ -536,7 +545,7 @@ user id:int53 first_name:string last_name:string username:string phone_number:st
|
|||||||
botInfo share_text:string description:string photo:photo animation:animation menu_button:botMenuButton commands:vector<botCommand> default_group_administrator_rights:chatAdministratorRights default_channel_administrator_rights:chatAdministratorRights = BotInfo;
|
botInfo share_text:string description:string photo:photo animation:animation menu_button:botMenuButton commands:vector<botCommand> default_group_administrator_rights:chatAdministratorRights default_channel_administrator_rights:chatAdministratorRights = BotInfo;
|
||||||
|
|
||||||
//@description Contains full information about a user
|
//@description Contains full information about a user
|
||||||
//@photo User profile photo; may be null
|
//@photo User profile photo; may be null if empty or unknown. If non-null, then it is the same photo as in user.profile_photo and chat.photo
|
||||||
//@is_blocked True, if the user is blocked by the current user
|
//@is_blocked True, if the user is blocked by the current user
|
||||||
//@can_be_called True, if the user can be called
|
//@can_be_called True, if the user can be called
|
||||||
//@supports_video_calls True, if a video call can be created with the user
|
//@supports_video_calls True, if a video call can be created with the user
|
||||||
@ -719,7 +728,7 @@ chatJoinRequestsInfo total_count:int32 user_ids:vector<int53> = ChatJoinRequests
|
|||||||
basicGroup id:int53 member_count:int32 status:ChatMemberStatus is_active:Bool upgraded_to_supergroup_id:int53 = BasicGroup;
|
basicGroup id:int53 member_count:int32 status:ChatMemberStatus is_active:Bool upgraded_to_supergroup_id:int53 = BasicGroup;
|
||||||
|
|
||||||
//@description Contains full information about a basic group
|
//@description Contains full information about a basic group
|
||||||
//@photo Chat photo; may be null
|
//@photo Chat photo; may be null if empty or unknown. If non-null, then it is the same photo as in chat.photo
|
||||||
//@param_description Group description. Updated only after the basic group is opened
|
//@param_description Group description. Updated only after the basic group is opened
|
||||||
//@creator_user_id User identifier of the creator of the group; 0 if unknown
|
//@creator_user_id User identifier of the creator of the group; 0 if unknown
|
||||||
//@members Group members
|
//@members Group members
|
||||||
@ -730,9 +739,9 @@ basicGroupFullInfo photo:chatPhoto description:string creator_user_id:int53 memb
|
|||||||
|
|
||||||
//@description Represents a supergroup or channel with zero or more members (subscribers in the case of channels). From the point of view of the system, a channel is a special kind of a supergroup: only administrators can post and see the list of members, and posts from all administrators use the name and photo of the channel instead of individual names and profile photos. Unlike supergroups, channels can have an unlimited number of subscribers
|
//@description Represents a supergroup or channel with zero or more members (subscribers in the case of channels). From the point of view of the system, a channel is a special kind of a supergroup: only administrators can post and see the list of members, and posts from all administrators use the name and photo of the channel instead of individual names and profile photos. Unlike supergroups, channels can have an unlimited number of subscribers
|
||||||
//@id Supergroup or channel identifier
|
//@id Supergroup or channel identifier
|
||||||
//@username Username of the supergroup or channel; empty for private supergroups or channels
|
//@usernames Usernames of the supergroup or channel; may be null
|
||||||
//@date Point in time (Unix timestamp) when the current user joined, or the point in time when the supergroup or channel was created, in case the user is not a member
|
//@date Point in time (Unix timestamp) when the current user joined, or the point in time when the supergroup or channel was created, in case the user is not a member
|
||||||
//@status Status of the current user in the supergroup or channel; custom title will be always empty
|
//@status Status of the current user in the supergroup or channel; custom title will always be empty
|
||||||
//@member_count Number of members in the supergroup or channel; 0 if unknown. Currently, it is guaranteed to be known only if the supergroup or channel was received through searchPublicChats, searchChatsNearby, getInactiveSupergroupChats, getSuitableDiscussionChats, getGroupsInCommon, or getUserPrivacySettingRules
|
//@member_count Number of members in the supergroup or channel; 0 if unknown. Currently, it is guaranteed to be known only if the supergroup or channel was received through searchPublicChats, searchChatsNearby, getInactiveSupergroupChats, getSuitableDiscussionChats, getGroupsInCommon, or getUserPrivacySettingRules
|
||||||
//@has_linked_chat True, if the channel has a discussion group, or the supergroup is the designated discussion group for a channel
|
//@has_linked_chat True, if the channel has a discussion group, or the supergroup is the designated discussion group for a channel
|
||||||
//@has_location True, if the supergroup is connected to a location, i.e. the supergroup is a location-based supergroup
|
//@has_location True, if the supergroup is connected to a location, i.e. the supergroup is a location-based supergroup
|
||||||
@ -742,14 +751,15 @@ basicGroupFullInfo photo:chatPhoto description:string creator_user_id:int53 memb
|
|||||||
//@is_slow_mode_enabled True, if the slow mode is enabled in the supergroup
|
//@is_slow_mode_enabled True, if the slow mode is enabled in the supergroup
|
||||||
//@is_channel True, if the supergroup is a channel
|
//@is_channel True, if the supergroup is a channel
|
||||||
//@is_broadcast_group True, if the supergroup is a broadcast group, i.e. only administrators can send messages and there is no limit on the number of members
|
//@is_broadcast_group True, if the supergroup is a broadcast group, i.e. only administrators can send messages and there is no limit on the number of members
|
||||||
|
//@is_forum True, if the supergroup must be shown as a forum by default
|
||||||
//@is_verified True, if the supergroup or channel is verified
|
//@is_verified True, if the supergroup or channel is verified
|
||||||
//@restriction_reason If non-empty, contains a human-readable description of the reason why access to this supergroup or channel must be restricted
|
//@restriction_reason If non-empty, contains a human-readable description of the reason why access to this supergroup or channel must be restricted
|
||||||
//@is_scam True, if many users reported this supergroup or channel as a scam
|
//@is_scam True, if many users reported this supergroup or channel as a scam
|
||||||
//@is_fake True, if many users reported this supergroup or channel as a fake account
|
//@is_fake True, if many users reported this supergroup or channel as a fake account
|
||||||
supergroup id:int53 username:string date:int32 status:ChatMemberStatus member_count:int32 has_linked_chat:Bool has_location:Bool sign_messages:Bool join_to_send_messages:Bool join_by_request:Bool is_slow_mode_enabled:Bool is_channel:Bool is_broadcast_group:Bool is_verified:Bool restriction_reason:string is_scam:Bool is_fake:Bool = Supergroup;
|
supergroup id:int53 usernames:usernames date:int32 status:ChatMemberStatus member_count:int32 has_linked_chat:Bool has_location:Bool sign_messages:Bool join_to_send_messages:Bool join_by_request:Bool is_slow_mode_enabled:Bool is_channel:Bool is_broadcast_group:Bool is_forum:Bool is_verified:Bool restriction_reason:string is_scam:Bool is_fake:Bool = Supergroup;
|
||||||
|
|
||||||
//@description Contains full information about a supergroup or channel
|
//@description Contains full information about a supergroup or channel
|
||||||
//@photo Chat photo; may be null
|
//@photo Chat photo; may be null if empty or unknown. If non-null, then it is the same photo as in chat.photo
|
||||||
//@param_description Supergroup or channel description
|
//@param_description Supergroup or channel description
|
||||||
//@member_count Number of members in the supergroup or channel; 0 if unknown
|
//@member_count Number of members in the supergroup or channel; 0 if unknown
|
||||||
//@administrator_count Number of privileged users in the supergroup or channel; 0 if unknown
|
//@administrator_count Number of privileged users in the supergroup or channel; 0 if unknown
|
||||||
@ -763,7 +773,7 @@ supergroup id:int53 username:string date:int32 status:ChatMemberStatus member_co
|
|||||||
//@can_set_sticker_set True, if the supergroup sticker set can be changed
|
//@can_set_sticker_set True, if the supergroup sticker set can be changed
|
||||||
//@can_set_location True, if the supergroup location can be changed
|
//@can_set_location True, if the supergroup location can be changed
|
||||||
//@can_get_statistics True, if the supergroup or channel statistics are available
|
//@can_get_statistics True, if the supergroup or channel statistics are available
|
||||||
//@is_all_history_available True, if new chat members will have access to old messages. In public or discussion groups and both public and private channels, old messages are always available, so this option affects only private supergroups without a linked chat. The value of this field is only available for chat administrators
|
//@is_all_history_available True, if new chat members will have access to old messages. In public, discussion, of forum groups and all channels, old messages are always available, so this option affects only private non-forum supergroups without a linked chat. The value of this field is only available for chat administrators
|
||||||
//@sticker_set_id Identifier of the supergroup sticker set; 0 if none
|
//@sticker_set_id Identifier of the supergroup sticker set; 0 if none
|
||||||
//@location Location to which the supergroup is connected; may be null
|
//@location Location to which the supergroup is connected; may be null
|
||||||
//@invite_link Primary invite link for the chat; may be null. For chat administrators with can_invite_users right only
|
//@invite_link Primary invite link for the chat; may be null. For chat administrators with can_invite_users right only
|
||||||
@ -809,6 +819,13 @@ messageSenderChat chat_id:int53 = MessageSender;
|
|||||||
messageSenders total_count:int32 senders:vector<MessageSender> = MessageSenders;
|
messageSenders total_count:int32 senders:vector<MessageSender> = MessageSenders;
|
||||||
|
|
||||||
|
|
||||||
|
//@description Represents a message sender, which can be used to send messages in a chat @sender Available message senders @needs_premium True, if Telegram Premium is needed to use the message sender
|
||||||
|
chatMessageSender sender:MessageSender needs_premium:Bool = ChatMessageSender;
|
||||||
|
|
||||||
|
//@description Represents a list of message senders, which can be used to send messages in a chat @senders List of available message senders
|
||||||
|
chatMessageSenders senders:vector<chatMessageSender> = ChatMessageSenders;
|
||||||
|
|
||||||
|
|
||||||
//@class MessageForwardOrigin @description Contains information about the origin of a forwarded message
|
//@class MessageForwardOrigin @description Contains information about the origin of a forwarded message
|
||||||
|
|
||||||
//@description The message was originally sent by a known user @sender_user_id Identifier of the user that originally sent the message
|
//@description The message was originally sent by a known user @sender_user_id Identifier of the user that originally sent the message
|
||||||
@ -911,6 +928,7 @@ messageSendingStateFailed error_code:int32 error_message:string can_retry:Bool n
|
|||||||
//@can_report_reactions True, if reactions on the message can be reported through reportMessageReactions
|
//@can_report_reactions True, if reactions on the message can be reported through reportMessageReactions
|
||||||
//@has_timestamped_media True, if media timestamp entities refers to a media in this message as opposed to a media in the replied message
|
//@has_timestamped_media True, if media timestamp entities refers to a media in this message as opposed to a media in the replied message
|
||||||
//@is_channel_post True, if the message is a channel post. All messages to channels are channel posts, all other messages are not channel posts
|
//@is_channel_post True, if the message is a channel post. All messages to channels are channel posts, all other messages are not channel posts
|
||||||
|
//@is_topic_message True, if the message is a forum topic message
|
||||||
//@contains_unread_mention True, if the message contains an unread mention for the current user
|
//@contains_unread_mention True, if the message contains an unread mention for the current user
|
||||||
//@date Point in time (Unix timestamp) when the message was sent
|
//@date Point in time (Unix timestamp) when the message was sent
|
||||||
//@edit_date Point in time (Unix timestamp) when the message was last edited
|
//@edit_date Point in time (Unix timestamp) when the message was last edited
|
||||||
@ -928,7 +946,7 @@ messageSendingStateFailed error_code:int32 error_message:string can_retry:Bool n
|
|||||||
//@restriction_reason If non-empty, contains a human-readable description of the reason why access to this message must be restricted
|
//@restriction_reason If non-empty, contains a human-readable description of the reason why access to this message must be restricted
|
||||||
//@content Content of the message
|
//@content Content of the message
|
||||||
//@reply_markup Reply markup for the message; may be null
|
//@reply_markup Reply markup for the message; may be null
|
||||||
message id:int53 sender_id:MessageSender chat_id:int53 sending_state:MessageSendingState scheduling_state:MessageSchedulingState is_outgoing:Bool is_pinned:Bool can_be_edited:Bool can_be_forwarded:Bool can_be_saved:Bool can_be_deleted_only_for_self:Bool can_be_deleted_for_all_users:Bool can_get_added_reactions:Bool can_get_statistics:Bool can_get_message_thread:Bool can_get_viewers:Bool can_get_media_timestamp_links:Bool can_report_reactions:Bool has_timestamped_media:Bool is_channel_post:Bool contains_unread_mention:Bool date:int32 edit_date:int32 forward_info:messageForwardInfo interaction_info:messageInteractionInfo unread_reactions:vector<unreadReaction> reply_in_chat_id:int53 reply_to_message_id:int53 message_thread_id:int53 ttl:int32 ttl_expires_in:double via_bot_user_id:int53 author_signature:string media_album_id:int64 restriction_reason:string content:MessageContent reply_markup:ReplyMarkup = Message;
|
message id:int53 sender_id:MessageSender chat_id:int53 sending_state:MessageSendingState scheduling_state:MessageSchedulingState is_outgoing:Bool is_pinned:Bool can_be_edited:Bool can_be_forwarded:Bool can_be_saved:Bool can_be_deleted_only_for_self:Bool can_be_deleted_for_all_users:Bool can_get_added_reactions:Bool can_get_statistics:Bool can_get_message_thread:Bool can_get_viewers:Bool can_get_media_timestamp_links:Bool can_report_reactions:Bool has_timestamped_media:Bool is_channel_post:Bool is_topic_message:Bool contains_unread_mention:Bool date:int32 edit_date:int32 forward_info:messageForwardInfo interaction_info:messageInteractionInfo unread_reactions:vector<unreadReaction> reply_in_chat_id:int53 reply_to_message_id:int53 message_thread_id:int53 ttl:int32 ttl_expires_in:double via_bot_user_id:int53 author_signature:string media_album_id:int64 restriction_reason:string content:MessageContent reply_markup:ReplyMarkup = Message;
|
||||||
|
|
||||||
//@description Contains a list of messages @total_count Approximate total number of messages found @messages List of messages; messages may be null
|
//@description Contains a list of messages @total_count Approximate total number of messages found @messages List of messages; messages may be null
|
||||||
messages total_count:int32 messages:vector<message> = Messages;
|
messages total_count:int32 messages:vector<message> = Messages;
|
||||||
@ -954,9 +972,13 @@ messageCalendar total_count:int32 days:vector<messageCalendarDay> = MessageCalen
|
|||||||
//@is_recommended True, if the message needs to be labeled as "recommended" instead of "sponsored"
|
//@is_recommended True, if the message needs to be labeled as "recommended" instead of "sponsored"
|
||||||
//@sponsor_chat_id Sponsor chat identifier; 0 if the sponsor chat is accessible through an invite link
|
//@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
|
//@sponsor_chat_info Information about the sponsor chat; may be null unless sponsor_chat_id == 0
|
||||||
|
//@show_chat_photo True, if the sponsor's chat photo must be shown
|
||||||
//@link An internal link to be opened when the sponsored message is clicked; may be null if the sponsor chat needs to be opened instead
|
//@link An internal link to be opened when the sponsored message is clicked; may be null if the sponsor chat needs to be opened instead
|
||||||
//@content Content of the message. Currently, can be only of the type messageText
|
//@content Content of the message. Currently, can be only of the type messageText
|
||||||
sponsoredMessage message_id:int53 is_recommended:Bool sponsor_chat_id:int53 sponsor_chat_info:chatInviteLinkInfo link:InternalLinkType content:MessageContent = SponsoredMessage;
|
sponsoredMessage message_id:int53 is_recommended:Bool sponsor_chat_id:int53 sponsor_chat_info:chatInviteLinkInfo show_chat_photo:Bool link:InternalLinkType content:MessageContent = SponsoredMessage;
|
||||||
|
|
||||||
|
//@description Contains a list of sponsored messages @messages List of sponsored messages @messages_between The minimum number of messages between shown sponsored messages, or 0 if only one sponsored message must be shown after all ordinary messages
|
||||||
|
sponsoredMessages messages:vector<sponsoredMessage> messages_between:int32 = SponsoredMessages;
|
||||||
|
|
||||||
|
|
||||||
//@description Describes a file added to file download list
|
//@description Describes a file added to file download list
|
||||||
@ -1156,7 +1178,7 @@ chatsNearby users_nearby:vector<chatNearby> supergroups_nearby:vector<chatNearby
|
|||||||
|
|
||||||
//@class PublicChatType @description Describes a type of public chats
|
//@class PublicChatType @description Describes a type of public chats
|
||||||
|
|
||||||
//@description The chat is public, because it has username
|
//@description The chat is public, because it has an active username
|
||||||
publicChatTypeHasUsername = PublicChatType;
|
publicChatTypeHasUsername = PublicChatType;
|
||||||
|
|
||||||
//@description The chat is public, because it is a location-based supergroup
|
//@description The chat is public, because it is a location-based supergroup
|
||||||
@ -1165,7 +1187,7 @@ publicChatTypeIsLocationBased = PublicChatType;
|
|||||||
|
|
||||||
//@class ChatActionBar @description Describes actions which must be possible to do through a chat action bar
|
//@class ChatActionBar @description Describes actions which must be possible to do through a chat action bar
|
||||||
|
|
||||||
//@description The chat can be reported as spam using the method reportChat with the reason chatReportReasonSpam
|
//@description The chat can be reported as spam using the method reportChat with the reason chatReportReasonSpam. If the chat is a private chat with a user with an emoji status, then a notice about emoji status usage must be shown
|
||||||
//@can_unarchive If true, the chat was automatically archived and can be moved back to the main chat list using addChatToList simultaneously with setting chat notification settings to default using setChatNotificationSettings
|
//@can_unarchive If true, the chat was automatically archived and can be moved back to the main chat list using addChatToList simultaneously with setting chat notification settings to default using setChatNotificationSettings
|
||||||
chatActionBarReportSpam can_unarchive:Bool = ChatActionBar;
|
chatActionBarReportSpam can_unarchive:Bool = ChatActionBar;
|
||||||
|
|
||||||
@ -1175,7 +1197,7 @@ chatActionBarReportUnrelatedLocation = ChatActionBar;
|
|||||||
//@description The chat is a recently created group chat to which new members can be invited
|
//@description The chat is a recently created group chat to which new members can be invited
|
||||||
chatActionBarInviteMembers = ChatActionBar;
|
chatActionBarInviteMembers = ChatActionBar;
|
||||||
|
|
||||||
//@description The chat is a private or secret chat, which can be reported using the method reportChat, or the other user can be blocked using the method toggleMessageSenderIsBlocked, or the other user can be added to the contact list using the method addContact
|
//@description The chat is a private or secret chat, which can be reported using the method reportChat, or the other user can be blocked using the method toggleMessageSenderIsBlocked, or the other user can be added to the contact list using the method addContact. If the chat is a private chat with a user with an emoji status, then a notice about emoji status usage must be shown
|
||||||
//@can_unarchive If true, the chat was automatically archived and can be moved back to the main chat list using addChatToList simultaneously with setting chat notification settings to default using setChatNotificationSettings
|
//@can_unarchive If true, the chat was automatically archived and can be moved back to the main chat list using addChatToList simultaneously with setting chat notification settings to default using setChatNotificationSettings
|
||||||
//@distance If non-negative, the current user was found by the peer through searchChatsNearby and this is the distance between the users
|
//@distance If non-negative, the current user was found by the peer through searchChatsNearby and this is the distance between the users
|
||||||
chatActionBarReportAddBlock can_unarchive:Bool distance:int32 = ChatActionBar;
|
chatActionBarReportAddBlock can_unarchive:Bool distance:int32 = ChatActionBar;
|
||||||
@ -1290,13 +1312,40 @@ webAppInfo launch_id:int64 url:string = WebAppInfo;
|
|||||||
//@description Contains information about a message thread
|
//@description Contains information about a message thread
|
||||||
//@chat_id Identifier of the chat to which the message thread belongs
|
//@chat_id Identifier of the chat to which the message thread belongs
|
||||||
//@message_thread_id Message thread identifier, unique within the chat
|
//@message_thread_id Message thread identifier, unique within the chat
|
||||||
//@reply_info Information about the message thread
|
//@reply_info Information about the message thread; may be null for forum topic threads
|
||||||
//@unread_message_count Approximate number of unread messages in the message thread
|
//@unread_message_count Approximate number of unread messages in the message thread
|
||||||
//@messages The messages from which the thread starts. The messages are returned in a reverse chronological order (i.e., in order of decreasing message_id)
|
//@messages The messages from which the thread starts. The messages are returned in a reverse chronological order (i.e., in order of decreasing message_id)
|
||||||
//@draft_message A draft of a message in the message thread; may be null
|
//@draft_message A draft of a message in the message thread; may be null
|
||||||
messageThreadInfo chat_id:int53 message_thread_id:int53 reply_info:messageReplyInfo unread_message_count:int32 messages:vector<message> draft_message:draftMessage = MessageThreadInfo;
|
messageThreadInfo chat_id:int53 message_thread_id:int53 reply_info:messageReplyInfo unread_message_count:int32 messages:vector<message> draft_message:draftMessage = MessageThreadInfo;
|
||||||
|
|
||||||
|
|
||||||
|
//@description Describes a forum topic icon @color Color of the topic icon in RGB format @custom_emoji_id Unique identifier of the custom emoji shown on the topic icon; 0 if none
|
||||||
|
forumTopicIcon color:int32 custom_emoji_id:int64 = ForumTopicIcon;
|
||||||
|
|
||||||
|
//@description Contains basic information about a forum topic
|
||||||
|
//@message_thread_id Message thread identifier of the topic
|
||||||
|
//@name Name of the topic
|
||||||
|
//@icon Icon of the topic
|
||||||
|
//@creation_date Date the topic was created
|
||||||
|
//@creator_id Identifier of the creator of the topic
|
||||||
|
//@is_outgoing True, if the topic was created by the current user
|
||||||
|
//@is_closed True, if the topic is closed
|
||||||
|
forumTopicInfo message_thread_id:int53 name:string icon:forumTopicIcon creation_date:int32 creator_id:MessageSender is_outgoing:Bool is_closed:Bool = ForumTopicInfo;
|
||||||
|
|
||||||
|
//@description Describes a forum topic
|
||||||
|
//@info Basic information about the topic
|
||||||
|
//@last_message Last message in the topic; may be null
|
||||||
|
//@is_pinned True, if the topic is pinned in the topic list
|
||||||
|
//@unread_count Number of unread messages in the topic
|
||||||
|
//@last_read_inbox_message_id Identifier of the last read incoming message
|
||||||
|
//@last_read_outbox_message_id Identifier of the last read outgoing message
|
||||||
|
//@unread_mention_count Number of unread messages with a mention/reply in the topic
|
||||||
|
//@unread_reaction_count Number of messages with unread reactions in the topic
|
||||||
|
//@notification_settings Notification settings for the topic
|
||||||
|
//@draft_message A draft of a message in the topic; may be null
|
||||||
|
forumTopic info:forumTopicInfo last_message:message is_pinned:Bool unread_count:int32 last_read_inbox_message_id:int53 last_read_outbox_message_id:int53 unread_mention_count:int32 unread_reaction_count:int32 notification_settings:chatNotificationSettings draft_message:draftMessage = ForumTopic;
|
||||||
|
|
||||||
|
|
||||||
//@class RichText @description Describes a text object inside an instant-view web page
|
//@class RichText @description Describes a text object inside an instant-view web page
|
||||||
|
|
||||||
//@description A plain text @text Text
|
//@description A plain text @text Text
|
||||||
@ -1648,7 +1697,7 @@ paymentResult success:Bool verification_url:string = PaymentResult;
|
|||||||
paymentReceipt title:string description:formattedText photo:photo date:int32 seller_bot_user_id:int53 payment_provider_user_id:int53 invoice:invoice order_info:orderInfo shipping_option:shippingOption credentials_title:string tip_amount:int53 = PaymentReceipt;
|
paymentReceipt title:string description:formattedText photo:photo date:int32 seller_bot_user_id:int53 payment_provider_user_id:int53 invoice:invoice order_info:orderInfo shipping_option:shippingOption credentials_title:string tip_amount:int53 = PaymentReceipt;
|
||||||
|
|
||||||
|
|
||||||
//@class InputInvoice @description Describe an invoice to process
|
//@class InputInvoice @description Describes an invoice to process
|
||||||
|
|
||||||
//@description An invoice from a message of the type messageInvoice @chat_id Chat identifier of the message @message_id Message identifier
|
//@description An invoice from a message of the type messageInvoice @chat_id Chat identifier of the message @message_id Message identifier
|
||||||
inputInvoiceMessage chat_id:int53 message_id:int53 = InputInvoice;
|
inputInvoiceMessage chat_id:int53 message_id:int53 = InputInvoice;
|
||||||
@ -1657,6 +1706,27 @@ inputInvoiceMessage chat_id:int53 message_id:int53 = InputInvoice;
|
|||||||
inputInvoiceName name:string = InputInvoice;
|
inputInvoiceName name:string = InputInvoice;
|
||||||
|
|
||||||
|
|
||||||
|
//@class MessageExtendedMedia @description Describes a media, which is attached to an invoice
|
||||||
|
|
||||||
|
//@description The media is hidden until the invoice is paid
|
||||||
|
//@width Media width; 0 if unknown
|
||||||
|
//@height Media height; 0 if unknown
|
||||||
|
//@duration Media duration; 0 if unknown
|
||||||
|
//@minithumbnail Media minithumbnail; may be null
|
||||||
|
//@caption Media caption
|
||||||
|
messageExtendedMediaPreview width:int32 height:int32 duration:int32 minithumbnail:minithumbnail caption:formattedText = MessageExtendedMedia;
|
||||||
|
|
||||||
|
//@description The media is a photo @photo The photo @caption Photo caption
|
||||||
|
messageExtendedMediaPhoto photo:photo caption:formattedText = MessageExtendedMedia;
|
||||||
|
|
||||||
|
//@description The media is a video @video The video @caption Photo caption
|
||||||
|
messageExtendedMediaVideo video:video caption:formattedText = MessageExtendedMedia;
|
||||||
|
|
||||||
|
//@description The media is unuspported @caption Media caption
|
||||||
|
messageExtendedMediaUnsupported caption:formattedText = MessageExtendedMedia;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//@description File with the date it was uploaded @file The file @date Point in time (Unix timestamp) when the file was uploaded
|
//@description File with the date it was uploaded @file The file @date Point in time (Unix timestamp) when the file was uploaded
|
||||||
datedFile file:file date:int32 = DatedFile;
|
datedFile file:file date:int32 = DatedFile;
|
||||||
|
|
||||||
@ -1974,7 +2044,8 @@ messagePoll poll:poll = MessageContent;
|
|||||||
//@description A message with an invoice from a bot @title Product title @param_description Product description @photo Product photo; may be null @currency Currency for the product price @total_amount Product total price in the smallest units of the currency
|
//@description A message with an invoice from a bot @title Product title @param_description Product description @photo Product photo; may be null @currency Currency for the product price @total_amount Product total price in the smallest units of the currency
|
||||||
//@start_parameter Unique invoice bot start_parameter. To share an invoice use the URL https://t.me/{bot_username}?start={start_parameter} @is_test True, if the invoice is a test invoice
|
//@start_parameter Unique invoice bot start_parameter. To share an invoice use the URL https://t.me/{bot_username}?start={start_parameter} @is_test True, if the invoice is a test invoice
|
||||||
//@need_shipping_address True, if the shipping address must be specified @receipt_message_id The identifier of the message with the receipt, after the product has been purchased
|
//@need_shipping_address True, if the shipping address must be specified @receipt_message_id The identifier of the message with the receipt, after the product has been purchased
|
||||||
messageInvoice title:string description:formattedText photo:photo currency:string total_amount:int53 start_parameter:string is_test:Bool need_shipping_address:Bool receipt_message_id:int53 = MessageContent;
|
//@extended_media Extended media attached to the invoice; may be null
|
||||||
|
messageInvoice title:string description:formattedText photo:photo currency:string total_amount:int53 start_parameter:string is_test:Bool need_shipping_address:Bool receipt_message_id:int53 extended_media:MessageExtendedMedia = MessageContent;
|
||||||
|
|
||||||
//@description A message with information about an ended call @is_video True, if the call was a video call @discard_reason Reason why the call was discarded @duration Call duration, in seconds
|
//@description A message with information about an ended call @is_video True, if the call was a video call @discard_reason Reason why the call was discarded @duration Call duration, in seconds
|
||||||
messageCall is_video:Bool discard_reason:CallDiscardReason duration:int32 = MessageContent;
|
messageCall is_video:Bool discard_reason:CallDiscardReason duration:int32 = MessageContent;
|
||||||
@ -2036,13 +2107,22 @@ messageChatSetTheme theme_name:string = MessageContent;
|
|||||||
//@description The TTL (Time To Live) setting for messages in the chat has been changed @ttl New message TTL
|
//@description The TTL (Time To Live) setting for messages in the chat has been changed @ttl New message TTL
|
||||||
messageChatSetTtl ttl:int32 = MessageContent;
|
messageChatSetTtl ttl:int32 = MessageContent;
|
||||||
|
|
||||||
|
//@description A forum topic has been created @name Name of the topic @icon Icon of the topic
|
||||||
|
messageForumTopicCreated name:string icon:forumTopicIcon = MessageContent;
|
||||||
|
|
||||||
|
//@description A forum topic has been edited @name If non-empty, the new name of the topic @edit_icon_custom_emoji_id True, if icon's custom_emoji_id is changed @icon_custom_emoji_id New unique identifier of the custom emoji shown on the topic icon; 0 if none. Must be ignored if edit_icon_custom_emoji_id is false
|
||||||
|
messageForumTopicEdited name:string edit_icon_custom_emoji_id:Bool icon_custom_emoji_id:int64 = MessageContent;
|
||||||
|
|
||||||
|
//@description A forum topic has been closed or opened @is_closed True if the topic was closed or reopened
|
||||||
|
messageForumTopicIsClosedToggled is_closed:Bool = MessageContent;
|
||||||
|
|
||||||
//@description A non-standard action has happened in the chat @text Message text to be shown in the chat
|
//@description A non-standard action has happened in the chat @text Message text to be shown in the chat
|
||||||
messageCustomServiceAction text:string = MessageContent;
|
messageCustomServiceAction text:string = MessageContent;
|
||||||
|
|
||||||
//@description A new high score was achieved in a game @game_message_id Identifier of the message with the game, can be an identifier of a deleted message @game_id Identifier of the game; may be different from the games presented in the message with the game @score New score
|
//@description A new high score was achieved in a game @game_message_id Identifier of the message with the game, can be an identifier of a deleted message @game_id Identifier of the game; may be different from the games presented in the message with the game @score New score
|
||||||
messageGameScore game_message_id:int53 game_id:int64 score:int32 = MessageContent;
|
messageGameScore game_message_id:int53 game_id:int64 score:int32 = MessageContent;
|
||||||
|
|
||||||
//@description A payment has been completed @invoice_chat_id Identifier of the chat, containing the corresponding invoice message; 0 if unknown @invoice_message_id Identifier of the message with the corresponding invoice; can be 0 or an identifier of a deleted message
|
//@description A payment has been completed @invoice_chat_id Identifier of the chat, containing the corresponding invoice message @invoice_message_id Identifier of the message with the corresponding invoice; can be 0 or an identifier of a deleted message
|
||||||
//@currency Currency for the price of the product @total_amount Total price for the product, in the smallest units of the currency
|
//@currency Currency for the price of the product @total_amount Total price for the product, in the smallest units of the currency
|
||||||
//@is_recurring True, if this is a recurring payment @is_first_recurring True, if this is the first recurring payment @invoice_name Name of the invoice; may be empty if unknown
|
//@is_recurring True, if this is a recurring payment @is_first_recurring True, if this is the first recurring payment @invoice_name Name of the invoice; may be empty if unknown
|
||||||
messagePaymentSuccessful invoice_chat_id:int53 invoice_message_id:int53 currency:string total_amount:int53 is_recurring:Bool is_first_recurring:Bool invoice_name:string = MessageContent;
|
messagePaymentSuccessful invoice_chat_id:int53 invoice_message_id:int53 currency:string total_amount:int53 is_recurring:Bool is_first_recurring:Bool invoice_name:string = MessageContent;
|
||||||
@ -2084,7 +2164,7 @@ messageUnsupported = MessageContent;
|
|||||||
|
|
||||||
//@class TextEntityType @description Represents a part of the text which must be formatted differently
|
//@class TextEntityType @description Represents a part of the text which must be formatted differently
|
||||||
|
|
||||||
//@description A mention of a user by their username
|
//@description A mention of a user, a supergroup, or a channel by their username
|
||||||
textEntityTypeMention = TextEntityType;
|
textEntityTypeMention = TextEntityType;
|
||||||
|
|
||||||
//@description A hashtag text, beginning with "#"
|
//@description A hashtag text, beginning with "#"
|
||||||
@ -2190,7 +2270,7 @@ inputMessageAnimation animation:InputFile thumbnail:inputThumbnail added_sticker
|
|||||||
//@performer Performer of the audio; 0-64 characters, may be replaced by the server @caption Audio caption; pass null to use an empty caption; 0-GetOption("message_caption_length_max") characters
|
//@performer Performer of the audio; 0-64 characters, may be replaced by the server @caption Audio caption; pass null to use an empty caption; 0-GetOption("message_caption_length_max") characters
|
||||||
inputMessageAudio audio:InputFile album_cover_thumbnail:inputThumbnail duration:int32 title:string performer:string caption:formattedText = InputMessageContent;
|
inputMessageAudio audio:InputFile album_cover_thumbnail:inputThumbnail duration:int32 title:string performer:string caption:formattedText = InputMessageContent;
|
||||||
|
|
||||||
//@description A document message (general file) @document Document to be sent @thumbnail Document thumbnail; pass null to skip thumbnail uploading @disable_content_type_detection If true, automatic file type detection will be disabled and the document will be always sent as file. Always true for files sent to secret chats @caption Document caption; pass null to use an empty caption; 0-GetOption("message_caption_length_max") characters
|
//@description A document message (general file) @document Document to be sent @thumbnail Document thumbnail; pass null to skip thumbnail uploading @disable_content_type_detection If true, automatic file type detection will be disabled and the document will always be sent as file. Always true for files sent to secret chats @caption Document caption; pass null to use an empty caption; 0-GetOption("message_caption_length_max") characters
|
||||||
inputMessageDocument document:InputFile thumbnail:inputThumbnail disable_content_type_detection:Bool caption:formattedText = InputMessageContent;
|
inputMessageDocument document:InputFile thumbnail:inputThumbnail disable_content_type_detection:Bool caption:formattedText = InputMessageContent;
|
||||||
|
|
||||||
//@description A photo message @photo Photo to send. The photo must be at most 10 MB in size. The photo's width and height must not exceed 10000 in total. Width and height ratio must be at most 20 @thumbnail Photo thumbnail to be sent; pass null to skip thumbnail uploading. The thumbnail is sent to the other party only in secret chats @added_sticker_file_ids File identifiers of the stickers added to the photo, if applicable @width Photo width @height Photo height @caption Photo caption; pass null to use an empty caption; 0-GetOption("message_caption_length_max") characters
|
//@description A photo message @photo Photo to send. The photo must be at most 10 MB in size. The photo's width and height must not exceed 10000 in total. Width and height ratio must be at most 20 @thumbnail Photo thumbnail to be sent; pass null to skip thumbnail uploading. The thumbnail is sent to the other party only in secret chats @added_sticker_file_ids File identifiers of the stickers added to the photo, if applicable @width Photo width @height Photo height @caption Photo caption; pass null to use an empty caption; 0-GetOption("message_caption_length_max") characters
|
||||||
@ -2208,7 +2288,7 @@ inputMessageVideo video:InputFile thumbnail:inputThumbnail added_sticker_file_id
|
|||||||
//@description A video note message @video_note Video note to be sent @thumbnail Video thumbnail; pass null to skip thumbnail uploading @duration Duration of the video, in seconds @length Video width and height; must be positive and not greater than 640
|
//@description A video note message @video_note Video note to be sent @thumbnail Video thumbnail; pass null to skip thumbnail uploading @duration Duration of the video, in seconds @length Video width and height; must be positive and not greater than 640
|
||||||
inputMessageVideoNote video_note:InputFile thumbnail:inputThumbnail duration:int32 length:int32 = InputMessageContent;
|
inputMessageVideoNote video_note:InputFile thumbnail:inputThumbnail duration:int32 length:int32 = InputMessageContent;
|
||||||
|
|
||||||
//@description A voice note message @voice_note Voice note to be sent @duration Duration of the voice note, in seconds @waveform Waveform representation of the voice note, in 5-bit format @caption Voice note caption; pass null to use an empty caption; 0-GetOption("message_caption_length_max") characters
|
//@description A voice note message @voice_note Voice note to be sent @duration Duration of the voice note, in seconds @waveform Waveform representation of the voice note in 5-bit format @caption Voice note caption; pass null to use an empty caption; 0-GetOption("message_caption_length_max") characters
|
||||||
inputMessageVoiceNote voice_note:InputFile duration:int32 waveform:bytes caption:formattedText = InputMessageContent;
|
inputMessageVoiceNote voice_note:InputFile duration:int32 waveform:bytes caption:formattedText = InputMessageContent;
|
||||||
|
|
||||||
//@description A message with a location @location Location to be sent @live_period Period for which the location can be updated, in seconds; must be between 60 and 86400 for a live location and 0 otherwise
|
//@description A message with a location @location Location to be sent @live_period Period for which the location can be updated, in seconds; must be between 60 and 86400 for a live location and 0 otherwise
|
||||||
@ -2232,7 +2312,8 @@ inputMessageGame bot_user_id:int53 game_short_name:string = InputMessageContent;
|
|||||||
//@photo_url Product photo URL; optional @photo_size Product photo size @photo_width Product photo width @photo_height Product photo height
|
//@photo_url Product photo URL; optional @photo_size Product photo size @photo_width Product photo width @photo_height Product photo height
|
||||||
//@payload The invoice payload @provider_token Payment provider token @provider_data JSON-encoded data about the invoice, which will be shared with the payment provider
|
//@payload The invoice payload @provider_token Payment provider token @provider_data JSON-encoded data about the invoice, which will be shared with the payment provider
|
||||||
//@start_parameter Unique invoice bot deep link parameter for the generation of this invoice. If empty, it would be possible to pay directly from forwards of the invoice message
|
//@start_parameter Unique invoice bot deep link parameter for the generation of this invoice. If empty, it would be possible to pay directly from forwards of the invoice message
|
||||||
inputMessageInvoice invoice:invoice title:string description:string photo_url:string photo_size:int32 photo_width:int32 photo_height:int32 payload:bytes provider_token:string provider_data:string start_parameter:string = InputMessageContent;
|
//@extended_media_content The content of extended media attached to the invoice. The content of the message to be sent. Must be one of the following types: inputMessagePhoto, inputMessageVideo
|
||||||
|
inputMessageInvoice invoice:invoice title:string description:string photo_url:string photo_size:int32 photo_width:int32 photo_height:int32 payload:bytes provider_token:string provider_data:string start_parameter:string extended_media_content:InputMessageContent = InputMessageContent;
|
||||||
|
|
||||||
//@description A message with a poll. Polls can't be sent to secret chats. Polls can be sent only to a private chat with a bot @question Poll question; 1-255 characters (up to 300 characters for bots) @options List of poll answer options, 2-10 strings 1-100 characters each
|
//@description A message with a poll. Polls can't be sent to secret chats. Polls can be sent only to a private chat with a bot @question Poll question; 1-255 characters (up to 300 characters for bots) @options List of poll answer options, 2-10 strings 1-100 characters each
|
||||||
//@is_anonymous True, if the poll voters are anonymous. Non-anonymous polls can't be sent or forwarded to channels @type Type of the poll
|
//@is_anonymous True, if the poll voters are anonymous. Non-anonymous polls can't be sent or forwarded to channels @type Type of the poll
|
||||||
@ -2901,9 +2982,12 @@ chatEventStickerSetChanged old_sticker_set_id:int64 new_sticker_set_id:int64 = C
|
|||||||
//@description The chat title was changed @old_title Previous chat title @new_title New chat title
|
//@description The chat title was changed @old_title Previous chat title @new_title New chat title
|
||||||
chatEventTitleChanged old_title:string new_title:string = ChatEventAction;
|
chatEventTitleChanged old_title:string new_title:string = ChatEventAction;
|
||||||
|
|
||||||
//@description The chat username was changed @old_username Previous chat username @new_username New chat username
|
//@description The chat editable username was changed @old_username Previous chat username @new_username New chat username
|
||||||
chatEventUsernameChanged old_username:string new_username:string = ChatEventAction;
|
chatEventUsernameChanged old_username:string new_username:string = ChatEventAction;
|
||||||
|
|
||||||
|
//@description The chat active usernames were changed @old_usernames Previous list of active usernames @new_usernames New list of active usernames
|
||||||
|
chatEventActiveUsernamesChanged old_usernames:vector<string> new_usernames:vector<string> = ChatEventAction;
|
||||||
|
|
||||||
//@description The has_protected_content setting of a channel was toggled @has_protected_content New value of has_protected_content
|
//@description The has_protected_content setting of a channel was toggled @has_protected_content New value of has_protected_content
|
||||||
chatEventHasProtectedContentToggled has_protected_content:Bool = ChatEventAction;
|
chatEventHasProtectedContentToggled has_protected_content:Bool = ChatEventAction;
|
||||||
|
|
||||||
@ -2940,6 +3024,24 @@ chatEventVideoChatParticipantIsMutedToggled participant_id:MessageSender is_mute
|
|||||||
//@description A video chat participant volume level was changed @participant_id Identifier of the affected group call participant @volume_level New value of volume_level; 1-20000 in hundreds of percents
|
//@description A video chat participant volume level was changed @participant_id Identifier of the affected group call participant @volume_level New value of volume_level; 1-20000 in hundreds of percents
|
||||||
chatEventVideoChatParticipantVolumeLevelChanged participant_id:MessageSender volume_level:int32 = ChatEventAction;
|
chatEventVideoChatParticipantVolumeLevelChanged participant_id:MessageSender volume_level:int32 = ChatEventAction;
|
||||||
|
|
||||||
|
//@description The is_forum setting of a channel was toggled @is_forum New value of is_forum
|
||||||
|
chatEventIsForumToggled is_forum:Bool = ChatEventAction;
|
||||||
|
|
||||||
|
//@description A new forum topic was created @topic_info Information about the topic
|
||||||
|
chatEventForumTopicCreated topic_info:forumTopicInfo = ChatEventAction;
|
||||||
|
|
||||||
|
//@description A forum topic was edited @old_topic_info Old information about the topic @new_topic_info New information about the topic
|
||||||
|
chatEventForumTopicEdited old_topic_info:forumTopicInfo new_topic_info:forumTopicInfo = ChatEventAction;
|
||||||
|
|
||||||
|
//@description A forum topic was closed or reopened @topic_info New information about the topic
|
||||||
|
chatEventForumTopicToggleIsClosed topic_info:forumTopicInfo = ChatEventAction;
|
||||||
|
|
||||||
|
//@description A forum topic was deleted @topic_info Information about the topic
|
||||||
|
chatEventForumTopicDeleted topic_info:forumTopicInfo = ChatEventAction;
|
||||||
|
|
||||||
|
//@description A pinned forum topic was changed @old_topic_info Information about the old pinned topic; may be null @new_topic_info Information about the new pinned topic; may be null
|
||||||
|
chatEventForumTopicPinned old_topic_info:forumTopicInfo new_topic_info:forumTopicInfo = ChatEventAction;
|
||||||
|
|
||||||
//@description Represents a chat event @id Chat event identifier @date Point in time (Unix timestamp) when the event happened @member_id Identifier of the user or chat who performed the action @action The action
|
//@description Represents a chat event @id Chat event identifier @date Point in time (Unix timestamp) when the event happened @member_id Identifier of the user or chat who performed the action @action The action
|
||||||
chatEvent id:int64 date:int32 member_id:MessageSender action:ChatEventAction = ChatEvent;
|
chatEvent id:int64 date:int32 member_id:MessageSender action:ChatEventAction = ChatEvent;
|
||||||
|
|
||||||
@ -2959,7 +3061,8 @@ chatEvents events:vector<chatEvent> = ChatEvents;
|
|||||||
//@setting_changes True, if changes in chat settings need to be returned
|
//@setting_changes True, if changes in chat settings need to be returned
|
||||||
//@invite_link_changes True, if changes to invite links need to be returned
|
//@invite_link_changes True, if changes to invite links need to be returned
|
||||||
//@video_chat_changes True, if video chat actions need to be returned
|
//@video_chat_changes True, if video chat actions need to be returned
|
||||||
chatEventLogFilters message_edits:Bool message_deletions:Bool message_pins:Bool member_joins:Bool member_leaves:Bool member_invites:Bool member_promotions:Bool member_restrictions:Bool info_changes:Bool setting_changes:Bool invite_link_changes:Bool video_chat_changes:Bool = ChatEventLogFilters;
|
//@forum_changes True, if forum-related actions need to be returned
|
||||||
|
chatEventLogFilters message_edits:Bool message_deletions:Bool message_pins:Bool member_joins:Bool member_leaves:Bool member_invites:Bool member_promotions:Bool member_restrictions:Bool info_changes:Bool setting_changes:Bool invite_link_changes:Bool video_chat_changes:Bool forum_changes:Bool = ChatEventLogFilters;
|
||||||
|
|
||||||
|
|
||||||
//@class LanguagePackStringValue @description Represents the value of a string in a language pack
|
//@class LanguagePackStringValue @description Represents the value of a string in a language pack
|
||||||
@ -3067,6 +3170,9 @@ premiumFeatureEmojiStatus = PremiumFeature;
|
|||||||
//@description Profile photo animation on message and chat screens
|
//@description Profile photo animation on message and chat screens
|
||||||
premiumFeatureAnimatedProfilePhoto = PremiumFeature;
|
premiumFeatureAnimatedProfilePhoto = PremiumFeature;
|
||||||
|
|
||||||
|
//@description The ability to set a custom emoji as a forum topic icon
|
||||||
|
premiumFeatureForumTopicIcon = PremiumFeature;
|
||||||
|
|
||||||
//@description Allowed to set a premium appllication icons
|
//@description Allowed to set a premium appllication icons
|
||||||
premiumFeatureAppIcons = PremiumFeature;
|
premiumFeatureAppIcons = PremiumFeature;
|
||||||
|
|
||||||
@ -3160,7 +3266,7 @@ pushReceiverId id:int64 = PushReceiverId;
|
|||||||
backgroundFillSolid color:int32 = BackgroundFill;
|
backgroundFillSolid color:int32 = BackgroundFill;
|
||||||
|
|
||||||
//@description Describes a gradient fill of a background @top_color A top color of the background in the RGB24 format @bottom_color A bottom color of the background in the RGB24 format
|
//@description Describes a gradient fill of a background @top_color A top color of the background in the RGB24 format @bottom_color A bottom color of the background in the RGB24 format
|
||||||
//@rotation_angle Clockwise rotation angle of the gradient, in degrees; 0-359. Must be always divisible by 45
|
//@rotation_angle Clockwise rotation angle of the gradient, in degrees; 0-359. Must always be divisible by 45
|
||||||
backgroundFillGradient top_color:int32 bottom_color:int32 rotation_angle:int32 = BackgroundFill;
|
backgroundFillGradient top_color:int32 bottom_color:int32 rotation_angle:int32 = BackgroundFill;
|
||||||
|
|
||||||
//@description Describes a freeform gradient fill of a background @colors A list of 3 or 4 colors of the freeform gradients in the RGB24 format
|
//@description Describes a freeform gradient fill of a background @colors A list of 3 or 4 colors of the freeform gradients in the RGB24 format
|
||||||
@ -3739,8 +3845,8 @@ internalLinkTypeFilterSettings = InternalLinkType;
|
|||||||
//@bot_username Username of the bot that owns the game @game_short_name Short name of the game
|
//@bot_username Username of the bot that owns the game @game_short_name Short name of the game
|
||||||
internalLinkTypeGame bot_username:string game_short_name:string = InternalLinkType;
|
internalLinkTypeGame bot_username:string game_short_name:string = InternalLinkType;
|
||||||
|
|
||||||
//@description The link must be opened in an Instant View. Call getWebPageInstantView with the given URL to process the link @url URL to be passed to getWebPageInstantView
|
//@description The link must be opened in an Instant View. Call getWebPageInstantView with the given URL to process the link @url URL to be passed to getWebPageInstantView @fallback_url An URL to open if getWebPageInstantView fails
|
||||||
internalLinkTypeInstantView url:string = InternalLinkType;
|
internalLinkTypeInstantView url:string fallback_url:string = InternalLinkType;
|
||||||
|
|
||||||
//@description The link is a link to an invoice. Call getPaymentForm with the given invoice name to process the link @invoice_name Name of the invoice
|
//@description The link is a link to an invoice. Call getPaymentForm with the given invoice name to process the link @invoice_name Name of the invoice
|
||||||
internalLinkTypeInvoice invoice_name:string = InternalLinkType;
|
internalLinkTypeInvoice invoice_name:string = InternalLinkType;
|
||||||
@ -3820,11 +3926,11 @@ messageLink link:string is_public:Bool = MessageLink;
|
|||||||
//@description Contains information about a link to a message in a chat
|
//@description Contains information about a link to a message in a chat
|
||||||
//@is_public True, if the link is a public link for a message in a chat
|
//@is_public True, if the link is a public link for a message in a chat
|
||||||
//@chat_id If found, identifier of the chat to which the message belongs, 0 otherwise
|
//@chat_id If found, identifier of the chat to which the message belongs, 0 otherwise
|
||||||
|
//@message_thread_id If found, identifier of the message thread in which to open the message, or which to open in case of a missing message
|
||||||
//@message If found, the linked message; may be null
|
//@message If found, the linked message; may be null
|
||||||
//@media_timestamp Timestamp from which the video/audio/video note/voice note playing must start, in seconds; 0 if not specified. The media can be in the message content or in its web page preview
|
//@media_timestamp Timestamp from which the video/audio/video note/voice note playing must start, in seconds; 0 if not specified. The media can be in the message content or in its web page preview
|
||||||
//@for_album True, if the whole media album to which the message belongs is linked
|
//@for_album True, if the whole media album to which the message belongs is linked
|
||||||
//@for_comment True, if the message is linked as a channel post comment or from a message thread
|
messageLinkInfo is_public:Bool chat_id:int53 message_thread_id:int53 message:message media_timestamp:int32 for_album:Bool = MessageLinkInfo;
|
||||||
messageLinkInfo is_public:Bool chat_id:int53 message:message media_timestamp:int32 for_album:Bool for_comment:Bool = MessageLinkInfo;
|
|
||||||
|
|
||||||
|
|
||||||
//@description Contains a part of a file @data File bytes
|
//@description Contains a part of a file @data File bytes
|
||||||
@ -4352,6 +4458,9 @@ updateChatFilters chat_filters:vector<chatFilterInfo> main_chat_list_position:in
|
|||||||
//@description The number of online group members has changed. This update with non-zero number of online group members is sent only for currently opened chats. There is no guarantee that it will be sent just after the number of online users has changed @chat_id Identifier of the chat @online_member_count New number of online members in the chat, or 0 if unknown
|
//@description The number of online group members has changed. This update with non-zero number of online group members is sent only for currently opened chats. There is no guarantee that it will be sent just after the number of online users has changed @chat_id Identifier of the chat @online_member_count New number of online members in the chat, or 0 if unknown
|
||||||
updateChatOnlineMemberCount chat_id:int53 online_member_count:int32 = Update;
|
updateChatOnlineMemberCount chat_id:int53 online_member_count:int32 = Update;
|
||||||
|
|
||||||
|
//@description Basic information about a topic in a forum chat was changed @chat_id Chat identifier @info New information about the topic
|
||||||
|
updateForumTopicInfo chat_id:int53 info:forumTopicInfo = Update;
|
||||||
|
|
||||||
//@description Notification settings for some type of chats were updated @scope Types of chats for which notification settings were updated @notification_settings The new notification settings
|
//@description Notification settings for some type of chats were updated @scope Types of chats for which notification settings were updated @notification_settings The new notification settings
|
||||||
updateScopeNotificationSettings scope:NotificationSettingsScope notification_settings:scopeNotificationSettings = Update;
|
updateScopeNotificationSettings scope:NotificationSettingsScope notification_settings:scopeNotificationSettings = Update;
|
||||||
|
|
||||||
@ -4917,11 +5026,12 @@ getMessageThreadHistory chat_id:int53 message_id:int53 from_message_id:int53 off
|
|||||||
//@chat_id Chat identifier @remove_from_chat_list Pass true to remove the chat from all chat lists @revoke Pass true to delete chat history for all users
|
//@chat_id Chat identifier @remove_from_chat_list Pass true to remove the chat from all chat lists @revoke Pass true to delete chat history for all users
|
||||||
deleteChatHistory chat_id:int53 remove_from_chat_list:Bool revoke:Bool = Ok;
|
deleteChatHistory chat_id:int53 remove_from_chat_list:Bool revoke:Bool = Ok;
|
||||||
|
|
||||||
//@description Deletes a chat along with all messages in the corresponding chat for all chat members. For group chats this will release the username and remove all members. Use the field chat.can_be_deleted_for_all_users to find whether the method can be applied to the chat @chat_id Chat identifier
|
//@description Deletes a chat along with all messages in the corresponding chat for all chat members. For group chats this will release the usernames and remove all members. Use the field chat.can_be_deleted_for_all_users to find whether the method can be applied to the chat @chat_id Chat identifier
|
||||||
deleteChat chat_id:int53 = Ok;
|
deleteChat chat_id:int53 = Ok;
|
||||||
|
|
||||||
//@description Searches for messages with given words in the chat. Returns the results in reverse chronological order, i.e. in order of decreasing message_id. Cannot be used in secret chats with a non-empty query
|
//@description Searches for messages with given words in the chat. Returns the results in reverse chronological order, i.e. in order of decreasing message_id. Cannot be used in secret chats with a non-empty query
|
||||||
//-(searchSecretMessages must be used instead), or without an enabled message database. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit
|
//-(searchSecretMessages must be used instead), or without an enabled message database. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit.
|
||||||
|
//-A combination of query, sender_id, filter and message_thread_id search criteria is expected to be supported, only if it is required for Telegram official application implementation
|
||||||
//@chat_id Identifier of the chat in which to search messages
|
//@chat_id Identifier of the chat in which to search messages
|
||||||
//@query Query to search for
|
//@query Query to search for
|
||||||
//@sender_id Identifier of the sender of messages to search for; pass null to search for messages from any sender. Not supported in secret chats
|
//@sender_id Identifier of the sender of messages to search for; pass null to search for messages from any sender. Not supported in secret chats
|
||||||
@ -4993,6 +5103,12 @@ getChatMessageCalendar chat_id:int53 filter:SearchMessagesFilter from_message_id
|
|||||||
//@description Returns approximate number of messages of the specified type in the chat @chat_id Identifier of the chat in which to count messages @filter Filter for message content; searchMessagesFilterEmpty is unsupported in this function @return_local Pass true to get the number of messages without sending network requests, or -1 if the number of messages is unknown locally
|
//@description Returns approximate number of messages of the specified type in the chat @chat_id Identifier of the chat in which to count messages @filter Filter for message content; searchMessagesFilterEmpty is unsupported in this function @return_local Pass true to get the number of messages without sending network requests, or -1 if the number of messages is unknown locally
|
||||||
getChatMessageCount chat_id:int53 filter:SearchMessagesFilter return_local:Bool = Count;
|
getChatMessageCount chat_id:int53 filter:SearchMessagesFilter return_local:Bool = Count;
|
||||||
|
|
||||||
|
//@description Returns approximate 1-based position of a message among messages, which can be found by the specified filter in the chat. Cannot be used in secret chats
|
||||||
|
//@chat_id Identifier of the chat in which to find message position @message_id Message identifier
|
||||||
|
//@filter Filter for message content; searchMessagesFilterEmpty, searchMessagesFilterUnreadMention, searchMessagesFilterUnreadReaction, and searchMessagesFilterFailedToSend are unsupported in this function
|
||||||
|
//@message_thread_id If not 0, only messages in the specified thread will be considered; supergroups only
|
||||||
|
getChatMessagePosition chat_id:int53 message_id:int53 filter:SearchMessagesFilter message_thread_id:int53 = Count;
|
||||||
|
|
||||||
//@description Returns all scheduled messages in a chat. The messages are returned in a reverse chronological order (i.e., in order of decreasing message_id) @chat_id Chat identifier
|
//@description Returns all scheduled messages in a chat. The messages are returned in a reverse chronological order (i.e., in order of decreasing message_id) @chat_id Chat identifier
|
||||||
getChatScheduledMessages chat_id:int53 = Messages;
|
getChatScheduledMessages chat_id:int53 = Messages;
|
||||||
|
|
||||||
@ -5003,8 +5119,8 @@ getChatScheduledMessages chat_id:int53 = Messages;
|
|||||||
//@limit The maximum number of messages to be returned; must be positive and can't be greater than 100. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit
|
//@limit The maximum number of messages to be returned; must be positive and can't be greater than 100. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit
|
||||||
getMessagePublicForwards chat_id:int53 message_id:int53 offset:string limit:int32 = FoundMessages;
|
getMessagePublicForwards chat_id:int53 message_id:int53 offset:string limit:int32 = FoundMessages;
|
||||||
|
|
||||||
//@description Returns sponsored message to be shown in a chat; for channel chats only. Returns a 404 error if there is no sponsored message in the chat @chat_id Identifier of the chat
|
//@description Returns sponsored messages to be shown in a chat; for channel chats only @chat_id Identifier of the chat
|
||||||
getChatSponsoredMessage chat_id:int53 = SponsoredMessage;
|
getChatSponsoredMessages chat_id:int53 = SponsoredMessages;
|
||||||
|
|
||||||
|
|
||||||
//@description Removes an active notification from notification list. Needs to be called only if the notification is removed by the current user @notification_group_id Identifier of notification group to which the notification belongs @notification_id Identifier of removed notification
|
//@description Removes an active notification from notification list. Needs to be called only if the notification is removed by the current user @notification_group_id Identifier of notification group to which the notification belongs @notification_id Identifier of removed notification
|
||||||
@ -5019,8 +5135,8 @@ removeNotificationGroup notification_group_id:int32 max_notification_id:int32 =
|
|||||||
//@message_id Identifier of the message
|
//@message_id Identifier of the message
|
||||||
//@media_timestamp If not 0, timestamp from which the video/audio/video note/voice note playing must start, in seconds. The media can be in the message content or in its web page preview
|
//@media_timestamp If not 0, timestamp from which the video/audio/video note/voice note playing must start, in seconds. The media can be in the message content or in its web page preview
|
||||||
//@for_album Pass true to create a link for the whole media album
|
//@for_album Pass true to create a link for the whole media album
|
||||||
//@for_comment Pass true to create a link to the message as a channel post comment, or from a message thread
|
//@in_message_thread Pass true to create a link to the message as a channel post comment, in a message thread, or a forum topic
|
||||||
getMessageLink chat_id:int53 message_id:int53 media_timestamp:int32 for_album:Bool for_comment:Bool = MessageLink;
|
getMessageLink chat_id:int53 message_id:int53 media_timestamp:int32 for_album:Bool in_message_thread:Bool = MessageLink;
|
||||||
|
|
||||||
//@description Returns an HTML code for embedding the message. Available only for messages in supergroups and channels with a username
|
//@description Returns an HTML code for embedding the message. Available only for messages in supergroups and channels with a username
|
||||||
//@chat_id Identifier of the chat to which the message belongs
|
//@chat_id Identifier of the chat to which the message belongs
|
||||||
@ -5038,17 +5154,17 @@ getMessageLinkInfo url:string = MessageLinkInfo;
|
|||||||
//@to_language_code A two-letter ISO 639-1 language code of the language to which the message is translated
|
//@to_language_code A two-letter ISO 639-1 language code of the language to which the message is translated
|
||||||
translateText text:string from_language_code:string to_language_code:string = Text;
|
translateText text:string from_language_code:string to_language_code:string = Text;
|
||||||
|
|
||||||
//@description Recognizes speech in a voice note message. The message must be successfully sent and must not be scheduled. May return an error with a message "MSG_VOICE_TOO_LONG" if the voice note is too long to be recognized
|
//@description Recognizes speech in a video note or a voice note message. The message must be successfully sent and must not be scheduled. May return an error with a message "MSG_VOICE_TOO_LONG" if media duration is too big to be recognized
|
||||||
//@chat_id Identifier of the chat to which the message belongs
|
//@chat_id Identifier of the chat to which the message belongs
|
||||||
//@message_id Identifier of the message
|
//@message_id Identifier of the message
|
||||||
recognizeSpeech chat_id:int53 message_id:int53 = Ok;
|
recognizeSpeech chat_id:int53 message_id:int53 = Ok;
|
||||||
|
|
||||||
//@description Rates recognized speech in a voice note message @chat_id Identifier of the chat to which the message belongs @message_id Identifier of the message @is_good Pass true if the speech recognition is good
|
//@description Rates recognized speech in a video note or a voice note message @chat_id Identifier of the chat to which the message belongs @message_id Identifier of the message @is_good Pass true if the speech recognition is good
|
||||||
rateSpeechRecognition chat_id:int53 message_id:int53 is_good:Bool = Ok;
|
rateSpeechRecognition chat_id:int53 message_id:int53 is_good:Bool = Ok;
|
||||||
|
|
||||||
|
|
||||||
//@description Returns list of message sender identifiers, which can be used to send messages in a chat @chat_id Chat identifier
|
//@description Returns list of message sender identifiers, which can be used to send messages in a chat @chat_id Chat identifier
|
||||||
getChatAvailableMessageSenders chat_id:int53 = MessageSenders;
|
getChatAvailableMessageSenders chat_id:int53 = ChatMessageSenders;
|
||||||
|
|
||||||
//@description Selects a message sender to send messages in a chat @chat_id Chat identifier @message_sender_id New message sender for the chat
|
//@description Selects a message sender to send messages in a chat @chat_id Chat identifier @message_sender_id New message sender for the chat
|
||||||
setChatMessageSender chat_id:int53 message_sender_id:MessageSender = Ok;
|
setChatMessageSender chat_id:int53 message_sender_id:MessageSender = Ok;
|
||||||
@ -5087,13 +5203,14 @@ sendInlineQueryResultMessage chat_id:int53 message_thread_id:int53 reply_to_mess
|
|||||||
|
|
||||||
//@description Forwards previously sent messages. Returns the forwarded messages in the same order as the message identifiers passed in message_ids. If a message can't be forwarded, null will be returned instead of the message
|
//@description Forwards previously sent messages. Returns the forwarded messages in the same order as the message identifiers passed in message_ids. If a message can't be forwarded, null will be returned instead of the message
|
||||||
//@chat_id Identifier of the chat to which to forward messages
|
//@chat_id Identifier of the chat to which to forward messages
|
||||||
|
//@message_thread_id If not 0, a message thread identifier in which the message will be sent; for forum threads only
|
||||||
//@from_chat_id Identifier of the chat from which to forward messages
|
//@from_chat_id Identifier of the chat from which to forward messages
|
||||||
//@message_ids Identifiers of the messages to forward. Message identifiers must be in a strictly increasing order. At most 100 messages can be forwarded simultaneously
|
//@message_ids Identifiers of the messages to forward. Message identifiers must be in a strictly increasing order. At most 100 messages can be forwarded simultaneously
|
||||||
//@options Options to be used to send the messages; pass null to use default options
|
//@options Options to be used to send the messages; pass null to use default options
|
||||||
//@send_copy Pass true to copy content of the messages without reference to the original sender. Always true if the messages are forwarded to a secret chat or are local
|
//@send_copy Pass true to copy content of the messages without reference to the original sender. Always true if the messages are forwarded to a secret chat or are local
|
||||||
//@remove_caption Pass true to remove media captions of message copies. Ignored if send_copy is false
|
//@remove_caption Pass true to remove media captions of message copies. Ignored if send_copy is false
|
||||||
//@only_preview Pass true to get fake messages instead of actually forwarding them
|
//@only_preview Pass true to get fake messages instead of actually forwarding them
|
||||||
forwardMessages chat_id:int53 from_chat_id:int53 message_ids:vector<int53> options:messageSendOptions send_copy:Bool remove_caption:Bool only_preview:Bool = Messages;
|
forwardMessages chat_id:int53 message_thread_id:int53 from_chat_id:int53 message_ids:vector<int53> options:messageSendOptions send_copy:Bool remove_caption:Bool only_preview:Bool = Messages;
|
||||||
|
|
||||||
//@description Resends messages which failed to send. Can be called only for messages for which messageSendingStateFailed.can_retry is true and after specified in messageSendingStateFailed.retry_after time passed.
|
//@description Resends messages which failed to send. Can be called only for messages for which messageSendingStateFailed.can_retry is true and after specified in messageSendingStateFailed.retry_after time passed.
|
||||||
//-If a message is re-sent, the corresponding failed to send message is deleted. Returns the sent messages in the same order as the message identifiers passed in message_ids. If a message can't be re-sent, null will be returned instead of the message
|
//-If a message is re-sent, the corresponding failed to send message is deleted. Returns the sent messages in the same order as the message identifiers passed in message_ids. If a message can't be re-sent, null will be returned instead of the message
|
||||||
@ -5197,11 +5314,39 @@ editInlineMessageReplyMarkup inline_message_id:string reply_markup:ReplyMarkup =
|
|||||||
editMessageSchedulingState chat_id:int53 message_id:int53 scheduling_state:MessageSchedulingState = Ok;
|
editMessageSchedulingState chat_id:int53 message_id:int53 scheduling_state:MessageSchedulingState = Ok;
|
||||||
|
|
||||||
|
|
||||||
|
//@description Returns list of custom emojis, which can be used as forum topic icon by all users
|
||||||
|
getForumTopicDefaultIcons = Stickers;
|
||||||
|
|
||||||
|
//@description Creates a topic in a forum supergroup chat; requires can_manage_topics rights in the supergroup
|
||||||
|
//@chat_id Identifier of the chat
|
||||||
|
//@name Name of the topic; 1-128 characters
|
||||||
|
//@icon Icon of the topic. Icon color must be one of 0x6FB9F0, 0xFFD67E, 0xCB86DB, 0x8EEE98, 0xFF93B2, or 0xFB6F5F. Telegram Premium users can use any custom emoji as topic icon, other users can use only a custom emoji returned by getForumTopicDefaultIcons
|
||||||
|
createForumTopic chat_id:int53 name:string icon:forumTopicIcon = ForumTopicInfo;
|
||||||
|
|
||||||
|
//@description Edits title and icon of a topic in a forum supergroup chat; requires can_manage_topics administrator rights in the supergroup unless the user is creator of the topic
|
||||||
|
//@chat_id Identifier of the chat
|
||||||
|
//@message_thread_id Message thread identifier of the forum topic
|
||||||
|
//@name New name of the topic; 1-128 characters
|
||||||
|
//@icon_custom_emoji_id Identifier of the new custom emoji for topic icon. Telegram Premium users can use any custom emoji, other users can use only a custom emoji returned by getForumTopicDefaultIcons
|
||||||
|
editForumTopic chat_id:int53 message_thread_id:int53 name:string icon_custom_emoji_id:int64 = Ok;
|
||||||
|
|
||||||
|
//@description Toggles whether a topic is closed in a forum supergroup chat; requires can_manage_topics administrator rights in the supergroup unless the user is creator of the topic
|
||||||
|
//@chat_id Identifier of the chat
|
||||||
|
//@message_thread_id Message thread identifier of the forum topic
|
||||||
|
//@is_closed Pass true to close the topic; pass false to reopen it
|
||||||
|
toggleForumTopicIsClosed chat_id:int53 message_thread_id:int53 is_closed:Bool = Ok;
|
||||||
|
|
||||||
|
//@description Deletes all messages in a forum topic; requires can_delete_messages administrator rights in the supergroup unless the user is creator of the topic, the topic has no messages from other users and has at most 11 messages
|
||||||
|
//@chat_id Identifier of the chat
|
||||||
|
//@message_thread_id Message thread identifier of the forum topic
|
||||||
|
deleteForumTopic chat_id:int53 message_thread_id:int53 = Ok;
|
||||||
|
|
||||||
|
|
||||||
//@description Returns information about a emoji reaction. Returns a 404 error if the reaction is not found @emoji Text representation of the reaction
|
//@description Returns information about a emoji reaction. Returns a 404 error if the reaction is not found @emoji Text representation of the reaction
|
||||||
getEmojiReaction emoji:string = EmojiReaction;
|
getEmojiReaction emoji:string = EmojiReaction;
|
||||||
|
|
||||||
//@description Returns TGS files with generic animations for custom emoji reactions
|
//@description Returns TGS stickers with generic animations for custom emoji reactions
|
||||||
getCustomEmojiReactionAnimations = Files;
|
getCustomEmojiReactionAnimations = Stickers;
|
||||||
|
|
||||||
//@description Returns reactions, which can be added to a message. The list can change after updateActiveEmojiReactions, updateChatAvailableReactions for the chat, or updateMessageInteractionInfo for the message
|
//@description Returns reactions, which can be added to a message. The list can change after updateActiveEmojiReactions, updateChatAvailableReactions for the chat, or updateMessageInteractionInfo for the message
|
||||||
//@chat_id Identifier of the chat to which the message belongs
|
//@chat_id Identifier of the chat to which the message belongs
|
||||||
@ -5238,10 +5383,10 @@ getMessageAddedReactions chat_id:int53 message_id:int53 reaction_type:ReactionTy
|
|||||||
setDefaultReactionType reaction_type:ReactionType = Ok;
|
setDefaultReactionType reaction_type:ReactionType = Ok;
|
||||||
|
|
||||||
|
|
||||||
//@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
|
//@description Returns all entities (mentions, hashtags, cashtags, bot commands, bank card numbers, URLs, and email addresses) found in the text. Can be called synchronously @text The text in which to look for entites
|
||||||
getTextEntities text:string = TextEntities;
|
getTextEntities text:string = TextEntities;
|
||||||
|
|
||||||
//@description Parses Bold, Italic, Underline, Strikethrough, Spoiler, CustomEmoji, 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, CustomEmoji, Code, Pre, PreCode, TextUrl and MentionName entities from a marked-up text. Can be called synchronously @text The text to parse @parse_mode Text parse mode
|
||||||
parseTextEntities text:string parse_mode:TextParseMode = FormattedText;
|
parseTextEntities text:string parse_mode:TextParseMode = FormattedText;
|
||||||
|
|
||||||
//@description Parses Markdown entities in a human-friendly format, ignoring markup errors. Can be called synchronously
|
//@description Parses Markdown entities in a human-friendly format, ignoring markup errors. Can be called synchronously
|
||||||
@ -5347,8 +5492,9 @@ sendWebAppData bot_user_id:int53 button_text:string data:string = Ok;
|
|||||||
//@url The URL from an inlineKeyboardButtonTypeWebApp button, a botMenuButton button, or an internalLinkTypeAttachmentMenuBot link, or an empty string otherwise
|
//@url The URL from an inlineKeyboardButtonTypeWebApp button, a botMenuButton button, or an internalLinkTypeAttachmentMenuBot link, or an empty string otherwise
|
||||||
//@theme Preferred Web App theme; pass null to use the default theme
|
//@theme Preferred Web App theme; pass null to use the default theme
|
||||||
//@application_name Short name of the application; 0-64 English letters, digits, and underscores
|
//@application_name Short name of the application; 0-64 English letters, digits, and underscores
|
||||||
|
//@message_thread_id If not 0, a message thread identifier in which the message will be sent
|
||||||
//@reply_to_message_id Identifier of the replied message for the message sent by the Web App; 0 if none
|
//@reply_to_message_id Identifier of the replied message for the message sent by the Web App; 0 if none
|
||||||
openWebApp chat_id:int53 bot_user_id:int53 url:string theme:themeParameters application_name:string reply_to_message_id:int53 = WebAppInfo;
|
openWebApp chat_id:int53 bot_user_id:int53 url:string theme:themeParameters application_name:string message_thread_id:int53 reply_to_message_id:int53 = WebAppInfo;
|
||||||
|
|
||||||
//@description Informs TDLib that a previously opened Web App was closed @web_app_launch_id Identifier of Web App launch, received from openWebApp
|
//@description Informs TDLib that a previously opened Web App was closed @web_app_launch_id Identifier of Web App launch, received from openWebApp
|
||||||
closeWebApp web_app_launch_id:int64 = Ok;
|
closeWebApp web_app_launch_id:int64 = Ok;
|
||||||
@ -5432,9 +5578,15 @@ getExternalLink link:string allow_write_access:Bool = HttpUrl;
|
|||||||
//@description Marks all mentions in a chat as read @chat_id Chat identifier
|
//@description Marks all mentions in a chat as read @chat_id Chat identifier
|
||||||
readAllChatMentions chat_id:int53 = Ok;
|
readAllChatMentions chat_id:int53 = Ok;
|
||||||
|
|
||||||
//@description Marks all reactions in a chat as read @chat_id Chat identifier
|
//@description Marks all mentions in a forum topic as read @chat_id Chat identifier @message_thread_id Message thread identifier in which mentions are marked as read
|
||||||
|
readAllMessageThreadMentions chat_id:int53 message_thread_id:int53 = Ok;
|
||||||
|
|
||||||
|
//@description Marks all reactions in a chat or a forum topic as read @chat_id Chat identifier
|
||||||
readAllChatReactions chat_id:int53 = Ok;
|
readAllChatReactions chat_id:int53 = Ok;
|
||||||
|
|
||||||
|
//@description Marks all reactions in a forum topic as read @chat_id Chat identifier @message_thread_id Message thread identifier in which reactions are marked as read
|
||||||
|
readAllMessageThreadReactions chat_id:int53 message_thread_id:int53 = Ok;
|
||||||
|
|
||||||
|
|
||||||
//@description Returns an existing chat corresponding to a given user @user_id User identifier @force Pass true to create the chat without a network request. In this case all information about the chat except its type, title and photo can be incorrect
|
//@description Returns an existing chat corresponding to a given user @user_id User identifier @force Pass true to create the chat without a network request. In this case all information about the chat except its type, title and photo can be incorrect
|
||||||
createPrivateChat user_id:int53 force:Bool = Chat;
|
createPrivateChat user_id:int53 force:Bool = Chat;
|
||||||
@ -5564,6 +5716,10 @@ unpinChatMessage chat_id:int53 message_id:int53 = Ok;
|
|||||||
//@description Removes all pinned messages from a chat; requires can_pin_messages rights in the group or can_edit_messages rights in the channel @chat_id Identifier of the chat
|
//@description Removes all pinned messages from a chat; requires can_pin_messages rights in the group or can_edit_messages rights in the channel @chat_id Identifier of the chat
|
||||||
unpinAllChatMessages chat_id:int53 = Ok;
|
unpinAllChatMessages chat_id:int53 = Ok;
|
||||||
|
|
||||||
|
//@description Removes all pinned messages from a forum topic; requires can_pin_messages rights in the supergroup @chat_id Identifier of the chat
|
||||||
|
//@message_thread_id Message thread identifier in which messages will be unpinned
|
||||||
|
unpinAllMessageThreadMessages chat_id:int53 message_thread_id:int53 = Ok;
|
||||||
|
|
||||||
|
|
||||||
//@description Adds the current user as a new member to a chat. Private and secret chats can't be joined using this method. May return an error with a message "INVITE_REQUEST_SENT" if only a join request was created @chat_id Chat identifier
|
//@description Adds the current user as a new member to a chat. Private and secret chats can't be joined using this method. May return an error with a message "INVITE_REQUEST_SENT" if only a join request was created @chat_id Chat identifier
|
||||||
joinChat chat_id:int53 = Ok;
|
joinChat chat_id:int53 = Ok;
|
||||||
@ -5600,7 +5756,7 @@ transferChatOwnership chat_id:int53 user_id:int53 password:string = Ok;
|
|||||||
//@description Returns information about a single member of a chat @chat_id Chat identifier @member_id Member identifier
|
//@description Returns information about a single member of a chat @chat_id Chat identifier @member_id Member identifier
|
||||||
getChatMember chat_id:int53 member_id:MessageSender = ChatMember;
|
getChatMember chat_id:int53 member_id:MessageSender = ChatMember;
|
||||||
|
|
||||||
//@description Searches for a specified query in the first name, last name and username of the members of a specified chat. Requires administrator rights in channels
|
//@description Searches for a specified query in the first name, last name and usernames of the members of a specified chat. Requires administrator rights in channels
|
||||||
//@chat_id Chat identifier
|
//@chat_id Chat identifier
|
||||||
//@query Query to search for
|
//@query Query to search for
|
||||||
//@limit The maximum number of users to be returned; up to 200
|
//@limit The maximum number of users to be returned; up to 200
|
||||||
@ -6045,12 +6201,12 @@ sharePhoneNumber user_id:int53 = Ok;
|
|||||||
getUserProfilePhotos user_id:int53 offset:int32 limit:int32 = ChatPhotos;
|
getUserProfilePhotos user_id:int53 offset:int32 limit:int32 = ChatPhotos;
|
||||||
|
|
||||||
|
|
||||||
//@description Returns stickers from the installed sticker sets that correspond to a given emoji. If the emoji is non-empty, then favorite, recently used or trending stickers may also be returned
|
//@description Returns stickers from the installed sticker sets that correspond to a given emoji or can be found by sticker-specific keywords. If the query is non-empty, then favorite, recently used or trending stickers may also be returned
|
||||||
//@sticker_type Type of the sticker sets to return
|
//@sticker_type Type of the stickers to return
|
||||||
//@emoji String representation of emoji. If empty, returns all known installed stickers
|
//@query Search query; an emoji or a keyword prefix. If empty, returns all known installed stickers
|
||||||
//@limit The maximum number of stickers to be returned
|
//@limit The maximum number of stickers to be returned
|
||||||
//@chat_id Chat identifier for which to return stickers. Available custom emoji may be different for different chats
|
//@chat_id Chat identifier for which to return stickers. Available custom emoji stickers may be different for different chats
|
||||||
getStickers sticker_type:StickerType emoji:string limit:int32 chat_id:int53 = Stickers;
|
getStickers sticker_type:StickerType query:string limit:int32 chat_id:int53 = Stickers;
|
||||||
|
|
||||||
//@description Searches for stickers from public sticker sets that correspond to a given emoji @emoji String representation of emoji; must be non-empty @limit The maximum number of stickers to be returned; 0-100
|
//@description Searches for stickers from public sticker sets that correspond to a given emoji @emoji String representation of emoji; must be non-empty @limit The maximum number of stickers to be returned; 0-100
|
||||||
searchStickers emoji:string limit:int32 = Stickers;
|
searchStickers emoji:string limit:int32 = Stickers;
|
||||||
@ -6174,9 +6330,15 @@ setName first_name:string last_name:string = Ok;
|
|||||||
//@description Changes the bio of the current user @bio The new value of the user bio; 0-GetOption("bio_length_max") characters without line feeds
|
//@description Changes the bio of the current user @bio The new value of the user bio; 0-GetOption("bio_length_max") characters without line feeds
|
||||||
setBio bio:string = Ok;
|
setBio bio:string = Ok;
|
||||||
|
|
||||||
//@description Changes the username of the current user @username The new value of the username. Use an empty string to remove the username
|
//@description Changes the editable username of the current user @username The new value of the username. Use an empty string to remove the username. The username can't be completely removed if there is another active or disabled username
|
||||||
setUsername username:string = Ok;
|
setUsername username:string = Ok;
|
||||||
|
|
||||||
|
//@description Changes active state for a username of the current user. The editable username can't be disabled. May return an error with a message "USERNAMES_ACTIVE_TOO_MUCH" if the maximum number of active usernames has been reached @username The username to change @is_active Pass true to activate the username; pass false to disable it
|
||||||
|
toggleUsernameIsActive username:string is_active:Bool = Ok;
|
||||||
|
|
||||||
|
//@description Changes order of active usernames of the current user @usernames The new order of active usernames. All currently active usernames must be specified
|
||||||
|
reorderActiveUsernames usernames:vector<string> = Ok;
|
||||||
|
|
||||||
//@description Changes the emoji status of the current user; for Telegram Premium users only
|
//@description Changes the emoji status of the current user; for Telegram Premium users only
|
||||||
//@emoji_status New emoji status; pass null to switch to the default badge
|
//@emoji_status New emoji status; pass null to switch to the default badge
|
||||||
//@duration Duration of the status, in seconds; pass 0 to keep the status active until it will be changed manually
|
//@duration Duration of the status, in seconds; pass 0 to keep the status active until it will be changed manually
|
||||||
@ -6256,9 +6418,18 @@ disconnectWebsite website_id:int64 = Ok;
|
|||||||
disconnectAllWebsites = Ok;
|
disconnectAllWebsites = Ok;
|
||||||
|
|
||||||
|
|
||||||
//@description Changes the username of a supergroup or channel, requires owner privileges in the supergroup or channel @supergroup_id Identifier of the supergroup or channel @username New value of the username. Use an empty string to remove the username
|
//@description Changes the editable username of a supergroup or channel, requires owner privileges in the supergroup or channel @supergroup_id Identifier of the supergroup or channel @username New value of the username. Use an empty string to remove the username. The username can't be completely removed if there is another active or disabled username
|
||||||
setSupergroupUsername supergroup_id:int53 username:string = Ok;
|
setSupergroupUsername supergroup_id:int53 username:string = Ok;
|
||||||
|
|
||||||
|
//@description Changes active state for a username of a supergroup or channel, requires owner privileges in the supergroup or channel. The editable username can't be disabled. May return an error with a message "USERNAMES_ACTIVE_TOO_MUCH" if the maximum number of active usernames has been reached @supergroup_id Identifier of the supergroup or channel @username The username to change @is_active Pass true to activate the username; pass false to disable it
|
||||||
|
toggleSupergroupUsernameIsActive supergroup_id:int53 username:string is_active:Bool = Ok;
|
||||||
|
|
||||||
|
//@description Disables all active non-editable usernames of a supergroup or channel, requires owner privileges in the supergroup or channel @supergroup_id Identifier of the supergroup or channel
|
||||||
|
disableAllSupergroupUsernames supergroup_id:int53 = Ok;
|
||||||
|
|
||||||
|
//@description Changes order of active usernames of a supergroup or channel, requires owner privileges in the supergroup or channel @supergroup_id Identifier of the supergroup or channel @usernames The new order of active usernames. All currently active usernames must be specified
|
||||||
|
reorderSupergroupActiveUsernames supergroup_id:int53 usernames:vector<string> = Ok;
|
||||||
|
|
||||||
//@description Changes the sticker set of a supergroup; requires can_change_info administrator right @supergroup_id Identifier of the supergroup @sticker_set_id New value of the supergroup sticker set identifier. Use 0 to remove the supergroup sticker set
|
//@description Changes the sticker set of a supergroup; requires can_change_info administrator right @supergroup_id Identifier of the supergroup @sticker_set_id New value of the supergroup sticker set identifier. Use 0 to remove the supergroup sticker set
|
||||||
setSupergroupStickerSet supergroup_id:int53 sticker_set_id:int64 = Ok;
|
setSupergroupStickerSet supergroup_id:int53 sticker_set_id:int64 = Ok;
|
||||||
|
|
||||||
@ -6274,6 +6445,9 @@ toggleSupergroupJoinByRequest supergroup_id:int53 join_by_request:Bool = Ok;
|
|||||||
//@description Toggles whether the message history of a supergroup is available to new members; requires can_change_info administrator right @supergroup_id The identifier of the supergroup @is_all_history_available The new value of is_all_history_available
|
//@description Toggles whether the message history of a supergroup is available to new members; requires can_change_info administrator right @supergroup_id The identifier of the supergroup @is_all_history_available The new value of is_all_history_available
|
||||||
toggleSupergroupIsAllHistoryAvailable supergroup_id:int53 is_all_history_available:Bool = Ok;
|
toggleSupergroupIsAllHistoryAvailable supergroup_id:int53 is_all_history_available:Bool = Ok;
|
||||||
|
|
||||||
|
//@description Toggles whether the supergroup is a forum; requires owner privileges in the supergroup @supergroup_id Identifier of the supergroup @is_forum New value of is_forum. A supergroup can be converted to a forum, only if it has at least GetOption("forum_member_count_min") members
|
||||||
|
toggleSupergroupIsForum supergroup_id:int53 is_forum:Bool = Ok;
|
||||||
|
|
||||||
//@description Upgrades supergroup to a broadcast group; requires owner privileges in the supergroup @supergroup_id Identifier of the supergroup
|
//@description Upgrades supergroup to a broadcast group; requires owner privileges in the supergroup @supergroup_id Identifier of the supergroup
|
||||||
toggleSupergroupIsBroadcastGroup supergroup_id:int53 = Ok;
|
toggleSupergroupIsBroadcastGroup supergroup_id:int53 = Ok;
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string pro
|
|||||||
inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
||||||
inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
||||||
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
|
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
|
||||||
inputMediaInvoice#d9799874 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:flags.1?string = InputMedia;
|
inputMediaInvoice#8eb5a6d5 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:flags.1?string extended_media:flags.2?InputMedia = InputMedia;
|
||||||
inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia;
|
inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia;
|
||||||
inputMediaPoll#f94e5f1 flags:# poll:Poll correct_answers:flags.0?Vector<bytes> solution:flags.1?string solution_entities:flags.1?Vector<MessageEntity> = InputMedia;
|
inputMediaPoll#f94e5f1 flags:# poll:Poll correct_answers:flags.0?Vector<bytes> solution:flags.1?string solution_entities:flags.1?Vector<MessageEntity> = InputMedia;
|
||||||
inputMediaDice#e66fbf7b emoticon:string = InputMedia;
|
inputMediaDice#e66fbf7b emoticon:string = InputMedia;
|
||||||
@ -101,7 +101,7 @@ storage.fileMp4#b3cea0e4 = storage.FileType;
|
|||||||
storage.fileWebp#1081464c = storage.FileType;
|
storage.fileWebp#1081464c = storage.FileType;
|
||||||
|
|
||||||
userEmpty#d3bc4b7a id:long = User;
|
userEmpty#d3bc4b7a id:long = User;
|
||||||
user#5d99adee flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus = User;
|
user#8f97c628 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true flags2:# id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus usernames:flags2.0?Vector<Username> = User;
|
||||||
|
|
||||||
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
|
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
|
||||||
userProfilePhoto#82d1f706 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto;
|
userProfilePhoto#82d1f706 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto;
|
||||||
@ -116,7 +116,7 @@ userStatusLastMonth#77ebc742 = UserStatus;
|
|||||||
chatEmpty#29562865 id:long = Chat;
|
chatEmpty#29562865 id:long = Chat;
|
||||||
chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
|
chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
|
||||||
chatForbidden#6592a1a7 id:long title:string = Chat;
|
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 join_to_send:flags.28?true join_request:flags.29?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector<RestrictionReason> admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat;
|
channel#83259464 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 join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector<RestrictionReason> admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector<Username> = 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;
|
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#c9d31138 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<BotInfo> 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<long> available_reactions:flags.18?ChatReactions = ChatFull;
|
chatFull#c9d31138 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<BotInfo> 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<long> available_reactions:flags.18?ChatReactions = ChatFull;
|
||||||
@ -145,7 +145,7 @@ messageMediaDocument#9cb070d7 flags:# nopremium:flags.3?true document:flags.0?Do
|
|||||||
messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
|
messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
|
||||||
messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
|
messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
|
||||||
messageMediaGame#fdb19008 game:Game = MessageMedia;
|
messageMediaGame#fdb19008 game:Game = MessageMedia;
|
||||||
messageMediaInvoice#84551347 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string = MessageMedia;
|
messageMediaInvoice#f6a548d3 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string extended_media:flags.4?MessageExtendedMedia = MessageMedia;
|
||||||
messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int proximity_notification_radius:flags.1?int = MessageMedia;
|
messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int proximity_notification_radius:flags.1?int = MessageMedia;
|
||||||
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
|
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
|
||||||
messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia;
|
messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia;
|
||||||
@ -183,6 +183,8 @@ messageActionChatJoinedByRequest#ebbca3cb = MessageAction;
|
|||||||
messageActionWebViewDataSentMe#47dd8079 text:string data:string = MessageAction;
|
messageActionWebViewDataSentMe#47dd8079 text:string data:string = MessageAction;
|
||||||
messageActionWebViewDataSent#b4c38cb5 text:string = MessageAction;
|
messageActionWebViewDataSent#b4c38cb5 text:string = MessageAction;
|
||||||
messageActionGiftPremium#aba0f5c6 currency:string amount:long months:int = MessageAction;
|
messageActionGiftPremium#aba0f5c6 currency:string amount:long months:int = MessageAction;
|
||||||
|
messageActionTopicCreate#d999256 flags:# title:string icon_color:int icon_emoji_id:flags.0?long = MessageAction;
|
||||||
|
messageActionTopicEdit#b18a431c flags:# title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool = MessageAction;
|
||||||
|
|
||||||
dialog#a8edd0f5 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int = Dialog;
|
dialog#a8edd0f5 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int = Dialog;
|
||||||
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
||||||
@ -211,6 +213,7 @@ inputNotifyPeer#b8bc5b0c peer:InputPeer = InputNotifyPeer;
|
|||||||
inputNotifyUsers#193b4417 = InputNotifyPeer;
|
inputNotifyUsers#193b4417 = InputNotifyPeer;
|
||||||
inputNotifyChats#4a95e84e = InputNotifyPeer;
|
inputNotifyChats#4a95e84e = InputNotifyPeer;
|
||||||
inputNotifyBroadcasts#b1db7c7e = InputNotifyPeer;
|
inputNotifyBroadcasts#b1db7c7e = InputNotifyPeer;
|
||||||
|
inputNotifyForumTopic#5c467992 peer:InputPeer top_msg_id:int = InputNotifyPeer;
|
||||||
|
|
||||||
inputPeerNotifySettings#df1f002b flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?NotificationSound = InputPeerNotifySettings;
|
inputPeerNotifySettings#df1f002b flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?NotificationSound = InputPeerNotifySettings;
|
||||||
|
|
||||||
@ -289,7 +292,7 @@ updateUserTyping#c01e857f user_id:long action:SendMessageAction = Update;
|
|||||||
updateChatUserTyping#83487af0 chat_id:long from_id:Peer action:SendMessageAction = Update;
|
updateChatUserTyping#83487af0 chat_id:long from_id:Peer action:SendMessageAction = Update;
|
||||||
updateChatParticipants#7761198 participants:ChatParticipants = Update;
|
updateChatParticipants#7761198 participants:ChatParticipants = Update;
|
||||||
updateUserStatus#e5bdf8de user_id:long status:UserStatus = Update;
|
updateUserStatus#e5bdf8de user_id:long status:UserStatus = Update;
|
||||||
updateUserName#c3f202e0 user_id:long first_name:string last_name:string username:string = Update;
|
updateUserName#a7848924 user_id:long first_name:string last_name:string usernames:Vector<Username> = Update;
|
||||||
updateUserPhoto#f227868c user_id:long date:int photo:UserProfilePhoto previous:Bool = Update;
|
updateUserPhoto#f227868c user_id:long date:int photo:UserProfilePhoto previous:Bool = Update;
|
||||||
updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update;
|
updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update;
|
||||||
updateEncryptedChatTyping#1710f156 chat_id:int = Update;
|
updateEncryptedChatTyping#1710f156 chat_id:int = Update;
|
||||||
@ -324,7 +327,7 @@ updateBotCallbackQuery#b9cfc48d flags:# query_id:long user_id:long peer:Peer msg
|
|||||||
updateEditMessage#e40370a3 message:Message pts:int pts_count:int = Update;
|
updateEditMessage#e40370a3 message:Message pts:int pts_count:int = Update;
|
||||||
updateInlineBotCallbackQuery#691e9052 flags:# query_id:long user_id:long msg_id:InputBotInlineMessageID chat_instance:long data:flags.0?bytes game_short_name:flags.1?string = Update;
|
updateInlineBotCallbackQuery#691e9052 flags:# query_id:long user_id:long msg_id:InputBotInlineMessageID chat_instance:long data:flags.0?bytes game_short_name:flags.1?string = Update;
|
||||||
updateReadChannelOutbox#b75f99a9 channel_id:long max_id:int = Update;
|
updateReadChannelOutbox#b75f99a9 channel_id:long max_id:int = Update;
|
||||||
updateDraftMessage#ee2bb969 peer:Peer draft:DraftMessage = Update;
|
updateDraftMessage#1b49ec6d flags:# peer:Peer top_msg_id:flags.0?int draft:DraftMessage = Update;
|
||||||
updateReadFeaturedStickers#571d2742 = Update;
|
updateReadFeaturedStickers#571d2742 = Update;
|
||||||
updateRecentStickers#9a422c20 = Update;
|
updateRecentStickers#9a422c20 = Update;
|
||||||
updateConfig#a229dd06 = Update;
|
updateConfig#a229dd06 = Update;
|
||||||
@ -340,7 +343,7 @@ updatePhoneCall#ab0f6b1e phone_call:PhoneCall = Update;
|
|||||||
updateLangPackTooLong#46560264 lang_code:string = Update;
|
updateLangPackTooLong#46560264 lang_code:string = Update;
|
||||||
updateLangPack#56022f4d difference:LangPackDifference = Update;
|
updateLangPack#56022f4d difference:LangPackDifference = Update;
|
||||||
updateFavedStickers#e511996d = Update;
|
updateFavedStickers#e511996d = Update;
|
||||||
updateChannelReadMessagesContents#44bdd535 channel_id:long messages:Vector<int> = Update;
|
updateChannelReadMessagesContents#ea29055d flags:# channel_id:long top_msg_id:flags.0?int messages:Vector<int> = Update;
|
||||||
updateContactsReset#7084a7be = Update;
|
updateContactsReset#7084a7be = Update;
|
||||||
updateChannelAvailableMessages#b23fc698 channel_id:long available_min_id:int = Update;
|
updateChannelAvailableMessages#b23fc698 channel_id:long available_min_id:int = Update;
|
||||||
updateDialogUnreadMark#e16459c3 flags:# unread:flags.0?true peer:DialogPeer = Update;
|
updateDialogUnreadMark#e16459c3 flags:# unread:flags.0?true peer:DialogPeer = Update;
|
||||||
@ -377,7 +380,7 @@ updateGroupCallConnection#b783982 flags:# presentation:flags.0?true params:DataJ
|
|||||||
updateBotCommands#4d712f2e peer:Peer bot_id:long commands:Vector<BotCommand> = Update;
|
updateBotCommands#4d712f2e peer:Peer bot_id:long commands:Vector<BotCommand> = Update;
|
||||||
updatePendingJoinRequests#7063c3db peer:Peer requests_pending:int recent_requesters:Vector<long> = Update;
|
updatePendingJoinRequests#7063c3db peer:Peer requests_pending:int recent_requesters:Vector<long> = Update;
|
||||||
updateBotChatInviteRequester#11dfa986 peer:Peer date:int user_id:long about:string invite:ExportedChatInvite qts:int = 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;
|
updateMessageReactions#5e1b3cb8 flags:# peer:Peer msg_id:int top_msg_id:flags.0?int reactions:MessageReactions = Update;
|
||||||
updateAttachMenuBots#17b7a20b = Update;
|
updateAttachMenuBots#17b7a20b = Update;
|
||||||
updateWebViewResultSent#1592b79d query_id:long = Update;
|
updateWebViewResultSent#1592b79d query_id:long = Update;
|
||||||
updateBotMenuButton#14b85813 bot_id:long button:BotMenuButton = Update;
|
updateBotMenuButton#14b85813 bot_id:long button:BotMenuButton = Update;
|
||||||
@ -388,6 +391,8 @@ updateUserEmojiStatus#28373599 user_id:long emoji_status:EmojiStatus = Update;
|
|||||||
updateRecentEmojiStatuses#30f443db = Update;
|
updateRecentEmojiStatuses#30f443db = Update;
|
||||||
updateRecentReactions#6f7863f4 = Update;
|
updateRecentReactions#6f7863f4 = Update;
|
||||||
updateMoveStickerSetToTop#86fccf85 flags:# masks:flags.0?true emojis:flags.1?true stickerset:long = Update;
|
updateMoveStickerSetToTop#86fccf85 flags:# masks:flags.0?true emojis:flags.1?true stickerset:long = Update;
|
||||||
|
updateMessageExtendedMedia#5a73a98c peer:Peer msg_id:int extended_media:MessageExtendedMedia = Update;
|
||||||
|
updateChannelPinnedTopic#f694b0ae flags:# channel_id:long topic_id:flags.0?int = Update;
|
||||||
|
|
||||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||||
|
|
||||||
@ -460,6 +465,7 @@ notifyPeer#9fd40bd8 peer:Peer = NotifyPeer;
|
|||||||
notifyUsers#b4c83b4c = NotifyPeer;
|
notifyUsers#b4c83b4c = NotifyPeer;
|
||||||
notifyChats#c007cec3 = NotifyPeer;
|
notifyChats#c007cec3 = NotifyPeer;
|
||||||
notifyBroadcasts#d612e8ef = NotifyPeer;
|
notifyBroadcasts#d612e8ef = NotifyPeer;
|
||||||
|
notifyForumTopic#226e6308 peer:Peer top_msg_id:int = NotifyPeer;
|
||||||
|
|
||||||
sendMessageTypingAction#16bf744e = SendMessageAction;
|
sendMessageTypingAction#16bf744e = SendMessageAction;
|
||||||
sendMessageCancelAction#fd5ec8f5 = SendMessageAction;
|
sendMessageCancelAction#fd5ec8f5 = SendMessageAction;
|
||||||
@ -578,10 +584,11 @@ inputStickerSetAnimatedEmojiAnimations#cde3739 = InputStickerSet;
|
|||||||
inputStickerSetPremiumGifts#c88b3b02 = InputStickerSet;
|
inputStickerSetPremiumGifts#c88b3b02 = InputStickerSet;
|
||||||
inputStickerSetEmojiGenericAnimations#4c4d4ce = InputStickerSet;
|
inputStickerSetEmojiGenericAnimations#4c4d4ce = InputStickerSet;
|
||||||
inputStickerSetEmojiDefaultStatuses#29d0f5ee = InputStickerSet;
|
inputStickerSetEmojiDefaultStatuses#29d0f5ee = InputStickerSet;
|
||||||
|
inputStickerSetEmojiDefaultTopicIcons#44c1f8e9 = InputStickerSet;
|
||||||
|
|
||||||
stickerSet#2dd14edc flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true videos:flags.6?true emojis:flags.7?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector<PhotoSize> thumb_dc_id:flags.4?int thumb_version:flags.4?int thumb_document_id:flags.8?long count:int hash:int = StickerSet;
|
stickerSet#2dd14edc flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true videos:flags.6?true emojis:flags.7?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector<PhotoSize> thumb_dc_id:flags.4?int thumb_version:flags.4?int thumb_document_id:flags.8?long count:int hash:int = StickerSet;
|
||||||
|
|
||||||
messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = messages.StickerSet;
|
messages.stickerSet#6e153f16 set:StickerSet packs:Vector<StickerPack> keywords:Vector<StickerKeyword> documents:Vector<Document> = messages.StickerSet;
|
||||||
messages.stickerSetNotModified#d3f924eb = messages.StickerSet;
|
messages.stickerSetNotModified#d3f924eb = messages.StickerSet;
|
||||||
|
|
||||||
botCommand#c27ac8c7 command:string description:string = BotCommand;
|
botCommand#c27ac8c7 command:string description:string = BotCommand;
|
||||||
@ -760,7 +767,7 @@ messages.stickerSetInstallResultArchive#35e410a8 sets:Vector<StickerSetCovered>
|
|||||||
|
|
||||||
stickerSetCovered#6410a5d2 set:StickerSet cover:Document = StickerSetCovered;
|
stickerSetCovered#6410a5d2 set:StickerSet cover:Document = StickerSetCovered;
|
||||||
stickerSetMultiCovered#3407e51b set:StickerSet covers:Vector<Document> = StickerSetCovered;
|
stickerSetMultiCovered#3407e51b set:StickerSet covers:Vector<Document> = StickerSetCovered;
|
||||||
stickerSetFullCovered#1aed5ee5 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = StickerSetCovered;
|
stickerSetFullCovered#40d13c0e set:StickerSet packs:Vector<StickerPack> keywords:Vector<StickerKeyword> documents:Vector<Document> = StickerSetCovered;
|
||||||
|
|
||||||
maskCoords#aed6dbb2 n:int x:double y:double zoom:double = MaskCoords;
|
maskCoords#aed6dbb2 n:int x:double y:double zoom:double = MaskCoords;
|
||||||
|
|
||||||
@ -942,12 +949,18 @@ channelAdminLogEventActionParticipantJoinByRequest#afb6144a invite:ExportedChatI
|
|||||||
channelAdminLogEventActionToggleNoForwards#cb2ac766 new_value:Bool = ChannelAdminLogEventAction;
|
channelAdminLogEventActionToggleNoForwards#cb2ac766 new_value:Bool = ChannelAdminLogEventAction;
|
||||||
channelAdminLogEventActionSendMessage#278f2868 message:Message = ChannelAdminLogEventAction;
|
channelAdminLogEventActionSendMessage#278f2868 message:Message = ChannelAdminLogEventAction;
|
||||||
channelAdminLogEventActionChangeAvailableReactions#be4e0ef8 prev_value:ChatReactions new_value:ChatReactions = ChannelAdminLogEventAction;
|
channelAdminLogEventActionChangeAvailableReactions#be4e0ef8 prev_value:ChatReactions new_value:ChatReactions = ChannelAdminLogEventAction;
|
||||||
|
channelAdminLogEventActionChangeUsernames#f04fb3a9 prev_value:Vector<string> new_value:Vector<string> = ChannelAdminLogEventAction;
|
||||||
|
channelAdminLogEventActionToggleForum#2cc6383 new_value:Bool = ChannelAdminLogEventAction;
|
||||||
|
channelAdminLogEventActionCreateTopic#58707d28 topic:ForumTopic = ChannelAdminLogEventAction;
|
||||||
|
channelAdminLogEventActionEditTopic#f06fe208 prev_topic:ForumTopic new_topic:ForumTopic = ChannelAdminLogEventAction;
|
||||||
|
channelAdminLogEventActionDeleteTopic#ae168909 topic:ForumTopic = ChannelAdminLogEventAction;
|
||||||
|
channelAdminLogEventActionPinTopic#5d8d353b flags:# prev_topic:flags.0?ForumTopic new_topic:flags.1?ForumTopic = ChannelAdminLogEventAction;
|
||||||
|
|
||||||
channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
|
channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
|
||||||
|
|
||||||
channels.adminLogResults#ed8af74d events:Vector<ChannelAdminLogEvent> chats:Vector<Chat> users:Vector<User> = channels.AdminLogResults;
|
channels.adminLogResults#ed8af74d events:Vector<ChannelAdminLogEvent> chats:Vector<Chat> users:Vector<User> = channels.AdminLogResults;
|
||||||
|
|
||||||
channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?true invite:flags.2?true ban:flags.3?true unban:flags.4?true kick:flags.5?true unkick:flags.6?true promote:flags.7?true demote:flags.8?true info:flags.9?true settings:flags.10?true pinned:flags.11?true edit:flags.12?true delete:flags.13?true group_call:flags.14?true invites:flags.15?true send:flags.16?true = ChannelAdminLogEventsFilter;
|
channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?true invite:flags.2?true ban:flags.3?true unban:flags.4?true kick:flags.5?true unkick:flags.6?true promote:flags.7?true demote:flags.8?true info:flags.9?true settings:flags.10?true pinned:flags.11?true edit:flags.12?true delete:flags.13?true group_call:flags.14?true invites:flags.15?true send:flags.16?true forums:flags.17?true = ChannelAdminLogEventsFilter;
|
||||||
|
|
||||||
popularContact#5ce14175 client_id:long importers:int = PopularContact;
|
popularContact#5ce14175 client_id:long importers:int = PopularContact;
|
||||||
|
|
||||||
@ -1105,9 +1118,9 @@ chatOnlines#f041e250 onlines:int = ChatOnlines;
|
|||||||
|
|
||||||
statsURL#47a971e0 url:string = StatsURL;
|
statsURL#47a971e0 url:string = StatsURL;
|
||||||
|
|
||||||
chatAdminRights#5fb224d5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true pin_messages:flags.7?true add_admins:flags.9?true anonymous:flags.10?true manage_call:flags.11?true other:flags.12?true = ChatAdminRights;
|
chatAdminRights#5fb224d5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true pin_messages:flags.7?true add_admins:flags.9?true anonymous:flags.10?true manage_call:flags.11?true other:flags.12?true manage_topics:flags.13?true = ChatAdminRights;
|
||||||
|
|
||||||
chatBannedRights#9f120418 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true send_polls:flags.8?true change_info:flags.10?true invite_users:flags.15?true pin_messages:flags.17?true until_date:int = ChatBannedRights;
|
chatBannedRights#9f120418 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true send_polls:flags.8?true change_info:flags.10?true invite_users:flags.15?true pin_messages:flags.17?true manage_topics:flags.18?true until_date:int = ChatBannedRights;
|
||||||
|
|
||||||
inputWallPaper#e630b979 id:long access_hash:long = InputWallPaper;
|
inputWallPaper#e630b979 id:long access_hash:long = InputWallPaper;
|
||||||
inputWallPaperSlug#72091c80 slug:string = InputWallPaper;
|
inputWallPaperSlug#72091c80 slug:string = InputWallPaper;
|
||||||
@ -1238,7 +1251,7 @@ messages.messageViews#b6c4f543 views:Vector<MessageViews> chats:Vector<Chat> use
|
|||||||
|
|
||||||
messages.discussionMessage#a6341782 flags:# messages:Vector<Message> max_id:flags.0?int read_inbox_max_id:flags.1?int read_outbox_max_id:flags.2?int unread_count:int chats:Vector<Chat> users:Vector<User> = messages.DiscussionMessage;
|
messages.discussionMessage#a6341782 flags:# messages:Vector<Message> max_id:flags.0?int read_inbox_max_id:flags.1?int read_outbox_max_id:flags.2?int unread_count:int chats:Vector<Chat> users:Vector<User> = messages.DiscussionMessage;
|
||||||
|
|
||||||
messageReplyHeader#a6d57763 flags:# reply_to_scheduled:flags.2?true reply_to_msg_id:int reply_to_peer_id:flags.0?Peer reply_to_top_id:flags.1?int = MessageReplyHeader;
|
messageReplyHeader#a6d57763 flags:# reply_to_scheduled:flags.2?true forum_topic:flags.3?true reply_to_msg_id:int reply_to_peer_id:flags.0?Peer reply_to_top_id:flags.1?int = MessageReplyHeader;
|
||||||
|
|
||||||
messageReplies#83d60fc2 flags:# comments:flags.0?true replies:int replies_pts:int recent_repliers:flags.1?Vector<Peer> channel_id:flags.0?long max_id:flags.2?int read_max_id:flags.3?int = MessageReplies;
|
messageReplies#83d60fc2 flags:# comments:flags.0?true replies:int replies_pts:int recent_repliers:flags.1?Vector<Peer> channel_id:flags.0?long max_id:flags.2?int read_max_id:flags.3?int = MessageReplies;
|
||||||
|
|
||||||
@ -1306,9 +1319,10 @@ account.resetPasswordFailedWait#e3779861 retry_date:int = account.ResetPasswordR
|
|||||||
account.resetPasswordRequestedWait#e9effc7d until_date:int = account.ResetPasswordResult;
|
account.resetPasswordRequestedWait#e9effc7d until_date:int = account.ResetPasswordResult;
|
||||||
account.resetPasswordOk#e926d63e = account.ResetPasswordResult;
|
account.resetPasswordOk#e926d63e = account.ResetPasswordResult;
|
||||||
|
|
||||||
sponsoredMessage#3a836df8 flags:# recommended:flags.5?true 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<MessageEntity> = SponsoredMessage;
|
sponsoredMessage#3a836df8 flags:# recommended:flags.5?true show_peer_photo:flags.6?true 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<MessageEntity> = SponsoredMessage;
|
||||||
|
|
||||||
messages.sponsoredMessages#65a4c7d5 messages:Vector<SponsoredMessage> chats:Vector<Chat> users:Vector<User> = messages.SponsoredMessages;
|
messages.sponsoredMessages#c9ee1d87 flags:# posts_between:flags.0?int messages:Vector<SponsoredMessage> chats:Vector<Chat> users:Vector<User> = messages.SponsoredMessages;
|
||||||
|
messages.sponsoredMessagesEmpty#1839490f = messages.SponsoredMessages;
|
||||||
|
|
||||||
searchResultsCalendarPeriod#c9b0539f date:int min_msg_id:int max_msg_id:int count:int = SearchResultsCalendarPeriod;
|
searchResultsCalendarPeriod#c9b0539f date:int min_msg_id:int max_msg_id:int count:int = SearchResultsCalendarPeriod;
|
||||||
|
|
||||||
@ -1318,7 +1332,7 @@ searchResultPosition#7f648b67 msg_id:int date:int offset:int = SearchResultsPosi
|
|||||||
|
|
||||||
messages.searchResultsPositions#53b22baf count:int positions:Vector<SearchResultsPosition> = messages.SearchResultsPositions;
|
messages.searchResultsPositions#53b22baf count:int positions:Vector<SearchResultsPosition> = messages.SearchResultsPositions;
|
||||||
|
|
||||||
channels.sendAsPeers#8356cda9 peers:Vector<Peer> chats:Vector<Chat> users:Vector<User> = channels.SendAsPeers;
|
channels.sendAsPeers#f496b0c6 peers:Vector<SendAsPeer> chats:Vector<Chat> users:Vector<User> = channels.SendAsPeers;
|
||||||
|
|
||||||
users.userFull#3b6d152e full_user:UserFull chats:Vector<Chat> users:Vector<User> = users.UserFull;
|
users.userFull#3b6d152e full_user:UserFull chats:Vector<Chat> users:Vector<User> = users.UserFull;
|
||||||
|
|
||||||
@ -1433,6 +1447,20 @@ account.emailVerifiedLogin#e1bb0d61 email:string sent_code:auth.SentCode = accou
|
|||||||
|
|
||||||
premiumSubscriptionOption#b6f11ebe flags:# current:flags.1?true can_purchase_upgrade:flags.2?true months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumSubscriptionOption;
|
premiumSubscriptionOption#b6f11ebe flags:# current:flags.1?true can_purchase_upgrade:flags.2?true months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumSubscriptionOption;
|
||||||
|
|
||||||
|
sendAsPeer#b81c7034 flags:# premium_required:flags.0?true peer:Peer = SendAsPeer;
|
||||||
|
|
||||||
|
messageExtendedMediaPreview#ad628cc8 flags:# w:flags.0?int h:flags.0?int thumb:flags.1?PhotoSize video_duration:flags.2?int = MessageExtendedMedia;
|
||||||
|
messageExtendedMedia#ee479c64 media:MessageMedia = MessageExtendedMedia;
|
||||||
|
|
||||||
|
stickerKeyword#fcfeb29c document_id:long keyword:Vector<string> = StickerKeyword;
|
||||||
|
|
||||||
|
username#b4073647 flags:# editable:flags.0?true active:flags.1?true username:string = Username;
|
||||||
|
|
||||||
|
forumTopicDeleted#23f109b id:int = ForumTopic;
|
||||||
|
forumTopic#71701da9 flags:# my:flags.1?true closed:flags.2?true pinned:flags.3?true id:int date:int title:string icon_color:int icon_emoji_id:flags.0?long top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int from_id:Peer notify_settings:PeerNotifySettings draft:flags.4?DraftMessage = ForumTopic;
|
||||||
|
|
||||||
|
messages.forumTopics#367617d3 flags:# order_by_create_date:flags.0?true count:int topics:Vector<ForumTopic> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> pts:int = messages.ForumTopics;
|
||||||
|
|
||||||
---functions---
|
---functions---
|
||||||
|
|
||||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||||
@ -1523,7 +1551,7 @@ account.createTheme#652e4400 flags:# slug:string title:string document:flags.2?I
|
|||||||
account.updateTheme#2bf40ccc flags:# format:string theme:InputTheme slug:flags.0?string title:flags.1?string document:flags.2?InputDocument settings:flags.3?Vector<InputThemeSettings> = Theme;
|
account.updateTheme#2bf40ccc flags:# format:string theme:InputTheme slug:flags.0?string title:flags.1?string document:flags.2?InputDocument settings:flags.3?Vector<InputThemeSettings> = Theme;
|
||||||
account.saveTheme#f257106c theme:InputTheme unsave:Bool = Bool;
|
account.saveTheme#f257106c theme:InputTheme unsave:Bool = Bool;
|
||||||
account.installTheme#c727bb3b flags:# dark:flags.0?true theme:flags.1?InputTheme format:flags.2?string base_theme:flags.3?BaseTheme = Bool;
|
account.installTheme#c727bb3b flags:# dark:flags.0?true theme:flags.1?InputTheme format:flags.2?string base_theme:flags.3?BaseTheme = Bool;
|
||||||
account.getTheme#8d9d742b format:string theme:InputTheme document_id:long = Theme;
|
account.getTheme#3a5869ec format:string theme:InputTheme = Theme;
|
||||||
account.getThemes#7206e458 format:string hash:long = account.Themes;
|
account.getThemes#7206e458 format:string hash:long = account.Themes;
|
||||||
account.setContentSettings#b574b16b flags:# sensitive_enabled:flags.0?true = Bool;
|
account.setContentSettings#b574b16b flags:# sensitive_enabled:flags.0?true = Bool;
|
||||||
account.getContentSettings#8b9b4dae = account.ContentSettings;
|
account.getContentSettings#8b9b4dae = account.ContentSettings;
|
||||||
@ -1543,6 +1571,8 @@ account.updateEmojiStatus#fbd3de6b emoji_status:EmojiStatus = Bool;
|
|||||||
account.getDefaultEmojiStatuses#d6753386 hash:long = account.EmojiStatuses;
|
account.getDefaultEmojiStatuses#d6753386 hash:long = account.EmojiStatuses;
|
||||||
account.getRecentEmojiStatuses#f578105 hash:long = account.EmojiStatuses;
|
account.getRecentEmojiStatuses#f578105 hash:long = account.EmojiStatuses;
|
||||||
account.clearRecentEmojiStatuses#18201aae = Bool;
|
account.clearRecentEmojiStatuses#18201aae = Bool;
|
||||||
|
account.reorderUsernames#ef500eab order:Vector<string> = Bool;
|
||||||
|
account.toggleUsername#58d6b376 username:string active:Bool = Bool;
|
||||||
|
|
||||||
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
||||||
users.getFullUser#b60f5918 id:InputUser = users.UserFull;
|
users.getFullUser#b60f5918 id:InputUser = users.UserFull;
|
||||||
@ -1579,9 +1609,9 @@ messages.deleteHistory#b08f922a flags:# just_clear:flags.0?true revoke:flags.1?t
|
|||||||
messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector<int> = messages.AffectedMessages;
|
messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector<int> = messages.AffectedMessages;
|
||||||
messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
|
messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
|
||||||
messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool;
|
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 noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
messages.sendMessage#1cc20387 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int top_msg_id:flags.9?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> 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 update_stickersets_order:flags.15?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<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
messages.sendMedia#7547c966 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int top_msg_id:flags.9?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> 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<int> random_id:Vector<long> to_peer:InputPeer schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
messages.forwardMessages#c661bbc4 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<int> random_id:Vector<long> to_peer:InputPeer top_msg_id:flags.9?int schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||||
messages.reportSpam#cf1592db peer:InputPeer = Bool;
|
messages.reportSpam#cf1592db peer:InputPeer = Bool;
|
||||||
messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings;
|
messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings;
|
||||||
messages.report#8953ab4e peer:InputPeer id:Vector<int> reason:ReportReason message:string = Bool;
|
messages.report#8953ab4e peer:InputPeer id:Vector<int> reason:ReportReason message:string = Bool;
|
||||||
@ -1624,14 +1654,14 @@ messages.getSavedGifs#5cf09635 hash:long = messages.SavedGifs;
|
|||||||
messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool;
|
messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool;
|
||||||
messages.getInlineBotResults#514e999d flags:# bot:InputUser peer:InputPeer geo_point:flags.0?InputGeoPoint query:string offset:string = messages.BotResults;
|
messages.getInlineBotResults#514e999d flags:# bot:InputUser peer:InputPeer geo_point:flags.0?InputGeoPoint query:string offset:string = messages.BotResults;
|
||||||
messages.setInlineBotResults#eb5ea206 flags:# gallery:flags.0?true private:flags.1?true query_id:long results:Vector<InputBotInlineResult> cache_time:int next_offset:flags.2?string switch_pm:flags.3?InlineBotSwitchPM = Bool;
|
messages.setInlineBotResults#eb5ea206 flags:# gallery:flags.0?true private:flags.1?true query_id:long results:Vector<InputBotInlineResult> cache_time:int next_offset:flags.2?string switch_pm:flags.3?InlineBotSwitchPM = Bool;
|
||||||
messages.sendInlineBotResult#7aa11297 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true hide_via:flags.11?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
messages.sendInlineBotResult#d3fbdccb flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true hide_via:flags.11?true peer:InputPeer reply_to_msg_id:flags.0?int top_msg_id:flags.9?int random_id:long query_id:long id:string schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||||
messages.getMessageEditData#fda68d36 peer:InputPeer id:int = messages.MessageEditData;
|
messages.getMessageEditData#fda68d36 peer:InputPeer id:int = messages.MessageEditData;
|
||||||
messages.editMessage#48f71778 flags:# no_webpage:flags.1?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.15?int = Updates;
|
messages.editMessage#48f71778 flags:# no_webpage:flags.1?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.15?int = Updates;
|
||||||
messages.editInlineBotMessage#83557dba flags:# no_webpage:flags.1?true id:InputBotInlineMessageID message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Bool;
|
messages.editInlineBotMessage#83557dba flags:# no_webpage:flags.1?true id:InputBotInlineMessageID message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Bool;
|
||||||
messages.getBotCallbackAnswer#9342ca07 flags:# game:flags.1?true peer:InputPeer msg_id:int data:flags.0?bytes password:flags.2?InputCheckPasswordSRP = messages.BotCallbackAnswer;
|
messages.getBotCallbackAnswer#9342ca07 flags:# game:flags.1?true peer:InputPeer msg_id:int data:flags.0?bytes password:flags.2?InputCheckPasswordSRP = messages.BotCallbackAnswer;
|
||||||
messages.setBotCallbackAnswer#d58f130a flags:# alert:flags.1?true query_id:long message:flags.0?string url:flags.2?string cache_time:int = Bool;
|
messages.setBotCallbackAnswer#d58f130a flags:# alert:flags.1?true query_id:long message:flags.0?string url:flags.2?string cache_time:int = Bool;
|
||||||
messages.getPeerDialogs#e470bcfd peers:Vector<InputDialogPeer> = messages.PeerDialogs;
|
messages.getPeerDialogs#e470bcfd peers:Vector<InputDialogPeer> = messages.PeerDialogs;
|
||||||
messages.saveDraft#bc39e14b flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int peer:InputPeer message:string entities:flags.3?Vector<MessageEntity> = Bool;
|
messages.saveDraft#b4331e3f flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int top_msg_id:flags.2?int peer:InputPeer message:string entities:flags.3?Vector<MessageEntity> = Bool;
|
||||||
messages.getAllDrafts#6a3f8d65 = Updates;
|
messages.getAllDrafts#6a3f8d65 = Updates;
|
||||||
messages.getFeaturedStickers#64780b14 hash:long = messages.FeaturedStickers;
|
messages.getFeaturedStickers#64780b14 hash:long = messages.FeaturedStickers;
|
||||||
messages.readFeaturedStickers#5b118126 id:Vector<long> = Bool;
|
messages.readFeaturedStickers#5b118126 id:Vector<long> = Bool;
|
||||||
@ -1657,10 +1687,10 @@ messages.uploadMedia#519bc2b1 peer:InputPeer media:InputMedia = MessageMedia;
|
|||||||
messages.sendScreenshotNotification#c97df020 peer:InputPeer reply_to_msg_id:int random_id:long = Updates;
|
messages.sendScreenshotNotification#c97df020 peer:InputPeer reply_to_msg_id:int random_id:long = Updates;
|
||||||
messages.getFavedStickers#4f1aaa9 hash:long = messages.FavedStickers;
|
messages.getFavedStickers#4f1aaa9 hash:long = messages.FavedStickers;
|
||||||
messages.faveSticker#b9ffc55b id:InputDocument unfave:Bool = Bool;
|
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.getUnreadMentions#f107e790 flags:# peer:InputPeer top_msg_id:flags.0?int offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||||
messages.readMentions#f0189d3 peer:InputPeer = messages.AffectedHistory;
|
messages.readMentions#36e5bf4d flags:# peer:InputPeer top_msg_id:flags.0?int = messages.AffectedHistory;
|
||||||
messages.getRecentLocations#702a40e0 peer:InputPeer limit:int hash:long = messages.Messages;
|
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 noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector<InputSingleMedia> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
messages.sendMultiMedia#b6f11a1c flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int top_msg_id:flags.9?int multi_media:Vector<InputSingleMedia> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||||
messages.uploadEncryptedFile#5057c497 peer:InputEncryptedChat file:InputEncryptedFile = EncryptedFile;
|
messages.uploadEncryptedFile#5057c497 peer:InputEncryptedChat file:InputEncryptedFile = EncryptedFile;
|
||||||
messages.searchStickerSets#35705b8a flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets;
|
messages.searchStickerSets#35705b8a flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets;
|
||||||
messages.getSplitRanges#1cff7e08 = Vector<MessageRange>;
|
messages.getSplitRanges#1cff7e08 = Vector<MessageRange>;
|
||||||
@ -1677,7 +1707,7 @@ messages.getEmojiKeywords#35a0e062 lang_code:string = EmojiKeywordsDifference;
|
|||||||
messages.getEmojiKeywordsDifference#1508b6af lang_code:string from_version:int = EmojiKeywordsDifference;
|
messages.getEmojiKeywordsDifference#1508b6af lang_code:string from_version:int = EmojiKeywordsDifference;
|
||||||
messages.getEmojiKeywordsLanguages#4e9963b2 lang_codes:Vector<string> = Vector<EmojiLanguage>;
|
messages.getEmojiKeywordsLanguages#4e9963b2 lang_codes:Vector<string> = Vector<EmojiLanguage>;
|
||||||
messages.getEmojiURL#d5b10c26 lang_code:string = EmojiURL;
|
messages.getEmojiURL#d5b10c26 lang_code:string = EmojiURL;
|
||||||
messages.getSearchCounters#732eef00 peer:InputPeer filters:Vector<MessagesFilter> = Vector<messages.SearchCounter>;
|
messages.getSearchCounters#ae7cc1 flags:# peer:InputPeer top_msg_id:flags.0?int filters:Vector<MessagesFilter> = Vector<messages.SearchCounter>;
|
||||||
messages.requestUrlAuth#198fb446 flags:# peer:flags.1?InputPeer msg_id:flags.1?int button_id:flags.1?int url:flags.2?string = UrlAuthResult;
|
messages.requestUrlAuth#198fb446 flags:# peer:flags.1?InputPeer msg_id:flags.1?int button_id:flags.1?int url:flags.2?string = UrlAuthResult;
|
||||||
messages.acceptUrlAuth#b12c7125 flags:# write_allowed:flags.0?true peer:flags.1?InputPeer msg_id:flags.1?int button_id:flags.1?int url:flags.2?string = UrlAuthResult;
|
messages.acceptUrlAuth#b12c7125 flags:# write_allowed:flags.0?true peer:flags.1?InputPeer msg_id:flags.1?int button_id:flags.1?int url:flags.2?string = UrlAuthResult;
|
||||||
messages.hidePeerSettingsBar#4facb138 peer:InputPeer = Bool;
|
messages.hidePeerSettingsBar#4facb138 peer:InputPeer = Bool;
|
||||||
@ -1695,7 +1725,7 @@ messages.getOldFeaturedStickers#7ed094a1 offset:int limit:int hash:long = messag
|
|||||||
messages.getReplies#22ddd30c peer:InputPeer msg_id:int offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages;
|
messages.getReplies#22ddd30c peer:InputPeer msg_id:int offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages;
|
||||||
messages.getDiscussionMessage#446972fd peer:InputPeer msg_id:int = messages.DiscussionMessage;
|
messages.getDiscussionMessage#446972fd peer:InputPeer msg_id:int = messages.DiscussionMessage;
|
||||||
messages.readDiscussion#f731a9f4 peer:InputPeer msg_id:int read_max_id:int = Bool;
|
messages.readDiscussion#f731a9f4 peer:InputPeer msg_id:int read_max_id:int = Bool;
|
||||||
messages.unpinAllMessages#f025bc8b peer:InputPeer = messages.AffectedHistory;
|
messages.unpinAllMessages#ee22b9a8 flags:# peer:InputPeer top_msg_id:flags.0?int = messages.AffectedHistory;
|
||||||
messages.deleteChat#5bd0ee50 chat_id:long = Bool;
|
messages.deleteChat#5bd0ee50 chat_id:long = Bool;
|
||||||
messages.deletePhoneCallHistory#f9cbe409 flags:# revoke:flags.0?true = messages.AffectedFoundMessages;
|
messages.deletePhoneCallHistory#f9cbe409 flags:# revoke:flags.0?true = messages.AffectedFoundMessages;
|
||||||
messages.checkHistoryImport#43fe19f3 import_head:string = messages.HistoryImportParsed;
|
messages.checkHistoryImport#43fe19f3 import_head:string = messages.HistoryImportParsed;
|
||||||
@ -1726,14 +1756,14 @@ messages.setChatAvailableReactions#feb16771 peer:InputPeer available_reactions:C
|
|||||||
messages.getAvailableReactions#18dea0ac hash:int = messages.AvailableReactions;
|
messages.getAvailableReactions#18dea0ac hash:int = messages.AvailableReactions;
|
||||||
messages.setDefaultReaction#4f47a016 reaction:Reaction = Bool;
|
messages.setDefaultReaction#4f47a016 reaction:Reaction = Bool;
|
||||||
messages.translateText#24ce6dee flags:# peer:flags.0?InputPeer msg_id:flags.0?int text:flags.1?string from_lang:flags.2?string to_lang:string = messages.TranslatedText;
|
messages.translateText#24ce6dee flags:# peer:flags.0?InputPeer msg_id:flags.0?int text:flags.1?string from_lang:flags.2?string to_lang:string = messages.TranslatedText;
|
||||||
messages.getUnreadReactions#e85bae1a peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
messages.getUnreadReactions#3223495b flags:# peer:InputPeer top_msg_id:flags.0?int offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||||
messages.readReactions#82e251d7 peer:InputPeer = messages.AffectedHistory;
|
messages.readReactions#54aa7f8e flags:# peer:InputPeer top_msg_id:flags.0?int = messages.AffectedHistory;
|
||||||
messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = messages.Messages;
|
messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = messages.Messages;
|
||||||
messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots;
|
messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots;
|
||||||
messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot;
|
messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot;
|
||||||
messages.toggleBotInAttachMenu#1aee33af bot:InputUser enabled:Bool = Bool;
|
messages.toggleBotInAttachMenu#1aee33af bot:InputUser enabled:Bool = Bool;
|
||||||
messages.requestWebView#fc87a53c flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to_msg_id:flags.0?int send_as:flags.13?InputPeer = WebViewResult;
|
messages.requestWebView#178b480b flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to_msg_id:flags.0?int top_msg_id:flags.9?int send_as:flags.13?InputPeer = WebViewResult;
|
||||||
messages.prolongWebView#ea5fbcce flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to_msg_id:flags.0?int send_as:flags.13?InputPeer = Bool;
|
messages.prolongWebView#7ff34309 flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to_msg_id:flags.0?int top_msg_id:flags.9?int send_as:flags.13?InputPeer = Bool;
|
||||||
messages.requestSimpleWebView#299bec8e flags:# bot:InputUser url:string theme_params:flags.0?DataJSON platform:string = SimpleWebViewResult;
|
messages.requestSimpleWebView#299bec8e flags:# bot:InputUser url:string theme_params:flags.0?DataJSON platform:string = SimpleWebViewResult;
|
||||||
messages.sendWebViewResultMessage#a4314f5 bot_query_id:string result:InputBotInlineResult = WebViewMessageSent;
|
messages.sendWebViewResultMessage#a4314f5 bot_query_id:string result:InputBotInlineResult = WebViewMessageSent;
|
||||||
messages.sendWebViewData#dc0242c8 bot:InputUser random_id:long button_text:string data:string = Updates;
|
messages.sendWebViewData#dc0242c8 bot:InputUser random_id:long button_text:string data:string = Updates;
|
||||||
@ -1746,6 +1776,7 @@ messages.reportReaction#3f64c076 peer:InputPeer id:int reaction_peer:InputPeer =
|
|||||||
messages.getTopReactions#bb8125ba limit:int hash:long = messages.Reactions;
|
messages.getTopReactions#bb8125ba limit:int hash:long = messages.Reactions;
|
||||||
messages.getRecentReactions#39461db2 limit:int hash:long = messages.Reactions;
|
messages.getRecentReactions#39461db2 limit:int hash:long = messages.Reactions;
|
||||||
messages.clearRecentReactions#9dfeefb4 = Bool;
|
messages.clearRecentReactions#9dfeefb4 = Bool;
|
||||||
|
messages.getExtendedMedia#84f80814 peer:InputPeer id:Vector<int> = Updates;
|
||||||
|
|
||||||
updates.getState#edd4882a = updates.State;
|
updates.getState#edd4882a = updates.State;
|
||||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||||
@ -1830,6 +1861,16 @@ channels.getSendAs#dc770ee peer:InputPeer = channels.SendAsPeers;
|
|||||||
channels.deleteParticipantHistory#367544db channel:InputChannel participant:InputPeer = messages.AffectedHistory;
|
channels.deleteParticipantHistory#367544db channel:InputChannel participant:InputPeer = messages.AffectedHistory;
|
||||||
channels.toggleJoinToSend#e4cb9580 channel:InputChannel enabled:Bool = Updates;
|
channels.toggleJoinToSend#e4cb9580 channel:InputChannel enabled:Bool = Updates;
|
||||||
channels.toggleJoinRequest#4c2985b6 channel:InputChannel enabled:Bool = Updates;
|
channels.toggleJoinRequest#4c2985b6 channel:InputChannel enabled:Bool = Updates;
|
||||||
|
channels.reorderUsernames#b45ced1d channel:InputChannel order:Vector<string> = Bool;
|
||||||
|
channels.toggleUsername#50f24105 channel:InputChannel username:string active:Bool = Bool;
|
||||||
|
channels.deactivateAllUsernames#a245dd3 channel:InputChannel = Bool;
|
||||||
|
channels.toggleForum#a4298b29 channel:InputChannel enabled:Bool = Updates;
|
||||||
|
channels.createForumTopic#f40c0224 flags:# channel:InputChannel title:string icon_color:flags.0?int icon_emoji_id:flags.3?long random_id:long send_as:flags.2?InputPeer = Updates;
|
||||||
|
channels.getForumTopics#de560d1 flags:# channel:InputChannel q:flags.0?string offset_date:int offset_id:int offset_topic:int limit:int = messages.ForumTopics;
|
||||||
|
channels.getForumTopicsByID#b0831eb9 channel:InputChannel topics:Vector<int> = messages.ForumTopics;
|
||||||
|
channels.editForumTopic#6c883e2d flags:# channel:InputChannel topic_id:int title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool = Updates;
|
||||||
|
channels.updatePinnedForumTopic#6c2d9026 channel:InputChannel topic_id:int pinned:Bool = Updates;
|
||||||
|
channels.deleteTopicHistory#34435f2d channel:InputChannel top_msg_id:int = messages.AffectedHistory;
|
||||||
|
|
||||||
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
|
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
|
||||||
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
|
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
|
||||||
|
@ -202,6 +202,10 @@ std::string TD_TL_writer_java::gen_output_begin() const {
|
|||||||
" } catch (UnsatisfiedLinkError e) {\n"
|
" } catch (UnsatisfiedLinkError e) {\n"
|
||||||
" e.printStackTrace();\n" +
|
" e.printStackTrace();\n" +
|
||||||
" }\n"
|
" }\n"
|
||||||
|
" }\n\n"
|
||||||
|
" private " +
|
||||||
|
tl_name +
|
||||||
|
"() {\n"
|
||||||
" }\n\n";
|
" }\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1042,7 +1042,7 @@ Status SessionConnection::do_flush() {
|
|||||||
auto start_time = Time::now();
|
auto start_time = Time::now();
|
||||||
auto result = raw_connection_->flush(auth_data_->get_auth_key(), *this);
|
auto result = raw_connection_->flush(auth_data_->get_auth_key(), *this);
|
||||||
auto elapsed_time = Time::now() - start_time;
|
auto elapsed_time = Time::now() - start_time;
|
||||||
if (elapsed_time >= 0.01) {
|
if (elapsed_time >= 0.1) {
|
||||||
LOG(ERROR) << "RawConnection::flush took " << elapsed_time << " seconds, written " << last_write_size_
|
LOG(ERROR) << "RawConnection::flush took " << elapsed_time << " seconds, written " << last_write_size_
|
||||||
<< " bytes, read " << last_read_size_ << " bytes and returned " << result;
|
<< " bytes, read " << last_read_size_ << " bytes and returned " << result;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ FileId AnimationsManager::on_get_animation(unique_ptr<Animation> new_animation,
|
|||||||
CHECK(a->file_id == file_id);
|
CHECK(a->file_id == file_id);
|
||||||
if (a->mime_type != new_animation->mime_type) {
|
if (a->mime_type != new_animation->mime_type) {
|
||||||
LOG(DEBUG) << "Animation " << file_id << " info has changed";
|
LOG(DEBUG) << "Animation " << file_id << " info has changed";
|
||||||
a->mime_type = new_animation->mime_type;
|
a->mime_type = std::move(new_animation->mime_type);
|
||||||
}
|
}
|
||||||
if (a->file_name != new_animation->file_name) {
|
if (a->file_name != new_animation->file_name) {
|
||||||
LOG(DEBUG) << "Animation " << file_id << " file name has changed";
|
LOG(DEBUG) << "Animation " << file_id << " file name has changed";
|
||||||
@ -205,7 +205,7 @@ FileId AnimationsManager::on_get_animation(unique_ptr<Animation> new_animation,
|
|||||||
LOG(INFO) << "Animation " << file_id << " thumbnail has changed from " << a->thumbnail << " to "
|
LOG(INFO) << "Animation " << file_id << " thumbnail has changed from " << a->thumbnail << " to "
|
||||||
<< new_animation->thumbnail;
|
<< new_animation->thumbnail;
|
||||||
}
|
}
|
||||||
a->thumbnail = new_animation->thumbnail;
|
a->thumbnail = std::move(new_animation->thumbnail);
|
||||||
}
|
}
|
||||||
if (a->animated_thumbnail != new_animation->animated_thumbnail) {
|
if (a->animated_thumbnail != new_animation->animated_thumbnail) {
|
||||||
if (!a->animated_thumbnail.file_id.is_valid()) {
|
if (!a->animated_thumbnail.file_id.is_valid()) {
|
||||||
@ -214,7 +214,7 @@ FileId AnimationsManager::on_get_animation(unique_ptr<Animation> new_animation,
|
|||||||
LOG(INFO) << "Animation " << file_id << " animated thumbnail has changed from " << a->animated_thumbnail
|
LOG(INFO) << "Animation " << file_id << " animated thumbnail has changed from " << a->animated_thumbnail
|
||||||
<< " to " << new_animation->animated_thumbnail;
|
<< " to " << new_animation->animated_thumbnail;
|
||||||
}
|
}
|
||||||
a->animated_thumbnail = new_animation->animated_thumbnail;
|
a->animated_thumbnail = std::move(new_animation->animated_thumbnail);
|
||||||
}
|
}
|
||||||
if (a->has_stickers != new_animation->has_stickers && new_animation->has_stickers) {
|
if (a->has_stickers != new_animation->has_stickers && new_animation->has_stickers) {
|
||||||
a->has_stickers = new_animation->has_stickers;
|
a->has_stickers = new_animation->has_stickers;
|
||||||
@ -389,7 +389,7 @@ SecretInputMedia AnimationsManager::get_secret_input_media(FileId animation_file
|
|||||||
attributes.push_back(make_tl_object<secret_api::documentAttributeFilename>(animation->file_name));
|
attributes.push_back(make_tl_object<secret_api::documentAttributeFilename>(animation->file_name));
|
||||||
}
|
}
|
||||||
if (animation->duration != 0 && animation->mime_type == "video/mp4") {
|
if (animation->duration != 0 && animation->mime_type == "video/mp4") {
|
||||||
attributes.push_back(make_tl_object<secret_api::documentAttributeVideo66>(
|
attributes.push_back(make_tl_object<secret_api::documentAttributeVideo>(
|
||||||
0, false, animation->duration, animation->dimensions.width, animation->dimensions.height));
|
0, false, animation->duration, animation->dimensions.width, animation->dimensions.height));
|
||||||
}
|
}
|
||||||
if (animation->dimensions.width != 0 && animation->dimensions.height != 0) {
|
if (animation->dimensions.width != 0 && animation->dimensions.height != 0) {
|
||||||
|
@ -39,6 +39,7 @@ class RequestWebViewQuery final : public Td::ResultHandler {
|
|||||||
Promise<td_api::object_ptr<td_api::webAppInfo>> promise_;
|
Promise<td_api::object_ptr<td_api::webAppInfo>> promise_;
|
||||||
DialogId dialog_id_;
|
DialogId dialog_id_;
|
||||||
UserId bot_user_id_;
|
UserId bot_user_id_;
|
||||||
|
MessageId top_thread_message_id_;
|
||||||
MessageId reply_to_message_id_;
|
MessageId reply_to_message_id_;
|
||||||
DialogId as_dialog_id_;
|
DialogId as_dialog_id_;
|
||||||
bool from_attach_menu_ = false;
|
bool from_attach_menu_ = false;
|
||||||
@ -49,8 +50,8 @@ class RequestWebViewQuery final : public Td::ResultHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void send(DialogId dialog_id, UserId bot_user_id, tl_object_ptr<telegram_api::InputUser> &&input_user, string &&url,
|
void send(DialogId dialog_id, UserId bot_user_id, tl_object_ptr<telegram_api::InputUser> &&input_user, string &&url,
|
||||||
td_api::object_ptr<td_api::themeParameters> &&theme, string &&platform, MessageId reply_to_message_id,
|
td_api::object_ptr<td_api::themeParameters> &&theme, string &&platform, MessageId top_thread_message_id,
|
||||||
bool silent, DialogId as_dialog_id) {
|
MessageId reply_to_message_id, bool silent, DialogId as_dialog_id) {
|
||||||
dialog_id_ = dialog_id;
|
dialog_id_ = dialog_id;
|
||||||
bot_user_id_ = bot_user_id;
|
bot_user_id_ = bot_user_id;
|
||||||
reply_to_message_id_ = reply_to_message_id;
|
reply_to_message_id_ = reply_to_message_id;
|
||||||
@ -86,6 +87,10 @@ class RequestWebViewQuery final : public Td::ResultHandler {
|
|||||||
flags |= telegram_api::messages_requestWebView::THEME_PARAMS_MASK;
|
flags |= telegram_api::messages_requestWebView::THEME_PARAMS_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (top_thread_message_id.is_valid()) {
|
||||||
|
flags |= telegram_api::messages_requestWebView::TOP_MSG_ID_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
if (reply_to_message_id.is_valid()) {
|
if (reply_to_message_id.is_valid()) {
|
||||||
flags |= telegram_api::messages_requestWebView::REPLY_TO_MSG_ID_MASK;
|
flags |= telegram_api::messages_requestWebView::REPLY_TO_MSG_ID_MASK;
|
||||||
}
|
}
|
||||||
@ -105,7 +110,7 @@ class RequestWebViewQuery final : public Td::ResultHandler {
|
|||||||
send_query(G()->net_query_creator().create(telegram_api::messages_requestWebView(
|
send_query(G()->net_query_creator().create(telegram_api::messages_requestWebView(
|
||||||
flags, false /*ignored*/, false /*ignored*/, std::move(input_peer), std::move(input_user), url, start_parameter,
|
flags, false /*ignored*/, false /*ignored*/, std::move(input_peer), std::move(input_user), url, start_parameter,
|
||||||
std::move(theme_parameters), platform, reply_to_message_id.get_server_message_id().get(),
|
std::move(theme_parameters), platform, reply_to_message_id.get_server_message_id().get(),
|
||||||
std::move(as_input_peer))));
|
top_thread_message_id.get_server_message_id().get(), std::move(as_input_peer))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_result(BufferSlice packet) final {
|
void on_result(BufferSlice packet) final {
|
||||||
@ -115,8 +120,8 @@ class RequestWebViewQuery final : public Td::ResultHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto ptr = result_ptr.move_as_ok();
|
auto ptr = result_ptr.move_as_ok();
|
||||||
td_->attach_menu_manager_->open_web_view(ptr->query_id_, dialog_id_, bot_user_id_, reply_to_message_id_,
|
td_->attach_menu_manager_->open_web_view(ptr->query_id_, dialog_id_, bot_user_id_, top_thread_message_id_,
|
||||||
as_dialog_id_);
|
reply_to_message_id_, as_dialog_id_);
|
||||||
promise_.set_value(td_api::make_object<td_api::webAppInfo>(ptr->query_id_, ptr->url_));
|
promise_.set_value(td_api::make_object<td_api::webAppInfo>(ptr->query_id_, ptr->url_));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,8 +139,8 @@ class ProlongWebViewQuery final : public Td::ResultHandler {
|
|||||||
DialogId dialog_id_;
|
DialogId dialog_id_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void send(DialogId dialog_id, UserId bot_user_id, int64 query_id, MessageId reply_to_message_id, bool silent,
|
void send(DialogId dialog_id, UserId bot_user_id, int64 query_id, MessageId top_thread_message_id,
|
||||||
DialogId as_dialog_id) {
|
MessageId reply_to_message_id, bool silent, DialogId as_dialog_id) {
|
||||||
dialog_id_ = dialog_id;
|
dialog_id_ = dialog_id;
|
||||||
|
|
||||||
auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write);
|
auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write);
|
||||||
@ -149,6 +154,10 @@ class ProlongWebViewQuery final : public Td::ResultHandler {
|
|||||||
flags |= telegram_api::messages_prolongWebView::REPLY_TO_MSG_ID_MASK;
|
flags |= telegram_api::messages_prolongWebView::REPLY_TO_MSG_ID_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (top_thread_message_id.is_valid()) {
|
||||||
|
flags |= telegram_api::messages_prolongWebView::TOP_MSG_ID_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
if (silent) {
|
if (silent) {
|
||||||
flags |= telegram_api::messages_prolongWebView::SILENT_MASK;
|
flags |= telegram_api::messages_prolongWebView::SILENT_MASK;
|
||||||
}
|
}
|
||||||
@ -163,7 +172,8 @@ class ProlongWebViewQuery final : public Td::ResultHandler {
|
|||||||
|
|
||||||
send_query(G()->net_query_creator().create(telegram_api::messages_prolongWebView(
|
send_query(G()->net_query_creator().create(telegram_api::messages_prolongWebView(
|
||||||
flags, false /*ignored*/, std::move(input_peer), r_input_user.move_as_ok(), query_id,
|
flags, false /*ignored*/, std::move(input_peer), r_input_user.move_as_ok(), query_id,
|
||||||
reply_to_message_id.get_server_message_id().get(), std::move(as_input_peer))));
|
reply_to_message_id.get_server_message_id().get(), top_thread_message_id.get_server_message_id().get(),
|
||||||
|
std::move(as_input_peer))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_result(BufferSlice packet) final {
|
void on_result(BufferSlice packet) final {
|
||||||
@ -585,9 +595,9 @@ void AttachMenuManager::ping_web_view() {
|
|||||||
for (const auto &it : opened_web_views_) {
|
for (const auto &it : opened_web_views_) {
|
||||||
const auto &opened_web_view = it.second;
|
const auto &opened_web_view = it.second;
|
||||||
bool silent = td_->messages_manager_->get_dialog_silent_send_message(opened_web_view.dialog_id_);
|
bool silent = td_->messages_manager_->get_dialog_silent_send_message(opened_web_view.dialog_id_);
|
||||||
td_->create_handler<ProlongWebViewQuery>()->send(opened_web_view.dialog_id_, opened_web_view.bot_user_id_, it.first,
|
td_->create_handler<ProlongWebViewQuery>()->send(
|
||||||
opened_web_view.reply_to_message_id_, silent,
|
opened_web_view.dialog_id_, opened_web_view.bot_user_id_, it.first, opened_web_view.top_thread_message_id_,
|
||||||
opened_web_view.as_dialog_id_);
|
opened_web_view.reply_to_message_id_, silent, opened_web_view.as_dialog_id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
schedule_ping_web_view();
|
schedule_ping_web_view();
|
||||||
@ -599,9 +609,10 @@ void AttachMenuManager::schedule_ping_web_view() {
|
|||||||
ping_web_view_timeout_.set_timeout_in(PING_WEB_VIEW_TIMEOUT);
|
ping_web_view_timeout_.set_timeout_in(PING_WEB_VIEW_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachMenuManager::request_web_view(DialogId dialog_id, UserId bot_user_id, MessageId reply_to_message_id,
|
void AttachMenuManager::request_web_view(DialogId dialog_id, UserId bot_user_id, MessageId top_thread_message_id,
|
||||||
string &&url, td_api::object_ptr<td_api::themeParameters> &&theme,
|
MessageId reply_to_message_id, string &&url,
|
||||||
string &&platform, Promise<td_api::object_ptr<td_api::webAppInfo>> &&promise) {
|
td_api::object_ptr<td_api::themeParameters> &&theme, string &&platform,
|
||||||
|
Promise<td_api::object_ptr<td_api::webAppInfo>> &&promise) {
|
||||||
TRY_STATUS_PROMISE(promise, td_->contacts_manager_->get_bot_data(bot_user_id));
|
TRY_STATUS_PROMISE(promise, td_->contacts_manager_->get_bot_data(bot_user_id));
|
||||||
TRY_RESULT_PROMISE(promise, input_user, td_->contacts_manager_->get_input_user(bot_user_id));
|
TRY_RESULT_PROMISE(promise, input_user, td_->contacts_manager_->get_input_user(bot_user_id));
|
||||||
|
|
||||||
@ -630,17 +641,23 @@ void AttachMenuManager::request_web_view(DialogId dialog_id, UserId bot_user_id,
|
|||||||
!td_->messages_manager_->have_message_force({dialog_id, reply_to_message_id}, "request_web_view")) {
|
!td_->messages_manager_->have_message_force({dialog_id, reply_to_message_id}, "request_web_view")) {
|
||||||
reply_to_message_id = MessageId();
|
reply_to_message_id = MessageId();
|
||||||
}
|
}
|
||||||
|
if (!top_thread_message_id.is_valid() || !top_thread_message_id.is_server() ||
|
||||||
|
dialog_id.get_type() != DialogType::Channel ||
|
||||||
|
!td_->contacts_manager_->is_megagroup_channel(dialog_id.get_channel_id())) {
|
||||||
|
top_thread_message_id = MessageId();
|
||||||
|
}
|
||||||
|
|
||||||
bool silent = td_->messages_manager_->get_dialog_silent_send_message(dialog_id);
|
bool silent = td_->messages_manager_->get_dialog_silent_send_message(dialog_id);
|
||||||
DialogId as_dialog_id = td_->messages_manager_->get_dialog_default_send_message_as_dialog_id(dialog_id);
|
DialogId as_dialog_id = td_->messages_manager_->get_dialog_default_send_message_as_dialog_id(dialog_id);
|
||||||
|
|
||||||
td_->create_handler<RequestWebViewQuery>(std::move(promise))
|
td_->create_handler<RequestWebViewQuery>(std::move(promise))
|
||||||
->send(dialog_id, bot_user_id, std::move(input_user), std::move(url), std::move(theme), std::move(platform),
|
->send(dialog_id, bot_user_id, std::move(input_user), std::move(url), std::move(theme), std::move(platform),
|
||||||
reply_to_message_id, silent, as_dialog_id);
|
top_thread_message_id, reply_to_message_id, silent, as_dialog_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachMenuManager::open_web_view(int64 query_id, DialogId dialog_id, UserId bot_user_id,
|
void AttachMenuManager::open_web_view(int64 query_id, DialogId dialog_id, UserId bot_user_id,
|
||||||
MessageId reply_to_message_id, DialogId as_dialog_id) {
|
MessageId top_thread_message_id, MessageId reply_to_message_id,
|
||||||
|
DialogId as_dialog_id) {
|
||||||
if (query_id == 0) {
|
if (query_id == 0) {
|
||||||
LOG(ERROR) << "Receive Web App query identifier == 0";
|
LOG(ERROR) << "Receive Web App query identifier == 0";
|
||||||
return;
|
return;
|
||||||
@ -652,6 +669,7 @@ void AttachMenuManager::open_web_view(int64 query_id, DialogId dialog_id, UserId
|
|||||||
OpenedWebView opened_web_view;
|
OpenedWebView opened_web_view;
|
||||||
opened_web_view.dialog_id_ = dialog_id;
|
opened_web_view.dialog_id_ = dialog_id;
|
||||||
opened_web_view.bot_user_id_ = bot_user_id;
|
opened_web_view.bot_user_id_ = bot_user_id;
|
||||||
|
opened_web_view.top_thread_message_id_ = top_thread_message_id;
|
||||||
opened_web_view.reply_to_message_id_ = reply_to_message_id;
|
opened_web_view.reply_to_message_id_ = reply_to_message_id;
|
||||||
opened_web_view.as_dialog_id_ = as_dialog_id;
|
opened_web_view.as_dialog_id_ = as_dialog_id;
|
||||||
opened_web_views_.emplace(query_id, std::move(opened_web_view));
|
opened_web_views_.emplace(query_id, std::move(opened_web_view));
|
||||||
|
@ -32,12 +32,13 @@ class AttachMenuManager final : public Actor {
|
|||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
void request_web_view(DialogId dialog_id, UserId bot_user_id, MessageId reply_to_message_id, string &&url,
|
void request_web_view(DialogId dialog_id, UserId bot_user_id, MessageId top_thread_message_id,
|
||||||
|
MessageId reply_to_message_id, string &&url,
|
||||||
td_api::object_ptr<td_api::themeParameters> &&theme, string &&platform,
|
td_api::object_ptr<td_api::themeParameters> &&theme, string &&platform,
|
||||||
Promise<td_api::object_ptr<td_api::webAppInfo>> &&promise);
|
Promise<td_api::object_ptr<td_api::webAppInfo>> &&promise);
|
||||||
|
|
||||||
void open_web_view(int64 query_id, DialogId dialog_id, UserId bot_user_id, MessageId reply_to_message_id,
|
void open_web_view(int64 query_id, DialogId dialog_id, UserId bot_user_id, MessageId top_thread_message_id,
|
||||||
DialogId as_dialog_id);
|
MessageId reply_to_message_id, DialogId as_dialog_id);
|
||||||
|
|
||||||
void close_web_view(int64 query_id, Promise<Unit> &&promise);
|
void close_web_view(int64 query_id, Promise<Unit> &&promise);
|
||||||
|
|
||||||
@ -154,6 +155,7 @@ class AttachMenuManager final : public Actor {
|
|||||||
struct OpenedWebView {
|
struct OpenedWebView {
|
||||||
DialogId dialog_id_;
|
DialogId dialog_id_;
|
||||||
UserId bot_user_id_;
|
UserId bot_user_id_;
|
||||||
|
MessageId top_thread_message_id_;
|
||||||
MessageId reply_to_message_id_;
|
MessageId reply_to_message_id_;
|
||||||
DialogId as_dialog_id_;
|
DialogId as_dialog_id_;
|
||||||
};
|
};
|
||||||
|
@ -101,13 +101,13 @@ FileId AudiosManager::on_get_audio(unique_ptr<Audio> new_audio, bool replace) {
|
|||||||
CHECK(a->file_id == new_audio->file_id);
|
CHECK(a->file_id == new_audio->file_id);
|
||||||
if (a->mime_type != new_audio->mime_type) {
|
if (a->mime_type != new_audio->mime_type) {
|
||||||
LOG(DEBUG) << "Audio " << file_id << " info has changed";
|
LOG(DEBUG) << "Audio " << file_id << " info has changed";
|
||||||
a->mime_type = new_audio->mime_type;
|
a->mime_type = std::move(new_audio->mime_type);
|
||||||
}
|
}
|
||||||
if (a->duration != new_audio->duration || a->title != new_audio->title || a->performer != new_audio->performer) {
|
if (a->duration != new_audio->duration || a->title != new_audio->title || a->performer != new_audio->performer) {
|
||||||
LOG(DEBUG) << "Audio " << file_id << " info has changed";
|
LOG(DEBUG) << "Audio " << file_id << " info has changed";
|
||||||
a->duration = new_audio->duration;
|
a->duration = new_audio->duration;
|
||||||
a->title = new_audio->title;
|
a->title = std::move(new_audio->title);
|
||||||
a->performer = new_audio->performer;
|
a->performer = std::move(new_audio->performer);
|
||||||
}
|
}
|
||||||
if (a->file_name != new_audio->file_name) {
|
if (a->file_name != new_audio->file_name) {
|
||||||
LOG(DEBUG) << "Audio " << file_id << " file name has changed";
|
LOG(DEBUG) << "Audio " << file_id << " file name has changed";
|
||||||
@ -126,7 +126,7 @@ FileId AudiosManager::on_get_audio(unique_ptr<Audio> new_audio, bool replace) {
|
|||||||
LOG(INFO) << "Audio " << file_id << " thumbnail has changed from " << a->thumbnail << " to "
|
LOG(INFO) << "Audio " << file_id << " thumbnail has changed from " << a->thumbnail << " to "
|
||||||
<< new_audio->thumbnail;
|
<< new_audio->thumbnail;
|
||||||
}
|
}
|
||||||
a->thumbnail = new_audio->thumbnail;
|
a->thumbnail = std::move(new_audio->thumbnail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -845,7 +845,7 @@ void AuthManager::on_log_out_result(NetQueryPtr &result) {
|
|||||||
} else {
|
} else {
|
||||||
status = std::move(result->error());
|
status = std::move(result->error());
|
||||||
}
|
}
|
||||||
LOG_IF(ERROR, status.is_error() && status.error().code() != 401) << "Receive error for auth.logOut: " << status;
|
LOG_IF(ERROR, status.is_error() && status.code() != 401) << "Receive error for auth.logOut: " << status;
|
||||||
// state_ will stay LoggingOut, so no queries will work.
|
// state_ will stay LoggingOut, so no queries will work.
|
||||||
destroy_auth_keys();
|
destroy_auth_keys();
|
||||||
if (query_id_ != 0) {
|
if (query_id_ != 0) {
|
||||||
@ -897,7 +897,7 @@ void AuthManager::on_delete_account_result(NetQueryPtr &result) {
|
|||||||
} else {
|
} else {
|
||||||
status = std::move(result->error());
|
status = std::move(result->error());
|
||||||
}
|
}
|
||||||
if (status.is_error() && status.error().message() != "USER_DEACTIVATED") {
|
if (status.is_error() && status.message() != "USER_DEACTIVATED") {
|
||||||
LOG(WARNING) << "Request account.deleteAccount failed: " << status;
|
LOG(WARNING) << "Request account.deleteAccount failed: " << status;
|
||||||
// TODO handle some errors
|
// TODO handle some errors
|
||||||
if (query_id_ != 0) {
|
if (query_id_ != 0) {
|
||||||
|
@ -449,23 +449,6 @@ void BackgroundManager::get_backgrounds(bool for_dark_theme,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<string> BackgroundManager::get_background_url(const string &name,
|
|
||||||
td_api::object_ptr<td_api::BackgroundType> background_type) {
|
|
||||||
TRY_RESULT(type, BackgroundType::get_background_type(background_type.get()));
|
|
||||||
auto url = PSTRING() << G()->get_option_string("t_me_url", "https://t.me/") << "bg/";
|
|
||||||
auto link = type.get_link();
|
|
||||||
if (type.has_file()) {
|
|
||||||
url += name;
|
|
||||||
if (!link.empty()) {
|
|
||||||
url += '?';
|
|
||||||
url += link;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
url += link;
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BackgroundManager::reload_background_from_server(
|
void BackgroundManager::reload_background_from_server(
|
||||||
BackgroundId background_id, const string &background_name,
|
BackgroundId background_id, const string &background_name,
|
||||||
telegram_api::object_ptr<telegram_api::InputWallPaper> &&input_wallpaper, Promise<Unit> &&promise) const {
|
telegram_api::object_ptr<telegram_api::InputWallPaper> &&input_wallpaper, Promise<Unit> &&promise) const {
|
||||||
|
@ -37,9 +37,6 @@ class BackgroundManager final : public Actor {
|
|||||||
|
|
||||||
void get_backgrounds(bool for_dark_theme, Promise<td_api::object_ptr<td_api::backgrounds>> &&promise);
|
void get_backgrounds(bool for_dark_theme, Promise<td_api::object_ptr<td_api::backgrounds>> &&promise);
|
||||||
|
|
||||||
static Result<string> get_background_url(const string &name,
|
|
||||||
td_api::object_ptr<td_api::BackgroundType> background_type);
|
|
||||||
|
|
||||||
void reload_background(BackgroundId background_id, int64 access_hash, Promise<Unit> &&promise);
|
void reload_background(BackgroundId background_id, int64 access_hash, Promise<Unit> &&promise);
|
||||||
|
|
||||||
std::pair<BackgroundId, BackgroundType> search_background(const string &name, Promise<Unit> &&promise);
|
std::pair<BackgroundId, BackgroundType> search_background(const string &name, Promise<Unit> &&promise);
|
||||||
|
@ -82,6 +82,8 @@ BackgroundFill::BackgroundFill(const telegram_api::wallPaperSettings *settings)
|
|||||||
LOG(ERROR) << "Receive " << to_string(*settings);
|
LOG(ERROR) << "Receive " << to_string(*settings);
|
||||||
rotation_angle_ = 0;
|
rotation_angle_ = 0;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
bottom_color_ = top_color_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -953,6 +953,8 @@ void CallActor::loop() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LOG(INFO) << "Close " << local_call_id_;
|
LOG(INFO) << "Close " << local_call_id_;
|
||||||
|
container_.for_each(
|
||||||
|
[](auto id, Promise<NetQueryPtr> &promise) { promise.set_error(Global::request_aborted_error()); });
|
||||||
stop();
|
stop();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include "td/telegram/telegram_api.hpp"
|
#include "td/telegram/telegram_api.hpp"
|
||||||
|
|
||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
#include "td/utils/format.h"
|
|
||||||
#include "td/utils/logging.h"
|
#include "td/utils/logging.h"
|
||||||
#include "td/utils/misc.h"
|
#include "td/utils/misc.h"
|
||||||
#include "td/utils/SliceBuilder.h"
|
#include "td/utils/SliceBuilder.h"
|
||||||
@ -174,25 +173,24 @@ ActorId<CallActor> CallManager::get_call_actor(CallId call_id) {
|
|||||||
void CallManager::hangup() {
|
void CallManager::hangup() {
|
||||||
close_flag_ = true;
|
close_flag_ = true;
|
||||||
for (auto &it : id_to_actor_) {
|
for (auto &it : id_to_actor_) {
|
||||||
LOG(INFO) << "Ask close CallActor " << it.first;
|
LOG(INFO) << "Ask to close CallActor " << it.first.get();
|
||||||
it.second.reset();
|
it.second.reset();
|
||||||
}
|
}
|
||||||
if (id_to_actor_.empty()) {
|
if (id_to_actor_.empty()) {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallManager::hangup_shared() {
|
void CallManager::hangup_shared() {
|
||||||
auto token = narrow_cast<int32>(get_link_token());
|
auto token = narrow_cast<int32>(get_link_token());
|
||||||
auto it = id_to_actor_.find(CallId(token));
|
auto it = id_to_actor_.find(CallId(token));
|
||||||
if (it != id_to_actor_.end()) {
|
CHECK(it != id_to_actor_.end());
|
||||||
LOG(INFO) << "Close CallActor " << tag("id", it->first);
|
LOG(INFO) << "Closed CallActor " << it->first.get();
|
||||||
it->second.release();
|
it->second.release();
|
||||||
id_to_actor_.erase(it);
|
id_to_actor_.erase(it);
|
||||||
} else {
|
|
||||||
LOG(FATAL) << "Unknown CallActor hangup " << tag("id", static_cast<int32>(token));
|
|
||||||
}
|
|
||||||
if (close_flag_ && id_to_actor_.empty()) {
|
if (close_flag_ && id_to_actor_.empty()) {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "td/telegram/CallId.h"
|
#include "td/telegram/CallId.h"
|
||||||
#include "td/telegram/td_api.h"
|
#include "td/telegram/td_api.h"
|
||||||
#include "td/telegram/telegram_api.h"
|
#include "td/telegram/telegram_api.h"
|
||||||
|
#include "td/telegram/UserId.h"
|
||||||
|
|
||||||
#include "td/actor/actor.h"
|
#include "td/actor/actor.h"
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ void CallbackQueriesManager::on_new_query(int32 flags, int64 callback_query_id,
|
|||||||
LOG(ERROR) << "Receive new callback query from invalid " << sender_user_id << " in " << dialog_id;
|
LOG(ERROR) << "Receive new callback query from invalid " << sender_user_id << " in " << dialog_id;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_IF(ERROR, !td_->contacts_manager_->have_user(sender_user_id)) << "Have no info about " << sender_user_id;
|
LOG_IF(ERROR, !td_->contacts_manager_->have_user(sender_user_id)) << "Receive unknown " << sender_user_id;
|
||||||
if (!td_->auth_manager_->is_bot()) {
|
if (!td_->auth_manager_->is_bot()) {
|
||||||
LOG(ERROR) << "Receive new callback query";
|
LOG(ERROR) << "Receive new callback query";
|
||||||
return;
|
return;
|
||||||
@ -208,7 +208,7 @@ void CallbackQueriesManager::on_new_inline_query(
|
|||||||
LOG(ERROR) << "Receive new callback query from invalid " << sender_user_id;
|
LOG(ERROR) << "Receive new callback query from invalid " << sender_user_id;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_IF(ERROR, !td_->contacts_manager_->have_user(sender_user_id)) << "Have no info about " << sender_user_id;
|
LOG_IF(ERROR, !td_->contacts_manager_->have_user(sender_user_id)) << "Receive unknown " << sender_user_id;
|
||||||
if (!td_->auth_manager_->is_bot()) {
|
if (!td_->auth_manager_->is_bot()) {
|
||||||
LOG(ERROR) << "Receive new callback query";
|
LOG(ERROR) << "Receive new callback query";
|
||||||
return;
|
return;
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/ChannelId.h"
|
||||||
|
#include "td/telegram/ChatId.h"
|
||||||
#include "td/telegram/DialogId.h"
|
#include "td/telegram/DialogId.h"
|
||||||
#include "td/telegram/FolderId.h"
|
#include "td/telegram/FolderId.h"
|
||||||
#include "td/telegram/FullMessageId.h"
|
#include "td/telegram/FullMessageId.h"
|
||||||
@ -22,6 +24,12 @@ class ChainId {
|
|||||||
uint64 id = 0;
|
uint64 id = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
ChainId(ChannelId channel_id) : ChainId(DialogId(channel_id)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ChainId(ChatId chat_id) : ChainId(DialogId(chat_id)) {
|
||||||
|
}
|
||||||
|
|
||||||
ChainId(DialogId dialog_id, MessageContentType message_content_type)
|
ChainId(DialogId dialog_id, MessageContentType message_content_type)
|
||||||
: id((static_cast<uint64>(dialog_id.get()) << 10) + get_message_content_chain_id(message_content_type)) {
|
: id((static_cast<uint64>(dialog_id.get()) << 10) + get_message_content_chain_id(message_content_type)) {
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,14 @@
|
|||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
ClientActor::ClientActor(unique_ptr<TdCallback> callback, Options options) {
|
ClientActor::ClientActor(unique_ptr<TdCallback> callback, Options options)
|
||||||
|
: callback_(std::move(callback)), options_(std::move(options)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientActor::start_up() {
|
||||||
Td::Options td_options;
|
Td::Options td_options;
|
||||||
td_options.net_query_stats = std::move(options.net_query_stats);
|
td_options.net_query_stats = std::move(options_.net_query_stats);
|
||||||
td_ = create_actor<Td>("Td", std::move(callback), std::move(td_options));
|
td_ = create_actor<Td>("Td", std::move(callback_), std::move(td_options));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientActor::request(uint64 id, td_api::object_ptr<td_api::Function> request) {
|
void ClientActor::request(uint64 id, td_api::object_ptr<td_api::Function> request) {
|
||||||
|
@ -81,7 +81,11 @@ class ClientActor final : public Actor {
|
|||||||
ClientActor &operator=(const ClientActor &other) = delete;
|
ClientActor &operator=(const ClientActor &other) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void start_up() final;
|
||||||
|
|
||||||
ActorOwn<Td> td_;
|
ActorOwn<Td> td_;
|
||||||
|
unique_ptr<TdCallback> callback_;
|
||||||
|
Options options_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,8 +48,7 @@ static std::pair<td_api::object_ptr<td_api::Function>, string> to_request(Slice
|
|||||||
td_api::object_ptr<td_api::Function> func;
|
td_api::object_ptr<td_api::Function> func;
|
||||||
auto status = from_json(func, std::move(json_value));
|
auto status = from_json(func, std::move(json_value));
|
||||||
if (status.is_error()) {
|
if (status.is_error()) {
|
||||||
return {get_return_error_function(PSLICE()
|
return {get_return_error_function(PSLICE() << "Failed to parse JSON object as TDLib request: " << status.message()),
|
||||||
<< "Failed to parse JSON object as TDLib request: " << status.error().message()),
|
|
||||||
std::move(extra)};
|
std::move(extra)};
|
||||||
}
|
}
|
||||||
return std::make_pair(std::move(func), std::move(extra));
|
return std::make_pair(std::move(func), std::move(extra));
|
||||||
|
@ -1467,9 +1467,11 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
|
|||||||
string autologin_token;
|
string autologin_token;
|
||||||
vector<string> autologin_domains;
|
vector<string> autologin_domains;
|
||||||
vector<string> url_auth_domains;
|
vector<string> url_auth_domains;
|
||||||
|
vector<string> whitelisted_domains;
|
||||||
|
|
||||||
vector<tl_object_ptr<telegram_api::jsonObjectValue>> new_values;
|
vector<tl_object_ptr<telegram_api::jsonObjectValue>> new_values;
|
||||||
string ignored_restriction_reasons;
|
string ignored_restriction_reasons;
|
||||||
|
string restriction_add_platforms;
|
||||||
vector<string> dice_emojis;
|
vector<string> dice_emojis;
|
||||||
FlatHashMap<string, size_t> dice_emoji_index;
|
FlatHashMap<string, size_t> dice_emoji_index;
|
||||||
FlatHashMap<string, string> dice_emoji_success_value;
|
FlatHashMap<string, string> dice_emoji_success_value;
|
||||||
@ -1489,6 +1491,7 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
|
|||||||
bool is_premium_available = false;
|
bool is_premium_available = false;
|
||||||
int32 stickers_premium_by_emoji_num = 0;
|
int32 stickers_premium_by_emoji_num = 0;
|
||||||
int32 stickers_normal_by_emoji_per_premium_num = 2;
|
int32 stickers_normal_by_emoji_per_premium_num = 2;
|
||||||
|
int32 forum_upgrade_participants_min = 200;
|
||||||
if (config->get_id() == telegram_api::jsonObject::ID) {
|
if (config->get_id() == telegram_api::jsonObject::ID) {
|
||||||
for (auto &key_value : static_cast<telegram_api::jsonObject *>(config.get())->value_) {
|
for (auto &key_value : static_cast<telegram_api::jsonObject *>(config.get())->value_) {
|
||||||
Slice key = key_value->key_;
|
Slice key = key_value->key_;
|
||||||
@ -1518,6 +1521,25 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (key == "restriction_add_platforms") {
|
||||||
|
if (value->get_id() == telegram_api::jsonArray::ID) {
|
||||||
|
auto platforms = std::move(static_cast<telegram_api::jsonArray *>(value)->value_);
|
||||||
|
for (auto &platform : platforms) {
|
||||||
|
auto platform_name = get_json_value_string(std::move(platform), key);
|
||||||
|
if (!platform_name.empty() && platform_name.find(',') == string::npos) {
|
||||||
|
if (!restriction_add_platforms.empty()) {
|
||||||
|
restriction_add_platforms += ',';
|
||||||
|
}
|
||||||
|
restriction_add_platforms += platform_name;
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << "Receive unexpected restriction platform " << platform_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << "Receive unexpected restriction_add_platforms " << to_string(*value);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (key == "emojies_animated_zoom") {
|
if (key == "emojies_animated_zoom") {
|
||||||
animated_emoji_zoom = get_json_value_double(std::move(key_value->value_), key);
|
animated_emoji_zoom = get_json_value_double(std::move(key_value->value_), key);
|
||||||
continue;
|
continue;
|
||||||
@ -1680,13 +1702,24 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
|
|||||||
if (value->get_id() == telegram_api::jsonArray::ID) {
|
if (value->get_id() == telegram_api::jsonArray::ID) {
|
||||||
auto domains = std::move(static_cast<telegram_api::jsonArray *>(value)->value_);
|
auto domains = std::move(static_cast<telegram_api::jsonArray *>(value)->value_);
|
||||||
for (auto &domain : domains) {
|
for (auto &domain : domains) {
|
||||||
autologin_domains.push_back(get_json_value_string(std::move(domain), key));
|
url_auth_domains.push_back(get_json_value_string(std::move(domain), key));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG(ERROR) << "Receive unexpected url_auth_domains " << to_string(*value);
|
LOG(ERROR) << "Receive unexpected url_auth_domains " << to_string(*value);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (key == "whitelisted_domains") {
|
||||||
|
if (value->get_id() == telegram_api::jsonArray::ID) {
|
||||||
|
auto domains = std::move(static_cast<telegram_api::jsonArray *>(value)->value_);
|
||||||
|
for (auto &domain : domains) {
|
||||||
|
whitelisted_domains.push_back(get_json_value_string(std::move(domain), key));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << "Receive unexpected whitelisted_domains " << to_string(*value);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (key == "round_video_encoding") {
|
if (key == "round_video_encoding") {
|
||||||
if (value->get_id() == telegram_api::jsonObject::ID) {
|
if (value->get_id() == telegram_api::jsonObject::ID) {
|
||||||
auto video_note_settings = std::move(static_cast<telegram_api::jsonObject *>(value)->value_);
|
auto video_note_settings = std::move(static_cast<telegram_api::jsonObject *>(value)->value_);
|
||||||
@ -1811,6 +1844,10 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
|
|||||||
G()->set_option_integer(key, setting_value);
|
G()->set_option_integer(key, setting_value);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (key == "forum_upgrade_participants_min") {
|
||||||
|
forum_upgrade_participants_min = get_json_value_int(std::move(key_value->value_), key);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
new_values.push_back(std::move(key_value));
|
new_values.push_back(std::move(key_value));
|
||||||
}
|
}
|
||||||
@ -1820,7 +1857,7 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
|
|||||||
config = make_tl_object<telegram_api::jsonObject>(std::move(new_values));
|
config = make_tl_object<telegram_api::jsonObject>(std::move(new_values));
|
||||||
|
|
||||||
send_closure(G()->link_manager(), &LinkManager::update_autologin_domains, std::move(autologin_token),
|
send_closure(G()->link_manager(), &LinkManager::update_autologin_domains, std::move(autologin_token),
|
||||||
std::move(autologin_domains), std::move(url_auth_domains));
|
std::move(autologin_domains), std::move(url_auth_domains), std::move(whitelisted_domains));
|
||||||
|
|
||||||
Global &options = *G();
|
Global &options = *G();
|
||||||
|
|
||||||
@ -1839,6 +1876,11 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
|
|||||||
get_content_settings(Auto());
|
get_content_settings(Auto());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (restriction_add_platforms.empty()) {
|
||||||
|
options.set_option_empty("restriction_add_platforms");
|
||||||
|
} else {
|
||||||
|
options.set_option_string("restriction_add_platforms", restriction_add_platforms);
|
||||||
|
}
|
||||||
|
|
||||||
if (!dice_emojis.empty()) {
|
if (!dice_emojis.empty()) {
|
||||||
vector<string> dice_success_values(dice_emojis.size());
|
vector<string> dice_success_values(dice_emojis.size());
|
||||||
@ -1892,6 +1934,11 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
|
|||||||
} else {
|
} else {
|
||||||
options.set_option_integer("reactions_uniq_max", reactions_uniq_max);
|
options.set_option_integer("reactions_uniq_max", reactions_uniq_max);
|
||||||
}
|
}
|
||||||
|
if (forum_upgrade_participants_min < 0) {
|
||||||
|
options.set_option_empty("forum_member_count_min");
|
||||||
|
} else {
|
||||||
|
options.set_option_integer("forum_member_count_min", forum_upgrade_participants_min);
|
||||||
|
}
|
||||||
|
|
||||||
bool is_premium = options.get_option_boolean("is_premium");
|
bool is_premium = options.get_option_boolean("is_premium");
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -13,6 +13,7 @@
|
|||||||
#include "td/telegram/ChannelType.h"
|
#include "td/telegram/ChannelType.h"
|
||||||
#include "td/telegram/ChatId.h"
|
#include "td/telegram/ChatId.h"
|
||||||
#include "td/telegram/Contact.h"
|
#include "td/telegram/Contact.h"
|
||||||
|
#include "td/telegram/CustomEmojiId.h"
|
||||||
#include "td/telegram/DialogAdministrator.h"
|
#include "td/telegram/DialogAdministrator.h"
|
||||||
#include "td/telegram/DialogId.h"
|
#include "td/telegram/DialogId.h"
|
||||||
#include "td/telegram/DialogInviteLink.h"
|
#include "td/telegram/DialogInviteLink.h"
|
||||||
@ -38,6 +39,7 @@
|
|||||||
#include "td/telegram/td_api.h"
|
#include "td/telegram/td_api.h"
|
||||||
#include "td/telegram/telegram_api.h"
|
#include "td/telegram/telegram_api.h"
|
||||||
#include "td/telegram/UserId.h"
|
#include "td/telegram/UserId.h"
|
||||||
|
#include "td/telegram/Usernames.h"
|
||||||
|
|
||||||
#include "td/actor/actor.h"
|
#include "td/actor/actor.h"
|
||||||
#include "td/actor/MultiPromise.h"
|
#include "td/actor/MultiPromise.h"
|
||||||
@ -128,13 +130,12 @@ class ContactsManager final : public Actor {
|
|||||||
|
|
||||||
string get_dialog_about(DialogId dialog_id);
|
string get_dialog_about(DialogId dialog_id);
|
||||||
|
|
||||||
bool is_update_about_username_change_received(UserId user_id) const;
|
string get_dialog_search_text(DialogId dialog_id) const;
|
||||||
|
|
||||||
void for_each_secret_chat_with_user(UserId user_id, const std::function<void(SecretChatId)> &f);
|
void for_each_secret_chat_with_user(UserId user_id, const std::function<void(SecretChatId)> &f);
|
||||||
|
|
||||||
string get_user_username(UserId user_id) const;
|
string get_user_first_username(UserId user_id) const;
|
||||||
string get_channel_username(ChannelId channel_id) const;
|
string get_channel_first_username(ChannelId channel_id) const;
|
||||||
string get_secret_chat_username(SecretChatId secret_chat_id) const;
|
|
||||||
|
|
||||||
int32 get_secret_chat_date(SecretChatId secret_chat_id) const;
|
int32 get_secret_chat_date(SecretChatId secret_chat_id) const;
|
||||||
int32 get_secret_chat_ttl(SecretChatId secret_chat_id) const;
|
int32 get_secret_chat_ttl(SecretChatId secret_chat_id) const;
|
||||||
@ -178,7 +179,7 @@ class ContactsManager final : public Actor {
|
|||||||
|
|
||||||
void on_update_profile_success(int32 flags, const string &first_name, const string &last_name, const string &about);
|
void on_update_profile_success(int32 flags, const string &first_name, const string &last_name, const string &about);
|
||||||
|
|
||||||
void on_update_user_name(UserId user_id, string &&first_name, string &&last_name, string &&username);
|
void on_update_user_name(UserId user_id, string &&first_name, string &&last_name, Usernames &&usernames);
|
||||||
void on_update_user_phone_number(UserId user_id, string &&phone_number);
|
void on_update_user_phone_number(UserId user_id, string &&phone_number);
|
||||||
void on_update_user_photo(UserId user_id, tl_object_ptr<telegram_api::UserProfilePhoto> &&photo_ptr);
|
void on_update_user_photo(UserId user_id, tl_object_ptr<telegram_api::UserProfilePhoto> &&photo_ptr);
|
||||||
void on_update_user_emoji_status(UserId user_id, tl_object_ptr<telegram_api::EmojiStatus> &&emoji_status);
|
void on_update_user_emoji_status(UserId user_id, tl_object_ptr<telegram_api::EmojiStatus> &&emoji_status);
|
||||||
@ -201,7 +202,8 @@ class ContactsManager final : public Actor {
|
|||||||
void on_update_chat_default_permissions(ChatId chat_id, RestrictedRights default_permissions, int32 version);
|
void on_update_chat_default_permissions(ChatId chat_id, RestrictedRights default_permissions, int32 version);
|
||||||
void on_update_chat_pinned_message(ChatId chat_id, MessageId pinned_message_id, int32 version);
|
void on_update_chat_pinned_message(ChatId chat_id, MessageId pinned_message_id, int32 version);
|
||||||
|
|
||||||
void on_update_channel_username(ChannelId channel_id, string &&username);
|
void on_update_channel_editable_username(ChannelId channel_id, string &&username);
|
||||||
|
void on_update_channel_usernames(ChannelId channel_id, Usernames &&usernames);
|
||||||
void on_update_channel_description(ChannelId channel_id, string &&description);
|
void on_update_channel_description(ChannelId channel_id, string &&description);
|
||||||
void on_update_channel_sticker_set(ChannelId channel_id, StickerSetId sticker_set_id);
|
void on_update_channel_sticker_set(ChannelId channel_id, StickerSetId sticker_set_id);
|
||||||
void on_update_channel_linked_channel_id(ChannelId channel_id, ChannelId group_channel_id);
|
void on_update_channel_linked_channel_id(ChannelId channel_id, ChannelId group_channel_id);
|
||||||
@ -285,6 +287,18 @@ class ContactsManager final : public Actor {
|
|||||||
|
|
||||||
UserId add_channel_bot_user();
|
UserId add_channel_bot_user();
|
||||||
|
|
||||||
|
void on_update_username_is_active(string &&username, bool is_active, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void on_update_active_usernames_order(vector<string> &&usernames, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void on_update_channel_username_is_active(ChannelId channel_id, string &&username, bool is_active,
|
||||||
|
Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void on_deactivate_channel_usernames(ChannelId channel_id, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void on_update_channel_active_usernames_order(ChannelId channel_id, vector<string> &&usernames,
|
||||||
|
Promise<Unit> &&promise);
|
||||||
|
|
||||||
void on_update_online_status_privacy();
|
void on_update_online_status_privacy();
|
||||||
|
|
||||||
void on_update_phone_number_privacy();
|
void on_update_phone_number_privacy();
|
||||||
@ -347,12 +361,23 @@ class ContactsManager final : public Actor {
|
|||||||
|
|
||||||
void set_username(const string &username, Promise<Unit> &&promise);
|
void set_username(const string &username, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void toggle_username_is_active(string &&username, bool is_active, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void reorder_usernames(vector<string> &&usernames, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void set_emoji_status(EmojiStatus emoji_status, Promise<Unit> &&promise);
|
void set_emoji_status(EmojiStatus emoji_status, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void set_chat_description(ChatId chat_id, const string &description, Promise<Unit> &&promise);
|
void set_chat_description(ChatId chat_id, const string &description, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void set_channel_username(ChannelId channel_id, const string &username, Promise<Unit> &&promise);
|
void set_channel_username(ChannelId channel_id, const string &username, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void toggle_channel_username_is_active(ChannelId channel_id, string &&username, bool is_active,
|
||||||
|
Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void disable_all_channel_usernames(ChannelId channel_id, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void reorder_channel_usernames(ChannelId channel_id, vector<string> &&usernames, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void set_channel_sticker_set(ChannelId channel_id, StickerSetId sticker_set_id, Promise<Unit> &&promise);
|
void set_channel_sticker_set(ChannelId channel_id, StickerSetId sticker_set_id, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void toggle_channel_sign_messages(ChannelId channel_id, bool sign_messages, Promise<Unit> &&promise);
|
void toggle_channel_sign_messages(ChannelId channel_id, bool sign_messages, Promise<Unit> &&promise);
|
||||||
@ -364,6 +389,8 @@ class ContactsManager final : public Actor {
|
|||||||
void toggle_channel_is_all_history_available(ChannelId channel_id, bool is_all_history_available,
|
void toggle_channel_is_all_history_available(ChannelId channel_id, bool is_all_history_available,
|
||||||
Promise<Unit> &&promise);
|
Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void toggle_channel_is_forum(ChannelId channel_id, bool is_forum, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void convert_channel_to_gigagroup(ChannelId channel_id, Promise<Unit> &&promise);
|
void convert_channel_to_gigagroup(ChannelId channel_id, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void set_channel_description(ChannelId channel_id, const string &description, Promise<Unit> &&promise);
|
void set_channel_description(ChannelId channel_id, const string &description, Promise<Unit> &&promise);
|
||||||
@ -545,9 +572,11 @@ class ContactsManager final : public Actor {
|
|||||||
ChannelType get_channel_type(ChannelId channel_id) const;
|
ChannelType get_channel_type(ChannelId channel_id) const;
|
||||||
bool is_broadcast_channel(ChannelId channel_id) const;
|
bool is_broadcast_channel(ChannelId channel_id) const;
|
||||||
bool is_megagroup_channel(ChannelId channel_id) const;
|
bool is_megagroup_channel(ChannelId channel_id) const;
|
||||||
|
bool is_forum_channel(ChannelId channel_id) const;
|
||||||
int32 get_channel_date(ChannelId channel_id) const;
|
int32 get_channel_date(ChannelId channel_id) const;
|
||||||
DialogParticipantStatus get_channel_status(ChannelId channel_id) const;
|
DialogParticipantStatus get_channel_status(ChannelId channel_id) const;
|
||||||
DialogParticipantStatus get_channel_permissions(ChannelId channel_id) const;
|
DialogParticipantStatus get_channel_permissions(ChannelId channel_id) const;
|
||||||
|
bool get_channel_is_verified(ChannelId channel_id) const;
|
||||||
int32 get_channel_participant_count(ChannelId channel_id) const;
|
int32 get_channel_participant_count(ChannelId channel_id) const;
|
||||||
bool get_channel_sign_messages(ChannelId channel_id) const;
|
bool get_channel_sign_messages(ChannelId channel_id) const;
|
||||||
bool get_channel_has_linked_channel(ChannelId channel_id) const;
|
bool get_channel_has_linked_channel(ChannelId channel_id) const;
|
||||||
@ -644,11 +673,11 @@ class ContactsManager final : public Actor {
|
|||||||
struct User {
|
struct User {
|
||||||
string first_name;
|
string first_name;
|
||||||
string last_name;
|
string last_name;
|
||||||
string username;
|
Usernames usernames;
|
||||||
string phone_number;
|
string phone_number;
|
||||||
int64 access_hash = -1;
|
int64 access_hash = -1;
|
||||||
EmojiStatus emoji_status;
|
EmojiStatus emoji_status;
|
||||||
int64 last_sent_emoji_status = 0;
|
CustomEmojiId last_sent_emoji_status;
|
||||||
|
|
||||||
ProfilePhoto photo;
|
ProfilePhoto photo;
|
||||||
|
|
||||||
@ -778,7 +807,8 @@ class ContactsManager final : public Actor {
|
|||||||
ChannelId migrated_to_channel_id;
|
ChannelId migrated_to_channel_id;
|
||||||
|
|
||||||
DialogParticipantStatus status = DialogParticipantStatus::Banned(0);
|
DialogParticipantStatus status = DialogParticipantStatus::Banned(0);
|
||||||
RestrictedRights default_permissions{false, false, false, false, false, false, false, false, false, false, false};
|
RestrictedRights default_permissions{false, false, false, false, false, false,
|
||||||
|
false, false, false, false, false, false};
|
||||||
|
|
||||||
static constexpr uint32 CACHE_VERSION = 4;
|
static constexpr uint32 CACHE_VERSION = 4;
|
||||||
uint32 cache_version = 0;
|
uint32 cache_version = 0;
|
||||||
@ -846,14 +876,15 @@ class ContactsManager final : public Actor {
|
|||||||
int64 access_hash = 0;
|
int64 access_hash = 0;
|
||||||
string title;
|
string title;
|
||||||
DialogPhoto photo;
|
DialogPhoto photo;
|
||||||
string username;
|
Usernames usernames;
|
||||||
vector<RestrictionReason> restriction_reasons;
|
vector<RestrictionReason> restriction_reasons;
|
||||||
DialogParticipantStatus status = DialogParticipantStatus::Banned(0);
|
DialogParticipantStatus status = DialogParticipantStatus::Banned(0);
|
||||||
RestrictedRights default_permissions{false, false, false, false, false, false, false, false, false, false, false};
|
RestrictedRights default_permissions{false, false, false, false, false, false,
|
||||||
|
false, false, false, false, false, false};
|
||||||
int32 date = 0;
|
int32 date = 0;
|
||||||
int32 participant_count = 0;
|
int32 participant_count = 0;
|
||||||
|
|
||||||
static constexpr uint32 CACHE_VERSION = 9;
|
static constexpr uint32 CACHE_VERSION = 10;
|
||||||
uint32 cache_version = 0;
|
uint32 cache_version = 0;
|
||||||
|
|
||||||
bool has_linked_channel = false;
|
bool has_linked_channel = false;
|
||||||
@ -867,6 +898,7 @@ class ContactsManager final : public Actor {
|
|||||||
|
|
||||||
bool is_megagroup = false;
|
bool is_megagroup = false;
|
||||||
bool is_gigagroup = false;
|
bool is_gigagroup = false;
|
||||||
|
bool is_forum = false;
|
||||||
bool is_verified = false;
|
bool is_verified = false;
|
||||||
bool is_scam = false;
|
bool is_scam = false;
|
||||||
bool is_fake = false;
|
bool is_fake = false;
|
||||||
@ -1079,6 +1111,7 @@ class ContactsManager final : public Actor {
|
|||||||
static constexpr int32 USER_FLAG_IS_PREMIUM = 1 << 28;
|
static constexpr int32 USER_FLAG_IS_PREMIUM = 1 << 28;
|
||||||
static constexpr int32 USER_FLAG_ATTACH_MENU_ENABLED = 1 << 29;
|
static constexpr int32 USER_FLAG_ATTACH_MENU_ENABLED = 1 << 29;
|
||||||
static constexpr int32 USER_FLAG_HAS_EMOJI_STATUS = 1 << 30;
|
static constexpr int32 USER_FLAG_HAS_EMOJI_STATUS = 1 << 30;
|
||||||
|
static constexpr int32 USER_FLAG_HAS_USERNAMES = 1 << 0;
|
||||||
|
|
||||||
static constexpr int32 USER_FULL_FLAG_IS_BLOCKED = 1 << 0;
|
static constexpr int32 USER_FULL_FLAG_IS_BLOCKED = 1 << 0;
|
||||||
static constexpr int32 USER_FULL_FLAG_HAS_ABOUT = 1 << 1;
|
static constexpr int32 USER_FULL_FLAG_HAS_ABOUT = 1 << 1;
|
||||||
@ -1115,7 +1148,7 @@ class ContactsManager final : public Actor {
|
|||||||
static constexpr int32 CHANNEL_FLAG_USER_IS_CREATOR = 1 << 0;
|
static constexpr int32 CHANNEL_FLAG_USER_IS_CREATOR = 1 << 0;
|
||||||
static constexpr int32 CHANNEL_FLAG_USER_HAS_LEFT = 1 << 2;
|
static constexpr int32 CHANNEL_FLAG_USER_HAS_LEFT = 1 << 2;
|
||||||
static constexpr int32 CHANNEL_FLAG_IS_BROADCAST = 1 << 5;
|
static constexpr int32 CHANNEL_FLAG_IS_BROADCAST = 1 << 5;
|
||||||
static constexpr int32 CHANNEL_FLAG_IS_PUBLIC = 1 << 6;
|
static constexpr int32 CHANNEL_FLAG_HAS_USERNAME = 1 << 6;
|
||||||
static constexpr int32 CHANNEL_FLAG_IS_VERIFIED = 1 << 7;
|
static constexpr int32 CHANNEL_FLAG_IS_VERIFIED = 1 << 7;
|
||||||
static constexpr int32 CHANNEL_FLAG_IS_MEGAGROUP = 1 << 8;
|
static constexpr int32 CHANNEL_FLAG_IS_MEGAGROUP = 1 << 8;
|
||||||
static constexpr int32 CHANNEL_FLAG_IS_RESTRICTED = 1 << 9;
|
static constexpr int32 CHANNEL_FLAG_IS_RESTRICTED = 1 << 9;
|
||||||
@ -1138,6 +1171,8 @@ class ContactsManager final : public Actor {
|
|||||||
static constexpr int32 CHANNEL_FLAG_NOFORWARDS = 1 << 27;
|
static constexpr int32 CHANNEL_FLAG_NOFORWARDS = 1 << 27;
|
||||||
static constexpr int32 CHANNEL_FLAG_JOIN_TO_SEND = 1 << 28;
|
static constexpr int32 CHANNEL_FLAG_JOIN_TO_SEND = 1 << 28;
|
||||||
static constexpr int32 CHANNEL_FLAG_JOIN_REQUEST = 1 << 29;
|
static constexpr int32 CHANNEL_FLAG_JOIN_REQUEST = 1 << 29;
|
||||||
|
static constexpr int32 CHANNEL_FLAG_IS_FORUM = 1 << 30;
|
||||||
|
static constexpr int32 CHANNEL_FLAG_HAS_USERNAMES = 1 << 0;
|
||||||
|
|
||||||
static constexpr int32 CHANNEL_FULL_FLAG_HAS_PARTICIPANT_COUNT = 1 << 0;
|
static constexpr int32 CHANNEL_FULL_FLAG_HAS_PARTICIPANT_COUNT = 1 << 0;
|
||||||
static constexpr int32 CHANNEL_FULL_FLAG_HAS_ADMINISTRATOR_COUNT = 1 << 1;
|
static constexpr int32 CHANNEL_FULL_FLAG_HAS_ADMINISTRATOR_COUNT = 1 << 1;
|
||||||
@ -1239,6 +1274,9 @@ class ContactsManager final : public Actor {
|
|||||||
|
|
||||||
SecretChat *add_secret_chat(SecretChatId secret_chat_id);
|
SecretChat *add_secret_chat(SecretChatId secret_chat_id);
|
||||||
|
|
||||||
|
string get_user_search_text(UserId user_id) const;
|
||||||
|
static string get_user_search_text(const User *u);
|
||||||
|
|
||||||
static DialogParticipantStatus get_chat_status(const Chat *c);
|
static DialogParticipantStatus get_chat_status(const Chat *c);
|
||||||
DialogParticipantStatus get_chat_permissions(const Chat *c) const;
|
DialogParticipantStatus get_chat_permissions(const Chat *c) const;
|
||||||
|
|
||||||
@ -1251,13 +1289,17 @@ class ContactsManager final : public Actor {
|
|||||||
static bool get_channel_join_to_send(const Channel *c);
|
static bool get_channel_join_to_send(const Channel *c);
|
||||||
static bool get_channel_join_request(const Channel *c);
|
static bool get_channel_join_request(const Channel *c);
|
||||||
|
|
||||||
|
string get_channel_search_text(ChannelId channel_id) const;
|
||||||
|
static string get_channel_search_text(const Channel *c);
|
||||||
|
|
||||||
void set_my_id(UserId my_id);
|
void set_my_id(UserId my_id);
|
||||||
|
|
||||||
static bool is_valid_username(const string &username);
|
static bool is_allowed_username(const string &username);
|
||||||
|
|
||||||
void on_set_emoji_status(EmojiStatus emoji_status, Promise<Unit> &&promise);
|
void on_set_emoji_status(EmojiStatus emoji_status, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void on_update_user_name(User *u, UserId user_id, string &&first_name, string &&last_name, string &&username);
|
void on_update_user_name(User *u, UserId user_id, string &&first_name, string &&last_name);
|
||||||
|
void on_update_user_usernames(User *u, UserId user_id, Usernames &&usernames);
|
||||||
void on_update_user_phone_number(User *u, UserId user_id, string &&phone_number);
|
void on_update_user_phone_number(User *u, UserId user_id, string &&phone_number);
|
||||||
void on_update_user_photo(User *u, UserId user_id, tl_object_ptr<telegram_api::UserProfilePhoto> &&photo,
|
void on_update_user_photo(User *u, UserId user_id, tl_object_ptr<telegram_api::UserProfilePhoto> &&photo,
|
||||||
const char *source);
|
const char *source);
|
||||||
@ -1317,7 +1359,7 @@ class ContactsManager final : public Actor {
|
|||||||
tl_object_ptr<telegram_api::ChatPhoto> &&chat_photo_ptr);
|
tl_object_ptr<telegram_api::ChatPhoto> &&chat_photo_ptr);
|
||||||
void on_update_channel_photo(Channel *c, ChannelId channel_id, DialogPhoto &&photo, bool invalidate_photo_cache);
|
void on_update_channel_photo(Channel *c, ChannelId channel_id, DialogPhoto &&photo, bool invalidate_photo_cache);
|
||||||
static void on_update_channel_title(Channel *c, ChannelId channel_id, string &&title);
|
static void on_update_channel_title(Channel *c, ChannelId channel_id, string &&title);
|
||||||
void on_update_channel_username(Channel *c, ChannelId channel_id, string &&username);
|
void on_update_channel_usernames(Channel *c, ChannelId channel_id, Usernames &&usernames);
|
||||||
void on_update_channel_status(Channel *c, ChannelId channel_id, DialogParticipantStatus &&status);
|
void on_update_channel_status(Channel *c, ChannelId channel_id, DialogParticipantStatus &&status);
|
||||||
static void on_update_channel_default_permissions(Channel *c, ChannelId channel_id,
|
static void on_update_channel_default_permissions(Channel *c, ChannelId channel_id,
|
||||||
RestrictedRights default_permissions);
|
RestrictedRights default_permissions);
|
||||||
@ -1339,10 +1381,14 @@ class ContactsManager final : public Actor {
|
|||||||
static void on_update_channel_full_bot_user_ids(ChannelFull *channel_full, ChannelId channel_id,
|
static void on_update_channel_full_bot_user_ids(ChannelFull *channel_full, ChannelId channel_id,
|
||||||
vector<UserId> &&bot_user_ids);
|
vector<UserId> &&bot_user_ids);
|
||||||
|
|
||||||
|
void toggle_username_is_active_impl(string &&username, bool is_active, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void reorder_usernames_impl(vector<string> &&usernames, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void on_channel_status_changed(Channel *c, ChannelId channel_id, const DialogParticipantStatus &old_status,
|
void on_channel_status_changed(Channel *c, ChannelId channel_id, const DialogParticipantStatus &old_status,
|
||||||
const DialogParticipantStatus &new_status);
|
const DialogParticipantStatus &new_status);
|
||||||
void on_channel_username_changed(const Channel *c, ChannelId channel_id, const string &old_username,
|
void on_channel_usernames_changed(const Channel *c, ChannelId channel_id, const Usernames &old_usernames,
|
||||||
const string &new_username);
|
const Usernames &new_usernames);
|
||||||
|
|
||||||
void remove_linked_channel_id(ChannelId channel_id);
|
void remove_linked_channel_id(ChannelId channel_id);
|
||||||
ChannelId get_linked_channel_id(ChannelId channel_id) const;
|
ChannelId get_linked_channel_id(ChannelId channel_id) const;
|
||||||
@ -1836,7 +1882,7 @@ class ContactsManager final : public Actor {
|
|||||||
|
|
||||||
bool are_contacts_loaded_ = false;
|
bool are_contacts_loaded_ = false;
|
||||||
int32 next_contacts_sync_date_ = 0;
|
int32 next_contacts_sync_date_ = 0;
|
||||||
Hints contacts_hints_; // search contacts by first name, last name and username
|
Hints contacts_hints_; // search contacts by first name, last name and usernames
|
||||||
vector<Promise<Unit>> load_contacts_queries_;
|
vector<Promise<Unit>> load_contacts_queries_;
|
||||||
MultiPromiseActor load_contact_users_multipromise_{"LoadContactUsersMultiPromiseActor"};
|
MultiPromiseActor load_contact_users_multipromise_{"LoadContactUsersMultiPromiseActor"};
|
||||||
int32 saved_contact_count_ = -1;
|
int32 saved_contact_count_ = -1;
|
||||||
|
@ -136,7 +136,7 @@ void CountryInfoManager::tear_down() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
string CountryInfoManager::get_main_language_code() {
|
string CountryInfoManager::get_main_language_code() {
|
||||||
return to_lower(td_->language_pack_manager_->get_actor_unsafe()->get_main_language_code());
|
return to_lower(td_->language_pack_manager_.get_actor_unsafe()->get_main_language_code());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CountryInfoManager::get_countries(Promise<td_api::object_ptr<td_api::countries>> &&promise) {
|
void CountryInfoManager::get_countries(Promise<td_api::object_ptr<td_api::countries>> &&promise) {
|
||||||
|
65
td/telegram/CustomEmojiId.h
Normal file
65
td/telegram/CustomEmojiId.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/StringBuilder.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class CustomEmojiId {
|
||||||
|
int64 id = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CustomEmojiId() = default;
|
||||||
|
|
||||||
|
explicit CustomEmojiId(int64 custom_emoji_id) : id(custom_emoji_id) {
|
||||||
|
}
|
||||||
|
template <class T, typename = std::enable_if_t<std::is_convertible<T, int64>::value>>
|
||||||
|
CustomEmojiId(T custom_emoji_id) = delete;
|
||||||
|
|
||||||
|
bool is_valid() const {
|
||||||
|
return id != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64 get() const {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const CustomEmojiId &other) const {
|
||||||
|
return id == other.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const CustomEmojiId &other) const {
|
||||||
|
return id != other.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class StorerT>
|
||||||
|
void store(StorerT &storer) const {
|
||||||
|
storer.store_long(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ParserT>
|
||||||
|
void parse(ParserT &parser) {
|
||||||
|
id = parser.fetch_long();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CustomEmojiIdHash {
|
||||||
|
std::size_t operator()(CustomEmojiId custom_emoji_id) const {
|
||||||
|
return std::hash<int64>()(custom_emoji_id.get());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline StringBuilder &operator<<(StringBuilder &string_builder, CustomEmojiId custom_emoji_id) {
|
||||||
|
return string_builder << "custom emoji " << custom_emoji_id.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
@ -10,6 +10,7 @@
|
|||||||
#include "td/telegram/TdDb.h"
|
#include "td/telegram/TdDb.h"
|
||||||
|
|
||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/misc.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
@ -20,6 +21,18 @@ static string good_prime_key(Slice prime_str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int DhCache::is_good_prime(Slice prime_str) const {
|
int DhCache::is_good_prime(Slice prime_str) const {
|
||||||
|
static string built_in_good_prime =
|
||||||
|
hex_decode(
|
||||||
|
"c71caeb9c6b1c9048e6c522f70f13f73980d40238e3e21c14934d037563d930f48198a0aa7c14058229493d22530f4dbfa336f6e0ac9"
|
||||||
|
"25139543aed44cce7c3720fd51f69458705ac68cd4fe6b6b13abdc9746512969328454f18faf8c595f642477fe96bb2a941d5bcd1d4a"
|
||||||
|
"c8cc49880708fa9b378e3c4f3a9060bee67cf9a4a4a695811051907e162753b56b0f6b410dba74d8a84b2a14b3144e0ef1284754fd17"
|
||||||
|
"ed950d5965b4b9dd46582db1178d169c6bc465b0d6ff9ca3928fef5b9ae4e418fc15e83ebea0f87fa9ff5eed70050ded2849f47bf959"
|
||||||
|
"d956850ce929851f0d8115f635b105ee2e4e15d04b2454bf6f4fadf034b10403119cd8e3b92fcc5b")
|
||||||
|
.move_as_ok();
|
||||||
|
if (prime_str == built_in_good_prime) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
string value = G()->td_db()->get_binlog_pmc()->get(good_prime_key(prime_str));
|
string value = G()->td_db()->get_binlog_pmc()->get(good_prime_key(prime_str));
|
||||||
if (value == "good") {
|
if (value == "good") {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -403,6 +403,8 @@ bool DialogAction::is_canceled_by_message_of_type(MessageContentType message_con
|
|||||||
case MessageContentType::WebViewDataSent:
|
case MessageContentType::WebViewDataSent:
|
||||||
case MessageContentType::WebViewDataReceived:
|
case MessageContentType::WebViewDataReceived:
|
||||||
case MessageContentType::GiftPremium:
|
case MessageContentType::GiftPremium:
|
||||||
|
case MessageContentType::TopicCreate:
|
||||||
|
case MessageContentType::TopicEdit:
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "td/telegram/DialogInviteLink.h"
|
#include "td/telegram/DialogInviteLink.h"
|
||||||
#include "td/telegram/DialogLocation.h"
|
#include "td/telegram/DialogLocation.h"
|
||||||
#include "td/telegram/DialogParticipant.h"
|
#include "td/telegram/DialogParticipant.h"
|
||||||
|
#include "td/telegram/ForumTopicInfo.h"
|
||||||
#include "td/telegram/Global.h"
|
#include "td/telegram/Global.h"
|
||||||
#include "td/telegram/GroupCallManager.h"
|
#include "td/telegram/GroupCallManager.h"
|
||||||
#include "td/telegram/GroupCallParticipant.h"
|
#include "td/telegram/GroupCallParticipant.h"
|
||||||
@ -127,6 +128,11 @@ static td_api::object_ptr<td_api::ChatEventAction> get_chat_event_action_object(
|
|||||||
return td_api::make_object<td_api::chatEventUsernameChanged>(std::move(action->prev_value_),
|
return td_api::make_object<td_api::chatEventUsernameChanged>(std::move(action->prev_value_),
|
||||||
std::move(action->new_value_));
|
std::move(action->new_value_));
|
||||||
}
|
}
|
||||||
|
case telegram_api::channelAdminLogEventActionChangeUsernames::ID: {
|
||||||
|
auto action = move_tl_object_as<telegram_api::channelAdminLogEventActionChangeUsernames>(action_ptr);
|
||||||
|
return td_api::make_object<td_api::chatEventActiveUsernamesChanged>(std::move(action->prev_value_),
|
||||||
|
std::move(action->new_value_));
|
||||||
|
}
|
||||||
case telegram_api::channelAdminLogEventActionChangePhoto::ID: {
|
case telegram_api::channelAdminLogEventActionChangePhoto::ID: {
|
||||||
auto action = move_tl_object_as<telegram_api::channelAdminLogEventActionChangePhoto>(action_ptr);
|
auto action = move_tl_object_as<telegram_api::channelAdminLogEventActionChangePhoto>(action_ptr);
|
||||||
auto file_manager = td->file_manager_.get();
|
auto file_manager = td->file_manager_.get();
|
||||||
@ -352,6 +358,59 @@ static td_api::object_ptr<td_api::ChatEventAction> get_chat_event_action_object(
|
|||||||
old_available_reactions.get_chat_available_reactions_object(),
|
old_available_reactions.get_chat_available_reactions_object(),
|
||||||
new_available_reactions.get_chat_available_reactions_object());
|
new_available_reactions.get_chat_available_reactions_object());
|
||||||
}
|
}
|
||||||
|
case telegram_api::channelAdminLogEventActionToggleForum::ID: {
|
||||||
|
auto action = move_tl_object_as<telegram_api::channelAdminLogEventActionToggleForum>(action_ptr);
|
||||||
|
return td_api::make_object<td_api::chatEventIsForumToggled>(action->new_value_);
|
||||||
|
}
|
||||||
|
case telegram_api::channelAdminLogEventActionCreateTopic::ID: {
|
||||||
|
auto action = move_tl_object_as<telegram_api::channelAdminLogEventActionCreateTopic>(action_ptr);
|
||||||
|
auto topic_info = ForumTopicInfo(action->topic_);
|
||||||
|
if (topic_info.is_empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
actor_dialog_id = topic_info.get_creator_dialog_id();
|
||||||
|
return td_api::make_object<td_api::chatEventForumTopicCreated>(topic_info.get_forum_topic_info_object(td));
|
||||||
|
}
|
||||||
|
case telegram_api::channelAdminLogEventActionEditTopic::ID: {
|
||||||
|
auto action = move_tl_object_as<telegram_api::channelAdminLogEventActionEditTopic>(action_ptr);
|
||||||
|
auto old_topic_info = ForumTopicInfo(action->prev_topic_);
|
||||||
|
auto new_topic_info = ForumTopicInfo(action->new_topic_);
|
||||||
|
if (old_topic_info.is_empty() || new_topic_info.is_empty() ||
|
||||||
|
old_topic_info.get_top_thread_message_id() != new_topic_info.get_top_thread_message_id()) {
|
||||||
|
LOG(ERROR) << "Receive " << to_string(action);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (old_topic_info.is_closed() != new_topic_info.is_closed()) {
|
||||||
|
return td_api::make_object<td_api::chatEventForumTopicToggleIsClosed>(
|
||||||
|
new_topic_info.get_forum_topic_info_object(td));
|
||||||
|
}
|
||||||
|
return td_api::make_object<td_api::chatEventForumTopicEdited>(old_topic_info.get_forum_topic_info_object(td),
|
||||||
|
new_topic_info.get_forum_topic_info_object(td));
|
||||||
|
}
|
||||||
|
case telegram_api::channelAdminLogEventActionDeleteTopic::ID: {
|
||||||
|
auto action = move_tl_object_as<telegram_api::channelAdminLogEventActionDeleteTopic>(action_ptr);
|
||||||
|
auto topic_info = ForumTopicInfo(action->topic_);
|
||||||
|
if (topic_info.is_empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return td_api::make_object<td_api::chatEventForumTopicDeleted>(topic_info.get_forum_topic_info_object(td));
|
||||||
|
}
|
||||||
|
case telegram_api::channelAdminLogEventActionPinTopic::ID: {
|
||||||
|
auto action = move_tl_object_as<telegram_api::channelAdminLogEventActionPinTopic>(action_ptr);
|
||||||
|
ForumTopicInfo old_topic_info;
|
||||||
|
ForumTopicInfo new_topic_info;
|
||||||
|
if (action->prev_topic_ != nullptr) {
|
||||||
|
old_topic_info = ForumTopicInfo(action->prev_topic_);
|
||||||
|
}
|
||||||
|
if (action->new_topic_ != nullptr) {
|
||||||
|
new_topic_info = ForumTopicInfo(action->new_topic_);
|
||||||
|
}
|
||||||
|
if (old_topic_info.is_empty() && new_topic_info.is_empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return td_api::make_object<td_api::chatEventForumTopicPinned>(old_topic_info.get_forum_topic_info_object(td),
|
||||||
|
new_topic_info.get_forum_topic_info_object(td));
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -411,7 +470,7 @@ class GetChannelAdminLogQuery final : public Td::ResultHandler {
|
|||||||
LOG(ERROR) << "Receive invalid " << user_id;
|
LOG(ERROR) << "Receive invalid " << user_id;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
LOG_IF(ERROR, !td_->contacts_manager_->have_user(user_id)) << "Have no info about " << user_id;
|
LOG_IF(ERROR, !td_->contacts_manager_->have_user(user_id)) << "Receive unknown " << user_id;
|
||||||
|
|
||||||
DialogId actor_dialog_id;
|
DialogId actor_dialog_id;
|
||||||
auto action = get_chat_event_action_object(td_, channel_id_, std::move(event->action_), actor_dialog_id);
|
auto action = get_chat_event_action_object(td_, channel_id_, std::move(event->action_), actor_dialog_id);
|
||||||
@ -485,11 +544,15 @@ static telegram_api::object_ptr<telegram_api::channelAdminLogEventsFilter> get_i
|
|||||||
if (filters->video_chat_changes_) {
|
if (filters->video_chat_changes_) {
|
||||||
flags |= telegram_api::channelAdminLogEventsFilter::GROUP_CALL_MASK;
|
flags |= telegram_api::channelAdminLogEventsFilter::GROUP_CALL_MASK;
|
||||||
}
|
}
|
||||||
|
if (filters->forum_changes_) {
|
||||||
|
flags |= telegram_api::channelAdminLogEventsFilter::FORUMS_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
return telegram_api::make_object<telegram_api::channelAdminLogEventsFilter>(
|
return telegram_api::make_object<telegram_api::channelAdminLogEventsFilter>(
|
||||||
flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
||||||
false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
||||||
false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/);
|
false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
||||||
|
false /*ignored*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_dialog_event_log(Td *td, DialogId dialog_id, const string &query, int64 from_event_id, int32 limit,
|
void get_dialog_event_log(Td *td, DialogId dialog_id, const string &query, int64 from_event_id, int32 limit,
|
||||||
|
102
td/telegram/DialogNotificationSettings.cpp
Normal file
102
td/telegram/DialogNotificationSettings.cpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#include "td/telegram/DialogNotificationSettings.h"
|
||||||
|
|
||||||
|
#include "td/telegram/Global.h"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &string_builder, const DialogNotificationSettings ¬ification_settings) {
|
||||||
|
return string_builder << "[" << notification_settings.mute_until << ", " << notification_settings.sound << ", "
|
||||||
|
<< notification_settings.show_preview << ", " << notification_settings.silent_send_message
|
||||||
|
<< ", " << notification_settings.disable_pinned_message_notifications << ", "
|
||||||
|
<< notification_settings.disable_mention_notifications << ", "
|
||||||
|
<< notification_settings.use_default_mute_until << ", "
|
||||||
|
<< notification_settings.use_default_show_preview << ", "
|
||||||
|
<< notification_settings.use_default_disable_pinned_message_notifications << ", "
|
||||||
|
<< notification_settings.use_default_disable_mention_notifications << ", "
|
||||||
|
<< notification_settings.is_synchronized << "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
td_api::object_ptr<td_api::chatNotificationSettings> get_chat_notification_settings_object(
|
||||||
|
const DialogNotificationSettings *notification_settings) {
|
||||||
|
CHECK(notification_settings != nullptr);
|
||||||
|
return td_api::make_object<td_api::chatNotificationSettings>(
|
||||||
|
notification_settings->use_default_mute_until, max(0, notification_settings->mute_until - G()->unix_time()),
|
||||||
|
is_notification_sound_default(notification_settings->sound),
|
||||||
|
get_notification_sound_ringtone_id(notification_settings->sound), notification_settings->use_default_show_preview,
|
||||||
|
notification_settings->show_preview, notification_settings->use_default_disable_pinned_message_notifications,
|
||||||
|
notification_settings->disable_pinned_message_notifications,
|
||||||
|
notification_settings->use_default_disable_mention_notifications,
|
||||||
|
notification_settings->disable_mention_notifications);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32 get_mute_until(int32 mute_for) {
|
||||||
|
if (mute_for <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int32 MAX_PRECISE_MUTE_FOR = 366 * 86400;
|
||||||
|
int32 current_time = G()->unix_time();
|
||||||
|
if (mute_for > MAX_PRECISE_MUTE_FOR || mute_for >= std::numeric_limits<int32>::max() - current_time) {
|
||||||
|
return std::numeric_limits<int32>::max();
|
||||||
|
}
|
||||||
|
return mute_for + current_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<DialogNotificationSettings> get_dialog_notification_settings(
|
||||||
|
td_api::object_ptr<td_api::chatNotificationSettings> &¬ification_settings, bool old_silent_send_message) {
|
||||||
|
if (notification_settings == nullptr) {
|
||||||
|
return Status::Error(400, "New notification settings must be non-empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 mute_until =
|
||||||
|
notification_settings->use_default_mute_for_ ? 0 : get_mute_until(notification_settings->mute_for_);
|
||||||
|
return DialogNotificationSettings(
|
||||||
|
notification_settings->use_default_mute_for_, mute_until,
|
||||||
|
get_notification_sound(notification_settings->use_default_sound_, notification_settings->sound_id_),
|
||||||
|
notification_settings->use_default_show_preview_, notification_settings->show_preview_, old_silent_send_message,
|
||||||
|
notification_settings->use_default_disable_pinned_message_notifications_,
|
||||||
|
notification_settings->disable_pinned_message_notifications_,
|
||||||
|
notification_settings->use_default_disable_mention_notifications_,
|
||||||
|
notification_settings->disable_mention_notifications_);
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogNotificationSettings get_dialog_notification_settings(tl_object_ptr<telegram_api::peerNotifySettings> &&settings,
|
||||||
|
bool old_use_default_disable_pinned_message_notifications,
|
||||||
|
bool old_disable_pinned_message_notifications,
|
||||||
|
bool old_use_default_disable_mention_notifications,
|
||||||
|
bool old_disable_mention_notifications) {
|
||||||
|
if (settings == nullptr) {
|
||||||
|
return DialogNotificationSettings();
|
||||||
|
}
|
||||||
|
bool use_default_mute_until = (settings->flags_ & telegram_api::peerNotifySettings::MUTE_UNTIL_MASK) == 0;
|
||||||
|
bool use_default_show_preview = (settings->flags_ & telegram_api::peerNotifySettings::SHOW_PREVIEWS_MASK) == 0;
|
||||||
|
auto mute_until = use_default_mute_until || settings->mute_until_ <= G()->unix_time() ? 0 : settings->mute_until_;
|
||||||
|
bool silent_send_message =
|
||||||
|
(settings->flags_ & telegram_api::peerNotifySettings::SILENT_MASK) == 0 ? false : settings->silent_;
|
||||||
|
return {use_default_mute_until,
|
||||||
|
mute_until,
|
||||||
|
get_notification_sound(settings.get()),
|
||||||
|
use_default_show_preview,
|
||||||
|
settings->show_previews_,
|
||||||
|
silent_send_message,
|
||||||
|
old_use_default_disable_pinned_message_notifications,
|
||||||
|
old_disable_pinned_message_notifications,
|
||||||
|
old_use_default_disable_mention_notifications,
|
||||||
|
old_disable_mention_notifications};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool are_default_dialog_notification_settings(const DialogNotificationSettings &settings, bool compare_sound) {
|
||||||
|
return settings.use_default_mute_until && (!compare_sound || is_notification_sound_default(settings.sound)) &&
|
||||||
|
settings.use_default_show_preview && settings.use_default_disable_pinned_message_notifications &&
|
||||||
|
settings.use_default_disable_mention_notifications;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
@ -55,68 +55,20 @@ class DialogNotificationSettings {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class NotificationSettingsScope : int32 { Private, Group, Channel };
|
|
||||||
|
|
||||||
class ScopeNotificationSettings {
|
|
||||||
public:
|
|
||||||
int32 mute_until = 0;
|
|
||||||
unique_ptr<NotificationSound> sound;
|
|
||||||
bool show_preview = true;
|
|
||||||
bool is_synchronized = false;
|
|
||||||
|
|
||||||
// local settings
|
|
||||||
bool disable_pinned_message_notifications = false;
|
|
||||||
bool disable_mention_notifications = false;
|
|
||||||
|
|
||||||
ScopeNotificationSettings() = default;
|
|
||||||
|
|
||||||
ScopeNotificationSettings(int32 mute_until, unique_ptr<NotificationSound> &&sound, bool show_preview,
|
|
||||||
bool disable_pinned_message_notifications, bool disable_mention_notifications)
|
|
||||||
: mute_until(mute_until)
|
|
||||||
, sound(std::move(sound))
|
|
||||||
, show_preview(show_preview)
|
|
||||||
, is_synchronized(true)
|
|
||||||
, disable_pinned_message_notifications(disable_pinned_message_notifications)
|
|
||||||
, disable_mention_notifications(disable_mention_notifications) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
StringBuilder &operator<<(StringBuilder &string_builder, const DialogNotificationSettings ¬ification_settings);
|
StringBuilder &operator<<(StringBuilder &string_builder, const DialogNotificationSettings ¬ification_settings);
|
||||||
|
|
||||||
StringBuilder &operator<<(StringBuilder &string_builder, NotificationSettingsScope scope);
|
|
||||||
|
|
||||||
StringBuilder &operator<<(StringBuilder &string_builder, const ScopeNotificationSettings ¬ification_settings);
|
|
||||||
|
|
||||||
td_api::object_ptr<td_api::NotificationSettingsScope> get_notification_settings_scope_object(
|
|
||||||
NotificationSettingsScope scope);
|
|
||||||
|
|
||||||
td_api::object_ptr<td_api::chatNotificationSettings> get_chat_notification_settings_object(
|
td_api::object_ptr<td_api::chatNotificationSettings> get_chat_notification_settings_object(
|
||||||
const DialogNotificationSettings *notification_settings);
|
const DialogNotificationSettings *notification_settings);
|
||||||
|
|
||||||
td_api::object_ptr<td_api::scopeNotificationSettings> get_scope_notification_settings_object(
|
|
||||||
const ScopeNotificationSettings *notification_settings);
|
|
||||||
|
|
||||||
telegram_api::object_ptr<telegram_api::InputNotifyPeer> get_input_notify_peer(NotificationSettingsScope scope);
|
|
||||||
|
|
||||||
NotificationSettingsScope get_notification_settings_scope(
|
|
||||||
const td_api::object_ptr<td_api::NotificationSettingsScope> &scope);
|
|
||||||
|
|
||||||
Result<DialogNotificationSettings> get_dialog_notification_settings(
|
Result<DialogNotificationSettings> get_dialog_notification_settings(
|
||||||
td_api::object_ptr<td_api::chatNotificationSettings> &¬ification_settings, bool old_silent_send_message);
|
td_api::object_ptr<td_api::chatNotificationSettings> &¬ification_settings, bool old_silent_send_message);
|
||||||
|
|
||||||
Result<ScopeNotificationSettings> get_scope_notification_settings(
|
|
||||||
td_api::object_ptr<td_api::scopeNotificationSettings> &¬ification_settings);
|
|
||||||
|
|
||||||
DialogNotificationSettings get_dialog_notification_settings(tl_object_ptr<telegram_api::peerNotifySettings> &&settings,
|
DialogNotificationSettings get_dialog_notification_settings(tl_object_ptr<telegram_api::peerNotifySettings> &&settings,
|
||||||
bool old_use_default_disable_pinned_message_notifications,
|
bool old_use_default_disable_pinned_message_notifications,
|
||||||
bool old_disable_pinned_message_notifications,
|
bool old_disable_pinned_message_notifications,
|
||||||
bool old_use_default_disable_mention_notifications,
|
bool old_use_default_disable_mention_notifications,
|
||||||
bool old_disable_mention_notifications);
|
bool old_disable_mention_notifications);
|
||||||
|
|
||||||
ScopeNotificationSettings get_scope_notification_settings(tl_object_ptr<telegram_api::peerNotifySettings> &&settings,
|
|
||||||
bool old_disable_pinned_message_notifications,
|
|
||||||
bool old_disable_mention_notifications);
|
|
||||||
|
|
||||||
bool are_default_dialog_notification_settings(const DialogNotificationSettings &settings, bool compare_sound);
|
bool are_default_dialog_notification_settings(const DialogNotificationSettings &settings, bool compare_sound);
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
@ -6,8 +6,8 @@
|
|||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/DialogNotificationSettings.h"
|
||||||
#include "td/telegram/Global.h"
|
#include "td/telegram/Global.h"
|
||||||
#include "td/telegram/NotificationSettings.h"
|
|
||||||
#include "td/telegram/NotificationSound.h"
|
#include "td/telegram/NotificationSound.h"
|
||||||
|
|
||||||
#include "td/utils/tl_helpers.h"
|
#include "td/utils/tl_helpers.h"
|
||||||
@ -86,58 +86,4 @@ void parse(DialogNotificationSettings ¬ification_settings, ParserT &parser) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class StorerT>
|
|
||||||
void store(const ScopeNotificationSettings ¬ification_settings, StorerT &storer) {
|
|
||||||
bool is_muted = notification_settings.mute_until != 0 && notification_settings.mute_until > G()->unix_time();
|
|
||||||
bool has_sound = notification_settings.sound != nullptr;
|
|
||||||
bool has_ringtone_support = true;
|
|
||||||
BEGIN_STORE_FLAGS();
|
|
||||||
STORE_FLAG(is_muted);
|
|
||||||
STORE_FLAG(has_sound);
|
|
||||||
STORE_FLAG(notification_settings.show_preview);
|
|
||||||
STORE_FLAG(false);
|
|
||||||
STORE_FLAG(notification_settings.is_synchronized);
|
|
||||||
STORE_FLAG(notification_settings.disable_pinned_message_notifications);
|
|
||||||
STORE_FLAG(notification_settings.disable_mention_notifications);
|
|
||||||
STORE_FLAG(has_ringtone_support);
|
|
||||||
END_STORE_FLAGS();
|
|
||||||
if (is_muted) {
|
|
||||||
store(notification_settings.mute_until, storer);
|
|
||||||
}
|
|
||||||
if (has_sound) {
|
|
||||||
store(notification_settings.sound, storer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ParserT>
|
|
||||||
void parse(ScopeNotificationSettings ¬ification_settings, ParserT &parser) {
|
|
||||||
bool is_muted;
|
|
||||||
bool has_sound;
|
|
||||||
bool silent_send_message_ignored;
|
|
||||||
bool has_ringtone_support;
|
|
||||||
BEGIN_PARSE_FLAGS();
|
|
||||||
PARSE_FLAG(is_muted);
|
|
||||||
PARSE_FLAG(has_sound);
|
|
||||||
PARSE_FLAG(notification_settings.show_preview);
|
|
||||||
PARSE_FLAG(silent_send_message_ignored);
|
|
||||||
PARSE_FLAG(notification_settings.is_synchronized);
|
|
||||||
PARSE_FLAG(notification_settings.disable_pinned_message_notifications);
|
|
||||||
PARSE_FLAG(notification_settings.disable_mention_notifications);
|
|
||||||
PARSE_FLAG(has_ringtone_support);
|
|
||||||
END_PARSE_FLAGS();
|
|
||||||
(void)silent_send_message_ignored;
|
|
||||||
if (is_muted) {
|
|
||||||
parse(notification_settings.mute_until, parser);
|
|
||||||
}
|
|
||||||
if (has_sound) {
|
|
||||||
if (has_ringtone_support) {
|
|
||||||
parse_notification_sound(notification_settings.sound, parser);
|
|
||||||
} else {
|
|
||||||
string sound;
|
|
||||||
parse(sound, parser);
|
|
||||||
notification_settings.sound = get_legacy_notification_sound(sound);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
@ -28,10 +28,10 @@ AdministratorRights::AdministratorRights(const tl_object_ptr<telegram_api::chatA
|
|||||||
if (!rights->other_) {
|
if (!rights->other_) {
|
||||||
LOG(ERROR) << "Receive wrong other flag in " << to_string(rights);
|
LOG(ERROR) << "Receive wrong other flag in " << to_string(rights);
|
||||||
}
|
}
|
||||||
*this =
|
*this = AdministratorRights(rights->anonymous_, rights->other_, rights->change_info_, rights->post_messages_,
|
||||||
AdministratorRights(rights->anonymous_, rights->other_, rights->change_info_, rights->post_messages_,
|
rights->edit_messages_, rights->delete_messages_, rights->invite_users_,
|
||||||
rights->edit_messages_, rights->delete_messages_, rights->invite_users_, rights->ban_users_,
|
rights->ban_users_, rights->pin_messages_, rights->manage_topics_, rights->add_admins_,
|
||||||
rights->pin_messages_, rights->add_admins_, rights->manage_call_, channel_type);
|
rights->manage_call_, channel_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
AdministratorRights::AdministratorRights(const td_api::object_ptr<td_api::chatAdministratorRights> &rights,
|
AdministratorRights::AdministratorRights(const td_api::object_ptr<td_api::chatAdministratorRights> &rights,
|
||||||
@ -43,16 +43,19 @@ AdministratorRights::AdministratorRights(const td_api::object_ptr<td_api::chatAd
|
|||||||
*this = AdministratorRights(rights->is_anonymous_, rights->can_manage_chat_, rights->can_change_info_,
|
*this = AdministratorRights(rights->is_anonymous_, rights->can_manage_chat_, rights->can_change_info_,
|
||||||
rights->can_post_messages_, rights->can_edit_messages_, rights->can_delete_messages_,
|
rights->can_post_messages_, rights->can_edit_messages_, rights->can_delete_messages_,
|
||||||
rights->can_invite_users_, rights->can_restrict_members_, rights->can_pin_messages_,
|
rights->can_invite_users_, rights->can_restrict_members_, rights->can_pin_messages_,
|
||||||
rights->can_promote_members_, rights->can_manage_video_chats_, channel_type);
|
rights->can_manage_topics_, rights->can_promote_members_, rights->can_manage_video_chats_,
|
||||||
|
channel_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
AdministratorRights::AdministratorRights(bool is_anonymous, bool can_manage_dialog, bool can_change_info,
|
AdministratorRights::AdministratorRights(bool is_anonymous, bool can_manage_dialog, bool can_change_info,
|
||||||
bool can_post_messages, bool can_edit_messages, bool can_delete_messages,
|
bool can_post_messages, bool can_edit_messages, bool can_delete_messages,
|
||||||
bool can_invite_users, bool can_restrict_members, bool can_pin_messages,
|
bool can_invite_users, bool can_restrict_members, bool can_pin_messages,
|
||||||
bool can_promote_members, bool can_manage_calls, ChannelType channel_type) {
|
bool can_manage_topics, bool can_promote_members, bool can_manage_calls,
|
||||||
|
ChannelType channel_type) {
|
||||||
switch (channel_type) {
|
switch (channel_type) {
|
||||||
case ChannelType::Broadcast:
|
case ChannelType::Broadcast:
|
||||||
can_pin_messages = false;
|
can_pin_messages = false;
|
||||||
|
can_manage_topics = false;
|
||||||
is_anonymous = false;
|
is_anonymous = false;
|
||||||
break;
|
break;
|
||||||
case ChannelType::Megagroup:
|
case ChannelType::Megagroup:
|
||||||
@ -70,6 +73,7 @@ AdministratorRights::AdministratorRights(bool is_anonymous, bool can_manage_dial
|
|||||||
(static_cast<uint32>(can_invite_users) * CAN_INVITE_USERS) |
|
(static_cast<uint32>(can_invite_users) * CAN_INVITE_USERS) |
|
||||||
(static_cast<uint32>(can_restrict_members) * CAN_RESTRICT_MEMBERS) |
|
(static_cast<uint32>(can_restrict_members) * CAN_RESTRICT_MEMBERS) |
|
||||||
(static_cast<uint32>(can_pin_messages) * CAN_PIN_MESSAGES) |
|
(static_cast<uint32>(can_pin_messages) * CAN_PIN_MESSAGES) |
|
||||||
|
(static_cast<uint32>(can_manage_topics) * CAN_MANAGE_TOPICS) |
|
||||||
(static_cast<uint32>(can_promote_members) * CAN_PROMOTE_MEMBERS) |
|
(static_cast<uint32>(can_promote_members) * CAN_PROMOTE_MEMBERS) |
|
||||||
(static_cast<uint32>(can_manage_calls) * CAN_MANAGE_CALLS) |
|
(static_cast<uint32>(can_manage_calls) * CAN_MANAGE_CALLS) |
|
||||||
(static_cast<uint32>(is_anonymous) * IS_ANONYMOUS);
|
(static_cast<uint32>(is_anonymous) * IS_ANONYMOUS);
|
||||||
@ -83,7 +87,7 @@ AdministratorRights::AdministratorRights(bool is_anonymous, bool can_manage_dial
|
|||||||
|
|
||||||
telegram_api::object_ptr<telegram_api::chatAdminRights> AdministratorRights::get_chat_admin_rights() const {
|
telegram_api::object_ptr<telegram_api::chatAdminRights> AdministratorRights::get_chat_admin_rights() const {
|
||||||
int32 flags = 0;
|
int32 flags = 0;
|
||||||
if ((flags_ & CAN_CHANGE_INFO_AND_SETTINGS) != 0) {
|
if (can_change_info_and_settings()) {
|
||||||
flags |= telegram_api::chatAdminRights::CHANGE_INFO_MASK;
|
flags |= telegram_api::chatAdminRights::CHANGE_INFO_MASK;
|
||||||
}
|
}
|
||||||
if (can_post_messages()) {
|
if (can_post_messages()) {
|
||||||
@ -95,15 +99,18 @@ telegram_api::object_ptr<telegram_api::chatAdminRights> AdministratorRights::get
|
|||||||
if (can_delete_messages()) {
|
if (can_delete_messages()) {
|
||||||
flags |= telegram_api::chatAdminRights::DELETE_MESSAGES_MASK;
|
flags |= telegram_api::chatAdminRights::DELETE_MESSAGES_MASK;
|
||||||
}
|
}
|
||||||
if ((flags_ & CAN_INVITE_USERS) != 0) {
|
if (can_invite_users()) {
|
||||||
flags |= telegram_api::chatAdminRights::INVITE_USERS_MASK;
|
flags |= telegram_api::chatAdminRights::INVITE_USERS_MASK;
|
||||||
}
|
}
|
||||||
if (can_restrict_members()) {
|
if (can_restrict_members()) {
|
||||||
flags |= telegram_api::chatAdminRights::BAN_USERS_MASK;
|
flags |= telegram_api::chatAdminRights::BAN_USERS_MASK;
|
||||||
}
|
}
|
||||||
if ((flags_ & CAN_PIN_MESSAGES) != 0) {
|
if (can_pin_messages()) {
|
||||||
flags |= telegram_api::chatAdminRights::PIN_MESSAGES_MASK;
|
flags |= telegram_api::chatAdminRights::PIN_MESSAGES_MASK;
|
||||||
}
|
}
|
||||||
|
if (can_manage_topics()) {
|
||||||
|
flags |= telegram_api::chatAdminRights::MANAGE_TOPICS_MASK;
|
||||||
|
}
|
||||||
if (can_promote_members()) {
|
if (can_promote_members()) {
|
||||||
flags |= telegram_api::chatAdminRights::ADD_ADMINS_MASK;
|
flags |= telegram_api::chatAdminRights::ADD_ADMINS_MASK;
|
||||||
}
|
}
|
||||||
@ -119,14 +126,15 @@ telegram_api::object_ptr<telegram_api::chatAdminRights> AdministratorRights::get
|
|||||||
|
|
||||||
return telegram_api::make_object<telegram_api::chatAdminRights>(
|
return telegram_api::make_object<telegram_api::chatAdminRights>(
|
||||||
flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
||||||
false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/);
|
false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
||||||
|
false /*ignored*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
td_api::object_ptr<td_api::chatAdministratorRights> AdministratorRights::get_chat_administrator_rights_object() const {
|
td_api::object_ptr<td_api::chatAdministratorRights> AdministratorRights::get_chat_administrator_rights_object() const {
|
||||||
return td_api::make_object<td_api::chatAdministratorRights>(
|
return td_api::make_object<td_api::chatAdministratorRights>(
|
||||||
can_manage_dialog(), can_change_info_and_settings(), can_post_messages(), can_edit_messages(),
|
can_manage_dialog(), can_change_info_and_settings(), can_post_messages(), can_edit_messages(),
|
||||||
can_delete_messages(), can_invite_users(), can_restrict_members(), can_pin_messages(), can_promote_members(),
|
can_delete_messages(), can_invite_users(), can_restrict_members(), can_pin_messages(), can_manage_topics(),
|
||||||
can_manage_calls(), is_anonymous());
|
can_promote_members(), can_manage_calls(), is_anonymous());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const AdministratorRights &lhs, const AdministratorRights &rhs) {
|
bool operator==(const AdministratorRights &lhs, const AdministratorRights &rhs) {
|
||||||
@ -163,6 +171,9 @@ StringBuilder &operator<<(StringBuilder &string_builder, const AdministratorRigh
|
|||||||
if (status.can_pin_messages()) {
|
if (status.can_pin_messages()) {
|
||||||
string_builder << "(pin)";
|
string_builder << "(pin)";
|
||||||
}
|
}
|
||||||
|
if (status.can_manage_topics()) {
|
||||||
|
string_builder << "(manage_topics)";
|
||||||
|
}
|
||||||
if (status.can_promote_members()) {
|
if (status.can_promote_members()) {
|
||||||
string_builder << "(promote)";
|
string_builder << "(promote)";
|
||||||
}
|
}
|
||||||
@ -186,9 +197,10 @@ RestrictedRights::RestrictedRights(const tl_object_ptr<telegram_api::chatBannedR
|
|||||||
LOG_IF(ERROR, rights->until_date_ != std::numeric_limits<int32>::max())
|
LOG_IF(ERROR, rights->until_date_ != std::numeric_limits<int32>::max())
|
||||||
<< "Have until date " << rights->until_date_ << " in restricted rights";
|
<< "Have until date " << rights->until_date_ << " in restricted rights";
|
||||||
|
|
||||||
*this = RestrictedRights(!rights->send_messages_, !rights->send_media_, !rights->send_stickers_, !rights->send_gifs_,
|
*this =
|
||||||
!rights->send_games_, !rights->send_inline_, !rights->embed_links_, !rights->send_polls_,
|
RestrictedRights(!rights->send_messages_, !rights->send_media_, !rights->send_stickers_, !rights->send_gifs_,
|
||||||
!rights->change_info_, !rights->invite_users_, !rights->pin_messages_);
|
!rights->send_games_, !rights->send_inline_, !rights->embed_links_, !rights->send_polls_,
|
||||||
|
!rights->change_info_, !rights->invite_users_, !rights->pin_messages_, !rights->manage_topics_);
|
||||||
}
|
}
|
||||||
|
|
||||||
RestrictedRights::RestrictedRights(const td_api::object_ptr<td_api::chatPermissions> &rights) {
|
RestrictedRights::RestrictedRights(const td_api::object_ptr<td_api::chatPermissions> &rights) {
|
||||||
@ -204,13 +216,15 @@ RestrictedRights::RestrictedRights(const td_api::object_ptr<td_api::chatPermissi
|
|||||||
*this = RestrictedRights(can_send_messages, can_send_media, rights->can_send_other_messages_,
|
*this = RestrictedRights(can_send_messages, can_send_media, rights->can_send_other_messages_,
|
||||||
rights->can_send_other_messages_, rights->can_send_other_messages_,
|
rights->can_send_other_messages_, rights->can_send_other_messages_,
|
||||||
rights->can_send_other_messages_, rights->can_add_web_page_previews_, can_send_polls,
|
rights->can_send_other_messages_, rights->can_add_web_page_previews_, can_send_polls,
|
||||||
rights->can_change_info_, rights->can_invite_users_, rights->can_pin_messages_);
|
rights->can_change_info_, rights->can_invite_users_, rights->can_pin_messages_,
|
||||||
|
rights->can_manage_topics_);
|
||||||
}
|
}
|
||||||
|
|
||||||
RestrictedRights::RestrictedRights(bool can_send_messages, bool can_send_media, bool can_send_stickers,
|
RestrictedRights::RestrictedRights(bool can_send_messages, bool can_send_media, bool can_send_stickers,
|
||||||
bool can_send_animations, bool can_send_games, bool can_use_inline_bots,
|
bool can_send_animations, bool can_send_games, bool can_use_inline_bots,
|
||||||
bool can_add_web_page_previews, bool can_send_polls,
|
bool can_add_web_page_previews, bool can_send_polls,
|
||||||
bool can_change_info_and_settings, bool can_invite_users, bool can_pin_messages) {
|
bool can_change_info_and_settings, bool can_invite_users, bool can_pin_messages,
|
||||||
|
bool can_manage_topics) {
|
||||||
flags_ = (static_cast<uint32>(can_send_messages) * CAN_SEND_MESSAGES) |
|
flags_ = (static_cast<uint32>(can_send_messages) * CAN_SEND_MESSAGES) |
|
||||||
(static_cast<uint32>(can_send_media) * CAN_SEND_MEDIA) |
|
(static_cast<uint32>(can_send_media) * CAN_SEND_MEDIA) |
|
||||||
(static_cast<uint32>(can_send_stickers) * CAN_SEND_STICKERS) |
|
(static_cast<uint32>(can_send_stickers) * CAN_SEND_STICKERS) |
|
||||||
@ -221,14 +235,16 @@ RestrictedRights::RestrictedRights(bool can_send_messages, bool can_send_media,
|
|||||||
(static_cast<uint32>(can_send_polls) * CAN_SEND_POLLS) |
|
(static_cast<uint32>(can_send_polls) * CAN_SEND_POLLS) |
|
||||||
(static_cast<uint32>(can_change_info_and_settings) * CAN_CHANGE_INFO_AND_SETTINGS) |
|
(static_cast<uint32>(can_change_info_and_settings) * CAN_CHANGE_INFO_AND_SETTINGS) |
|
||||||
(static_cast<uint32>(can_invite_users) * CAN_INVITE_USERS) |
|
(static_cast<uint32>(can_invite_users) * CAN_INVITE_USERS) |
|
||||||
(static_cast<uint32>(can_pin_messages) * CAN_PIN_MESSAGES);
|
(static_cast<uint32>(can_pin_messages) * CAN_PIN_MESSAGES) |
|
||||||
|
(static_cast<uint32>(can_manage_topics) * CAN_MANAGE_TOPICS);
|
||||||
}
|
}
|
||||||
|
|
||||||
td_api::object_ptr<td_api::chatPermissions> RestrictedRights::get_chat_permissions_object() const {
|
td_api::object_ptr<td_api::chatPermissions> RestrictedRights::get_chat_permissions_object() const {
|
||||||
return td_api::make_object<td_api::chatPermissions>(
|
return td_api::make_object<td_api::chatPermissions>(
|
||||||
can_send_messages(), can_send_media(), can_send_polls(),
|
can_send_messages(), can_send_media(), can_send_polls(),
|
||||||
can_send_stickers() || can_send_animations() || can_send_games() || can_use_inline_bots(),
|
can_send_stickers() || can_send_animations() || can_send_games() || can_use_inline_bots(),
|
||||||
can_add_web_page_previews(), can_change_info_and_settings(), can_invite_users(), can_pin_messages());
|
can_add_web_page_previews(), can_change_info_and_settings(), can_invite_users(), can_pin_messages(),
|
||||||
|
can_manage_topics());
|
||||||
}
|
}
|
||||||
|
|
||||||
tl_object_ptr<telegram_api::chatBannedRights> RestrictedRights::get_chat_banned_rights() const {
|
tl_object_ptr<telegram_api::chatBannedRights> RestrictedRights::get_chat_banned_rights() const {
|
||||||
@ -266,12 +282,15 @@ tl_object_ptr<telegram_api::chatBannedRights> RestrictedRights::get_chat_banned_
|
|||||||
if (!can_pin_messages()) {
|
if (!can_pin_messages()) {
|
||||||
flags |= telegram_api::chatBannedRights::PIN_MESSAGES_MASK;
|
flags |= telegram_api::chatBannedRights::PIN_MESSAGES_MASK;
|
||||||
}
|
}
|
||||||
|
if (!can_manage_topics()) {
|
||||||
|
flags |= telegram_api::chatBannedRights::MANAGE_TOPICS_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Create chat banned rights " << flags;
|
LOG(INFO) << "Create chat banned rights " << flags;
|
||||||
return make_tl_object<telegram_api::chatBannedRights>(flags, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
return make_tl_object<telegram_api::chatBannedRights>(
|
||||||
false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
||||||
false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
||||||
false /*ignored*/, false /*ignored*/, false /*ignored*/, 0);
|
false /*ignored*/, false /*ignored*/, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const RestrictedRights &lhs, const RestrictedRights &rhs) {
|
bool operator==(const RestrictedRights &lhs, const RestrictedRights &rhs) {
|
||||||
@ -317,6 +336,9 @@ StringBuilder &operator<<(StringBuilder &string_builder, const RestrictedRights
|
|||||||
if (!status.can_pin_messages()) {
|
if (!status.can_pin_messages()) {
|
||||||
string_builder << "(pin)";
|
string_builder << "(pin)";
|
||||||
}
|
}
|
||||||
|
if (!status.can_manage_topics()) {
|
||||||
|
string_builder << "(topics)";
|
||||||
|
}
|
||||||
return string_builder;
|
return string_builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,16 +397,16 @@ DialogParticipantStatus DialogParticipantStatus::Banned(int32 banned_until_date)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DialogParticipantStatus DialogParticipantStatus::GroupAdministrator(bool is_creator) {
|
DialogParticipantStatus DialogParticipantStatus::GroupAdministrator(bool is_creator) {
|
||||||
return Administrator(
|
return Administrator(AdministratorRights(false, true, true, false, false, true, true, true, true, false, false, true,
|
||||||
AdministratorRights(false, true, true, false, false, true, true, true, true, false, true, ChannelType::Unknown),
|
ChannelType::Unknown),
|
||||||
string(), is_creator);
|
string(), is_creator);
|
||||||
}
|
}
|
||||||
|
|
||||||
DialogParticipantStatus DialogParticipantStatus::ChannelAdministrator(bool is_creator, bool is_megagroup) {
|
DialogParticipantStatus DialogParticipantStatus::ChannelAdministrator(bool is_creator, bool is_megagroup) {
|
||||||
auto rights = is_megagroup ? AdministratorRights(false, true, true, false, false, true, true, true, true, false,
|
auto rights = is_megagroup ? AdministratorRights(false, true, true, false, false, true, true, true, true, true, false,
|
||||||
false, ChannelType::Megagroup)
|
false, ChannelType::Megagroup)
|
||||||
: AdministratorRights(false, true, false, true, true, true, false, true, false, false,
|
: AdministratorRights(false, true, false, true, true, true, false, true, false, false,
|
||||||
false, ChannelType::Broadcast);
|
false, false, ChannelType::Broadcast);
|
||||||
return Administrator(rights, string(), is_creator);
|
return Administrator(rights, string(), is_creator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,7 +439,7 @@ DialogParticipantStatus::DialogParticipantStatus(bool is_member,
|
|||||||
RestrictedRights DialogParticipantStatus::get_effective_restricted_rights() const {
|
RestrictedRights DialogParticipantStatus::get_effective_restricted_rights() const {
|
||||||
return RestrictedRights(can_send_messages(), can_send_media(), can_send_stickers(), can_send_animations(),
|
return RestrictedRights(can_send_messages(), can_send_media(), can_send_stickers(), can_send_animations(),
|
||||||
can_send_games(), can_use_inline_bots(), can_add_web_page_previews(), can_send_polls(),
|
can_send_games(), can_use_inline_bots(), can_add_web_page_previews(), can_send_polls(),
|
||||||
can_change_info_and_settings(), can_invite_users(), can_pin_messages());
|
can_change_info_and_settings(), can_invite_users(), can_pin_messages(), can_create_topics());
|
||||||
}
|
}
|
||||||
|
|
||||||
tl_object_ptr<td_api::ChatMemberStatus> DialogParticipantStatus::get_chat_member_status_object() const {
|
tl_object_ptr<td_api::ChatMemberStatus> DialogParticipantStatus::get_chat_member_status_object() const {
|
||||||
|
@ -33,11 +33,13 @@ class AdministratorRights {
|
|||||||
static constexpr uint32 CAN_PROMOTE_MEMBERS = 1 << 8;
|
static constexpr uint32 CAN_PROMOTE_MEMBERS = 1 << 8;
|
||||||
static constexpr uint32 CAN_MANAGE_CALLS = 1 << 9;
|
static constexpr uint32 CAN_MANAGE_CALLS = 1 << 9;
|
||||||
static constexpr uint32 CAN_MANAGE_DIALOG = 1 << 10;
|
static constexpr uint32 CAN_MANAGE_DIALOG = 1 << 10;
|
||||||
|
static constexpr uint32 CAN_MANAGE_TOPICS = 1 << 11;
|
||||||
static constexpr uint32 IS_ANONYMOUS = 1 << 13;
|
static constexpr uint32 IS_ANONYMOUS = 1 << 13;
|
||||||
|
|
||||||
static constexpr uint32 ALL_ADMINISTRATOR_RIGHTS =
|
static constexpr uint32 ALL_ADMINISTRATOR_RIGHTS = CAN_CHANGE_INFO_AND_SETTINGS | CAN_POST_MESSAGES |
|
||||||
CAN_CHANGE_INFO_AND_SETTINGS | CAN_POST_MESSAGES | CAN_EDIT_MESSAGES | CAN_DELETE_MESSAGES | CAN_INVITE_USERS |
|
CAN_EDIT_MESSAGES | CAN_DELETE_MESSAGES | CAN_INVITE_USERS |
|
||||||
CAN_RESTRICT_MEMBERS | CAN_PIN_MESSAGES | CAN_PROMOTE_MEMBERS | CAN_MANAGE_CALLS | CAN_MANAGE_DIALOG;
|
CAN_RESTRICT_MEMBERS | CAN_PIN_MESSAGES | CAN_MANAGE_TOPICS |
|
||||||
|
CAN_PROMOTE_MEMBERS | CAN_MANAGE_CALLS | CAN_MANAGE_DIALOG;
|
||||||
|
|
||||||
uint32 flags_;
|
uint32 flags_;
|
||||||
|
|
||||||
@ -57,8 +59,8 @@ class AdministratorRights {
|
|||||||
|
|
||||||
AdministratorRights(bool is_anonymous, bool can_manage_dialog, bool can_change_info, bool can_post_messages,
|
AdministratorRights(bool is_anonymous, bool can_manage_dialog, bool can_change_info, bool can_post_messages,
|
||||||
bool can_edit_messages, bool can_delete_messages, bool can_invite_users,
|
bool can_edit_messages, bool can_delete_messages, bool can_invite_users,
|
||||||
bool can_restrict_members, bool can_pin_messages, bool can_promote_members, bool can_manage_calls,
|
bool can_restrict_members, bool can_pin_messages, bool can_manage_topics,
|
||||||
ChannelType channel_type);
|
bool can_promote_members, bool can_manage_calls, ChannelType channel_type);
|
||||||
|
|
||||||
telegram_api::object_ptr<telegram_api::chatAdminRights> get_chat_admin_rights() const;
|
telegram_api::object_ptr<telegram_api::chatAdminRights> get_chat_admin_rights() const;
|
||||||
|
|
||||||
@ -88,11 +90,6 @@ class AdministratorRights {
|
|||||||
return (flags_ & CAN_INVITE_USERS) != 0;
|
return (flags_ & CAN_INVITE_USERS) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool can_manage_invite_links() const {
|
|
||||||
// invite links can be managed, only if administrator was explicitly granted the right
|
|
||||||
return (flags_ & CAN_INVITE_USERS) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool can_restrict_members() const {
|
bool can_restrict_members() const {
|
||||||
return (flags_ & CAN_RESTRICT_MEMBERS) != 0;
|
return (flags_ & CAN_RESTRICT_MEMBERS) != 0;
|
||||||
}
|
}
|
||||||
@ -101,6 +98,10 @@ class AdministratorRights {
|
|||||||
return (flags_ & CAN_PIN_MESSAGES) != 0;
|
return (flags_ & CAN_PIN_MESSAGES) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool can_manage_topics() const {
|
||||||
|
return (flags_ & CAN_MANAGE_TOPICS) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool can_promote_members() const {
|
bool can_promote_members() const {
|
||||||
return (flags_ & CAN_PROMOTE_MEMBERS) != 0;
|
return (flags_ & CAN_PROMOTE_MEMBERS) != 0;
|
||||||
}
|
}
|
||||||
@ -146,9 +147,10 @@ class RestrictedRights {
|
|||||||
static constexpr uint32 CAN_CHANGE_INFO_AND_SETTINGS = 1 << 24;
|
static constexpr uint32 CAN_CHANGE_INFO_AND_SETTINGS = 1 << 24;
|
||||||
static constexpr uint32 CAN_INVITE_USERS = 1 << 25;
|
static constexpr uint32 CAN_INVITE_USERS = 1 << 25;
|
||||||
static constexpr uint32 CAN_PIN_MESSAGES = 1 << 26;
|
static constexpr uint32 CAN_PIN_MESSAGES = 1 << 26;
|
||||||
|
static constexpr uint32 CAN_MANAGE_TOPICS = 1 << 12;
|
||||||
|
|
||||||
static constexpr uint32 ALL_ADMIN_PERMISSION_RIGHTS =
|
static constexpr uint32 ALL_ADMIN_PERMISSION_RIGHTS =
|
||||||
CAN_CHANGE_INFO_AND_SETTINGS | CAN_INVITE_USERS | CAN_PIN_MESSAGES;
|
CAN_CHANGE_INFO_AND_SETTINGS | CAN_INVITE_USERS | CAN_PIN_MESSAGES | CAN_MANAGE_TOPICS;
|
||||||
|
|
||||||
static constexpr uint32 ALL_RESTRICTED_RIGHTS =
|
static constexpr uint32 ALL_RESTRICTED_RIGHTS =
|
||||||
CAN_SEND_MESSAGES | CAN_SEND_MEDIA | CAN_SEND_STICKERS | CAN_SEND_ANIMATIONS | CAN_SEND_GAMES |
|
CAN_SEND_MESSAGES | CAN_SEND_MEDIA | CAN_SEND_STICKERS | CAN_SEND_ANIMATIONS | CAN_SEND_GAMES |
|
||||||
@ -168,7 +170,8 @@ class RestrictedRights {
|
|||||||
|
|
||||||
RestrictedRights(bool can_send_messages, bool can_send_media, bool can_send_stickers, bool can_send_animations,
|
RestrictedRights(bool can_send_messages, bool can_send_media, bool can_send_stickers, bool can_send_animations,
|
||||||
bool can_send_games, bool can_use_inline_bots, bool can_add_web_page_previews, bool can_send_polls,
|
bool can_send_games, bool can_use_inline_bots, bool can_add_web_page_previews, bool can_send_polls,
|
||||||
bool can_change_info_and_settings, bool can_invite_users, bool can_pin_messages);
|
bool can_change_info_and_settings, bool can_invite_users, bool can_pin_messages,
|
||||||
|
bool can_manage_topics);
|
||||||
|
|
||||||
td_api::object_ptr<td_api::chatPermissions> get_chat_permissions_object() const;
|
td_api::object_ptr<td_api::chatPermissions> get_chat_permissions_object() const;
|
||||||
|
|
||||||
@ -186,6 +189,10 @@ class RestrictedRights {
|
|||||||
return (flags_ & CAN_PIN_MESSAGES) != 0;
|
return (flags_ & CAN_PIN_MESSAGES) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool can_manage_topics() const {
|
||||||
|
return (flags_ & CAN_MANAGE_TOPICS) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool can_send_messages() const {
|
bool can_send_messages() const {
|
||||||
return (flags_ & CAN_SEND_MESSAGES) != 0;
|
return (flags_ & CAN_SEND_MESSAGES) != 0;
|
||||||
}
|
}
|
||||||
@ -240,7 +247,7 @@ bool operator!=(const RestrictedRights &lhs, const RestrictedRights &rhs);
|
|||||||
StringBuilder &operator<<(StringBuilder &string_builder, const RestrictedRights &status);
|
StringBuilder &operator<<(StringBuilder &string_builder, const RestrictedRights &status);
|
||||||
|
|
||||||
class DialogParticipantStatus {
|
class DialogParticipantStatus {
|
||||||
// only flags 11 and 12 are unused
|
// all flags are used
|
||||||
static constexpr uint32 HAS_RANK = 1 << 14;
|
static constexpr uint32 HAS_RANK = 1 << 14;
|
||||||
static constexpr uint32 CAN_BE_EDITED = 1 << 15;
|
static constexpr uint32 CAN_BE_EDITED = 1 << 15;
|
||||||
|
|
||||||
@ -348,6 +355,15 @@ class DialogParticipantStatus {
|
|||||||
return get_administrator_rights().can_pin_messages() || get_restricted_rights().can_pin_messages();
|
return get_administrator_rights().can_pin_messages() || get_restricted_rights().can_pin_messages();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool can_edit_topics() const {
|
||||||
|
// topics can be edited, only if administrator was explicitly granted the right
|
||||||
|
return get_administrator_rights().can_manage_topics();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool can_create_topics() const {
|
||||||
|
return get_administrator_rights().can_manage_topics() || get_restricted_rights().can_manage_topics();
|
||||||
|
}
|
||||||
|
|
||||||
bool can_promote_members() const {
|
bool can_promote_members() const {
|
||||||
return get_administrator_rights().can_promote_members();
|
return get_administrator_rights().can_promote_members();
|
||||||
}
|
}
|
||||||
|
@ -122,6 +122,7 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
int32 video_duration = 0;
|
int32 video_duration = 0;
|
||||||
|
string video_waveform;
|
||||||
if (video != nullptr) {
|
if (video != nullptr) {
|
||||||
video_duration = video->duration_;
|
video_duration = video->duration_;
|
||||||
auto video_dimensions = get_dimensions(video->w_, video->h_, "documentAttributeVideo");
|
auto video_dimensions = get_dimensions(video->w_, video->h_, "documentAttributeVideo");
|
||||||
@ -131,6 +132,11 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo
|
|||||||
}
|
}
|
||||||
dimensions = video_dimensions;
|
dimensions = video_dimensions;
|
||||||
}
|
}
|
||||||
|
if (audio != nullptr) {
|
||||||
|
video_waveform = audio->waveform_.as_slice().str();
|
||||||
|
type_attributes--;
|
||||||
|
audio = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (animated != nullptr) {
|
if (animated != nullptr) {
|
||||||
type_attributes--;
|
type_attributes--;
|
||||||
@ -514,7 +520,7 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo
|
|||||||
break;
|
break;
|
||||||
case Document::Type::VideoNote:
|
case Document::Type::VideoNote:
|
||||||
td_->video_notes_manager_->create_video_note(file_id, std::move(minithumbnail), std::move(thumbnail),
|
td_->video_notes_manager_->create_video_note(file_id, std::move(minithumbnail), std::move(thumbnail),
|
||||||
video_duration, dimensions, !is_web);
|
video_duration, dimensions, std::move(video_waveform), !is_web);
|
||||||
break;
|
break;
|
||||||
case Document::Type::VoiceNote: {
|
case Document::Type::VoiceNote: {
|
||||||
int32 duration = 0;
|
int32 duration = 0;
|
||||||
@ -545,11 +551,11 @@ FileId DocumentsManager::on_get_document(unique_ptr<GeneralDocument> new_documen
|
|||||||
CHECK(d->file_id == new_document->file_id);
|
CHECK(d->file_id == new_document->file_id);
|
||||||
if (d->mime_type != new_document->mime_type) {
|
if (d->mime_type != new_document->mime_type) {
|
||||||
LOG(DEBUG) << "Document " << file_id << " mime_type has changed";
|
LOG(DEBUG) << "Document " << file_id << " mime_type has changed";
|
||||||
d->mime_type = new_document->mime_type;
|
d->mime_type = std::move(new_document->mime_type);
|
||||||
}
|
}
|
||||||
if (d->file_name != new_document->file_name) {
|
if (d->file_name != new_document->file_name) {
|
||||||
LOG(DEBUG) << "Document " << file_id << " file_name has changed";
|
LOG(DEBUG) << "Document " << file_id << " file_name has changed";
|
||||||
d->file_name = new_document->file_name;
|
d->file_name = std::move(new_document->file_name);
|
||||||
}
|
}
|
||||||
if (d->minithumbnail != new_document->minithumbnail) {
|
if (d->minithumbnail != new_document->minithumbnail) {
|
||||||
d->minithumbnail = std::move(new_document->minithumbnail);
|
d->minithumbnail = std::move(new_document->minithumbnail);
|
||||||
@ -561,7 +567,7 @@ FileId DocumentsManager::on_get_document(unique_ptr<GeneralDocument> new_documen
|
|||||||
LOG(INFO) << "Document " << file_id << " thumbnail has changed from " << d->thumbnail << " to "
|
LOG(INFO) << "Document " << file_id << " thumbnail has changed from " << d->thumbnail << " to "
|
||||||
<< new_document->thumbnail;
|
<< new_document->thumbnail;
|
||||||
}
|
}
|
||||||
d->thumbnail = new_document->thumbnail;
|
d->thumbnail = std::move(new_document->thumbnail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "td/utils/misc.h"
|
#include "td/utils/misc.h"
|
||||||
#include "td/utils/Slice.h"
|
#include "td/utils/Slice.h"
|
||||||
#include "td/utils/SliceBuilder.h"
|
#include "td/utils/SliceBuilder.h"
|
||||||
|
#include "td/utils/Status.h"
|
||||||
#include "td/utils/tl_helpers.h"
|
#include "td/utils/tl_helpers.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -47,12 +47,14 @@ void DownloadManagerCallback::update_file_removed(FileId file_id, DownloadManage
|
|||||||
void DownloadManagerCallback::start_file(FileId file_id, int8 priority, ActorShared<DownloadManager> download_manager) {
|
void DownloadManagerCallback::start_file(FileId file_id, int8 priority, ActorShared<DownloadManager> download_manager) {
|
||||||
send_closure_later(td_->file_manager_actor_, &FileManager::download, file_id,
|
send_closure_later(td_->file_manager_actor_, &FileManager::download, file_id,
|
||||||
make_download_file_callback(td_, std::move(download_manager)), priority,
|
make_download_file_callback(td_, std::move(download_manager)), priority,
|
||||||
FileManager::KEEP_DOWNLOAD_OFFSET, FileManager::IGNORE_DOWNLOAD_LIMIT);
|
FileManager::KEEP_DOWNLOAD_OFFSET, FileManager::IGNORE_DOWNLOAD_LIMIT,
|
||||||
|
Promise<td_api::object_ptr<td_api::file>>());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadManagerCallback::pause_file(FileId file_id) {
|
void DownloadManagerCallback::pause_file(FileId file_id) {
|
||||||
send_closure_later(td_->file_manager_actor_, &FileManager::download, file_id, nullptr, 0,
|
send_closure_later(td_->file_manager_actor_, &FileManager::download, file_id, nullptr, 0,
|
||||||
FileManager::KEEP_DOWNLOAD_OFFSET, FileManager::KEEP_DOWNLOAD_LIMIT);
|
FileManager::KEEP_DOWNLOAD_OFFSET, FileManager::KEEP_DOWNLOAD_LIMIT,
|
||||||
|
Promise<td_api::object_ptr<td_api::file>>());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadManagerCallback::delete_file(FileId file_id) {
|
void DownloadManagerCallback::delete_file(FileId file_id) {
|
||||||
@ -75,7 +77,7 @@ FileView DownloadManagerCallback::get_file_view(FileId file_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FileView DownloadManagerCallback::get_sync_file_view(FileId file_id) {
|
FileView DownloadManagerCallback::get_sync_file_view(FileId file_id) {
|
||||||
td_->file_manager_->check_local_location(file_id);
|
td_->file_manager_->check_local_location(file_id, true);
|
||||||
return get_file_view(file_id);
|
return get_file_view(file_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,8 +14,11 @@
|
|||||||
|
|
||||||
#include "td/utils/algorithm.h"
|
#include "td/utils/algorithm.h"
|
||||||
#include "td/utils/buffer.h"
|
#include "td/utils/buffer.h"
|
||||||
|
#include "td/utils/logging.h"
|
||||||
#include "td/utils/Status.h"
|
#include "td/utils/Status.h"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
struct EmojiStatuses {
|
struct EmojiStatuses {
|
||||||
@ -203,7 +206,7 @@ EmojiStatus::EmojiStatus(const td_api::object_ptr<td_api::emojiStatus> &emoji_st
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
custom_emoji_id_ = emoji_status->custom_emoji_id_;
|
custom_emoji_id_ = CustomEmojiId(emoji_status->custom_emoji_id_);
|
||||||
if (duration != 0) {
|
if (duration != 0) {
|
||||||
int32 current_time = G()->unix_time();
|
int32 current_time = G()->unix_time();
|
||||||
if (duration >= std::numeric_limits<int32>::max() - current_time) {
|
if (duration >= std::numeric_limits<int32>::max() - current_time) {
|
||||||
@ -223,12 +226,12 @@ EmojiStatus::EmojiStatus(tl_object_ptr<telegram_api::EmojiStatus> &&emoji_status
|
|||||||
break;
|
break;
|
||||||
case telegram_api::emojiStatus::ID: {
|
case telegram_api::emojiStatus::ID: {
|
||||||
auto status = static_cast<const telegram_api::emojiStatus *>(emoji_status.get());
|
auto status = static_cast<const telegram_api::emojiStatus *>(emoji_status.get());
|
||||||
custom_emoji_id_ = status->document_id_;
|
custom_emoji_id_ = CustomEmojiId(status->document_id_);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case telegram_api::emojiStatusUntil::ID: {
|
case telegram_api::emojiStatusUntil::ID: {
|
||||||
auto status = static_cast<const telegram_api::emojiStatusUntil *>(emoji_status.get());
|
auto status = static_cast<const telegram_api::emojiStatusUntil *>(emoji_status.get());
|
||||||
custom_emoji_id_ = status->document_id_;
|
custom_emoji_id_ = CustomEmojiId(status->document_id_);
|
||||||
until_date_ = status->until_;
|
until_date_ = status->until_;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -242,24 +245,24 @@ tl_object_ptr<telegram_api::EmojiStatus> EmojiStatus::get_input_emoji_status() c
|
|||||||
return make_tl_object<telegram_api::emojiStatusEmpty>();
|
return make_tl_object<telegram_api::emojiStatusEmpty>();
|
||||||
}
|
}
|
||||||
if (until_date_ != 0) {
|
if (until_date_ != 0) {
|
||||||
return make_tl_object<telegram_api::emojiStatusUntil>(custom_emoji_id_, until_date_);
|
return make_tl_object<telegram_api::emojiStatusUntil>(custom_emoji_id_.get(), until_date_);
|
||||||
}
|
}
|
||||||
return make_tl_object<telegram_api::emojiStatus>(custom_emoji_id_);
|
return make_tl_object<telegram_api::emojiStatus>(custom_emoji_id_.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
td_api::object_ptr<td_api::emojiStatus> EmojiStatus::get_emoji_status_object() const {
|
td_api::object_ptr<td_api::emojiStatus> EmojiStatus::get_emoji_status_object() const {
|
||||||
if (is_empty()) {
|
if (is_empty()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return td_api::make_object<td_api::emojiStatus>(custom_emoji_id_);
|
return td_api::make_object<td_api::emojiStatus>(custom_emoji_id_.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 EmojiStatus::get_effective_custom_emoji_id(bool is_premium, int32 unix_time) const {
|
CustomEmojiId EmojiStatus::get_effective_custom_emoji_id(bool is_premium, int32 unix_time) const {
|
||||||
if (!is_premium) {
|
if (!is_premium) {
|
||||||
return 0;
|
return CustomEmojiId();
|
||||||
}
|
}
|
||||||
if (until_date_ != 0 && until_date_ <= unix_time) {
|
if (until_date_ != 0 && until_date_ <= unix_time) {
|
||||||
return 0;
|
return CustomEmojiId();
|
||||||
}
|
}
|
||||||
return custom_emoji_id_;
|
return custom_emoji_id_;
|
||||||
}
|
}
|
||||||
@ -268,7 +271,7 @@ StringBuilder &operator<<(StringBuilder &string_builder, const EmojiStatus &emoj
|
|||||||
if (emoji_status.is_empty()) {
|
if (emoji_status.is_empty()) {
|
||||||
return string_builder << "DefaultProfileBadge";
|
return string_builder << "DefaultProfileBadge";
|
||||||
}
|
}
|
||||||
string_builder << "CustomEmoji " << emoji_status.custom_emoji_id_;
|
string_builder << emoji_status.custom_emoji_id_;
|
||||||
if (emoji_status.until_date_ != 0) {
|
if (emoji_status.until_date_ != 0) {
|
||||||
string_builder << " until " << emoji_status.until_date_;
|
string_builder << " until " << emoji_status.until_date_;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/CustomEmojiId.h"
|
||||||
#include "td/telegram/td_api.h"
|
#include "td/telegram/td_api.h"
|
||||||
#include "td/telegram/telegram_api.h"
|
#include "td/telegram/telegram_api.h"
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ namespace td {
|
|||||||
class Td;
|
class Td;
|
||||||
|
|
||||||
class EmojiStatus {
|
class EmojiStatus {
|
||||||
int64 custom_emoji_id_ = 0;
|
CustomEmojiId custom_emoji_id_;
|
||||||
int32 until_date_ = 0;
|
int32 until_date_ = 0;
|
||||||
|
|
||||||
friend bool operator==(const EmojiStatus &lhs, const EmojiStatus &rhs);
|
friend bool operator==(const EmojiStatus &lhs, const EmojiStatus &rhs);
|
||||||
@ -37,13 +38,13 @@ class EmojiStatus {
|
|||||||
|
|
||||||
td_api::object_ptr<td_api::emojiStatus> get_emoji_status_object() const;
|
td_api::object_ptr<td_api::emojiStatus> get_emoji_status_object() const;
|
||||||
|
|
||||||
int64 get_effective_custom_emoji_id(bool is_premium, int32 unix_time) const;
|
CustomEmojiId get_effective_custom_emoji_id(bool is_premium, int32 unix_time) const;
|
||||||
|
|
||||||
bool is_empty() const {
|
bool is_empty() const {
|
||||||
return custom_emoji_id_ == 0;
|
return !custom_emoji_id_.is_valid();
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 get_custom_emoji_id() const {
|
CustomEmojiId get_custom_emoji_id() const {
|
||||||
return custom_emoji_id_;
|
return custom_emoji_id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ class EmojiStatus {
|
|||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
void store(StorerT &storer) const {
|
void store(StorerT &storer) const {
|
||||||
bool has_custom_emoji_id = custom_emoji_id_ != 0;
|
bool has_custom_emoji_id = custom_emoji_id_.is_valid();
|
||||||
bool has_until_date = until_date_ != 0;
|
bool has_until_date = until_date_ != 0;
|
||||||
BEGIN_STORE_FLAGS();
|
BEGIN_STORE_FLAGS();
|
||||||
STORE_FLAG(has_custom_emoji_id);
|
STORE_FLAG(has_custom_emoji_id);
|
||||||
|
52
td/telegram/ForumTopic.cpp
Normal file
52
td/telegram/ForumTopic.cpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#include "td/telegram/ForumTopic.h"
|
||||||
|
|
||||||
|
#include "td/telegram/DraftMessage.h"
|
||||||
|
#include "td/telegram/ServerMessageId.h"
|
||||||
|
#include "td/telegram/Td.h"
|
||||||
|
|
||||||
|
#include "td/utils/logging.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
ForumTopic::ForumTopic(Td *td, tl_object_ptr<telegram_api::ForumTopic> &&forum_topic_ptr) {
|
||||||
|
CHECK(forum_topic_ptr != nullptr);
|
||||||
|
if (forum_topic_ptr->get_id() != telegram_api::forumTopic::ID) {
|
||||||
|
LOG(INFO) << "Receive " << to_string(forum_topic_ptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
info_ = ForumTopicInfo(forum_topic_ptr);
|
||||||
|
auto *forum_topic = static_cast<telegram_api::forumTopic *>(forum_topic_ptr.get());
|
||||||
|
|
||||||
|
last_message_id_ = MessageId(ServerMessageId(forum_topic->top_message_));
|
||||||
|
is_pinned_ = forum_topic->pinned_;
|
||||||
|
unread_count_ = forum_topic->unread_count_;
|
||||||
|
last_read_inbox_message_id_ = MessageId(ServerMessageId(forum_topic->read_inbox_max_id_));
|
||||||
|
last_read_outbox_message_id_ = MessageId(ServerMessageId(forum_topic->read_outbox_max_id_));
|
||||||
|
unread_mention_count_ = forum_topic->unread_mentions_count_;
|
||||||
|
unread_reaction_count_ = forum_topic->unread_reactions_count_;
|
||||||
|
notification_settings_ =
|
||||||
|
get_dialog_notification_settings(std::move(forum_topic->notify_settings_), false, false, false, false);
|
||||||
|
draft_message_ = get_draft_message(td->contacts_manager_.get(), std::move(forum_topic->draft_));
|
||||||
|
}
|
||||||
|
|
||||||
|
td_api::object_ptr<td_api::forumTopic> ForumTopic::get_forum_topic_object(Td *td) const {
|
||||||
|
if (is_empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO draft_message = can_send_message(dialog_id, info_.get_top_thread_message_id()).is_ok() ? ... : nullptr;
|
||||||
|
// TODO last_message
|
||||||
|
auto draft_message = get_draft_message_object(draft_message_);
|
||||||
|
return td_api::make_object<td_api::forumTopic>(
|
||||||
|
info_.get_forum_topic_info_object(td), nullptr, is_pinned_, unread_count_, last_read_inbox_message_id_.get(),
|
||||||
|
last_read_outbox_message_id_.get(), unread_mention_count_, unread_reaction_count_,
|
||||||
|
get_chat_notification_settings_object(¬ification_settings_), std::move(draft_message));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
50
td/telegram/ForumTopic.h
Normal file
50
td/telegram/ForumTopic.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/DialogNotificationSettings.h"
|
||||||
|
#include "td/telegram/ForumTopicInfo.h"
|
||||||
|
#include "td/telegram/MessageId.h"
|
||||||
|
#include "td/telegram/td_api.h"
|
||||||
|
#include "td/telegram/telegram_api.h"
|
||||||
|
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class DraftMessage;
|
||||||
|
class Td;
|
||||||
|
|
||||||
|
class ForumTopic {
|
||||||
|
ForumTopicInfo info_;
|
||||||
|
MessageId last_message_id_;
|
||||||
|
bool is_pinned_ = false;
|
||||||
|
int32 unread_count_ = 0;
|
||||||
|
MessageId last_read_inbox_message_id_;
|
||||||
|
MessageId last_read_outbox_message_id_;
|
||||||
|
int32 unread_mention_count_ = 0;
|
||||||
|
int32 unread_reaction_count_ = 0;
|
||||||
|
DialogNotificationSettings notification_settings_;
|
||||||
|
unique_ptr<DraftMessage> draft_message_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ForumTopic() = default;
|
||||||
|
|
||||||
|
ForumTopic(Td *td, tl_object_ptr<telegram_api::ForumTopic> &&forum_topic_ptr);
|
||||||
|
|
||||||
|
bool is_empty() const {
|
||||||
|
return info_.is_empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageId get_top_thread_message_id() const {
|
||||||
|
return info_.get_top_thread_message_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
td_api::object_ptr<td_api::forumTopic> get_forum_topic_object(Td *td) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace td
|
42
td/telegram/ForumTopicEditedData.cpp
Normal file
42
td/telegram/ForumTopicEditedData.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#include "td/telegram/ForumTopicEditedData.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
td_api::object_ptr<td_api::MessageContent> ForumTopicEditedData::get_message_content_object() const {
|
||||||
|
if (edit_is_closed_) {
|
||||||
|
return td_api::make_object<td_api::messageForumTopicIsClosedToggled>(is_closed_);
|
||||||
|
}
|
||||||
|
return td_api::make_object<td_api::messageForumTopicEdited>(title_, edit_icon_custom_emoji_id_,
|
||||||
|
icon_custom_emoji_id_.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const ForumTopicEditedData &lhs, const ForumTopicEditedData &rhs) {
|
||||||
|
return lhs.title_ == rhs.title_ && lhs.icon_custom_emoji_id_ == rhs.icon_custom_emoji_id_ &&
|
||||||
|
lhs.edit_icon_custom_emoji_id_ == rhs.edit_icon_custom_emoji_id_ &&
|
||||||
|
lhs.edit_is_closed_ == rhs.edit_is_closed_ && lhs.is_closed_ == rhs.is_closed_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const ForumTopicEditedData &lhs, const ForumTopicEditedData &rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &string_builder, const ForumTopicEditedData &topic_edited_data) {
|
||||||
|
if (!topic_edited_data.title_.empty()) {
|
||||||
|
string_builder << "set title to \"" << topic_edited_data.title_ << '"';
|
||||||
|
}
|
||||||
|
if (topic_edited_data.edit_icon_custom_emoji_id_) {
|
||||||
|
string_builder << "set icon to " << topic_edited_data.icon_custom_emoji_id_;
|
||||||
|
}
|
||||||
|
if (topic_edited_data.edit_is_closed_) {
|
||||||
|
string_builder << "set is_closed to " << topic_edited_data.is_closed_;
|
||||||
|
}
|
||||||
|
return string_builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
60
td/telegram/ForumTopicEditedData.h
Normal file
60
td/telegram/ForumTopicEditedData.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/CustomEmojiId.h"
|
||||||
|
#include "td/telegram/td_api.h"
|
||||||
|
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/StringBuilder.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class ForumTopicEditedData {
|
||||||
|
string title_;
|
||||||
|
CustomEmojiId icon_custom_emoji_id_;
|
||||||
|
bool edit_icon_custom_emoji_id_ = false;
|
||||||
|
bool edit_is_closed_ = false;
|
||||||
|
bool is_closed_ = false;
|
||||||
|
|
||||||
|
friend bool operator==(const ForumTopicEditedData &lhs, const ForumTopicEditedData &rhs);
|
||||||
|
|
||||||
|
friend StringBuilder &operator<<(StringBuilder &string_builder, const ForumTopicEditedData &topic_edited_data);
|
||||||
|
|
||||||
|
friend class ForumTopicInfo;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ForumTopicEditedData() = default;
|
||||||
|
|
||||||
|
bool is_empty() const {
|
||||||
|
return title_.empty() && !edit_icon_custom_emoji_id_ && !edit_is_closed_;
|
||||||
|
}
|
||||||
|
|
||||||
|
ForumTopicEditedData(string &&title, bool edit_icon_custom_emoji_id, int64 icon_custom_emoji_id, bool edit_is_closed,
|
||||||
|
bool is_closed)
|
||||||
|
: title_(std::move(title))
|
||||||
|
, icon_custom_emoji_id_(icon_custom_emoji_id)
|
||||||
|
, edit_icon_custom_emoji_id_(edit_icon_custom_emoji_id)
|
||||||
|
, edit_is_closed_(edit_is_closed)
|
||||||
|
, is_closed_(is_closed) {
|
||||||
|
}
|
||||||
|
|
||||||
|
td_api::object_ptr<td_api::MessageContent> get_message_content_object() const;
|
||||||
|
|
||||||
|
template <class StorerT>
|
||||||
|
void store(StorerT &storer) const;
|
||||||
|
|
||||||
|
template <class ParserT>
|
||||||
|
void parse(ParserT &parser);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(const ForumTopicEditedData &lhs, const ForumTopicEditedData &rhs);
|
||||||
|
bool operator!=(const ForumTopicEditedData &lhs, const ForumTopicEditedData &rhs);
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &string_builder, const ForumTopicEditedData &topic_edited_data);
|
||||||
|
|
||||||
|
} // namespace td
|
54
td/telegram/ForumTopicEditedData.hpp
Normal file
54
td/telegram/ForumTopicEditedData.hpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/ForumTopicEditedData.h"
|
||||||
|
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/tl_helpers.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
template <class StorerT>
|
||||||
|
void ForumTopicEditedData::store(StorerT &storer) const {
|
||||||
|
bool has_title = !title_.empty();
|
||||||
|
bool has_icon_custom_emoji_id = icon_custom_emoji_id_.is_valid();
|
||||||
|
BEGIN_STORE_FLAGS();
|
||||||
|
STORE_FLAG(edit_icon_custom_emoji_id_);
|
||||||
|
STORE_FLAG(edit_is_closed_);
|
||||||
|
STORE_FLAG(is_closed_);
|
||||||
|
STORE_FLAG(has_title);
|
||||||
|
STORE_FLAG(has_icon_custom_emoji_id);
|
||||||
|
END_STORE_FLAGS();
|
||||||
|
if (has_title) {
|
||||||
|
td::store(title_, storer);
|
||||||
|
}
|
||||||
|
if (has_icon_custom_emoji_id) {
|
||||||
|
td::store(icon_custom_emoji_id_, storer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ParserT>
|
||||||
|
void ForumTopicEditedData::parse(ParserT &parser) {
|
||||||
|
bool has_title;
|
||||||
|
bool has_icon_custom_emoji_id;
|
||||||
|
BEGIN_PARSE_FLAGS();
|
||||||
|
PARSE_FLAG(edit_icon_custom_emoji_id_);
|
||||||
|
PARSE_FLAG(edit_is_closed_);
|
||||||
|
PARSE_FLAG(is_closed_);
|
||||||
|
PARSE_FLAG(has_title);
|
||||||
|
PARSE_FLAG(has_icon_custom_emoji_id);
|
||||||
|
END_PARSE_FLAGS();
|
||||||
|
if (has_title) {
|
||||||
|
td::parse(title_, parser);
|
||||||
|
}
|
||||||
|
if (has_icon_custom_emoji_id) {
|
||||||
|
td::parse(icon_custom_emoji_id_, parser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
43
td/telegram/ForumTopicIcon.cpp
Normal file
43
td/telegram/ForumTopicIcon.cpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#include "td/telegram/ForumTopicIcon.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
ForumTopicIcon::ForumTopicIcon(int32 color, int64 custom_emoji_id)
|
||||||
|
: color_(color & 0xFFFFFF), custom_emoji_id_(custom_emoji_id) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ForumTopicIcon::edit_custom_emoji_id(CustomEmojiId custom_emoji_id) {
|
||||||
|
if (custom_emoji_id_ != custom_emoji_id) {
|
||||||
|
custom_emoji_id_ = custom_emoji_id;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
td_api::object_ptr<td_api::forumTopicIcon> ForumTopicIcon::get_forum_topic_icon_object() const {
|
||||||
|
return td_api::make_object<td_api::forumTopicIcon>(color_, custom_emoji_id_.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const ForumTopicIcon &lhs, const ForumTopicIcon &rhs) {
|
||||||
|
return lhs.color_ == rhs.color_ && lhs.custom_emoji_id_ == rhs.custom_emoji_id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const ForumTopicIcon &lhs, const ForumTopicIcon &rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &string_builder, const ForumTopicIcon &topic_icon) {
|
||||||
|
string_builder << "icon color " << topic_icon.color_;
|
||||||
|
if (topic_icon.custom_emoji_id_.is_valid()) {
|
||||||
|
string_builder << " and " << topic_icon.custom_emoji_id_;
|
||||||
|
}
|
||||||
|
return string_builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
45
td/telegram/ForumTopicIcon.h
Normal file
45
td/telegram/ForumTopicIcon.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/CustomEmojiId.h"
|
||||||
|
#include "td/telegram/td_api.h"
|
||||||
|
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/StringBuilder.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class ForumTopicIcon {
|
||||||
|
int32 color_ = 0x6FB9F0;
|
||||||
|
CustomEmojiId custom_emoji_id_;
|
||||||
|
|
||||||
|
friend bool operator==(const ForumTopicIcon &lhs, const ForumTopicIcon &rhs);
|
||||||
|
|
||||||
|
friend StringBuilder &operator<<(StringBuilder &string_builder, const ForumTopicIcon &topic_icon);
|
||||||
|
|
||||||
|
public:
|
||||||
|
ForumTopicIcon() = default;
|
||||||
|
ForumTopicIcon(int32 color, int64 custom_emoji_id);
|
||||||
|
|
||||||
|
bool edit_custom_emoji_id(CustomEmojiId custom_emoji_id);
|
||||||
|
|
||||||
|
td_api::object_ptr<td_api::forumTopicIcon> get_forum_topic_icon_object() const;
|
||||||
|
|
||||||
|
template <class StorerT>
|
||||||
|
void store(StorerT &storer) const;
|
||||||
|
|
||||||
|
template <class ParserT>
|
||||||
|
void parse(ParserT &parser);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(const ForumTopicIcon &lhs, const ForumTopicIcon &rhs);
|
||||||
|
bool operator!=(const ForumTopicIcon &lhs, const ForumTopicIcon &rhs);
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &string_builder, const ForumTopicIcon &topic_icon);
|
||||||
|
|
||||||
|
} // namespace td
|
40
td/telegram/ForumTopicIcon.hpp
Normal file
40
td/telegram/ForumTopicIcon.hpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/ForumTopicIcon.h"
|
||||||
|
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/tl_helpers.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
template <class StorerT>
|
||||||
|
void ForumTopicIcon::store(StorerT &storer) const {
|
||||||
|
bool has_custom_emoji_id = custom_emoji_id_.is_valid();
|
||||||
|
BEGIN_STORE_FLAGS();
|
||||||
|
STORE_FLAG(has_custom_emoji_id);
|
||||||
|
END_STORE_FLAGS();
|
||||||
|
td::store(color_, storer);
|
||||||
|
if (has_custom_emoji_id) {
|
||||||
|
td::store(custom_emoji_id_, storer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ParserT>
|
||||||
|
void ForumTopicIcon::parse(ParserT &parser) {
|
||||||
|
bool has_custom_emoji_id;
|
||||||
|
BEGIN_PARSE_FLAGS();
|
||||||
|
PARSE_FLAG(has_custom_emoji_id);
|
||||||
|
END_PARSE_FLAGS();
|
||||||
|
td::parse(color_, parser);
|
||||||
|
if (has_custom_emoji_id) {
|
||||||
|
td::parse(custom_emoji_id_, parser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
70
td/telegram/ForumTopicInfo.cpp
Normal file
70
td/telegram/ForumTopicInfo.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#include "td/telegram/ForumTopicInfo.h"
|
||||||
|
|
||||||
|
#include "td/telegram/MessageSender.h"
|
||||||
|
#include "td/telegram/ServerMessageId.h"
|
||||||
|
|
||||||
|
#include "td/utils/logging.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
ForumTopicInfo::ForumTopicInfo(const tl_object_ptr<telegram_api::ForumTopic> &forum_topic_ptr) {
|
||||||
|
CHECK(forum_topic_ptr != nullptr);
|
||||||
|
if (forum_topic_ptr->get_id() != telegram_api::forumTopic::ID) {
|
||||||
|
LOG(ERROR) << "Receive " << to_string(forum_topic_ptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto *forum_topic = static_cast<const telegram_api::forumTopic *>(forum_topic_ptr.get());
|
||||||
|
|
||||||
|
top_thread_message_id_ = MessageId(ServerMessageId(forum_topic->id_));
|
||||||
|
title_ = forum_topic->title_;
|
||||||
|
icon_ = ForumTopicIcon(forum_topic->icon_color_, forum_topic->icon_emoji_id_);
|
||||||
|
creation_date_ = forum_topic->date_;
|
||||||
|
creator_dialog_id_ = DialogId(forum_topic->from_id_);
|
||||||
|
is_outgoing_ = forum_topic->my_;
|
||||||
|
is_closed_ = forum_topic->closed_;
|
||||||
|
|
||||||
|
if (creation_date_ <= 0 || !top_thread_message_id_.is_valid() || !creator_dialog_id_.is_valid()) {
|
||||||
|
LOG(ERROR) << "Receive " << to_string(forum_topic_ptr);
|
||||||
|
*this = ForumTopicInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ForumTopicInfo::apply_edited_data(const ForumTopicEditedData &edited_data) {
|
||||||
|
bool is_changed = false;
|
||||||
|
if (!edited_data.title_.empty() && edited_data.title_ != title_) {
|
||||||
|
title_ = edited_data.title_;
|
||||||
|
is_changed = true;
|
||||||
|
}
|
||||||
|
if (edited_data.edit_icon_custom_emoji_id_ && icon_.edit_custom_emoji_id(edited_data.icon_custom_emoji_id_)) {
|
||||||
|
is_changed = true;
|
||||||
|
}
|
||||||
|
if (edited_data.edit_is_closed_ && edited_data.is_closed_ != is_closed_) {
|
||||||
|
is_closed_ = edited_data.is_closed_;
|
||||||
|
is_changed = true;
|
||||||
|
}
|
||||||
|
return is_changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
td_api::object_ptr<td_api::forumTopicInfo> ForumTopicInfo::get_forum_topic_info_object(Td *td) const {
|
||||||
|
if (is_empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto creator_id = get_message_sender_object_const(td, creator_dialog_id_, "get_forum_topic_info_object");
|
||||||
|
return td_api::make_object<td_api::forumTopicInfo>(top_thread_message_id_.get(), title_,
|
||||||
|
icon_.get_forum_topic_icon_object(), creation_date_,
|
||||||
|
std::move(creator_id), is_outgoing_, is_closed_);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &string_builder, const ForumTopicInfo &topic_info) {
|
||||||
|
return string_builder << "Forum topic " << topic_info.top_thread_message_id_.get() << '/' << topic_info.title_
|
||||||
|
<< " by " << topic_info.creator_dialog_id_ << " with " << topic_info.icon_;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
77
td/telegram/ForumTopicInfo.h
Normal file
77
td/telegram/ForumTopicInfo.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/DialogId.h"
|
||||||
|
#include "td/telegram/ForumTopicEditedData.h"
|
||||||
|
#include "td/telegram/ForumTopicIcon.h"
|
||||||
|
#include "td/telegram/MessageId.h"
|
||||||
|
#include "td/telegram/td_api.h"
|
||||||
|
#include "td/telegram/telegram_api.h"
|
||||||
|
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/StringBuilder.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class Td;
|
||||||
|
|
||||||
|
class ForumTopicInfo {
|
||||||
|
MessageId top_thread_message_id_;
|
||||||
|
string title_;
|
||||||
|
ForumTopicIcon icon_;
|
||||||
|
int32 creation_date_ = 0;
|
||||||
|
DialogId creator_dialog_id_;
|
||||||
|
bool is_outgoing_ = false;
|
||||||
|
bool is_closed_ = false;
|
||||||
|
|
||||||
|
friend StringBuilder &operator<<(StringBuilder &string_builder, const ForumTopicInfo &topic_info);
|
||||||
|
|
||||||
|
public:
|
||||||
|
ForumTopicInfo() = default;
|
||||||
|
|
||||||
|
explicit ForumTopicInfo(const tl_object_ptr<telegram_api::ForumTopic> &forum_topic_ptr);
|
||||||
|
|
||||||
|
ForumTopicInfo(MessageId top_thread_message_id, string title, ForumTopicIcon icon, int32 creation_date,
|
||||||
|
DialogId creator_dialog_id, bool is_outgoing, bool is_closed)
|
||||||
|
: top_thread_message_id_(top_thread_message_id)
|
||||||
|
, title_(std::move(title))
|
||||||
|
, icon_(std::move(icon))
|
||||||
|
, creation_date_(creation_date)
|
||||||
|
, creator_dialog_id_(creator_dialog_id)
|
||||||
|
, is_outgoing_(is_outgoing)
|
||||||
|
, is_closed_(is_closed) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_empty() const {
|
||||||
|
return !top_thread_message_id_.is_valid();
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageId get_top_thread_message_id() const {
|
||||||
|
return top_thread_message_id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogId get_creator_dialog_id() const {
|
||||||
|
return creator_dialog_id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_outgoing() const {
|
||||||
|
return is_outgoing_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_closed() const {
|
||||||
|
return is_closed_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool apply_edited_data(const ForumTopicEditedData &edited_data);
|
||||||
|
|
||||||
|
td_api::object_ptr<td_api::forumTopicInfo> get_forum_topic_info_object(Td *td) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &string_builder, const ForumTopicInfo &topic_info);
|
||||||
|
|
||||||
|
} // namespace td
|
358
td/telegram/ForumTopicManager.cpp
Normal file
358
td/telegram/ForumTopicManager.cpp
Normal file
@ -0,0 +1,358 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#include "td/telegram/ForumTopicManager.h"
|
||||||
|
|
||||||
|
#include "td/telegram/AccessRights.h"
|
||||||
|
#include "td/telegram/AuthManager.h"
|
||||||
|
#include "td/telegram/ChannelId.h"
|
||||||
|
#include "td/telegram/ContactsManager.h"
|
||||||
|
#include "td/telegram/CustomEmojiId.h"
|
||||||
|
#include "td/telegram/ForumTopicIcon.h"
|
||||||
|
#include "td/telegram/Global.h"
|
||||||
|
#include "td/telegram/MessagesManager.h"
|
||||||
|
#include "td/telegram/misc.h"
|
||||||
|
#include "td/telegram/ServerMessageId.h"
|
||||||
|
#include "td/telegram/Td.h"
|
||||||
|
#include "td/telegram/telegram_api.h"
|
||||||
|
#include "td/telegram/UpdatesManager.h"
|
||||||
|
|
||||||
|
#include "td/utils/buffer.h"
|
||||||
|
#include "td/utils/logging.h"
|
||||||
|
#include "td/utils/Random.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class CreateForumTopicQuery final : public Td::ResultHandler {
|
||||||
|
Promise<td_api::object_ptr<td_api::forumTopicInfo>> promise_;
|
||||||
|
ChannelId channel_id_;
|
||||||
|
DialogId creator_dialog_id_;
|
||||||
|
int64 random_id_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CreateForumTopicQuery(Promise<td_api::object_ptr<td_api::forumTopicInfo>> &&promise)
|
||||||
|
: promise_(std::move(promise)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void send(ChannelId channel_id, const string &title, int32 icon_color, CustomEmojiId icon_custom_emoji_id,
|
||||||
|
DialogId as_dialog_id) {
|
||||||
|
channel_id_ = channel_id;
|
||||||
|
creator_dialog_id_ = DialogId(td_->contacts_manager_->get_my_id());
|
||||||
|
|
||||||
|
int32 flags = 0;
|
||||||
|
if (icon_color != -1) {
|
||||||
|
flags |= telegram_api::channels_createForumTopic::ICON_COLOR_MASK;
|
||||||
|
}
|
||||||
|
if (icon_custom_emoji_id.is_valid()) {
|
||||||
|
flags |= telegram_api::channels_createForumTopic::ICON_EMOJI_ID_MASK;
|
||||||
|
}
|
||||||
|
tl_object_ptr<telegram_api::InputPeer> as_input_peer;
|
||||||
|
if (as_dialog_id.is_valid()) {
|
||||||
|
as_input_peer = td_->messages_manager_->get_input_peer(as_dialog_id, AccessRights::Write);
|
||||||
|
if (as_input_peer != nullptr) {
|
||||||
|
flags |= telegram_api::channels_createForumTopic::SEND_AS_MASK;
|
||||||
|
creator_dialog_id_ = as_dialog_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
random_id_ = Random::secure_int64();
|
||||||
|
} while (random_id_ == 0);
|
||||||
|
|
||||||
|
auto input_channel = td_->contacts_manager_->get_input_channel(channel_id);
|
||||||
|
CHECK(input_channel != nullptr);
|
||||||
|
send_query(G()->net_query_creator().create(
|
||||||
|
telegram_api::channels_createForumTopic(flags, std::move(input_channel), title, icon_color,
|
||||||
|
icon_custom_emoji_id.get(), random_id_, std::move(as_input_peer)),
|
||||||
|
{{channel_id}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_result(BufferSlice packet) final {
|
||||||
|
auto result_ptr = fetch_result<telegram_api::channels_createForumTopic>(packet);
|
||||||
|
if (result_ptr.is_error()) {
|
||||||
|
return on_error(result_ptr.move_as_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ptr = result_ptr.move_as_ok();
|
||||||
|
LOG(INFO) << "Receive result for CreateForumTopicQuery: " << to_string(ptr);
|
||||||
|
auto message = UpdatesManager::get_message_by_random_id(ptr.get(), DialogId(channel_id_), random_id_);
|
||||||
|
if (message == nullptr || message->get_id() != telegram_api::messageService::ID) {
|
||||||
|
LOG(ERROR) << "Receive invalid result for CreateForumTopicQuery: " << to_string(ptr);
|
||||||
|
return promise_.set_error(Status::Error(400, "Invalid result received"));
|
||||||
|
}
|
||||||
|
auto service_message = static_cast<const telegram_api::messageService *>(message);
|
||||||
|
if (service_message->action_->get_id() != telegram_api::messageActionTopicCreate::ID) {
|
||||||
|
LOG(ERROR) << "Receive invalid result for CreateForumTopicQuery: " << to_string(ptr);
|
||||||
|
return promise_.set_error(Status::Error(400, "Invalid result received"));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto action = static_cast<const telegram_api::messageActionTopicCreate *>(service_message->action_.get());
|
||||||
|
auto forum_topic_info =
|
||||||
|
td::make_unique<ForumTopicInfo>(MessageId(ServerMessageId(service_message->id_)), action->title_,
|
||||||
|
ForumTopicIcon(action->icon_color_, action->icon_emoji_id_),
|
||||||
|
service_message->date_, creator_dialog_id_, true, false);
|
||||||
|
td_->updates_manager_->on_get_updates(
|
||||||
|
std::move(ptr),
|
||||||
|
PromiseCreator::lambda([dialog_id = DialogId(channel_id_), forum_topic_info = std::move(forum_topic_info),
|
||||||
|
promise = std::move(promise_)](Unit result) mutable {
|
||||||
|
send_closure(G()->forum_topic_manager(), &ForumTopicManager::on_forum_topic_created, dialog_id,
|
||||||
|
std::move(forum_topic_info), std::move(promise));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_error(Status status) final {
|
||||||
|
td_->contacts_manager_->on_get_channel_error(channel_id_, status, "CreateForumTopicQuery");
|
||||||
|
promise_.set_error(std::move(status));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class EditForumTopicQuery final : public Td::ResultHandler {
|
||||||
|
Promise<Unit> promise_;
|
||||||
|
ChannelId channel_id_;
|
||||||
|
MessageId top_thread_message_id_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit EditForumTopicQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void send(ChannelId channel_id, MessageId top_thread_message_id, const string &title,
|
||||||
|
CustomEmojiId icon_custom_emoji_id) {
|
||||||
|
channel_id_ = channel_id;
|
||||||
|
top_thread_message_id_ = top_thread_message_id;
|
||||||
|
|
||||||
|
auto input_channel = td_->contacts_manager_->get_input_channel(channel_id);
|
||||||
|
CHECK(input_channel != nullptr);
|
||||||
|
|
||||||
|
int32 flags =
|
||||||
|
telegram_api::channels_editForumTopic::TITLE_MASK | telegram_api::channels_editForumTopic::ICON_EMOJI_ID_MASK;
|
||||||
|
send_query(G()->net_query_creator().create(
|
||||||
|
telegram_api::channels_editForumTopic(flags, std::move(input_channel),
|
||||||
|
top_thread_message_id.get_server_message_id().get(), title,
|
||||||
|
icon_custom_emoji_id.get(), false),
|
||||||
|
{{channel_id}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void send(ChannelId channel_id, MessageId top_thread_message_id, bool is_closed) {
|
||||||
|
channel_id_ = channel_id;
|
||||||
|
top_thread_message_id_ = top_thread_message_id;
|
||||||
|
|
||||||
|
auto input_channel = td_->contacts_manager_->get_input_channel(channel_id);
|
||||||
|
CHECK(input_channel != nullptr);
|
||||||
|
|
||||||
|
int32 flags = telegram_api::channels_editForumTopic::CLOSED_MASK;
|
||||||
|
send_query(G()->net_query_creator().create(
|
||||||
|
telegram_api::channels_editForumTopic(flags, std::move(input_channel),
|
||||||
|
top_thread_message_id.get_server_message_id().get(), string(), 0,
|
||||||
|
is_closed),
|
||||||
|
{{channel_id}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_result(BufferSlice packet) final {
|
||||||
|
auto result_ptr = fetch_result<telegram_api::channels_editForumTopic>(packet);
|
||||||
|
if (result_ptr.is_error()) {
|
||||||
|
return on_error(result_ptr.move_as_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ptr = result_ptr.move_as_ok();
|
||||||
|
LOG(INFO) << "Receive result for EditForumTopicQuery: " << to_string(ptr);
|
||||||
|
td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_));
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_error(Status status) final {
|
||||||
|
if (status.message() == "TOPIC_NOT_MODIFIED" && !td_->auth_manager_->is_bot()) {
|
||||||
|
return promise_.set_value(Unit());
|
||||||
|
}
|
||||||
|
td_->contacts_manager_->on_get_channel_error(channel_id_, status, "EditForumTopicQuery");
|
||||||
|
promise_.set_error(std::move(status));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ForumTopicManager::ForumTopicManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ForumTopicManager::~ForumTopicManager() {
|
||||||
|
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), dialog_topics_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForumTopicManager::tear_down() {
|
||||||
|
parent_.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForumTopicManager::create_forum_topic(DialogId dialog_id, string &&title,
|
||||||
|
td_api::object_ptr<td_api::forumTopicIcon> &&icon,
|
||||||
|
Promise<td_api::object_ptr<td_api::forumTopicInfo>> &&promise) {
|
||||||
|
TRY_STATUS_PROMISE(promise, is_forum(dialog_id));
|
||||||
|
auto channel_id = dialog_id.get_channel_id();
|
||||||
|
|
||||||
|
if (!td_->contacts_manager_->get_channel_permissions(channel_id).can_create_topics()) {
|
||||||
|
return promise.set_error(Status::Error(400, "Not enough rights to create a topic"));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto new_title = clean_name(std::move(title), MAX_FORUM_TOPIC_TITLE_LENGTH);
|
||||||
|
if (new_title.empty()) {
|
||||||
|
return promise.set_error(Status::Error(400, "Title must be non-empty"));
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 icon_color = -1;
|
||||||
|
CustomEmojiId icon_custom_emoji_id;
|
||||||
|
if (icon != nullptr) {
|
||||||
|
icon_color = icon->color_;
|
||||||
|
if (icon_color < 0 || icon_color > 0xFFFFFF) {
|
||||||
|
return promise.set_error(Status::Error(400, "Invalid icon color specified"));
|
||||||
|
}
|
||||||
|
icon_custom_emoji_id = CustomEmojiId(icon->custom_emoji_id_);
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogId as_dialog_id = td_->messages_manager_->get_dialog_default_send_message_as_dialog_id(dialog_id);
|
||||||
|
|
||||||
|
td_->create_handler<CreateForumTopicQuery>(std::move(promise))
|
||||||
|
->send(channel_id, new_title, icon_color, icon_custom_emoji_id, as_dialog_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForumTopicManager::on_forum_topic_created(DialogId dialog_id, unique_ptr<ForumTopicInfo> &&forum_topic_info,
|
||||||
|
Promise<td_api::object_ptr<td_api::forumTopicInfo>> &&promise) {
|
||||||
|
TRY_STATUS_PROMISE(promise, G()->close_status());
|
||||||
|
|
||||||
|
auto topic_info = add_topic_info(dialog_id, std::move(forum_topic_info));
|
||||||
|
CHECK(topic_info != nullptr);
|
||||||
|
promise.set_value(topic_info->get_forum_topic_info_object(td_));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForumTopicManager::edit_forum_topic(DialogId dialog_id, MessageId top_thread_message_id, string &&title,
|
||||||
|
CustomEmojiId icon_custom_emoji_id, Promise<Unit> &&promise) {
|
||||||
|
TRY_STATUS_PROMISE(promise, is_forum(dialog_id));
|
||||||
|
auto channel_id = dialog_id.get_channel_id();
|
||||||
|
|
||||||
|
if (!top_thread_message_id.is_valid() || !top_thread_message_id.is_server()) {
|
||||||
|
return promise.set_error(Status::Error(400, "Invalid message thread identifier specified"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!td_->contacts_manager_->get_channel_permissions(channel_id).can_edit_topics()) {
|
||||||
|
auto topic_info = get_topic_info(dialog_id, top_thread_message_id);
|
||||||
|
if (topic_info != nullptr && !topic_info->is_outgoing()) {
|
||||||
|
return promise.set_error(Status::Error(400, "Not enough rights to edit the topic"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto new_title = clean_name(std::move(title), MAX_FORUM_TOPIC_TITLE_LENGTH);
|
||||||
|
if (new_title.empty()) {
|
||||||
|
return promise.set_error(Status::Error(400, "Title must be non-empty"));
|
||||||
|
}
|
||||||
|
|
||||||
|
td_->create_handler<EditForumTopicQuery>(std::move(promise))
|
||||||
|
->send(channel_id, top_thread_message_id, new_title, icon_custom_emoji_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForumTopicManager::toggle_forum_topic_is_closed(DialogId dialog_id, MessageId top_thread_message_id,
|
||||||
|
bool is_closed, Promise<Unit> &&promise) {
|
||||||
|
TRY_STATUS_PROMISE(promise, is_forum(dialog_id));
|
||||||
|
auto channel_id = dialog_id.get_channel_id();
|
||||||
|
|
||||||
|
if (!top_thread_message_id.is_valid() || !top_thread_message_id.is_server()) {
|
||||||
|
return promise.set_error(Status::Error(400, "Invalid message thread identifier specified"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!td_->contacts_manager_->get_channel_permissions(channel_id).can_edit_topics()) {
|
||||||
|
auto topic_info = get_topic_info(dialog_id, top_thread_message_id);
|
||||||
|
if (topic_info != nullptr && !topic_info->is_outgoing()) {
|
||||||
|
return promise.set_error(Status::Error(400, "Not enough rights to close or open the topic"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
td_->create_handler<EditForumTopicQuery>(std::move(promise))->send(channel_id, top_thread_message_id, is_closed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForumTopicManager::delete_forum_topic(DialogId dialog_id, MessageId top_thread_message_id,
|
||||||
|
Promise<Unit> &&promise) {
|
||||||
|
TRY_STATUS_PROMISE(promise, is_forum(dialog_id));
|
||||||
|
auto channel_id = dialog_id.get_channel_id();
|
||||||
|
|
||||||
|
if (!top_thread_message_id.is_valid() || !top_thread_message_id.is_server()) {
|
||||||
|
return promise.set_error(Status::Error(400, "Invalid message thread identifier specified"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!td_->contacts_manager_->get_channel_permissions(channel_id).can_delete_messages()) {
|
||||||
|
auto topic_info = get_topic_info(dialog_id, top_thread_message_id);
|
||||||
|
if (topic_info != nullptr && !topic_info->is_outgoing()) {
|
||||||
|
return promise.set_error(Status::Error(400, "Not enough rights to delete the topic"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
td_->messages_manager_->delete_topic_history(dialog_id, top_thread_message_id, std::move(promise));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForumTopicManager::on_forum_topic_edited(DialogId dialog_id, MessageId top_thread_message_id,
|
||||||
|
const ForumTopicEditedData &edited_data) {
|
||||||
|
auto topic_info = get_topic_info(dialog_id, top_thread_message_id);
|
||||||
|
if (topic_info == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (topic_info->apply_edited_data(edited_data)) {
|
||||||
|
send_update_forum_topic_info(dialog_id, topic_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Status ForumTopicManager::is_forum(DialogId dialog_id) {
|
||||||
|
if (!td_->messages_manager_->have_dialog_force(dialog_id, "ForumTopicManager::is_forum")) {
|
||||||
|
return Status::Error(400, "Chat not found");
|
||||||
|
}
|
||||||
|
if (dialog_id.get_type() != DialogType::Channel ||
|
||||||
|
!td_->contacts_manager_->is_forum_channel(dialog_id.get_channel_id())) {
|
||||||
|
return Status::Error(400, "The chat is not a forum");
|
||||||
|
}
|
||||||
|
return Status::OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
ForumTopicInfo *ForumTopicManager::add_topic_info(DialogId dialog_id, unique_ptr<ForumTopicInfo> &&forum_topic_info) {
|
||||||
|
CHECK(forum_topic_info != nullptr);
|
||||||
|
auto *dialog_info = dialog_topics_.get_pointer(dialog_id);
|
||||||
|
if (dialog_info == nullptr) {
|
||||||
|
dialog_topics_.set(dialog_id, make_unique<DialogTopics>());
|
||||||
|
dialog_info = dialog_topics_.get_pointer(dialog_id);
|
||||||
|
CHECK(dialog_info != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageId top_thread_message_id = forum_topic_info->get_top_thread_message_id();
|
||||||
|
auto topic_info = dialog_info->topic_infos_.get_pointer(top_thread_message_id);
|
||||||
|
if (topic_info == nullptr) {
|
||||||
|
dialog_info->topic_infos_.set(top_thread_message_id, std::move(forum_topic_info));
|
||||||
|
topic_info = get_topic_info(dialog_id, top_thread_message_id);
|
||||||
|
CHECK(topic_info != nullptr);
|
||||||
|
send_update_forum_topic_info(dialog_id, topic_info);
|
||||||
|
}
|
||||||
|
return topic_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
ForumTopicInfo *ForumTopicManager::get_topic_info(DialogId dialog_id, MessageId top_thread_message_id) {
|
||||||
|
auto *dialog_info = dialog_topics_.get_pointer(dialog_id);
|
||||||
|
if (dialog_info == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return dialog_info->topic_infos_.get_pointer(top_thread_message_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ForumTopicInfo *ForumTopicManager::get_topic_info(DialogId dialog_id, MessageId top_thread_message_id) const {
|
||||||
|
auto *dialog_info = dialog_topics_.get_pointer(dialog_id);
|
||||||
|
if (dialog_info == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return dialog_info->topic_infos_.get_pointer(top_thread_message_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
td_api::object_ptr<td_api::updateForumTopicInfo> ForumTopicManager::get_update_forum_topic_info(
|
||||||
|
DialogId dialog_id, const ForumTopicInfo *topic_info) const {
|
||||||
|
return td_api::make_object<td_api::updateForumTopicInfo>(dialog_id.get(),
|
||||||
|
topic_info->get_forum_topic_info_object(td_));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForumTopicManager::send_update_forum_topic_info(DialogId dialog_id, const ForumTopicInfo *topic_info) const {
|
||||||
|
if (td_->auth_manager_->is_bot()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
send_closure(G()->td(), &Td::send_update, get_update_forum_topic_info(dialog_id, topic_info));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
81
td/telegram/ForumTopicManager.h
Normal file
81
td/telegram/ForumTopicManager.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/CustomEmojiId.h"
|
||||||
|
#include "td/telegram/DialogId.h"
|
||||||
|
#include "td/telegram/ForumTopicEditedData.h"
|
||||||
|
#include "td/telegram/ForumTopicInfo.h"
|
||||||
|
#include "td/telegram/MessageId.h"
|
||||||
|
#include "td/telegram/td_api.h"
|
||||||
|
|
||||||
|
#include "td/actor/actor.h"
|
||||||
|
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/Promise.h"
|
||||||
|
#include "td/utils/Status.h"
|
||||||
|
#include "td/utils/WaitFreeHashMap.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class Td;
|
||||||
|
|
||||||
|
class ForumTopicManager final : public Actor {
|
||||||
|
public:
|
||||||
|
ForumTopicManager(Td *td, ActorShared<> parent);
|
||||||
|
ForumTopicManager(const ForumTopicManager &) = delete;
|
||||||
|
ForumTopicManager &operator=(const ForumTopicManager &) = delete;
|
||||||
|
ForumTopicManager(ForumTopicManager &&) = delete;
|
||||||
|
ForumTopicManager &operator=(ForumTopicManager &&) = delete;
|
||||||
|
~ForumTopicManager() final;
|
||||||
|
|
||||||
|
void create_forum_topic(DialogId dialog_id, string &&title, td_api::object_ptr<td_api::forumTopicIcon> &&icon,
|
||||||
|
Promise<td_api::object_ptr<td_api::forumTopicInfo>> &&promise);
|
||||||
|
|
||||||
|
void on_forum_topic_created(DialogId dialog_id, unique_ptr<ForumTopicInfo> &&forum_topic_info,
|
||||||
|
Promise<td_api::object_ptr<td_api::forumTopicInfo>> &&promise);
|
||||||
|
|
||||||
|
void edit_forum_topic(DialogId dialog_id, MessageId top_thread_message_id, string &&title,
|
||||||
|
CustomEmojiId icon_custom_emoji_id, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void toggle_forum_topic_is_closed(DialogId dialog_id, MessageId top_thread_message_id, bool is_closed,
|
||||||
|
Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void delete_forum_topic(DialogId dialog_id, MessageId top_thread_message_id, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void on_forum_topic_edited(DialogId dialog_id, MessageId top_thread_message_id,
|
||||||
|
const ForumTopicEditedData &edited_data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr size_t MAX_FORUM_TOPIC_TITLE_LENGTH = 128; // server side limit for forum topic title
|
||||||
|
|
||||||
|
struct DialogTopics {
|
||||||
|
WaitFreeHashMap<MessageId, unique_ptr<ForumTopicInfo>, MessageIdHash> topic_infos_;
|
||||||
|
};
|
||||||
|
|
||||||
|
void tear_down() final;
|
||||||
|
|
||||||
|
Status is_forum(DialogId dialog_id);
|
||||||
|
|
||||||
|
ForumTopicInfo *add_topic_info(DialogId dialog_id, unique_ptr<ForumTopicInfo> &&forum_topic_info);
|
||||||
|
|
||||||
|
ForumTopicInfo *get_topic_info(DialogId dialog_id, MessageId top_thread_message_id);
|
||||||
|
|
||||||
|
const ForumTopicInfo *get_topic_info(DialogId dialog_id, MessageId top_thread_message_id) const;
|
||||||
|
|
||||||
|
td_api::object_ptr<td_api::updateForumTopicInfo> get_update_forum_topic_info(DialogId dialog_id,
|
||||||
|
const ForumTopicInfo *topic_info) const;
|
||||||
|
|
||||||
|
void send_update_forum_topic_info(DialogId dialog_id, const ForumTopicInfo *topic_info) const;
|
||||||
|
|
||||||
|
Td *td_;
|
||||||
|
ActorShared<> parent_;
|
||||||
|
|
||||||
|
WaitFreeHashMap<DialogId, unique_ptr<DialogTopics>, DialogIdHash> dialog_topics_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace td
|
@ -42,6 +42,7 @@ class ContactsManager;
|
|||||||
class DownloadManager;
|
class DownloadManager;
|
||||||
class FileManager;
|
class FileManager;
|
||||||
class FileReferenceManager;
|
class FileReferenceManager;
|
||||||
|
class ForumTopicManager;
|
||||||
class GameManager;
|
class GameManager;
|
||||||
class GroupCallManager;
|
class GroupCallManager;
|
||||||
class LanguagePackManager;
|
class LanguagePackManager;
|
||||||
@ -303,6 +304,13 @@ class Global final : public ActorContext {
|
|||||||
file_reference_manager_ = std::move(file_reference_manager);
|
file_reference_manager_ = std::move(file_reference_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ActorId<ForumTopicManager> forum_topic_manager() const {
|
||||||
|
return forum_topic_manager_;
|
||||||
|
}
|
||||||
|
void set_forum_topic_manager(ActorId<ForumTopicManager> forum_topic_manager) {
|
||||||
|
forum_topic_manager_ = forum_topic_manager;
|
||||||
|
}
|
||||||
|
|
||||||
ActorId<GameManager> game_manager() const {
|
ActorId<GameManager> game_manager() const {
|
||||||
return game_manager_;
|
return game_manager_;
|
||||||
}
|
}
|
||||||
@ -532,6 +540,7 @@ class Global final : public ActorContext {
|
|||||||
ActorId<DownloadManager> download_manager_;
|
ActorId<DownloadManager> download_manager_;
|
||||||
ActorId<FileManager> file_manager_;
|
ActorId<FileManager> file_manager_;
|
||||||
ActorId<FileReferenceManager> file_reference_manager_;
|
ActorId<FileReferenceManager> file_reference_manager_;
|
||||||
|
ActorId<ForumTopicManager> forum_topic_manager_;
|
||||||
ActorId<GameManager> game_manager_;
|
ActorId<GameManager> game_manager_;
|
||||||
ActorId<GroupCallManager> group_call_manager_;
|
ActorId<GroupCallManager> group_call_manager_;
|
||||||
ActorId<LanguagePackManager> language_pack_manager_;
|
ActorId<LanguagePackManager> language_pack_manager_;
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "td/telegram/files/FileType.h"
|
#include "td/telegram/files/FileType.h"
|
||||||
#include "td/telegram/Game.h"
|
#include "td/telegram/Game.h"
|
||||||
#include "td/telegram/Global.h"
|
#include "td/telegram/Global.h"
|
||||||
|
#include "td/telegram/InputInvoice.h"
|
||||||
#include "td/telegram/InputMessageText.h"
|
#include "td/telegram/InputMessageText.h"
|
||||||
#include "td/telegram/Location.h"
|
#include "td/telegram/Location.h"
|
||||||
#include "td/telegram/MessageContent.h"
|
#include "td/telegram/MessageContent.h"
|
||||||
@ -27,7 +28,6 @@
|
|||||||
#include "td/telegram/MessagesManager.h"
|
#include "td/telegram/MessagesManager.h"
|
||||||
#include "td/telegram/misc.h"
|
#include "td/telegram/misc.h"
|
||||||
#include "td/telegram/net/DcId.h"
|
#include "td/telegram/net/DcId.h"
|
||||||
#include "td/telegram/Payments.h"
|
|
||||||
#include "td/telegram/Photo.h"
|
#include "td/telegram/Photo.h"
|
||||||
#include "td/telegram/PhotoFormat.h"
|
#include "td/telegram/PhotoFormat.h"
|
||||||
#include "td/telegram/PhotoSize.h"
|
#include "td/telegram/PhotoSize.h"
|
||||||
@ -377,8 +377,9 @@ Result<tl_object_ptr<telegram_api::InputBotInlineMessage>> InlineQueriesManager:
|
|||||||
return contact.get_input_bot_inline_message_media_contact(std::move(input_reply_markup));
|
return contact.get_input_bot_inline_message_media_contact(std::move(input_reply_markup));
|
||||||
}
|
}
|
||||||
if (constructor_id == td_api::inputMessageInvoice::ID) {
|
if (constructor_id == td_api::inputMessageInvoice::ID) {
|
||||||
TRY_RESULT(input_invoice, process_input_message_invoice(std::move(input_message_content), td_));
|
TRY_RESULT(input_invoice,
|
||||||
return get_input_bot_inline_message_media_invoice(input_invoice, std::move(input_reply_markup), td_);
|
InputInvoice::process_input_message_invoice(std::move(input_message_content), td_, DialogId(), false));
|
||||||
|
return input_invoice.get_input_bot_inline_message_media_invoice(std::move(input_reply_markup), td_);
|
||||||
}
|
}
|
||||||
if (constructor_id == td_api::inputMessageLocation::ID) {
|
if (constructor_id == td_api::inputMessageLocation::ID) {
|
||||||
TRY_RESULT(location, process_input_message_location(std::move(input_message_content)));
|
TRY_RESULT(location, process_input_message_location(std::move(input_message_content)));
|
||||||
@ -1948,7 +1949,7 @@ void InlineQueriesManager::save_recently_used_bots() {
|
|||||||
value += ',';
|
value += ',';
|
||||||
value_ids += ',';
|
value_ids += ',';
|
||||||
}
|
}
|
||||||
value += td_->contacts_manager_->get_user_username(bot_user_id);
|
value += td_->contacts_manager_->get_user_first_username(bot_user_id);
|
||||||
value_ids += to_string(bot_user_id.get());
|
value_ids += to_string(bot_user_id.get());
|
||||||
}
|
}
|
||||||
G()->td_db()->get_binlog_pmc()->set("recently_used_inline_bot_usernames", value);
|
G()->td_db()->get_binlog_pmc()->set("recently_used_inline_bot_usernames", value);
|
||||||
@ -2028,7 +2029,7 @@ void InlineQueriesManager::on_new_query(int64 query_id, UserId sender_user_id, L
|
|||||||
LOG(ERROR) << "Receive new inline query from invalid " << sender_user_id;
|
LOG(ERROR) << "Receive new inline query from invalid " << sender_user_id;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_IF(ERROR, !td_->contacts_manager_->have_user(sender_user_id)) << "Have no info about " << sender_user_id;
|
LOG_IF(ERROR, !td_->contacts_manager_->have_user(sender_user_id)) << "Receive unknown " << sender_user_id;
|
||||||
if (!td_->auth_manager_->is_bot()) {
|
if (!td_->auth_manager_->is_bot()) {
|
||||||
LOG(ERROR) << "Receive new inline query";
|
LOG(ERROR) << "Receive new inline query";
|
||||||
return;
|
return;
|
||||||
@ -2067,7 +2068,7 @@ void InlineQueriesManager::on_chosen_result(
|
|||||||
LOG(ERROR) << "Receive chosen inline query result from invalid " << user_id;
|
LOG(ERROR) << "Receive chosen inline query result from invalid " << user_id;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_IF(ERROR, !td_->contacts_manager_->have_user(user_id)) << "Have no info about " << user_id;
|
LOG_IF(ERROR, !td_->contacts_manager_->have_user(user_id)) << "Receive unknown " << user_id;
|
||||||
if (!td_->auth_manager_->is_bot()) {
|
if (!td_->auth_manager_->is_bot()) {
|
||||||
LOG(ERROR) << "Receive chosen inline query result";
|
LOG(ERROR) << "Receive chosen inline query result";
|
||||||
return;
|
return;
|
||||||
|
413
td/telegram/InputInvoice.cpp
Normal file
413
td/telegram/InputInvoice.cpp
Normal file
@ -0,0 +1,413 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#include "td/telegram/InputInvoice.h"
|
||||||
|
|
||||||
|
#include "td/telegram/Dimensions.h"
|
||||||
|
#include "td/telegram/files/FileManager.h"
|
||||||
|
#include "td/telegram/files/FileType.h"
|
||||||
|
#include "td/telegram/misc.h"
|
||||||
|
#include "td/telegram/PhotoSize.h"
|
||||||
|
#include "td/telegram/ServerMessageId.h"
|
||||||
|
#include "td/telegram/Td.h"
|
||||||
|
|
||||||
|
#include "td/utils/algorithm.h"
|
||||||
|
#include "td/utils/buffer.h"
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/HttpUrl.h"
|
||||||
|
#include "td/utils/logging.h"
|
||||||
|
#include "td/utils/MimeType.h"
|
||||||
|
#include "td/utils/PathView.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
bool operator==(const InputInvoice &lhs, const InputInvoice &rhs) {
|
||||||
|
auto are_invoice_equal = [](const InputInvoice::Invoice &lhs, const InputInvoice::Invoice &rhs) {
|
||||||
|
return lhs.is_test_ == rhs.is_test_ && lhs.need_name_ == rhs.need_name_ &&
|
||||||
|
lhs.need_phone_number_ == rhs.need_phone_number_ && lhs.need_email_address_ == rhs.need_email_address_ &&
|
||||||
|
lhs.need_shipping_address_ == rhs.need_shipping_address_ &&
|
||||||
|
lhs.send_phone_number_to_provider_ == rhs.send_phone_number_to_provider_ &&
|
||||||
|
lhs.send_email_address_to_provider_ == rhs.send_email_address_to_provider_ &&
|
||||||
|
lhs.is_flexible_ == rhs.is_flexible_ && lhs.currency_ == rhs.currency_ &&
|
||||||
|
lhs.price_parts_ == rhs.price_parts_ && lhs.max_tip_amount_ == rhs.max_tip_amount_ &&
|
||||||
|
lhs.suggested_tip_amounts_ == rhs.suggested_tip_amounts_ &&
|
||||||
|
lhs.recurring_payment_terms_of_service_url_ == rhs.recurring_payment_terms_of_service_url_;
|
||||||
|
};
|
||||||
|
|
||||||
|
return lhs.title_ == rhs.title_ && lhs.description_ == rhs.description_ && lhs.photo_ == rhs.photo_ &&
|
||||||
|
lhs.start_parameter_ == rhs.start_parameter_ && are_invoice_equal(lhs.invoice_, rhs.invoice_) &&
|
||||||
|
lhs.payload_ == rhs.payload_ && lhs.provider_token_ == rhs.provider_token_ &&
|
||||||
|
lhs.provider_data_ == rhs.provider_data_ && lhs.extended_media_ == rhs.extended_media_ &&
|
||||||
|
lhs.total_amount_ == rhs.total_amount_ && lhs.receipt_message_id_ == rhs.receipt_message_id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const InputInvoice &lhs, const InputInvoice &rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
InputInvoice::InputInvoice(tl_object_ptr<telegram_api::messageMediaInvoice> &&message_invoice, Td *td,
|
||||||
|
DialogId owner_dialog_id, FormattedText &&message) {
|
||||||
|
title_ = std::move(message_invoice->title_);
|
||||||
|
description_ = std::move(message_invoice->description_);
|
||||||
|
photo_ = get_web_document_photo(td->file_manager_.get(), std::move(message_invoice->photo_), owner_dialog_id);
|
||||||
|
start_parameter_ = std::move(message_invoice->start_param_);
|
||||||
|
invoice_.currency_ = std::move(message_invoice->currency_);
|
||||||
|
invoice_.is_test_ = message_invoice->test_;
|
||||||
|
invoice_.need_shipping_address_ = message_invoice->shipping_address_requested_;
|
||||||
|
// payload_ = string();
|
||||||
|
// provider_token_ = string();
|
||||||
|
// provider_data_ = string();
|
||||||
|
extended_media_ =
|
||||||
|
MessageExtendedMedia(td, std::move(message_invoice->extended_media_), std::move(message), owner_dialog_id);
|
||||||
|
if (message_invoice->total_amount_ <= 0 || !check_currency_amount(message_invoice->total_amount_)) {
|
||||||
|
LOG(ERROR) << "Receive invalid total amount " << message_invoice->total_amount_;
|
||||||
|
message_invoice->total_amount_ = 0;
|
||||||
|
}
|
||||||
|
total_amount_ = message_invoice->total_amount_;
|
||||||
|
if ((message_invoice->flags_ & telegram_api::messageMediaInvoice::RECEIPT_MSG_ID_MASK) != 0) {
|
||||||
|
receipt_message_id_ = MessageId(ServerMessageId(message_invoice->receipt_msg_id_));
|
||||||
|
if (!receipt_message_id_.is_valid()) {
|
||||||
|
LOG(ERROR) << "Receive as receipt message " << receipt_message_id_ << " in " << owner_dialog_id;
|
||||||
|
receipt_message_id_ = MessageId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InputInvoice::InputInvoice(tl_object_ptr<telegram_api::botInlineMessageMediaInvoice> &&message_invoice, Td *td,
|
||||||
|
DialogId owner_dialog_id) {
|
||||||
|
title_ = std::move(message_invoice->title_);
|
||||||
|
description_ = std::move(message_invoice->description_);
|
||||||
|
photo_ = get_web_document_photo(td->file_manager_.get(), std::move(message_invoice->photo_), owner_dialog_id);
|
||||||
|
// start_parameter_ = string();
|
||||||
|
invoice_.currency_ = std::move(message_invoice->currency_);
|
||||||
|
invoice_.is_test_ = message_invoice->test_;
|
||||||
|
invoice_.need_shipping_address_ = message_invoice->shipping_address_requested_;
|
||||||
|
// payload_ = string();
|
||||||
|
// provider_token_ = string();
|
||||||
|
// provider_data_ = string();
|
||||||
|
// extended_media_ = MessageExtendedMedia();
|
||||||
|
if (message_invoice->total_amount_ <= 0 || !check_currency_amount(message_invoice->total_amount_)) {
|
||||||
|
LOG(ERROR) << "Receive invalid total amount " << message_invoice->total_amount_;
|
||||||
|
message_invoice->total_amount_ = 0;
|
||||||
|
}
|
||||||
|
total_amount_ = message_invoice->total_amount_;
|
||||||
|
// receipt_message_id_ = MessageId();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<InputInvoice> InputInvoice::process_input_message_invoice(
|
||||||
|
td_api::object_ptr<td_api::InputMessageContent> &&input_message_content, Td *td, DialogId owner_dialog_id,
|
||||||
|
bool is_premium) {
|
||||||
|
CHECK(input_message_content != nullptr);
|
||||||
|
CHECK(input_message_content->get_id() == td_api::inputMessageInvoice::ID);
|
||||||
|
auto input_invoice = move_tl_object_as<td_api::inputMessageInvoice>(input_message_content);
|
||||||
|
if (input_invoice->invoice_ == nullptr) {
|
||||||
|
return Status::Error(400, "Invoice must be non-empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!clean_input_string(input_invoice->title_)) {
|
||||||
|
return Status::Error(400, "Invoice title must be encoded in UTF-8");
|
||||||
|
}
|
||||||
|
if (!clean_input_string(input_invoice->description_)) {
|
||||||
|
return Status::Error(400, "Invoice description must be encoded in UTF-8");
|
||||||
|
}
|
||||||
|
if (!clean_input_string(input_invoice->photo_url_)) {
|
||||||
|
return Status::Error(400, "Invoice photo URL must be encoded in UTF-8");
|
||||||
|
}
|
||||||
|
if (!clean_input_string(input_invoice->start_parameter_)) {
|
||||||
|
return Status::Error(400, "Invoice bot start parameter must be encoded in UTF-8");
|
||||||
|
}
|
||||||
|
if (!clean_input_string(input_invoice->provider_token_)) {
|
||||||
|
return Status::Error(400, "Invoice provider token must be encoded in UTF-8");
|
||||||
|
}
|
||||||
|
if (!clean_input_string(input_invoice->provider_data_)) {
|
||||||
|
return Status::Error(400, "Invoice provider data must be encoded in UTF-8");
|
||||||
|
}
|
||||||
|
if (!clean_input_string(input_invoice->invoice_->currency_)) {
|
||||||
|
return Status::Error(400, "Invoice currency must be encoded in UTF-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
InputInvoice result;
|
||||||
|
result.title_ = std::move(input_invoice->title_);
|
||||||
|
result.description_ = std::move(input_invoice->description_);
|
||||||
|
|
||||||
|
auto r_http_url = parse_url(input_invoice->photo_url_);
|
||||||
|
if (r_http_url.is_error()) {
|
||||||
|
if (!input_invoice->photo_url_.empty()) {
|
||||||
|
LOG(INFO) << "Can't register url " << input_invoice->photo_url_;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto url = r_http_url.ok().get_url();
|
||||||
|
auto r_invoice_file_id = td->file_manager_->from_persistent_id(url, FileType::Temp);
|
||||||
|
if (r_invoice_file_id.is_error()) {
|
||||||
|
LOG(INFO) << "Can't register url " << url;
|
||||||
|
} else {
|
||||||
|
auto invoice_file_id = r_invoice_file_id.move_as_ok();
|
||||||
|
|
||||||
|
PhotoSize s;
|
||||||
|
s.type = 'n';
|
||||||
|
s.dimensions = get_dimensions(input_invoice->photo_width_, input_invoice->photo_height_, nullptr);
|
||||||
|
s.size = input_invoice->photo_size_; // TODO use invoice_file_id size
|
||||||
|
s.file_id = invoice_file_id;
|
||||||
|
|
||||||
|
result.photo_.id = 0;
|
||||||
|
result.photo_.photos.push_back(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.start_parameter_ = std::move(input_invoice->start_parameter_);
|
||||||
|
|
||||||
|
result.invoice_.currency_ = std::move(input_invoice->invoice_->currency_);
|
||||||
|
result.invoice_.price_parts_.reserve(input_invoice->invoice_->price_parts_.size());
|
||||||
|
int64 total_amount = 0;
|
||||||
|
for (auto &price : input_invoice->invoice_->price_parts_) {
|
||||||
|
if (!clean_input_string(price->label_)) {
|
||||||
|
return Status::Error(400, "Invoice price label must be encoded in UTF-8");
|
||||||
|
}
|
||||||
|
if (!check_currency_amount(price->amount_)) {
|
||||||
|
return Status::Error(400, "Too big amount of the currency specified");
|
||||||
|
}
|
||||||
|
result.invoice_.price_parts_.emplace_back(std::move(price->label_), price->amount_);
|
||||||
|
total_amount += price->amount_;
|
||||||
|
}
|
||||||
|
if (total_amount <= 0) {
|
||||||
|
return Status::Error(400, "Total price must be positive");
|
||||||
|
}
|
||||||
|
if (!check_currency_amount(total_amount)) {
|
||||||
|
return Status::Error(400, "Total price is too big");
|
||||||
|
}
|
||||||
|
result.total_amount_ = total_amount;
|
||||||
|
|
||||||
|
if (input_invoice->invoice_->max_tip_amount_ < 0 ||
|
||||||
|
!check_currency_amount(input_invoice->invoice_->max_tip_amount_)) {
|
||||||
|
return Status::Error(400, "Invalid max_tip_amount of the currency specified");
|
||||||
|
}
|
||||||
|
for (auto tip_amount : input_invoice->invoice_->suggested_tip_amounts_) {
|
||||||
|
if (tip_amount <= 0) {
|
||||||
|
return Status::Error(400, "Suggested tip amount must be positive");
|
||||||
|
}
|
||||||
|
if (tip_amount > input_invoice->invoice_->max_tip_amount_) {
|
||||||
|
return Status::Error(400, "Suggested tip amount can't be bigger than max_tip_amount");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (input_invoice->invoice_->suggested_tip_amounts_.size() > 4) {
|
||||||
|
return Status::Error(400, "There can be at most 4 suggested tip amounts");
|
||||||
|
}
|
||||||
|
|
||||||
|
result.invoice_.max_tip_amount_ = input_invoice->invoice_->max_tip_amount_;
|
||||||
|
result.invoice_.suggested_tip_amounts_ = std::move(input_invoice->invoice_->suggested_tip_amounts_);
|
||||||
|
result.invoice_.recurring_payment_terms_of_service_url_ =
|
||||||
|
std::move(input_invoice->invoice_->recurring_payment_terms_of_service_url_);
|
||||||
|
result.invoice_.is_test_ = input_invoice->invoice_->is_test_;
|
||||||
|
result.invoice_.need_name_ = input_invoice->invoice_->need_name_;
|
||||||
|
result.invoice_.need_phone_number_ = input_invoice->invoice_->need_phone_number_;
|
||||||
|
result.invoice_.need_email_address_ = input_invoice->invoice_->need_email_address_;
|
||||||
|
result.invoice_.need_shipping_address_ = input_invoice->invoice_->need_shipping_address_;
|
||||||
|
result.invoice_.send_phone_number_to_provider_ = input_invoice->invoice_->send_phone_number_to_provider_;
|
||||||
|
result.invoice_.send_email_address_to_provider_ = input_invoice->invoice_->send_email_address_to_provider_;
|
||||||
|
result.invoice_.is_flexible_ = input_invoice->invoice_->is_flexible_;
|
||||||
|
if (result.invoice_.send_phone_number_to_provider_) {
|
||||||
|
result.invoice_.need_phone_number_ = true;
|
||||||
|
}
|
||||||
|
if (result.invoice_.send_email_address_to_provider_) {
|
||||||
|
result.invoice_.need_email_address_ = true;
|
||||||
|
}
|
||||||
|
if (result.invoice_.is_flexible_) {
|
||||||
|
result.invoice_.need_shipping_address_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.payload_ = std::move(input_invoice->payload_);
|
||||||
|
result.provider_token_ = std::move(input_invoice->provider_token_);
|
||||||
|
result.provider_data_ = std::move(input_invoice->provider_data_);
|
||||||
|
|
||||||
|
TRY_RESULT(extended_media, MessageExtendedMedia::get_message_extended_media(
|
||||||
|
td, std::move(input_invoice->extended_media_content_), owner_dialog_id, is_premium));
|
||||||
|
result.extended_media_ = std::move(extended_media);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
tl_object_ptr<td_api::messageInvoice> InputInvoice::get_message_invoice_object(Td *td, bool skip_bot_commands,
|
||||||
|
int32 max_media_timestamp) const {
|
||||||
|
return make_tl_object<td_api::messageInvoice>(
|
||||||
|
title_, get_product_description_object(description_), get_photo_object(td->file_manager_.get(), photo_),
|
||||||
|
invoice_.currency_, total_amount_, start_parameter_, invoice_.is_test_, invoice_.need_shipping_address_,
|
||||||
|
receipt_message_id_.get(),
|
||||||
|
extended_media_.get_message_extended_media_object(td, skip_bot_commands, max_media_timestamp));
|
||||||
|
}
|
||||||
|
|
||||||
|
tl_object_ptr<telegram_api::invoice> InputInvoice::Invoice::get_input_invoice() const {
|
||||||
|
int32 flags = 0;
|
||||||
|
if (is_test_) {
|
||||||
|
flags |= telegram_api::invoice::TEST_MASK;
|
||||||
|
}
|
||||||
|
if (need_name_) {
|
||||||
|
flags |= telegram_api::invoice::NAME_REQUESTED_MASK;
|
||||||
|
}
|
||||||
|
if (need_phone_number_) {
|
||||||
|
flags |= telegram_api::invoice::PHONE_REQUESTED_MASK;
|
||||||
|
}
|
||||||
|
if (need_email_address_) {
|
||||||
|
flags |= telegram_api::invoice::EMAIL_REQUESTED_MASK;
|
||||||
|
}
|
||||||
|
if (need_shipping_address_) {
|
||||||
|
flags |= telegram_api::invoice::SHIPPING_ADDRESS_REQUESTED_MASK;
|
||||||
|
}
|
||||||
|
if (send_phone_number_to_provider_) {
|
||||||
|
flags |= telegram_api::invoice::PHONE_TO_PROVIDER_MASK;
|
||||||
|
}
|
||||||
|
if (send_email_address_to_provider_) {
|
||||||
|
flags |= telegram_api::invoice::EMAIL_TO_PROVIDER_MASK;
|
||||||
|
}
|
||||||
|
if (is_flexible_) {
|
||||||
|
flags |= telegram_api::invoice::FLEXIBLE_MASK;
|
||||||
|
}
|
||||||
|
if (max_tip_amount_ != 0) {
|
||||||
|
flags |= telegram_api::invoice::MAX_TIP_AMOUNT_MASK;
|
||||||
|
}
|
||||||
|
if (!recurring_payment_terms_of_service_url_.empty()) {
|
||||||
|
flags |= telegram_api::invoice::RECURRING_TERMS_URL_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto prices = transform(price_parts_, [](const LabeledPricePart &price) {
|
||||||
|
return telegram_api::make_object<telegram_api::labeledPrice>(price.label, price.amount);
|
||||||
|
});
|
||||||
|
return make_tl_object<telegram_api::invoice>(
|
||||||
|
flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
||||||
|
false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, currency_, std::move(prices),
|
||||||
|
max_tip_amount_, vector<int64>(suggested_tip_amounts_), recurring_payment_terms_of_service_url_);
|
||||||
|
}
|
||||||
|
|
||||||
|
static tl_object_ptr<telegram_api::inputWebDocument> get_input_web_document(const FileManager *file_manager,
|
||||||
|
const Photo &photo) {
|
||||||
|
if (photo.is_empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(photo.photos.size() == 1);
|
||||||
|
const PhotoSize &size = photo.photos[0];
|
||||||
|
CHECK(size.file_id.is_valid());
|
||||||
|
|
||||||
|
vector<tl_object_ptr<telegram_api::DocumentAttribute>> attributes;
|
||||||
|
if (size.dimensions.width != 0 && size.dimensions.height != 0) {
|
||||||
|
attributes.push_back(
|
||||||
|
make_tl_object<telegram_api::documentAttributeImageSize>(size.dimensions.width, size.dimensions.height));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto file_view = file_manager->get_file_view(size.file_id);
|
||||||
|
CHECK(file_view.has_url());
|
||||||
|
|
||||||
|
auto file_name = get_url_file_name(file_view.url());
|
||||||
|
return make_tl_object<telegram_api::inputWebDocument>(
|
||||||
|
file_view.url(), size.size, MimeType::from_extension(PathView(file_name).extension(), "image/jpeg"),
|
||||||
|
std::move(attributes));
|
||||||
|
}
|
||||||
|
|
||||||
|
tl_object_ptr<telegram_api::inputMediaInvoice> InputInvoice::get_input_media_invoice(
|
||||||
|
Td *td, tl_object_ptr<telegram_api::InputFile> input_file,
|
||||||
|
tl_object_ptr<telegram_api::InputFile> input_thumbnail) const {
|
||||||
|
int32 flags = 0;
|
||||||
|
if (!start_parameter_.empty()) {
|
||||||
|
flags |= telegram_api::inputMediaInvoice::START_PARAM_MASK;
|
||||||
|
}
|
||||||
|
auto input_web_document = get_input_web_document(td->file_manager_.get(), photo_);
|
||||||
|
if (input_web_document != nullptr) {
|
||||||
|
flags |= telegram_api::inputMediaInvoice::PHOTO_MASK;
|
||||||
|
}
|
||||||
|
telegram_api::object_ptr<telegram_api::InputMedia> extended_media;
|
||||||
|
if (!extended_media_.is_empty()) {
|
||||||
|
flags |= telegram_api::inputMediaInvoice::EXTENDED_MEDIA_MASK;
|
||||||
|
extended_media = extended_media_.get_input_media(td, std::move(input_file), std::move(input_thumbnail));
|
||||||
|
if (extended_media == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return make_tl_object<telegram_api::inputMediaInvoice>(
|
||||||
|
flags, title_, description_, std::move(input_web_document), invoice_.get_input_invoice(), BufferSlice(payload_),
|
||||||
|
provider_token_,
|
||||||
|
telegram_api::make_object<telegram_api::dataJSON>(provider_data_.empty() ? "null" : provider_data_),
|
||||||
|
start_parameter_, std::move(extended_media));
|
||||||
|
}
|
||||||
|
|
||||||
|
tl_object_ptr<telegram_api::inputBotInlineMessageMediaInvoice> InputInvoice::get_input_bot_inline_message_media_invoice(
|
||||||
|
tl_object_ptr<telegram_api::ReplyMarkup> &&reply_markup, Td *td) const {
|
||||||
|
int32 flags = 0;
|
||||||
|
if (reply_markup != nullptr) {
|
||||||
|
flags |= telegram_api::inputBotInlineMessageMediaInvoice::REPLY_MARKUP_MASK;
|
||||||
|
}
|
||||||
|
auto input_web_document = get_input_web_document(td->file_manager_.get(), photo_);
|
||||||
|
if (input_web_document != nullptr) {
|
||||||
|
flags |= telegram_api::inputBotInlineMessageMediaInvoice::PHOTO_MASK;
|
||||||
|
}
|
||||||
|
return make_tl_object<telegram_api::inputBotInlineMessageMediaInvoice>(
|
||||||
|
flags, title_, description_, std::move(input_web_document), invoice_.get_input_invoice(), BufferSlice(payload_),
|
||||||
|
provider_token_,
|
||||||
|
telegram_api::make_object<telegram_api::dataJSON>(provider_data_.empty() ? "null" : provider_data_),
|
||||||
|
std::move(reply_markup));
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<FileId> InputInvoice::get_file_ids(const Td *td) const {
|
||||||
|
auto file_ids = photo_get_file_ids(photo_);
|
||||||
|
extended_media_.append_file_ids(td, file_ids);
|
||||||
|
return file_ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputInvoice::delete_thumbnail(Td *td) {
|
||||||
|
extended_media_.delete_thumbnail(td);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputInvoice::need_reget() const {
|
||||||
|
return extended_media_.need_reget();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputInvoice::has_media_timestamp() const {
|
||||||
|
return extended_media_.has_media_timestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputInvoice::is_equal_but_different(const InputInvoice &other) const {
|
||||||
|
return extended_media_.is_equal_but_different(other.extended_media_);
|
||||||
|
}
|
||||||
|
|
||||||
|
const FormattedText *InputInvoice::get_caption() const {
|
||||||
|
return extended_media_.get_caption();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 InputInvoice::get_duration(const Td *td) const {
|
||||||
|
return extended_media_.get_duration(td);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileId InputInvoice::get_upload_file_id() const {
|
||||||
|
return extended_media_.get_upload_file_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
FileId InputInvoice::get_any_file_id() const {
|
||||||
|
return extended_media_.get_any_file_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
FileId InputInvoice::get_thumbnail_file_id(const Td *td) const {
|
||||||
|
return extended_media_.get_thumbnail_file_id(td);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputInvoice::update_from(const InputInvoice &old_input_invoice) {
|
||||||
|
extended_media_.update_from(old_input_invoice.extended_media_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputInvoice::update_extended_media(telegram_api::object_ptr<telegram_api::MessageExtendedMedia> extended_media,
|
||||||
|
DialogId owner_dialog_id, Td *td) {
|
||||||
|
return extended_media_.update_to(td, std::move(extended_media), owner_dialog_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputInvoice::need_poll_extended_media() const {
|
||||||
|
return extended_media_.need_poll();
|
||||||
|
}
|
||||||
|
|
||||||
|
tl_object_ptr<td_api::formattedText> get_product_description_object(const string &description) {
|
||||||
|
FormattedText result;
|
||||||
|
result.text = description;
|
||||||
|
result.entities = find_entities(result.text, true, true);
|
||||||
|
return get_formatted_text_object(result, true, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
133
td/telegram/InputInvoice.h
Normal file
133
td/telegram/InputInvoice.h
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/DialogId.h"
|
||||||
|
#include "td/telegram/files/FileId.h"
|
||||||
|
#include "td/telegram/LabeledPricePart.h"
|
||||||
|
#include "td/telegram/MessageExtendedMedia.h"
|
||||||
|
#include "td/telegram/MessageId.h"
|
||||||
|
#include "td/telegram/Photo.h"
|
||||||
|
#include "td/telegram/td_api.h"
|
||||||
|
#include "td/telegram/telegram_api.h"
|
||||||
|
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/Status.h"
|
||||||
|
#include "td/utils/StringBuilder.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class Td;
|
||||||
|
|
||||||
|
class InputInvoice {
|
||||||
|
struct Invoice {
|
||||||
|
string currency_;
|
||||||
|
vector<LabeledPricePart> price_parts_;
|
||||||
|
int64 max_tip_amount_ = 0;
|
||||||
|
vector<int64> suggested_tip_amounts_;
|
||||||
|
string recurring_payment_terms_of_service_url_;
|
||||||
|
bool is_test_ = false;
|
||||||
|
bool need_name_ = false;
|
||||||
|
bool need_phone_number_ = false;
|
||||||
|
bool need_email_address_ = false;
|
||||||
|
bool need_shipping_address_ = false;
|
||||||
|
bool send_phone_number_to_provider_ = false;
|
||||||
|
bool send_email_address_to_provider_ = false;
|
||||||
|
bool is_flexible_ = false;
|
||||||
|
|
||||||
|
Invoice() = default;
|
||||||
|
Invoice(string &¤cy, bool is_test, bool need_shipping_address)
|
||||||
|
: currency_(std::move(currency)), is_test_(is_test), need_shipping_address_(need_shipping_address) {
|
||||||
|
}
|
||||||
|
|
||||||
|
tl_object_ptr<telegram_api::invoice> get_input_invoice() const;
|
||||||
|
|
||||||
|
template <class StorerT>
|
||||||
|
void store(StorerT &storer) const;
|
||||||
|
|
||||||
|
template <class ParserT>
|
||||||
|
void parse(ParserT &parser);
|
||||||
|
};
|
||||||
|
|
||||||
|
string title_;
|
||||||
|
string description_;
|
||||||
|
Photo photo_;
|
||||||
|
string start_parameter_;
|
||||||
|
Invoice invoice_;
|
||||||
|
string payload_;
|
||||||
|
string provider_token_;
|
||||||
|
string provider_data_;
|
||||||
|
MessageExtendedMedia extended_media_;
|
||||||
|
|
||||||
|
int64 total_amount_ = 0;
|
||||||
|
MessageId receipt_message_id_;
|
||||||
|
|
||||||
|
friend bool operator==(const InputInvoice &lhs, const InputInvoice &rhs);
|
||||||
|
|
||||||
|
public:
|
||||||
|
InputInvoice() = default;
|
||||||
|
|
||||||
|
InputInvoice(tl_object_ptr<telegram_api::messageMediaInvoice> &&message_invoice, Td *td, DialogId owner_dialog_id,
|
||||||
|
FormattedText &&message);
|
||||||
|
|
||||||
|
InputInvoice(tl_object_ptr<telegram_api::botInlineMessageMediaInvoice> &&message_invoice, Td *td,
|
||||||
|
DialogId owner_dialog_id);
|
||||||
|
|
||||||
|
static Result<InputInvoice> process_input_message_invoice(
|
||||||
|
td_api::object_ptr<td_api::InputMessageContent> &&input_message_content, Td *td, DialogId owner_dialog_id,
|
||||||
|
bool is_premium);
|
||||||
|
|
||||||
|
tl_object_ptr<td_api::messageInvoice> get_message_invoice_object(Td *td, bool skip_bot_commands,
|
||||||
|
int32 max_media_timestamp) const;
|
||||||
|
|
||||||
|
tl_object_ptr<telegram_api::inputMediaInvoice> get_input_media_invoice(
|
||||||
|
Td *td, tl_object_ptr<telegram_api::InputFile> input_file,
|
||||||
|
tl_object_ptr<telegram_api::InputFile> input_thumbnail) const;
|
||||||
|
|
||||||
|
tl_object_ptr<telegram_api::inputBotInlineMessageMediaInvoice> get_input_bot_inline_message_media_invoice(
|
||||||
|
tl_object_ptr<telegram_api::ReplyMarkup> &&reply_markup, Td *td) const;
|
||||||
|
|
||||||
|
vector<FileId> get_file_ids(const Td *td) const;
|
||||||
|
|
||||||
|
void delete_thumbnail(Td *td);
|
||||||
|
|
||||||
|
bool need_reget() const;
|
||||||
|
|
||||||
|
bool has_media_timestamp() const;
|
||||||
|
|
||||||
|
bool is_equal_but_different(const InputInvoice &other) const;
|
||||||
|
|
||||||
|
const FormattedText *get_caption() const;
|
||||||
|
|
||||||
|
int32 get_duration(const Td *td) const;
|
||||||
|
|
||||||
|
FileId get_upload_file_id() const;
|
||||||
|
|
||||||
|
FileId get_any_file_id() const;
|
||||||
|
|
||||||
|
FileId get_thumbnail_file_id(const Td *td) const;
|
||||||
|
|
||||||
|
void update_from(const InputInvoice &old_input_invoice);
|
||||||
|
|
||||||
|
bool update_extended_media(telegram_api::object_ptr<telegram_api::MessageExtendedMedia> extended_media,
|
||||||
|
DialogId owner_dialog_id, Td *td);
|
||||||
|
|
||||||
|
bool need_poll_extended_media() const;
|
||||||
|
|
||||||
|
template <class StorerT>
|
||||||
|
void store(StorerT &storer) const;
|
||||||
|
|
||||||
|
template <class ParserT>
|
||||||
|
void parse(ParserT &parser);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(const InputInvoice &lhs, const InputInvoice &rhs);
|
||||||
|
bool operator!=(const InputInvoice &lhs, const InputInvoice &rhs);
|
||||||
|
|
||||||
|
tl_object_ptr<td_api::formattedText> get_product_description_object(const string &description);
|
||||||
|
|
||||||
|
} // namespace td
|
195
td/telegram/InputInvoice.hpp
Normal file
195
td/telegram/InputInvoice.hpp
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/InputInvoice.h"
|
||||||
|
|
||||||
|
#include "td/telegram/MessageExtendedMedia.hpp"
|
||||||
|
#include "td/telegram/Photo.hpp"
|
||||||
|
#include "td/telegram/Version.h"
|
||||||
|
|
||||||
|
#include "td/utils/tl_helpers.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
template <class StorerT>
|
||||||
|
void InputInvoice::Invoice::store(StorerT &storer) const {
|
||||||
|
using td::store;
|
||||||
|
bool has_tip = max_tip_amount_ != 0;
|
||||||
|
bool is_recurring = !recurring_payment_terms_of_service_url_.empty();
|
||||||
|
BEGIN_STORE_FLAGS();
|
||||||
|
STORE_FLAG(is_test_);
|
||||||
|
STORE_FLAG(need_name_);
|
||||||
|
STORE_FLAG(need_phone_number_);
|
||||||
|
STORE_FLAG(need_email_address_);
|
||||||
|
STORE_FLAG(need_shipping_address_);
|
||||||
|
STORE_FLAG(is_flexible_);
|
||||||
|
STORE_FLAG(send_phone_number_to_provider_);
|
||||||
|
STORE_FLAG(send_email_address_to_provider_);
|
||||||
|
STORE_FLAG(has_tip);
|
||||||
|
STORE_FLAG(is_recurring);
|
||||||
|
END_STORE_FLAGS();
|
||||||
|
store(currency_, storer);
|
||||||
|
store(price_parts_, storer);
|
||||||
|
if (has_tip) {
|
||||||
|
store(max_tip_amount_, storer);
|
||||||
|
store(suggested_tip_amounts_, storer);
|
||||||
|
}
|
||||||
|
if (is_recurring) {
|
||||||
|
store(recurring_payment_terms_of_service_url_, storer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ParserT>
|
||||||
|
void InputInvoice::Invoice::parse(ParserT &parser) {
|
||||||
|
using td::parse;
|
||||||
|
bool has_tip;
|
||||||
|
bool is_recurring;
|
||||||
|
BEGIN_PARSE_FLAGS();
|
||||||
|
PARSE_FLAG(is_test_);
|
||||||
|
PARSE_FLAG(need_name_);
|
||||||
|
PARSE_FLAG(need_phone_number_);
|
||||||
|
PARSE_FLAG(need_email_address_);
|
||||||
|
PARSE_FLAG(need_shipping_address_);
|
||||||
|
PARSE_FLAG(is_flexible_);
|
||||||
|
PARSE_FLAG(send_phone_number_to_provider_);
|
||||||
|
PARSE_FLAG(send_email_address_to_provider_);
|
||||||
|
PARSE_FLAG(has_tip);
|
||||||
|
PARSE_FLAG(is_recurring);
|
||||||
|
END_PARSE_FLAGS();
|
||||||
|
parse(currency_, parser);
|
||||||
|
parse(price_parts_, parser);
|
||||||
|
if (has_tip) {
|
||||||
|
parse(max_tip_amount_, parser);
|
||||||
|
parse(suggested_tip_amounts_, parser);
|
||||||
|
}
|
||||||
|
if (is_recurring) {
|
||||||
|
parse(recurring_payment_terms_of_service_url_, parser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class StorerT>
|
||||||
|
void InputInvoice::store(StorerT &storer) const {
|
||||||
|
using td::store;
|
||||||
|
bool has_description = !description_.empty();
|
||||||
|
bool has_photo = !photo_.is_empty();
|
||||||
|
bool has_start_parameter = !start_parameter_.empty();
|
||||||
|
bool has_payload = !payload_.empty();
|
||||||
|
bool has_provider_token = !provider_token_.empty();
|
||||||
|
bool has_provider_data = !provider_data_.empty();
|
||||||
|
bool has_total_amount = total_amount_ != 0;
|
||||||
|
bool has_receipt_message_id = receipt_message_id_.is_valid();
|
||||||
|
bool has_extended_media = !extended_media_.is_empty();
|
||||||
|
BEGIN_STORE_FLAGS();
|
||||||
|
STORE_FLAG(has_description);
|
||||||
|
STORE_FLAG(has_photo);
|
||||||
|
STORE_FLAG(has_start_parameter);
|
||||||
|
STORE_FLAG(has_payload);
|
||||||
|
STORE_FLAG(has_provider_token);
|
||||||
|
STORE_FLAG(has_provider_data);
|
||||||
|
STORE_FLAG(has_total_amount);
|
||||||
|
STORE_FLAG(has_receipt_message_id);
|
||||||
|
STORE_FLAG(has_extended_media);
|
||||||
|
END_STORE_FLAGS();
|
||||||
|
store(title_, storer);
|
||||||
|
if (has_description) {
|
||||||
|
store(description_, storer);
|
||||||
|
}
|
||||||
|
if (has_photo) {
|
||||||
|
store(photo_, storer);
|
||||||
|
}
|
||||||
|
if (has_start_parameter) {
|
||||||
|
store(start_parameter_, storer);
|
||||||
|
}
|
||||||
|
store(invoice_, storer);
|
||||||
|
if (has_payload) {
|
||||||
|
store(payload_, storer);
|
||||||
|
}
|
||||||
|
if (has_provider_token) {
|
||||||
|
store(provider_token_, storer);
|
||||||
|
}
|
||||||
|
if (has_provider_data) {
|
||||||
|
store(provider_data_, storer);
|
||||||
|
}
|
||||||
|
if (has_total_amount) {
|
||||||
|
store(total_amount_, storer);
|
||||||
|
}
|
||||||
|
if (has_receipt_message_id) {
|
||||||
|
store(receipt_message_id_, storer);
|
||||||
|
}
|
||||||
|
if (has_extended_media) {
|
||||||
|
store(extended_media_, storer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ParserT>
|
||||||
|
void InputInvoice::parse(ParserT &parser) {
|
||||||
|
using td::parse;
|
||||||
|
bool has_description;
|
||||||
|
bool has_photo;
|
||||||
|
bool has_start_parameter;
|
||||||
|
bool has_payload;
|
||||||
|
bool has_provider_token;
|
||||||
|
bool has_provider_data;
|
||||||
|
bool has_total_amount;
|
||||||
|
bool has_receipt_message_id;
|
||||||
|
bool has_extended_media;
|
||||||
|
if (parser.version() >= static_cast<int32>(Version::AddInputInvoiceFlags)) {
|
||||||
|
BEGIN_PARSE_FLAGS();
|
||||||
|
PARSE_FLAG(has_description);
|
||||||
|
PARSE_FLAG(has_photo);
|
||||||
|
PARSE_FLAG(has_start_parameter);
|
||||||
|
PARSE_FLAG(has_payload);
|
||||||
|
PARSE_FLAG(has_provider_token);
|
||||||
|
PARSE_FLAG(has_provider_data);
|
||||||
|
PARSE_FLAG(has_total_amount);
|
||||||
|
PARSE_FLAG(has_receipt_message_id);
|
||||||
|
PARSE_FLAG(has_extended_media);
|
||||||
|
END_PARSE_FLAGS();
|
||||||
|
} else {
|
||||||
|
has_description = true;
|
||||||
|
has_photo = true;
|
||||||
|
has_start_parameter = true;
|
||||||
|
has_payload = true;
|
||||||
|
has_provider_token = true;
|
||||||
|
has_provider_data = parser.version() >= static_cast<int32>(Version::AddMessageInvoiceProviderData);
|
||||||
|
has_total_amount = true;
|
||||||
|
has_receipt_message_id = true;
|
||||||
|
has_extended_media = false;
|
||||||
|
}
|
||||||
|
parse(title_, parser);
|
||||||
|
if (has_description) {
|
||||||
|
parse(description_, parser);
|
||||||
|
}
|
||||||
|
if (has_photo) {
|
||||||
|
parse(photo_, parser);
|
||||||
|
}
|
||||||
|
if (has_start_parameter) {
|
||||||
|
parse(start_parameter_, parser);
|
||||||
|
}
|
||||||
|
parse(invoice_, parser);
|
||||||
|
if (has_payload) {
|
||||||
|
parse(payload_, parser);
|
||||||
|
}
|
||||||
|
if (has_provider_token) {
|
||||||
|
parse(provider_token_, parser);
|
||||||
|
}
|
||||||
|
if (has_provider_data) {
|
||||||
|
parse(provider_data_, parser);
|
||||||
|
}
|
||||||
|
if (has_total_amount) {
|
||||||
|
parse(total_amount_, parser);
|
||||||
|
}
|
||||||
|
if (has_receipt_message_id) {
|
||||||
|
parse(receipt_message_id_, parser);
|
||||||
|
}
|
||||||
|
if (has_extended_media) {
|
||||||
|
parse(extended_media_, parser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
47
td/telegram/LabeledPricePart.h
Normal file
47
td/telegram/LabeledPricePart.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/StringBuilder.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
struct LabeledPricePart {
|
||||||
|
string label;
|
||||||
|
int64 amount = 0;
|
||||||
|
|
||||||
|
LabeledPricePart() = default;
|
||||||
|
LabeledPricePart(string &&label, int64 amount) : label(std::move(label)), amount(amount) {
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class StorerT>
|
||||||
|
void store(StorerT &storer) const {
|
||||||
|
storer.store_string(label);
|
||||||
|
storer.store_binary(amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ParserT>
|
||||||
|
void parse(ParserT &parser) {
|
||||||
|
label = parser.template fetch_string<string>();
|
||||||
|
amount = parser.fetch_long();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator==(const LabeledPricePart &lhs, const LabeledPricePart &rhs) {
|
||||||
|
return lhs.label == rhs.label && lhs.amount == rhs.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(const LabeledPricePart &lhs, const LabeledPricePart &rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline StringBuilder &operator<<(StringBuilder &string_builder, const LabeledPricePart &labeled_price_part) {
|
||||||
|
return string_builder << '[' << labeled_price_part.label << ": " << labeled_price_part.amount << ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
@ -7,6 +7,7 @@
|
|||||||
#include "td/telegram/LinkManager.h"
|
#include "td/telegram/LinkManager.h"
|
||||||
|
|
||||||
#include "td/telegram/AccessRights.h"
|
#include "td/telegram/AccessRights.h"
|
||||||
|
#include "td/telegram/BackgroundType.h"
|
||||||
#include "td/telegram/ChannelId.h"
|
#include "td/telegram/ChannelId.h"
|
||||||
#include "td/telegram/ChannelType.h"
|
#include "td/telegram/ChannelType.h"
|
||||||
#include "td/telegram/ConfigManager.h"
|
#include "td/telegram/ConfigManager.h"
|
||||||
@ -45,30 +46,6 @@ static bool is_valid_start_parameter(Slice start_parameter) {
|
|||||||
return start_parameter.size() <= 64 && is_base64url_characters(start_parameter);
|
return start_parameter.size() <= 64 && is_base64url_characters(start_parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_valid_username(Slice username) {
|
|
||||||
if (username.empty() || username.size() > 32) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!is_alpha(username[0])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (auto c : username) {
|
|
||||||
if (!is_alpha(c) && !is_digit(c) && c != '_') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (username.back() == '_') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (size_t i = 1; i < username.size(); i++) {
|
|
||||||
if (username[i - 1] == '_' && username[i] == '_') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_valid_phone_number(Slice phone_number) {
|
static bool is_valid_phone_number(Slice phone_number) {
|
||||||
if (phone_number.empty() || phone_number.size() > 32) {
|
if (phone_number.empty() || phone_number.size() > 32) {
|
||||||
return false;
|
return false;
|
||||||
@ -113,6 +90,7 @@ static AdministratorRights get_administrator_rights(Slice rights, bool for_chann
|
|||||||
bool can_invite_users = false;
|
bool can_invite_users = false;
|
||||||
bool can_restrict_members = false;
|
bool can_restrict_members = false;
|
||||||
bool can_pin_messages = false;
|
bool can_pin_messages = false;
|
||||||
|
bool can_manage_topics = false;
|
||||||
bool can_promote_members = false;
|
bool can_promote_members = false;
|
||||||
bool can_manage_calls = false;
|
bool can_manage_calls = false;
|
||||||
bool is_anonymous = false;
|
bool is_anonymous = false;
|
||||||
@ -131,6 +109,8 @@ static AdministratorRights get_administrator_rights(Slice rights, bool for_chann
|
|||||||
can_invite_users = true;
|
can_invite_users = true;
|
||||||
} else if (right == "pin_messages") {
|
} else if (right == "pin_messages") {
|
||||||
can_pin_messages = true;
|
can_pin_messages = true;
|
||||||
|
} else if (right == "manage_topics") {
|
||||||
|
can_manage_topics = true;
|
||||||
} else if (right == "promote_members") {
|
} else if (right == "promote_members") {
|
||||||
can_promote_members = true;
|
can_promote_members = true;
|
||||||
} else if (right == "manage_video_chats") {
|
} else if (right == "manage_video_chats") {
|
||||||
@ -143,7 +123,7 @@ static AdministratorRights get_administrator_rights(Slice rights, bool for_chann
|
|||||||
}
|
}
|
||||||
return AdministratorRights(is_anonymous, can_manage_dialog, can_change_info, can_post_messages, can_edit_messages,
|
return AdministratorRights(is_anonymous, can_manage_dialog, can_change_info, can_post_messages, can_edit_messages,
|
||||||
can_delete_messages, can_invite_users, can_restrict_members, can_pin_messages,
|
can_delete_messages, can_invite_users, can_restrict_members, can_pin_messages,
|
||||||
can_promote_members, can_manage_calls,
|
can_manage_topics, can_promote_members, can_manage_calls,
|
||||||
for_channel ? ChannelType::Broadcast : ChannelType::Megagroup);
|
for_channel ? ChannelType::Broadcast : ChannelType::Megagroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,13 +319,15 @@ class LinkManager::InternalLinkGame final : public InternalLink {
|
|||||||
|
|
||||||
class LinkManager::InternalLinkInstantView final : public InternalLink {
|
class LinkManager::InternalLinkInstantView final : public InternalLink {
|
||||||
string url_;
|
string url_;
|
||||||
|
string fallback_url_;
|
||||||
|
|
||||||
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
|
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
|
||||||
return td_api::make_object<td_api::internalLinkTypeInstantView>(url_);
|
return td_api::make_object<td_api::internalLinkTypeInstantView>(url_, fallback_url_);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit InternalLinkInstantView(string url) : url_(std::move(url)) {
|
InternalLinkInstantView(string url, string fallback_url)
|
||||||
|
: url_(std::move(url)), fallback_url_(std::move(fallback_url)) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -772,6 +754,8 @@ void LinkManager::start_up() {
|
|||||||
autologin_domains_ = full_split(G()->td_db()->get_binlog_pmc()->get("autologin_domains"), '\xFF');
|
autologin_domains_ = full_split(G()->td_db()->get_binlog_pmc()->get("autologin_domains"), '\xFF');
|
||||||
|
|
||||||
url_auth_domains_ = full_split(G()->td_db()->get_binlog_pmc()->get("url_auth_domains"), '\xFF');
|
url_auth_domains_ = full_split(G()->td_db()->get_binlog_pmc()->get("url_auth_domains"), '\xFF');
|
||||||
|
|
||||||
|
whitelisted_domains_ = full_split(G()->td_db()->get_binlog_pmc()->get("whitelisted_domains"), '\xFF');
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkManager::tear_down() {
|
void LinkManager::tear_down() {
|
||||||
@ -975,7 +959,7 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_internal_link(Slice lin
|
|||||||
case LinkType::TMe:
|
case LinkType::TMe:
|
||||||
return parse_t_me_link_query(info.query_, is_trusted);
|
return parse_t_me_link_query(info.query_, is_trusted);
|
||||||
case LinkType::Telegraph:
|
case LinkType::Telegraph:
|
||||||
return td::make_unique<InternalLinkInstantView>(PSTRING() << "https://telegra.ph" << info.query_);
|
return td::make_unique<InternalLinkInstantView>(PSTRING() << "https://telegra.ph" << info.query_, link.str());
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -1257,10 +1241,17 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_t_me_link_query(Slice q
|
|||||||
if (path[0] == "c") {
|
if (path[0] == "c") {
|
||||||
if (path.size() >= 3 && to_integer<int64>(path[1]) > 0 && to_integer<int64>(path[2]) > 0) {
|
if (path.size() >= 3 && to_integer<int64>(path[1]) > 0 && to_integer<int64>(path[2]) > 0) {
|
||||||
// /c/123456789/12345?single&thread=<thread_id>&comment=<message_id>&t=<media_timestamp>
|
// /c/123456789/12345?single&thread=<thread_id>&comment=<message_id>&t=<media_timestamp>
|
||||||
|
// /c/123456789/1234/12345?single&comment=<message_id>&t=<media_timestamp>
|
||||||
is_first_arg = false;
|
is_first_arg = false;
|
||||||
return td::make_unique<InternalLinkMessage>(
|
auto post = to_integer<int64>(path[2]);
|
||||||
PSTRING() << "tg:privatepost?channel=" << to_integer<int64>(path[1]) << "&post=" << to_integer<int64>(path[2])
|
auto thread = PSTRING() << copy_arg("thread");
|
||||||
<< copy_arg("single") << copy_arg("thread") << copy_arg("comment") << copy_arg("t"));
|
if (path.size() >= 4 && to_integer<int64>(path[3]) > 0) {
|
||||||
|
thread = PSTRING() << "&thread=" << post;
|
||||||
|
post = to_integer<int64>(path[3]);
|
||||||
|
}
|
||||||
|
return td::make_unique<InternalLinkMessage>(PSTRING() << "tg:privatepost?channel=" << to_integer<int64>(path[1])
|
||||||
|
<< "&post=" << post << copy_arg("single") << thread
|
||||||
|
<< copy_arg("comment") << copy_arg("t"));
|
||||||
}
|
}
|
||||||
} else if (path[0] == "login") {
|
} else if (path[0] == "login") {
|
||||||
if (path.size() >= 2 && !path[1].empty()) {
|
if (path.size() >= 2 && !path[1].empty()) {
|
||||||
@ -1364,16 +1355,23 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_t_me_link_query(Slice q
|
|||||||
} else if (path[0] == "iv") {
|
} else if (path[0] == "iv") {
|
||||||
if (path.size() == 1 && has_arg("url")) {
|
if (path.size() == 1 && has_arg("url")) {
|
||||||
// /iv?url=<url>&rhash=<rhash>
|
// /iv?url=<url>&rhash=<rhash>
|
||||||
return td::make_unique<InternalLinkInstantView>(PSTRING()
|
return td::make_unique<InternalLinkInstantView>(
|
||||||
<< "https://t.me/iv" << copy_arg("url") << copy_arg("rhash"));
|
PSTRING() << "https://t.me/iv" << copy_arg("url") << copy_arg("rhash"), get_arg("url"));
|
||||||
}
|
}
|
||||||
} else if (is_valid_username(path[0])) {
|
} else if (is_valid_username(path[0])) {
|
||||||
if (path.size() >= 2 && to_integer<int64>(path[1]) > 0) {
|
if (path.size() >= 2 && to_integer<int64>(path[1]) > 0) {
|
||||||
// /<username>/12345?single&thread=<thread_id>&comment=<message_id>&t=<media_timestamp>
|
// /<username>/12345?single&thread=<thread_id>&comment=<message_id>&t=<media_timestamp>
|
||||||
|
// /<username>/1234/12345?single&comment=<message_id>&t=<media_timestamp>
|
||||||
is_first_arg = false;
|
is_first_arg = false;
|
||||||
return td::make_unique<InternalLinkMessage>(
|
auto post = to_integer<int64>(path[1]);
|
||||||
PSTRING() << "tg:resolve?domain=" << url_encode(path[0]) << "&post=" << to_integer<int64>(path[1])
|
auto thread = PSTRING() << copy_arg("thread");
|
||||||
<< copy_arg("single") << copy_arg("thread") << copy_arg("comment") << copy_arg("t"));
|
if (path.size() >= 3 && to_integer<int64>(path[2]) > 0) {
|
||||||
|
thread = PSTRING() << "&thread=" << post;
|
||||||
|
post = to_integer<int64>(path[2]);
|
||||||
|
}
|
||||||
|
return td::make_unique<InternalLinkMessage>(PSTRING() << "tg:resolve?domain=" << url_encode(path[0])
|
||||||
|
<< "&post=" << post << copy_arg("single") << thread
|
||||||
|
<< copy_arg("comment") << copy_arg("t"));
|
||||||
}
|
}
|
||||||
auto username = path[0];
|
auto username = path[0];
|
||||||
for (auto &arg : url_query.args_) {
|
for (auto &arg : url_query.args_) {
|
||||||
@ -1488,7 +1486,7 @@ unique_ptr<LinkManager::InternalLink> LinkManager::get_internal_link_passport(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LinkManager::update_autologin_domains(string autologin_token, vector<string> autologin_domains,
|
void LinkManager::update_autologin_domains(string autologin_token, vector<string> autologin_domains,
|
||||||
vector<string> url_auth_domains) {
|
vector<string> url_auth_domains, vector<string> whitelisted_domains) {
|
||||||
autologin_update_time_ = Time::now();
|
autologin_update_time_ = Time::now();
|
||||||
autologin_token_ = std::move(autologin_token);
|
autologin_token_ = std::move(autologin_token);
|
||||||
if (autologin_domains_ != autologin_domains) {
|
if (autologin_domains_ != autologin_domains) {
|
||||||
@ -1499,6 +1497,10 @@ void LinkManager::update_autologin_domains(string autologin_token, vector<string
|
|||||||
url_auth_domains_ = std::move(url_auth_domains);
|
url_auth_domains_ = std::move(url_auth_domains);
|
||||||
G()->td_db()->get_binlog_pmc()->set("url_auth_domains", implode(url_auth_domains_, '\xFF'));
|
G()->td_db()->get_binlog_pmc()->set("url_auth_domains", implode(url_auth_domains_, '\xFF'));
|
||||||
}
|
}
|
||||||
|
if (whitelisted_domains_ != whitelisted_domains) {
|
||||||
|
whitelisted_domains_ = std::move(whitelisted_domains);
|
||||||
|
G()->td_db()->get_binlog_pmc()->set("whitelisted_domains", implode(whitelisted_domains_, '\xFF'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkManager::get_deep_link_info(Slice link, Promise<td_api::object_ptr<td_api::deepLinkInfo>> &&promise) {
|
void LinkManager::get_deep_link_info(Slice link, Promise<td_api::object_ptr<td_api::deepLinkInfo>> &&promise) {
|
||||||
@ -1528,6 +1530,9 @@ void LinkManager::get_external_link_info(string &&link, Promise<td_api::object_p
|
|||||||
return promise.set_value(std::move(default_result));
|
return promise.set_value(std::move(default_result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool skip_confirm = td::contains(whitelisted_domains_, r_url.ok().host_);
|
||||||
|
default_result->skip_confirm_ = skip_confirm;
|
||||||
|
|
||||||
if (!td::contains(autologin_domains_, r_url.ok().host_)) {
|
if (!td::contains(autologin_domains_, r_url.ok().host_)) {
|
||||||
if (td::contains(url_auth_domains_, r_url.ok().host_)) {
|
if (td::contains(url_auth_domains_, r_url.ok().host_)) {
|
||||||
td_->create_handler<RequestUrlAuthQuery>(std::move(promise))->send(link, FullMessageId(), 0);
|
td_->create_handler<RequestUrlAuthQuery>(std::move(promise))->send(link, FullMessageId(), 0);
|
||||||
@ -1573,7 +1578,7 @@ void LinkManager::get_external_link_info(string &&link, Promise<td_api::object_p
|
|||||||
|
|
||||||
url.query_ = PSTRING() << path << parameters << added_parameter << hash;
|
url.query_ = PSTRING() << path << parameters << added_parameter << hash;
|
||||||
|
|
||||||
promise.set_value(td_api::make_object<td_api::loginUrlInfoOpen>(url.get_url(), false));
|
promise.set_value(td_api::make_object<td_api::loginUrlInfoOpen>(url.get_url(), skip_confirm));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkManager::get_login_url_info(FullMessageId full_message_id, int64 button_id,
|
void LinkManager::get_login_url_info(FullMessageId full_message_id, int64 button_id,
|
||||||
@ -1595,6 +1600,23 @@ void LinkManager::get_link_login_url(const string &url, bool allow_write_access,
|
|||||||
td_->create_handler<AcceptUrlAuthQuery>(std::move(promise))->send(url, FullMessageId(), 0, allow_write_access);
|
td_->create_handler<AcceptUrlAuthQuery>(std::move(promise))->send(url, FullMessageId(), 0, allow_write_access);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<string> LinkManager::get_background_url(const string &name,
|
||||||
|
td_api::object_ptr<td_api::BackgroundType> background_type) {
|
||||||
|
TRY_RESULT(type, BackgroundType::get_background_type(background_type.get()));
|
||||||
|
auto url = PSTRING() << G()->get_option_string("t_me_url", "https://t.me/") << "bg/";
|
||||||
|
auto link = type.get_link();
|
||||||
|
if (type.has_file()) {
|
||||||
|
url += name;
|
||||||
|
if (!link.empty()) {
|
||||||
|
url += '?';
|
||||||
|
url += link;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
url += link;
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
string LinkManager::get_dialog_invite_link_hash(Slice invite_link) {
|
string LinkManager::get_dialog_invite_link_hash(Slice invite_link) {
|
||||||
auto link_info = get_link_info(invite_link);
|
auto link_info = get_link_info(invite_link);
|
||||||
if (link_info.type_ != LinkType::Tg && link_info.type_ != LinkType::TMe) {
|
if (link_info.type_ != LinkType::Tg && link_info.type_ != LinkType::TMe) {
|
||||||
@ -1615,6 +1637,37 @@ string LinkManager::get_dialog_invite_link(Slice hash, bool is_internal) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string LinkManager::get_instant_view_link_url(Slice link) {
|
||||||
|
auto link_info = get_link_info(link);
|
||||||
|
if (link_info.type_ != LinkType::TMe) {
|
||||||
|
return string();
|
||||||
|
}
|
||||||
|
const auto url_query = parse_url_query(link_info.query_);
|
||||||
|
const auto &path = url_query.path_;
|
||||||
|
if (path.size() == 1 && path[0] == "iv") {
|
||||||
|
return url_query.get_arg("url").str();
|
||||||
|
}
|
||||||
|
return string();
|
||||||
|
}
|
||||||
|
|
||||||
|
string LinkManager::get_instant_view_link_rhash(Slice link) {
|
||||||
|
auto link_info = get_link_info(link);
|
||||||
|
if (link_info.type_ != LinkType::TMe) {
|
||||||
|
return string();
|
||||||
|
}
|
||||||
|
const auto url_query = parse_url_query(link_info.query_);
|
||||||
|
const auto &path = url_query.path_;
|
||||||
|
if (path.size() == 1 && path[0] == "iv" && !url_query.get_arg("url").empty()) {
|
||||||
|
return url_query.get_arg("rhash").str();
|
||||||
|
}
|
||||||
|
return string();
|
||||||
|
}
|
||||||
|
|
||||||
|
string LinkManager::get_instant_view_link(Slice url, Slice rhash) {
|
||||||
|
return PSTRING() << G()->get_option_string("t_me_url", "https://t.me/") << "iv?url=" << url_encode(url)
|
||||||
|
<< "&rhash=" << url_encode(rhash);
|
||||||
|
}
|
||||||
|
|
||||||
UserId LinkManager::get_link_user_id(Slice url) {
|
UserId LinkManager::get_link_user_id(Slice url) {
|
||||||
string lower_cased_url = to_lower(url);
|
string lower_cased_url = to_lower(url);
|
||||||
url = lower_cased_url;
|
url = lower_cased_url;
|
||||||
@ -1657,7 +1710,7 @@ UserId LinkManager::get_link_user_id(Slice url) {
|
|||||||
return UserId();
|
return UserId();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<int64> LinkManager::get_link_custom_emoji_document_id(Slice url) {
|
Result<CustomEmojiId> LinkManager::get_link_custom_emoji_id(Slice url) {
|
||||||
string lower_cased_url = to_lower(url);
|
string lower_cased_url = to_lower(url);
|
||||||
url = lower_cased_url;
|
url = lower_cased_url;
|
||||||
|
|
||||||
@ -1693,7 +1746,7 @@ Result<int64> LinkManager::get_link_custom_emoji_document_id(Slice url) {
|
|||||||
if (r_document_id.is_error() || r_document_id.ok() == 0) {
|
if (r_document_id.is_error() || r_document_id.ok() == 0) {
|
||||||
return Status::Error(400, "Invalid custom emoji identifier specified");
|
return Status::Error(400, "Invalid custom emoji identifier specified");
|
||||||
}
|
}
|
||||||
return r_document_id.ok();
|
return CustomEmojiId(r_document_id.ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Status::Error(400, "Custom emoji URL must have an emoji identifier");
|
return Status::Error(400, "Custom emoji URL must have an emoji identifier");
|
||||||
@ -1713,6 +1766,7 @@ Result<MessageLinkInfo> LinkManager::get_message_link_info(Slice url) {
|
|||||||
Slice channel_id_slice;
|
Slice channel_id_slice;
|
||||||
Slice message_id_slice;
|
Slice message_id_slice;
|
||||||
Slice comment_message_id_slice = "0";
|
Slice comment_message_id_slice = "0";
|
||||||
|
Slice top_thread_message_id_slice;
|
||||||
Slice media_timestamp_slice;
|
Slice media_timestamp_slice;
|
||||||
bool is_single = false;
|
bool is_single = false;
|
||||||
bool for_comment = false;
|
bool for_comment = false;
|
||||||
@ -1764,10 +1818,12 @@ Result<MessageLinkInfo> LinkManager::get_message_link_info(Slice url) {
|
|||||||
}
|
}
|
||||||
if (key_value.first == "thread") {
|
if (key_value.first == "thread") {
|
||||||
for_comment = true;
|
for_comment = true;
|
||||||
|
top_thread_message_id_slice = key_value.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// /c/123456789/12345
|
// /c/123456789/12345
|
||||||
|
// /c/123456789/1234/12345
|
||||||
// /username/12345?single
|
// /username/12345?single
|
||||||
|
|
||||||
CHECK(!url.empty() && url[0] == '/');
|
CHECK(!url.empty() && url[0] == '/');
|
||||||
@ -1806,9 +1862,15 @@ Result<MessageLinkInfo> LinkManager::get_message_link_info(Slice url) {
|
|||||||
}
|
}
|
||||||
if (key_value.first == "thread") {
|
if (key_value.first == "thread") {
|
||||||
for_comment = true;
|
for_comment = true;
|
||||||
|
top_thread_message_id_slice = key_value.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
auto slash_pos = message_id_slice.find('/');
|
||||||
|
if (slash_pos != Slice::npos) {
|
||||||
|
top_thread_message_id_slice = message_id_slice.substr(0, slash_pos);
|
||||||
|
message_id_slice.remove_prefix(slash_pos + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ChannelId channel_id;
|
ChannelId channel_id;
|
||||||
@ -1825,6 +1887,18 @@ Result<MessageLinkInfo> LinkManager::get_message_link_info(Slice url) {
|
|||||||
return Status::Error("Wrong message ID");
|
return Status::Error("Wrong message ID");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 top_thread_message_id = 0;
|
||||||
|
if (!top_thread_message_id_slice.empty()) {
|
||||||
|
auto r_top_thread_message_id = to_integer_safe<int32>(top_thread_message_id_slice);
|
||||||
|
if (r_top_thread_message_id.is_error()) {
|
||||||
|
return Status::Error("Wrong message thread ID");
|
||||||
|
}
|
||||||
|
top_thread_message_id = r_top_thread_message_id.ok();
|
||||||
|
if (!ServerMessageId(top_thread_message_id).is_valid()) {
|
||||||
|
return Status::Error("Invalid message thread ID");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto r_comment_message_id = to_integer_safe<int32>(comment_message_id_slice);
|
auto r_comment_message_id = to_integer_safe<int32>(comment_message_id_slice);
|
||||||
if (r_comment_message_id.is_error() ||
|
if (r_comment_message_id.is_error() ||
|
||||||
!(r_comment_message_id.ok() == 0 || ServerMessageId(r_comment_message_id.ok()).is_valid())) {
|
!(r_comment_message_id.ok() == 0 || ServerMessageId(r_comment_message_id.ok()).is_valid())) {
|
||||||
@ -1873,6 +1947,7 @@ Result<MessageLinkInfo> LinkManager::get_message_link_info(Slice url) {
|
|||||||
info.channel_id = channel_id;
|
info.channel_id = channel_id;
|
||||||
info.message_id = MessageId(ServerMessageId(r_message_id.ok()));
|
info.message_id = MessageId(ServerMessageId(r_message_id.ok()));
|
||||||
info.comment_message_id = MessageId(ServerMessageId(r_comment_message_id.ok()));
|
info.comment_message_id = MessageId(ServerMessageId(r_comment_message_id.ok()));
|
||||||
|
info.top_thread_message_id = MessageId(ServerMessageId(top_thread_message_id));
|
||||||
info.media_timestamp = is_media_timestamp_invalid ? 0 : media_timestamp;
|
info.media_timestamp = is_media_timestamp_invalid ? 0 : media_timestamp;
|
||||||
info.is_single = is_single;
|
info.is_single = is_single;
|
||||||
info.for_comment = for_comment;
|
info.for_comment = for_comment;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/CustomEmojiId.h"
|
||||||
#include "td/telegram/FullMessageId.h"
|
#include "td/telegram/FullMessageId.h"
|
||||||
#include "td/telegram/MessageLinkInfo.h"
|
#include "td/telegram/MessageLinkInfo.h"
|
||||||
#include "td/telegram/td_api.h"
|
#include "td/telegram/td_api.h"
|
||||||
@ -59,7 +60,7 @@ class LinkManager final : public Actor {
|
|||||||
static unique_ptr<InternalLink> parse_internal_link(Slice link, bool is_trusted = false);
|
static unique_ptr<InternalLink> parse_internal_link(Slice link, bool is_trusted = false);
|
||||||
|
|
||||||
void update_autologin_domains(string autologin_token, vector<string> autologin_domains,
|
void update_autologin_domains(string autologin_token, vector<string> autologin_domains,
|
||||||
vector<string> url_auth_domains);
|
vector<string> url_auth_domains, vector<string> whitelisted_domains);
|
||||||
|
|
||||||
void get_deep_link_info(Slice link, Promise<td_api::object_ptr<td_api::deepLinkInfo>> &&promise);
|
void get_deep_link_info(Slice link, Promise<td_api::object_ptr<td_api::deepLinkInfo>> &&promise);
|
||||||
|
|
||||||
@ -74,13 +75,22 @@ class LinkManager final : public Actor {
|
|||||||
void get_link_login_url(const string &url, bool allow_write_access,
|
void get_link_login_url(const string &url, bool allow_write_access,
|
||||||
Promise<td_api::object_ptr<td_api::httpUrl>> &&promise);
|
Promise<td_api::object_ptr<td_api::httpUrl>> &&promise);
|
||||||
|
|
||||||
|
static Result<string> get_background_url(const string &name,
|
||||||
|
td_api::object_ptr<td_api::BackgroundType> background_type);
|
||||||
|
|
||||||
static string get_dialog_invite_link_hash(Slice invite_link);
|
static string get_dialog_invite_link_hash(Slice invite_link);
|
||||||
|
|
||||||
static string get_dialog_invite_link(Slice hash, bool is_internal);
|
static string get_dialog_invite_link(Slice hash, bool is_internal);
|
||||||
|
|
||||||
|
static string get_instant_view_link_url(Slice link);
|
||||||
|
|
||||||
|
static string get_instant_view_link_rhash(Slice link);
|
||||||
|
|
||||||
|
static string get_instant_view_link(Slice url, Slice rhash);
|
||||||
|
|
||||||
static UserId get_link_user_id(Slice url);
|
static UserId get_link_user_id(Slice url);
|
||||||
|
|
||||||
static Result<int64> get_link_custom_emoji_document_id(Slice url);
|
static Result<CustomEmojiId> get_link_custom_emoji_id(Slice url);
|
||||||
|
|
||||||
static Result<MessageLinkInfo> get_message_link_info(Slice url);
|
static Result<MessageLinkInfo> get_message_link_info(Slice url);
|
||||||
|
|
||||||
@ -150,6 +160,7 @@ class LinkManager final : public Actor {
|
|||||||
vector<string> autologin_domains_;
|
vector<string> autologin_domains_;
|
||||||
double autologin_update_time_ = 0.0;
|
double autologin_update_time_ = 0.0;
|
||||||
vector<string> url_auth_domains_;
|
vector<string> url_auth_domains_;
|
||||||
|
vector<string> whitelisted_domains_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "td/telegram/ChatId.h"
|
#include "td/telegram/ChatId.h"
|
||||||
#include "td/telegram/Contact.h"
|
#include "td/telegram/Contact.h"
|
||||||
#include "td/telegram/ContactsManager.h"
|
#include "td/telegram/ContactsManager.h"
|
||||||
|
#include "td/telegram/CustomEmojiId.h"
|
||||||
#include "td/telegram/Dependencies.h"
|
#include "td/telegram/Dependencies.h"
|
||||||
#include "td/telegram/DialogAction.h"
|
#include "td/telegram/DialogAction.h"
|
||||||
#include "td/telegram/DialogParticipant.h"
|
#include "td/telegram/DialogParticipant.h"
|
||||||
@ -28,12 +29,19 @@
|
|||||||
#include "td/telegram/files/FileLocation.h"
|
#include "td/telegram/files/FileLocation.h"
|
||||||
#include "td/telegram/files/FileManager.h"
|
#include "td/telegram/files/FileManager.h"
|
||||||
#include "td/telegram/files/FileType.h"
|
#include "td/telegram/files/FileType.h"
|
||||||
|
#include "td/telegram/ForumTopicEditedData.h"
|
||||||
|
#include "td/telegram/ForumTopicEditedData.hpp"
|
||||||
|
#include "td/telegram/ForumTopicIcon.h"
|
||||||
|
#include "td/telegram/ForumTopicIcon.hpp"
|
||||||
|
#include "td/telegram/ForumTopicManager.h"
|
||||||
#include "td/telegram/Game.h"
|
#include "td/telegram/Game.h"
|
||||||
#include "td/telegram/Game.hpp"
|
#include "td/telegram/Game.hpp"
|
||||||
#include "td/telegram/Global.h"
|
#include "td/telegram/Global.h"
|
||||||
#include "td/telegram/GroupCallManager.h"
|
#include "td/telegram/GroupCallManager.h"
|
||||||
#include "td/telegram/HashtagHints.h"
|
#include "td/telegram/HashtagHints.h"
|
||||||
#include "td/telegram/InputGroupCallId.h"
|
#include "td/telegram/InputGroupCallId.h"
|
||||||
|
#include "td/telegram/InputInvoice.h"
|
||||||
|
#include "td/telegram/InputInvoice.hpp"
|
||||||
#include "td/telegram/InputMessageText.h"
|
#include "td/telegram/InputMessageText.h"
|
||||||
#include "td/telegram/Location.h"
|
#include "td/telegram/Location.h"
|
||||||
#include "td/telegram/MessageEntity.h"
|
#include "td/telegram/MessageEntity.h"
|
||||||
@ -44,8 +52,8 @@
|
|||||||
#include "td/telegram/misc.h"
|
#include "td/telegram/misc.h"
|
||||||
#include "td/telegram/net/DcId.h"
|
#include "td/telegram/net/DcId.h"
|
||||||
#include "td/telegram/OptionManager.h"
|
#include "td/telegram/OptionManager.h"
|
||||||
#include "td/telegram/Payments.h"
|
#include "td/telegram/OrderInfo.h"
|
||||||
#include "td/telegram/Payments.hpp"
|
#include "td/telegram/OrderInfo.hpp"
|
||||||
#include "td/telegram/Photo.h"
|
#include "td/telegram/Photo.h"
|
||||||
#include "td/telegram/Photo.hpp"
|
#include "td/telegram/Photo.hpp"
|
||||||
#include "td/telegram/PhotoFormat.h"
|
#include "td/telegram/PhotoFormat.h"
|
||||||
@ -454,7 +462,7 @@ class MessageChatSetTtl final : public MessageContent {
|
|||||||
|
|
||||||
class MessageUnsupported final : public MessageContent {
|
class MessageUnsupported final : public MessageContent {
|
||||||
public:
|
public:
|
||||||
static constexpr int32 CURRENT_VERSION = 13;
|
static constexpr int32 CURRENT_VERSION = 14;
|
||||||
int32 version = CURRENT_VERSION;
|
int32 version = CURRENT_VERSION;
|
||||||
|
|
||||||
MessageUnsupported() = default;
|
MessageUnsupported() = default;
|
||||||
@ -799,6 +807,33 @@ class MessageGiftPremium final : public MessageContent {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MessageTopicCreate final : public MessageContent {
|
||||||
|
public:
|
||||||
|
string title;
|
||||||
|
ForumTopicIcon icon;
|
||||||
|
|
||||||
|
MessageTopicCreate() = default;
|
||||||
|
MessageTopicCreate(string &&title, ForumTopicIcon &&icon) : title(std::move(title)), icon(std::move(icon)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageContentType get_type() const final {
|
||||||
|
return MessageContentType::TopicCreate;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class MessageTopicEdit final : public MessageContent {
|
||||||
|
public:
|
||||||
|
ForumTopicEditedData edited_data;
|
||||||
|
|
||||||
|
MessageTopicEdit() = default;
|
||||||
|
explicit MessageTopicEdit(ForumTopicEditedData &&edited_data) : edited_data(std::move(edited_data)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageContentType get_type() const final {
|
||||||
|
return MessageContentType::TopicEdit;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
static void store(const MessageContent *content, StorerT &storer) {
|
static void store(const MessageContent *content, StorerT &storer) {
|
||||||
CHECK(content != nullptr);
|
CHECK(content != nullptr);
|
||||||
@ -1127,6 +1162,17 @@ static void store(const MessageContent *content, StorerT &storer) {
|
|||||||
store(m->months, storer);
|
store(m->months, storer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MessageContentType::TopicCreate: {
|
||||||
|
const auto *m = static_cast<const MessageTopicCreate *>(content);
|
||||||
|
store(m->title, storer);
|
||||||
|
store(m->icon, storer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MessageContentType::TopicEdit: {
|
||||||
|
const auto *m = static_cast<const MessageTopicEdit *>(content);
|
||||||
|
store(m->edited_data, storer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
@ -1226,14 +1272,7 @@ static void parse(unique_ptr<MessageContent> &content, ParserT &parser) {
|
|||||||
case MessageContentType::Photo: {
|
case MessageContentType::Photo: {
|
||||||
auto m = make_unique<MessagePhoto>();
|
auto m = make_unique<MessagePhoto>();
|
||||||
parse(m->photo, parser);
|
parse(m->photo, parser);
|
||||||
for (auto &photo_size : m->photo.photos) {
|
is_bad |= m->photo.is_bad();
|
||||||
if (!photo_size.file_id.is_valid()) {
|
|
||||||
is_bad = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (m->photo.is_empty()) {
|
|
||||||
is_bad = true;
|
|
||||||
}
|
|
||||||
parse_caption(m->caption, parser);
|
parse_caption(m->caption, parser);
|
||||||
content = std::move(m);
|
content = std::move(m);
|
||||||
break;
|
break;
|
||||||
@ -1584,6 +1623,19 @@ static void parse(unique_ptr<MessageContent> &content, ParserT &parser) {
|
|||||||
content = std::move(m);
|
content = std::move(m);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MessageContentType::TopicCreate: {
|
||||||
|
auto m = make_unique<MessageTopicCreate>();
|
||||||
|
parse(m->title, parser);
|
||||||
|
parse(m->icon, parser);
|
||||||
|
content = std::move(m);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MessageContentType::TopicEdit: {
|
||||||
|
auto m = make_unique<MessageTopicEdit>();
|
||||||
|
parse(m->edited_data, parser);
|
||||||
|
content = std::move(m);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
LOG(FATAL) << "Have unknown message content type " << static_cast<int32>(content_type);
|
LOG(FATAL) << "Have unknown message content type " << static_cast<int32>(content_type);
|
||||||
}
|
}
|
||||||
@ -1642,8 +1694,7 @@ InlineMessageContent create_inline_message_content(Td *td, FileId file_id,
|
|||||||
case telegram_api::botInlineMessageMediaInvoice::ID: {
|
case telegram_api::botInlineMessageMediaInvoice::ID: {
|
||||||
auto inline_message = move_tl_object_as<telegram_api::botInlineMessageMediaInvoice>(bot_inline_message);
|
auto inline_message = move_tl_object_as<telegram_api::botInlineMessageMediaInvoice>(bot_inline_message);
|
||||||
reply_markup = std::move(inline_message->reply_markup_);
|
reply_markup = std::move(inline_message->reply_markup_);
|
||||||
result.message_content =
|
result.message_content = make_unique<MessageInvoice>(InputInvoice(std::move(inline_message), td, DialogId()));
|
||||||
make_unique<MessageInvoice>(get_input_invoice(std::move(inline_message), td, DialogId()));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case telegram_api::botInlineMessageMediaGeo::ID: {
|
case telegram_api::botInlineMessageMediaGeo::ID: {
|
||||||
@ -1767,6 +1818,11 @@ static Result<InputMessageContent> create_input_message_content(
|
|||||||
disable_web_page_preview = input_message_text.disable_web_page_preview;
|
disable_web_page_preview = input_message_text.disable_web_page_preview;
|
||||||
clear_draft = input_message_text.clear_draft;
|
clear_draft = input_message_text.clear_draft;
|
||||||
|
|
||||||
|
if (is_bot && static_cast<int64>(utf8_length(input_message_text.text.text)) >
|
||||||
|
G()->get_option_integer("message_text_length_max")) {
|
||||||
|
return Status::Error(400, "Message is too long");
|
||||||
|
}
|
||||||
|
|
||||||
WebPageId web_page_id;
|
WebPageId web_page_id;
|
||||||
bool can_add_web_page_previews =
|
bool can_add_web_page_previews =
|
||||||
dialog_id.get_type() != DialogType::Channel ||
|
dialog_id.get_type() != DialogType::Channel ||
|
||||||
@ -1911,7 +1967,7 @@ static Result<InputMessageContent> create_input_message_content(
|
|||||||
}
|
}
|
||||||
|
|
||||||
td->video_notes_manager_->create_video_note(file_id, string(), thumbnail, input_video_note->duration_,
|
td->video_notes_manager_->create_video_note(file_id, string(), thumbnail, input_video_note->duration_,
|
||||||
get_dimensions(length, length, nullptr), false);
|
get_dimensions(length, length, nullptr), string(), false);
|
||||||
|
|
||||||
content = make_unique<MessageVideoNote>(file_id, false);
|
content = make_unique<MessageVideoNote>(file_id, false);
|
||||||
break;
|
break;
|
||||||
@ -1960,7 +2016,8 @@ static Result<InputMessageContent> create_input_message_content(
|
|||||||
return Status::Error(400, "Invoices can be sent only by bots");
|
return Status::Error(400, "Invoices can be sent only by bots");
|
||||||
}
|
}
|
||||||
|
|
||||||
TRY_RESULT(input_invoice, process_input_message_invoice(std::move(input_message_content), td));
|
TRY_RESULT(input_invoice, InputInvoice::process_input_message_invoice(std::move(input_message_content), td,
|
||||||
|
dialog_id, is_premium));
|
||||||
content = make_unique<MessageInvoice>(std::move(input_invoice));
|
content = make_unique<MessageInvoice>(std::move(input_invoice));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2080,14 +2137,14 @@ Result<InputMessageContent> get_input_message_content(
|
|||||||
auto input_message = static_cast<td_api::inputMessageDocument *>(input_message_content.get());
|
auto input_message = static_cast<td_api::inputMessageDocument *>(input_message_content.get());
|
||||||
auto file_type = input_message->disable_content_type_detection_ ? FileType::DocumentAsFile : FileType::Document;
|
auto file_type = input_message->disable_content_type_detection_ ? FileType::DocumentAsFile : FileType::Document;
|
||||||
r_file_id =
|
r_file_id =
|
||||||
td->file_manager_->get_input_file_id(file_type, input_message->document_, dialog_id, false, is_secret);
|
td->file_manager_->get_input_file_id(file_type, input_message->document_, dialog_id, false, is_secret, true);
|
||||||
input_thumbnail = std::move(input_message->thumbnail_);
|
input_thumbnail = std::move(input_message->thumbnail_);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case td_api::inputMessagePhoto::ID: {
|
case td_api::inputMessagePhoto::ID: {
|
||||||
auto input_message = static_cast<td_api::inputMessagePhoto *>(input_message_content.get());
|
auto input_message = static_cast<td_api::inputMessagePhoto *>(input_message_content.get());
|
||||||
r_file_id = td->file_manager_->get_input_file_id(FileType::Photo, input_message->photo_, dialog_id, false,
|
r_file_id =
|
||||||
is_secret, false, false, true);
|
td->file_manager_->get_input_file_id(FileType::Photo, input_message->photo_, dialog_id, false, is_secret);
|
||||||
input_thumbnail = std::move(input_message->thumbnail_);
|
input_thumbnail = std::move(input_message->thumbnail_);
|
||||||
if (!input_message->added_sticker_file_ids_.empty()) {
|
if (!input_message->added_sticker_file_ids_.empty()) {
|
||||||
sticker_file_ids = td->stickers_manager_->get_attached_sticker_file_ids(input_message->added_sticker_file_ids_);
|
sticker_file_ids = td->stickers_manager_->get_attached_sticker_file_ids(input_message->added_sticker_file_ids_);
|
||||||
@ -2158,8 +2215,12 @@ Result<InputMessageContent> get_input_message_content(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRY_RESULT(caption, get_formatted_text(td, dialog_id, extract_input_caption(input_message_content),
|
bool is_bot = td->auth_manager_->is_bot();
|
||||||
td->auth_manager_->is_bot(), true, false, false));
|
TRY_RESULT(caption, get_formatted_text(td, dialog_id, extract_input_caption(input_message_content), is_bot, true,
|
||||||
|
false, false));
|
||||||
|
if (is_bot && static_cast<int64>(utf8_length(caption.text)) > G()->get_option_integer("message_caption_length_max")) {
|
||||||
|
return Status::Error(400, "Message caption is too long");
|
||||||
|
}
|
||||||
return create_input_message_content(dialog_id, std::move(input_message_content), td, std::move(caption), file_id,
|
return create_input_message_content(dialog_id, std::move(input_message_content), td, std::move(caption), file_id,
|
||||||
std::move(thumbnail), std::move(sticker_file_ids), is_premium);
|
std::move(thumbnail), std::move(sticker_file_ids), is_premium);
|
||||||
}
|
}
|
||||||
@ -2202,6 +2263,8 @@ bool can_have_input_media(const Td *td, const MessageContent *content, bool is_s
|
|||||||
case MessageContentType::WebViewDataSent:
|
case MessageContentType::WebViewDataSent:
|
||||||
case MessageContentType::WebViewDataReceived:
|
case MessageContentType::WebViewDataReceived:
|
||||||
case MessageContentType::GiftPremium:
|
case MessageContentType::GiftPremium:
|
||||||
|
case MessageContentType::TopicCreate:
|
||||||
|
case MessageContentType::TopicEdit:
|
||||||
return false;
|
return false;
|
||||||
case MessageContentType::Animation:
|
case MessageContentType::Animation:
|
||||||
case MessageContentType::Audio:
|
case MessageContentType::Audio:
|
||||||
@ -2323,6 +2386,8 @@ SecretInputMedia get_secret_input_media(const MessageContent *content, Td *td,
|
|||||||
case MessageContentType::WebViewDataSent:
|
case MessageContentType::WebViewDataSent:
|
||||||
case MessageContentType::WebViewDataReceived:
|
case MessageContentType::WebViewDataReceived:
|
||||||
case MessageContentType::GiftPremium:
|
case MessageContentType::GiftPremium:
|
||||||
|
case MessageContentType::TopicCreate:
|
||||||
|
case MessageContentType::TopicEdit:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -2363,7 +2428,7 @@ static tl_object_ptr<telegram_api::InputMedia> get_input_media_impl(
|
|||||||
}
|
}
|
||||||
case MessageContentType::Invoice: {
|
case MessageContentType::Invoice: {
|
||||||
const auto *m = static_cast<const MessageInvoice *>(content);
|
const auto *m = static_cast<const MessageInvoice *>(content);
|
||||||
return get_input_media_invoice(m->input_invoice, td);
|
return m->input_invoice.get_input_media_invoice(td, std::move(input_file), std::move(input_thumbnail));
|
||||||
}
|
}
|
||||||
case MessageContentType::LiveLocation: {
|
case MessageContentType::LiveLocation: {
|
||||||
const auto *m = static_cast<const MessageLiveLocation *>(content);
|
const auto *m = static_cast<const MessageLiveLocation *>(content);
|
||||||
@ -2442,6 +2507,8 @@ static tl_object_ptr<telegram_api::InputMedia> get_input_media_impl(
|
|||||||
case MessageContentType::WebViewDataSent:
|
case MessageContentType::WebViewDataSent:
|
||||||
case MessageContentType::WebViewDataReceived:
|
case MessageContentType::WebViewDataReceived:
|
||||||
case MessageContentType::GiftPremium:
|
case MessageContentType::GiftPremium:
|
||||||
|
case MessageContentType::TopicCreate:
|
||||||
|
case MessageContentType::TopicEdit:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -2545,6 +2612,10 @@ void delete_message_content_thumbnail(MessageContent *content, Td *td) {
|
|||||||
auto *m = static_cast<MessageDocument *>(content);
|
auto *m = static_cast<MessageDocument *>(content);
|
||||||
return td->documents_manager_->delete_document_thumbnail(m->file_id);
|
return td->documents_manager_->delete_document_thumbnail(m->file_id);
|
||||||
}
|
}
|
||||||
|
case MessageContentType::Invoice: {
|
||||||
|
auto *m = static_cast<MessageInvoice *>(content);
|
||||||
|
return m->input_invoice.delete_thumbnail(td);
|
||||||
|
}
|
||||||
case MessageContentType::Photo: {
|
case MessageContentType::Photo: {
|
||||||
auto *m = static_cast<MessagePhoto *>(content);
|
auto *m = static_cast<MessagePhoto *>(content);
|
||||||
return photo_delete_thumbnail(m->photo);
|
return photo_delete_thumbnail(m->photo);
|
||||||
@ -2564,7 +2635,6 @@ void delete_message_content_thumbnail(MessageContent *content, Td *td) {
|
|||||||
case MessageContentType::Contact:
|
case MessageContentType::Contact:
|
||||||
case MessageContentType::Dice:
|
case MessageContentType::Dice:
|
||||||
case MessageContentType::Game:
|
case MessageContentType::Game:
|
||||||
case MessageContentType::Invoice:
|
|
||||||
case MessageContentType::LiveLocation:
|
case MessageContentType::LiveLocation:
|
||||||
case MessageContentType::Location:
|
case MessageContentType::Location:
|
||||||
case MessageContentType::Venue:
|
case MessageContentType::Venue:
|
||||||
@ -2603,6 +2673,8 @@ void delete_message_content_thumbnail(MessageContent *content, Td *td) {
|
|||||||
case MessageContentType::WebViewDataSent:
|
case MessageContentType::WebViewDataSent:
|
||||||
case MessageContentType::WebViewDataReceived:
|
case MessageContentType::WebViewDataReceived:
|
||||||
case MessageContentType::GiftPremium:
|
case MessageContentType::GiftPremium:
|
||||||
|
case MessageContentType::TopicCreate:
|
||||||
|
case MessageContentType::TopicEdit:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -2785,6 +2857,8 @@ Status can_send_message_content(DialogId dialog_id, const MessageContent *conten
|
|||||||
case MessageContentType::WebViewDataSent:
|
case MessageContentType::WebViewDataSent:
|
||||||
case MessageContentType::WebViewDataReceived:
|
case MessageContentType::WebViewDataReceived:
|
||||||
case MessageContentType::GiftPremium:
|
case MessageContentType::GiftPremium:
|
||||||
|
case MessageContentType::TopicCreate:
|
||||||
|
case MessageContentType::TopicEdit:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
@ -2914,6 +2988,8 @@ static int32 get_message_content_media_index_mask(const MessageContent *content,
|
|||||||
case MessageContentType::WebViewDataSent:
|
case MessageContentType::WebViewDataSent:
|
||||||
case MessageContentType::WebViewDataReceived:
|
case MessageContentType::WebViewDataReceived:
|
||||||
case MessageContentType::GiftPremium:
|
case MessageContentType::GiftPremium:
|
||||||
|
case MessageContentType::TopicCreate:
|
||||||
|
case MessageContentType::TopicEdit:
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -3036,6 +3112,10 @@ bool can_message_content_have_media_timestamp(const MessageContent *content) {
|
|||||||
case MessageContentType::VideoNote:
|
case MessageContentType::VideoNote:
|
||||||
case MessageContentType::VoiceNote:
|
case MessageContentType::VoiceNote:
|
||||||
return true;
|
return true;
|
||||||
|
case MessageContentType::Invoice: {
|
||||||
|
const auto *m = static_cast<const MessageInvoice *>(content);
|
||||||
|
return m->input_invoice.has_media_timestamp();
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return has_message_content_web_page(content);
|
return has_message_content_web_page(content);
|
||||||
}
|
}
|
||||||
@ -3073,7 +3153,10 @@ static void merge_location_access_hash(const Location &first, const Location &se
|
|||||||
|
|
||||||
static bool need_message_text_changed_warning(const MessageText *old_content, const MessageText *new_content) {
|
static bool need_message_text_changed_warning(const MessageText *old_content, const MessageText *new_content) {
|
||||||
if (new_content->text.text == "Unsupported characters" ||
|
if (new_content->text.text == "Unsupported characters" ||
|
||||||
new_content->text.text == "This channel is blocked because it was used to spread pornographic content.") {
|
new_content->text.text == "This channel is blocked because it was used to spread pornographic content." ||
|
||||||
|
begins_with(new_content->text.text,
|
||||||
|
"This group has been temporarily suspended to give its moderators time to clean up after users who "
|
||||||
|
"posted illegal pornographic content.")) {
|
||||||
// message contained unsupported characters or is restricted, text is replaced
|
// message contained unsupported characters or is restricted, text is replaced
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -3219,9 +3302,12 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo
|
|||||||
}
|
}
|
||||||
case MessageContentType::Invoice: {
|
case MessageContentType::Invoice: {
|
||||||
const auto *old_ = static_cast<const MessageInvoice *>(old_content);
|
const auto *old_ = static_cast<const MessageInvoice *>(old_content);
|
||||||
const auto *new_ = static_cast<const MessageInvoice *>(new_content);
|
auto *new_ = static_cast<MessageInvoice *>(new_content);
|
||||||
|
new_->input_invoice.update_from(old_->input_invoice);
|
||||||
if (old_->input_invoice != new_->input_invoice) {
|
if (old_->input_invoice != new_->input_invoice) {
|
||||||
need_update = true;
|
need_update = true;
|
||||||
|
} else if (old_->input_invoice.is_equal_but_different(new_->input_invoice)) {
|
||||||
|
is_content_changed = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3649,6 +3735,22 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MessageContentType::TopicCreate: {
|
||||||
|
const auto *old_ = static_cast<const MessageTopicCreate *>(old_content);
|
||||||
|
const auto *new_ = static_cast<const MessageTopicCreate *>(new_content);
|
||||||
|
if (old_->title != new_->title || old_->icon != new_->icon) {
|
||||||
|
need_update = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MessageContentType::TopicEdit: {
|
||||||
|
const auto *old_ = static_cast<const MessageTopicEdit *>(old_content);
|
||||||
|
const auto *new_ = static_cast<const MessageTopicEdit *>(new_content);
|
||||||
|
if (old_->edited_data != new_->edited_data) {
|
||||||
|
need_update = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case MessageContentType::Unsupported: {
|
case MessageContentType::Unsupported: {
|
||||||
const auto *old_ = static_cast<const MessageUnsupported *>(old_content);
|
const auto *old_ = static_cast<const MessageUnsupported *>(old_content);
|
||||||
const auto *new_ = static_cast<const MessageUnsupported *>(new_content);
|
const auto *new_ = static_cast<const MessageUnsupported *>(new_content);
|
||||||
@ -3668,6 +3770,7 @@ bool merge_message_content_file_id(Td *td, MessageContent *message_content, File
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// secret chats only
|
||||||
LOG(INFO) << "Merge message content of a message with file " << new_file_id;
|
LOG(INFO) << "Merge message content of a message with file " << new_file_id;
|
||||||
MessageContentType content_type = message_content->get_type();
|
MessageContentType content_type = message_content->get_type();
|
||||||
switch (content_type) {
|
switch (content_type) {
|
||||||
@ -3788,6 +3891,8 @@ bool merge_message_content_file_id(Td *td, MessageContent *message_content, File
|
|||||||
case MessageContentType::WebViewDataSent:
|
case MessageContentType::WebViewDataSent:
|
||||||
case MessageContentType::WebViewDataReceived:
|
case MessageContentType::WebViewDataReceived:
|
||||||
case MessageContentType::GiftPremium:
|
case MessageContentType::GiftPremium:
|
||||||
|
case MessageContentType::TopicCreate:
|
||||||
|
case MessageContentType::TopicEdit:
|
||||||
LOG(ERROR) << "Receive new file " << new_file_id << " in a sent message of the type " << content_type;
|
LOG(ERROR) << "Receive new file " << new_file_id << " in a sent message of the type " << content_type;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -3806,14 +3911,14 @@ static bool can_be_animated_emoji(const FormattedText &text) {
|
|||||||
}
|
}
|
||||||
if (text.entities.size() == 1 && text.entities[0].type == MessageEntity::Type::CustomEmoji &&
|
if (text.entities.size() == 1 && text.entities[0].type == MessageEntity::Type::CustomEmoji &&
|
||||||
text.entities[0].offset == 0 && static_cast<size_t>(text.entities[0].length) == utf8_utf16_length(text.text) &&
|
text.entities[0].offset == 0 && static_cast<size_t>(text.entities[0].length) == utf8_utf16_length(text.text) &&
|
||||||
text.entities[0].document_id != 0) {
|
text.entities[0].custom_emoji_id.is_valid()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64 get_custom_emoji_id(const FormattedText &text) {
|
static CustomEmojiId get_custom_emoji_id(const FormattedText &text) {
|
||||||
return text.entities.empty() ? 0 : text.entities[0].document_id;
|
return text.entities.empty() ? CustomEmojiId() : text.entities[0].custom_emoji_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_message_content(Td *td, const MessageContent *content, FullMessageId full_message_id,
|
void register_message_content(Td *td, const MessageContent *content, FullMessageId full_message_id,
|
||||||
@ -3829,6 +3934,9 @@ void register_message_content(Td *td, const MessageContent *content, FullMessage
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
case MessageContentType::VideoNote:
|
||||||
|
return td->video_notes_manager_->register_video_note(static_cast<const MessageVideoNote *>(content)->file_id,
|
||||||
|
full_message_id, source);
|
||||||
case MessageContentType::VoiceNote:
|
case MessageContentType::VoiceNote:
|
||||||
return td->voice_notes_manager_->register_voice_note(static_cast<const MessageVoiceNote *>(content)->file_id,
|
return td->voice_notes_manager_->register_voice_note(static_cast<const MessageVoiceNote *>(content)->file_id,
|
||||||
full_message_id, source);
|
full_message_id, source);
|
||||||
@ -3863,6 +3971,12 @@ void reregister_message_content(Td *td, const MessageContent *old_content, const
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MessageContentType::VideoNote:
|
||||||
|
if (static_cast<const MessageVideoNote *>(old_content)->file_id ==
|
||||||
|
static_cast<const MessageVideoNote *>(new_content)->file_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case MessageContentType::VoiceNote:
|
case MessageContentType::VoiceNote:
|
||||||
if (static_cast<const MessageVoiceNote *>(old_content)->file_id ==
|
if (static_cast<const MessageVoiceNote *>(old_content)->file_id ==
|
||||||
static_cast<const MessageVoiceNote *>(new_content)->file_id) {
|
static_cast<const MessageVoiceNote *>(new_content)->file_id) {
|
||||||
@ -3910,6 +4024,9 @@ void unregister_message_content(Td *td, const MessageContent *content, FullMessa
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
case MessageContentType::VideoNote:
|
||||||
|
return td->video_notes_manager_->unregister_video_note(static_cast<const MessageVideoNote *>(content)->file_id,
|
||||||
|
full_message_id, source);
|
||||||
case MessageContentType::VoiceNote:
|
case MessageContentType::VoiceNote:
|
||||||
return td->voice_notes_manager_->unregister_voice_note(static_cast<const MessageVoiceNote *>(content)->file_id,
|
return td->voice_notes_manager_->unregister_voice_note(static_cast<const MessageVoiceNote *>(content)->file_id,
|
||||||
full_message_id, source);
|
full_message_id, source);
|
||||||
@ -3993,8 +4110,8 @@ static auto secret_to_telegram(secret_api::documentAttributeSticker &sticker) {
|
|||||||
nullptr);
|
nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentAttributeVideo duration:int w:int h:int = DocumentAttribute;
|
// documentAttributeVideo23 duration:int w:int h:int = DocumentAttribute;
|
||||||
static auto secret_to_telegram(secret_api::documentAttributeVideo &video) {
|
static auto secret_to_telegram(secret_api::documentAttributeVideo23 &video) {
|
||||||
return make_tl_object<telegram_api::documentAttributeVideo>(0, false /*ignored*/, false /*ignored*/, video.duration_,
|
return make_tl_object<telegram_api::documentAttributeVideo>(0, false /*ignored*/, false /*ignored*/, video.duration_,
|
||||||
video.w_, video.h_);
|
video.w_, video.h_);
|
||||||
}
|
}
|
||||||
@ -4007,10 +4124,10 @@ static auto secret_to_telegram(secret_api::documentAttributeFilename &filename)
|
|||||||
return make_tl_object<telegram_api::documentAttributeFilename>(filename.file_name_);
|
return make_tl_object<telegram_api::documentAttributeFilename>(filename.file_name_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentAttributeVideo66 flags:# round_message:flags.0?true duration:int w:int h:int = DocumentAttribute;
|
// documentAttributeVideo flags:# round_message:flags.0?true duration:int w:int h:int = DocumentAttribute;
|
||||||
static auto secret_to_telegram(secret_api::documentAttributeVideo66 &video) {
|
static auto secret_to_telegram(secret_api::documentAttributeVideo &video) {
|
||||||
return make_tl_object<telegram_api::documentAttributeVideo>(
|
return make_tl_object<telegram_api::documentAttributeVideo>(
|
||||||
(video.flags_ & secret_api::documentAttributeVideo66::ROUND_MESSAGE_MASK) != 0
|
(video.flags_ & secret_api::documentAttributeVideo::ROUND_MESSAGE_MASK) != 0
|
||||||
? telegram_api::documentAttributeVideo::ROUND_MESSAGE_MASK
|
? telegram_api::documentAttributeVideo::ROUND_MESSAGE_MASK
|
||||||
: 0,
|
: 0,
|
||||||
video.round_message_, false, video.duration_, video.w_, video.h_);
|
video.round_message_, false, video.duration_, video.w_, video.h_);
|
||||||
@ -4191,7 +4308,7 @@ unique_ptr<MessageContent> get_secret_message_content(
|
|||||||
auto media = move_tl_object_as<secret_api::decryptedMessageMediaVideo>(media_ptr);
|
auto media = move_tl_object_as<secret_api::decryptedMessageMediaVideo>(media_ptr);
|
||||||
vector<tl_object_ptr<secret_api::DocumentAttribute>> attributes;
|
vector<tl_object_ptr<secret_api::DocumentAttribute>> attributes;
|
||||||
attributes.emplace_back(
|
attributes.emplace_back(
|
||||||
make_tl_object<secret_api::documentAttributeVideo>(media->duration_, media->w_, media->h_));
|
make_tl_object<secret_api::documentAttributeVideo>(0, false, media->duration_, media->w_, media->h_));
|
||||||
media_ptr = make_tl_object<secret_api::decryptedMessageMediaDocument>(
|
media_ptr = make_tl_object<secret_api::decryptedMessageMediaDocument>(
|
||||||
std::move(media->thumb_), media->thumb_w_, media->thumb_h_, media->mime_type_, media->size_,
|
std::move(media->thumb_), media->thumb_w_, media->thumb_h_, media->mime_type_, media->size_,
|
||||||
std::move(media->key_), std::move(media->iv_), std::move(attributes), string());
|
std::move(media->key_), std::move(media->iv_), std::move(attributes), string());
|
||||||
@ -4467,15 +4584,16 @@ unique_ptr<MessageContent> get_message_content(Td *td, FormattedText message,
|
|||||||
case telegram_api::messageMediaGame::ID: {
|
case telegram_api::messageMediaGame::ID: {
|
||||||
auto media = move_tl_object_as<telegram_api::messageMediaGame>(media_ptr);
|
auto media = move_tl_object_as<telegram_api::messageMediaGame>(media_ptr);
|
||||||
|
|
||||||
auto m = make_unique<MessageGame>(Game(td, via_bot_user_id, std::move(media->game_), message, owner_dialog_id));
|
auto m = make_unique<MessageGame>(
|
||||||
|
Game(td, via_bot_user_id, std::move(media->game_), std::move(message), owner_dialog_id));
|
||||||
if (m->game.is_empty()) {
|
if (m->game.is_empty()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return std::move(m);
|
return std::move(m);
|
||||||
}
|
}
|
||||||
case telegram_api::messageMediaInvoice::ID:
|
case telegram_api::messageMediaInvoice::ID:
|
||||||
return td::make_unique<MessageInvoice>(
|
return td::make_unique<MessageInvoice>(InputInvoice(
|
||||||
get_input_invoice(move_tl_object_as<telegram_api::messageMediaInvoice>(media_ptr), td, owner_dialog_id));
|
move_tl_object_as<telegram_api::messageMediaInvoice>(media_ptr), td, owner_dialog_id, std::move(message)));
|
||||||
case telegram_api::messageMediaWebPage::ID: {
|
case telegram_api::messageMediaWebPage::ID: {
|
||||||
auto media = move_tl_object_as<telegram_api::messageMediaWebPage>(media_ptr);
|
auto media = move_tl_object_as<telegram_api::messageMediaWebPage>(media_ptr);
|
||||||
if (disable_web_page_preview != nullptr) {
|
if (disable_web_page_preview != nullptr) {
|
||||||
@ -4757,6 +4875,8 @@ unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const
|
|||||||
case MessageContentType::WebViewDataSent:
|
case MessageContentType::WebViewDataSent:
|
||||||
case MessageContentType::WebViewDataReceived:
|
case MessageContentType::WebViewDataReceived:
|
||||||
case MessageContentType::GiftPremium:
|
case MessageContentType::GiftPremium:
|
||||||
|
case MessageContentType::TopicCreate:
|
||||||
|
case MessageContentType::TopicEdit:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -5054,6 +5174,19 @@ unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<tele
|
|||||||
}
|
}
|
||||||
return td::make_unique<MessageGiftPremium>(std::move(action->currency_), action->amount_, action->months_);
|
return td::make_unique<MessageGiftPremium>(std::move(action->currency_), action->amount_, action->months_);
|
||||||
}
|
}
|
||||||
|
case telegram_api::messageActionTopicCreate::ID: {
|
||||||
|
auto action = move_tl_object_as<telegram_api::messageActionTopicCreate>(action_ptr);
|
||||||
|
return td::make_unique<MessageTopicCreate>(std::move(action->title_),
|
||||||
|
ForumTopicIcon(action->icon_color_, action->icon_emoji_id_));
|
||||||
|
}
|
||||||
|
case telegram_api::messageActionTopicEdit::ID: {
|
||||||
|
auto action = move_tl_object_as<telegram_api::messageActionTopicEdit>(action_ptr);
|
||||||
|
auto edit_icon_custom_emoji_id = (action->flags_ & telegram_api::messageActionTopicEdit::ICON_EMOJI_ID_MASK) != 0;
|
||||||
|
auto edit_is_closed = (action->flags_ & telegram_api::messageActionTopicEdit::CLOSED_MASK) != 0;
|
||||||
|
return td::make_unique<MessageTopicEdit>(ForumTopicEditedData{std::move(action->title_),
|
||||||
|
edit_icon_custom_emoji_id, action->icon_emoji_id_,
|
||||||
|
edit_is_closed, action->closed_});
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
@ -5095,7 +5228,7 @@ tl_object_ptr<td_api::MessageContent> get_message_content_object(const MessageCo
|
|||||||
}
|
}
|
||||||
case MessageContentType::Invoice: {
|
case MessageContentType::Invoice: {
|
||||||
const auto *m = static_cast<const MessageInvoice *>(content);
|
const auto *m = static_cast<const MessageInvoice *>(content);
|
||||||
return get_message_invoice_object(m->input_invoice, td);
|
return m->input_invoice.get_message_invoice_object(td, skip_bot_commands, max_media_timestamp);
|
||||||
}
|
}
|
||||||
case MessageContentType::LiveLocation: {
|
case MessageContentType::LiveLocation: {
|
||||||
const auto *m = static_cast<const MessageLiveLocation *>(content);
|
const auto *m = static_cast<const MessageLiveLocation *>(content);
|
||||||
@ -5330,6 +5463,14 @@ tl_object_ptr<td_api::MessageContent> get_message_content_object(const MessageCo
|
|||||||
return make_tl_object<td_api::messageGiftedPremium>(
|
return make_tl_object<td_api::messageGiftedPremium>(
|
||||||
m->currency, m->amount, m->months, td->stickers_manager_->get_premium_gift_sticker_object(m->months));
|
m->currency, m->amount, m->months, td->stickers_manager_->get_premium_gift_sticker_object(m->months));
|
||||||
}
|
}
|
||||||
|
case MessageContentType::TopicCreate: {
|
||||||
|
const auto *m = static_cast<const MessageTopicCreate *>(content);
|
||||||
|
return td_api::make_object<td_api::messageForumTopicCreated>(m->title, m->icon.get_forum_topic_icon_object());
|
||||||
|
}
|
||||||
|
case MessageContentType::TopicEdit: {
|
||||||
|
const auto *m = static_cast<const MessageTopicEdit *>(content);
|
||||||
|
return m->edited_data.get_message_content_object();
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -5361,6 +5502,8 @@ const FormattedText *get_message_content_caption(const MessageContent *content)
|
|||||||
return &static_cast<const MessageAudio *>(content)->caption;
|
return &static_cast<const MessageAudio *>(content)->caption;
|
||||||
case MessageContentType::Document:
|
case MessageContentType::Document:
|
||||||
return &static_cast<const MessageDocument *>(content)->caption;
|
return &static_cast<const MessageDocument *>(content)->caption;
|
||||||
|
case MessageContentType::Invoice:
|
||||||
|
return static_cast<const MessageInvoice *>(content)->input_invoice.get_caption();
|
||||||
case MessageContentType::Photo:
|
case MessageContentType::Photo:
|
||||||
return &static_cast<const MessagePhoto *>(content)->caption;
|
return &static_cast<const MessagePhoto *>(content)->caption;
|
||||||
case MessageContentType::Video:
|
case MessageContentType::Video:
|
||||||
@ -5383,6 +5526,8 @@ int32 get_message_content_duration(const MessageContent *content, const Td *td)
|
|||||||
auto audio_file_id = static_cast<const MessageAudio *>(content)->file_id;
|
auto audio_file_id = static_cast<const MessageAudio *>(content)->file_id;
|
||||||
return td->audios_manager_->get_audio_duration(audio_file_id);
|
return td->audios_manager_->get_audio_duration(audio_file_id);
|
||||||
}
|
}
|
||||||
|
case MessageContentType::Invoice:
|
||||||
|
return static_cast<const MessageInvoice *>(content)->input_invoice.get_duration(td);
|
||||||
case MessageContentType::Video: {
|
case MessageContentType::Video: {
|
||||||
auto video_file_id = static_cast<const MessageVideo *>(content)->file_id;
|
auto video_file_id = static_cast<const MessageVideo *>(content)->file_id;
|
||||||
return td->videos_manager_->get_video_duration(video_file_id);
|
return td->videos_manager_->get_video_duration(video_file_id);
|
||||||
@ -5407,6 +5552,8 @@ int32 get_message_content_media_duration(const MessageContent *content, const Td
|
|||||||
auto audio_file_id = static_cast<const MessageAudio *>(content)->file_id;
|
auto audio_file_id = static_cast<const MessageAudio *>(content)->file_id;
|
||||||
return td->audios_manager_->get_audio_duration(audio_file_id);
|
return td->audios_manager_->get_audio_duration(audio_file_id);
|
||||||
}
|
}
|
||||||
|
case MessageContentType::Invoice:
|
||||||
|
return static_cast<const MessageInvoice *>(content)->input_invoice.get_duration(td);
|
||||||
case MessageContentType::Text: {
|
case MessageContentType::Text: {
|
||||||
auto web_page_id = static_cast<const MessageText *>(content)->web_page_id;
|
auto web_page_id = static_cast<const MessageText *>(content)->web_page_id;
|
||||||
return td->web_pages_manager_->get_web_page_media_duration(web_page_id);
|
return td->web_pages_manager_->get_web_page_media_duration(web_page_id);
|
||||||
@ -5428,6 +5575,16 @@ int32 get_message_content_media_duration(const MessageContent *content, const Td
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Photo *get_message_content_photo(const MessageContent *content) {
|
||||||
|
switch (content->get_type()) {
|
||||||
|
case MessageContentType::Photo:
|
||||||
|
return &static_cast<const MessagePhoto *>(content)->photo;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
FileId get_message_content_upload_file_id(const MessageContent *content) {
|
FileId get_message_content_upload_file_id(const MessageContent *content) {
|
||||||
switch (content->get_type()) {
|
switch (content->get_type()) {
|
||||||
case MessageContentType::Animation:
|
case MessageContentType::Animation:
|
||||||
@ -5436,13 +5593,10 @@ FileId get_message_content_upload_file_id(const MessageContent *content) {
|
|||||||
return static_cast<const MessageAudio *>(content)->file_id;
|
return static_cast<const MessageAudio *>(content)->file_id;
|
||||||
case MessageContentType::Document:
|
case MessageContentType::Document:
|
||||||
return static_cast<const MessageDocument *>(content)->file_id;
|
return static_cast<const MessageDocument *>(content)->file_id;
|
||||||
|
case MessageContentType::Invoice:
|
||||||
|
return static_cast<const MessageInvoice *>(content)->input_invoice.get_upload_file_id();
|
||||||
case MessageContentType::Photo:
|
case MessageContentType::Photo:
|
||||||
for (auto &size : static_cast<const MessagePhoto *>(content)->photo.photos) {
|
return get_photo_upload_file_id(static_cast<const MessagePhoto *>(content)->photo);
|
||||||
if (size.type == 'i') {
|
|
||||||
return size.file_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MessageContentType::Sticker:
|
case MessageContentType::Sticker:
|
||||||
return static_cast<const MessageSticker *>(content)->file_id;
|
return static_cast<const MessageSticker *>(content)->file_id;
|
||||||
case MessageContentType::Video:
|
case MessageContentType::Video:
|
||||||
@ -5459,10 +5613,11 @@ FileId get_message_content_upload_file_id(const MessageContent *content) {
|
|||||||
|
|
||||||
FileId get_message_content_any_file_id(const MessageContent *content) {
|
FileId get_message_content_any_file_id(const MessageContent *content) {
|
||||||
FileId result = get_message_content_upload_file_id(content);
|
FileId result = get_message_content_upload_file_id(content);
|
||||||
if (!result.is_valid() && content->get_type() == MessageContentType::Photo) {
|
if (!result.is_valid()) {
|
||||||
const auto &sizes = static_cast<const MessagePhoto *>(content)->photo.photos;
|
if (content->get_type() == MessageContentType::Photo) {
|
||||||
if (!sizes.empty()) {
|
result = get_photo_any_file_id(static_cast<const MessagePhoto *>(content)->photo);
|
||||||
result = sizes.back().file_id;
|
} else if (content->get_type() == MessageContentType::Invoice) {
|
||||||
|
result = static_cast<const MessageInvoice *>(content)->input_invoice.get_any_file_id();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -5499,34 +5654,31 @@ void update_message_content_file_id_remote(MessageContent *content, FileId file_
|
|||||||
|
|
||||||
FileId get_message_content_thumbnail_file_id(const MessageContent *content, const Td *td) {
|
FileId get_message_content_thumbnail_file_id(const MessageContent *content, const Td *td) {
|
||||||
if (!G()->get_option_boolean("disable_minithumbnails")) {
|
if (!G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
switch (content->get_type()) {
|
switch (content->get_type()) {
|
||||||
case MessageContentType::Animation:
|
case MessageContentType::Animation:
|
||||||
return td->animations_manager_->get_animation_thumbnail_file_id(
|
return td->animations_manager_->get_animation_thumbnail_file_id(
|
||||||
static_cast<const MessageAnimation *>(content)->file_id);
|
static_cast<const MessageAnimation *>(content)->file_id);
|
||||||
case MessageContentType::Audio:
|
case MessageContentType::Audio:
|
||||||
return td->audios_manager_->get_audio_thumbnail_file_id(static_cast<const MessageAudio *>(content)->file_id);
|
return td->audios_manager_->get_audio_thumbnail_file_id(static_cast<const MessageAudio *>(content)->file_id);
|
||||||
case MessageContentType::Document:
|
case MessageContentType::Document:
|
||||||
return td->documents_manager_->get_document_thumbnail_file_id(
|
return td->documents_manager_->get_document_thumbnail_file_id(
|
||||||
static_cast<const MessageDocument *>(content)->file_id);
|
static_cast<const MessageDocument *>(content)->file_id);
|
||||||
case MessageContentType::Photo:
|
case MessageContentType::Invoice:
|
||||||
for (auto &size : static_cast<const MessagePhoto *>(content)->photo.photos) {
|
return static_cast<const MessageInvoice *>(content)->input_invoice.get_thumbnail_file_id(td);
|
||||||
if (size.type == 't') {
|
case MessageContentType::Photo:
|
||||||
return size.file_id;
|
return get_photo_thumbnail_file_id(static_cast<const MessagePhoto *>(content)->photo);
|
||||||
}
|
case MessageContentType::Sticker:
|
||||||
}
|
return td->stickers_manager_->get_sticker_thumbnail_file_id(
|
||||||
break;
|
static_cast<const MessageSticker *>(content)->file_id);
|
||||||
case MessageContentType::Sticker:
|
case MessageContentType::Video:
|
||||||
return td->stickers_manager_->get_sticker_thumbnail_file_id(
|
return td->videos_manager_->get_video_thumbnail_file_id(static_cast<const MessageVideo *>(content)->file_id);
|
||||||
static_cast<const MessageSticker *>(content)->file_id);
|
case MessageContentType::VideoNote:
|
||||||
case MessageContentType::Video:
|
return td->video_notes_manager_->get_video_note_thumbnail_file_id(
|
||||||
return td->videos_manager_->get_video_thumbnail_file_id(static_cast<const MessageVideo *>(content)->file_id);
|
static_cast<const MessageVideoNote *>(content)->file_id);
|
||||||
case MessageContentType::VideoNote:
|
case MessageContentType::VoiceNote:
|
||||||
return td->video_notes_manager_->get_video_note_thumbnail_file_id(
|
return FileId();
|
||||||
static_cast<const MessageVideoNote *>(content)->file_id);
|
default:
|
||||||
case MessageContentType::VoiceNote:
|
break;
|
||||||
return FileId();
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FileId();
|
return FileId();
|
||||||
@ -5569,7 +5721,7 @@ vector<FileId> get_message_content_file_ids(const MessageContent *content, const
|
|||||||
case MessageContentType::Game:
|
case MessageContentType::Game:
|
||||||
return static_cast<const MessageGame *>(content)->game.get_file_ids(td);
|
return static_cast<const MessageGame *>(content)->game.get_file_ids(td);
|
||||||
case MessageContentType::Invoice:
|
case MessageContentType::Invoice:
|
||||||
return get_input_invoice_file_ids(static_cast<const MessageInvoice *>(content)->input_invoice);
|
return static_cast<const MessageInvoice *>(content)->input_invoice.get_file_ids(td);
|
||||||
case MessageContentType::ChatChangePhoto:
|
case MessageContentType::ChatChangePhoto:
|
||||||
return photo_get_file_ids(static_cast<const MessageChatChangePhoto *>(content)->photo);
|
return photo_get_file_ids(static_cast<const MessageChatChangePhoto *>(content)->photo);
|
||||||
case MessageContentType::PassportDataReceived: {
|
case MessageContentType::PassportDataReceived: {
|
||||||
@ -5604,22 +5756,26 @@ string get_message_content_search_text(const Td *td, const MessageContent *conte
|
|||||||
if (!text->web_page_id.is_valid()) {
|
if (!text->web_page_id.is_valid()) {
|
||||||
return text->text.text;
|
return text->text.text;
|
||||||
}
|
}
|
||||||
return PSTRING() << text->text.text << " " << td->web_pages_manager_->get_web_page_search_text(text->web_page_id);
|
return PSTRING() << text->text.text << ' ' << td->web_pages_manager_->get_web_page_search_text(text->web_page_id);
|
||||||
}
|
}
|
||||||
case MessageContentType::Animation: {
|
case MessageContentType::Animation: {
|
||||||
const auto *animation = static_cast<const MessageAnimation *>(content);
|
const auto *animation = static_cast<const MessageAnimation *>(content);
|
||||||
return PSTRING() << td->animations_manager_->get_animation_search_text(animation->file_id) << " "
|
return PSTRING() << td->animations_manager_->get_animation_search_text(animation->file_id) << ' '
|
||||||
<< animation->caption.text;
|
<< animation->caption.text;
|
||||||
}
|
}
|
||||||
case MessageContentType::Audio: {
|
case MessageContentType::Audio: {
|
||||||
const auto *audio = static_cast<const MessageAudio *>(content);
|
const auto *audio = static_cast<const MessageAudio *>(content);
|
||||||
return PSTRING() << td->audios_manager_->get_audio_search_text(audio->file_id) << " " << audio->caption.text;
|
return PSTRING() << td->audios_manager_->get_audio_search_text(audio->file_id) << ' ' << audio->caption.text;
|
||||||
}
|
}
|
||||||
case MessageContentType::Document: {
|
case MessageContentType::Document: {
|
||||||
const auto *document = static_cast<const MessageDocument *>(content);
|
const auto *document = static_cast<const MessageDocument *>(content);
|
||||||
return PSTRING() << td->documents_manager_->get_document_search_text(document->file_id) << " "
|
return PSTRING() << td->documents_manager_->get_document_search_text(document->file_id) << ' '
|
||||||
<< document->caption.text;
|
<< document->caption.text;
|
||||||
}
|
}
|
||||||
|
case MessageContentType::Invoice: {
|
||||||
|
const auto *invoice = static_cast<const MessageInvoice *>(content);
|
||||||
|
return invoice->input_invoice.get_caption()->text;
|
||||||
|
}
|
||||||
case MessageContentType::Photo: {
|
case MessageContentType::Photo: {
|
||||||
const auto *photo = static_cast<const MessagePhoto *>(content);
|
const auto *photo = static_cast<const MessagePhoto *>(content);
|
||||||
return photo->caption.text;
|
return photo->caption.text;
|
||||||
@ -5634,7 +5790,6 @@ string get_message_content_search_text(const Td *td, const MessageContent *conte
|
|||||||
}
|
}
|
||||||
case MessageContentType::Contact:
|
case MessageContentType::Contact:
|
||||||
case MessageContentType::Game:
|
case MessageContentType::Game:
|
||||||
case MessageContentType::Invoice:
|
|
||||||
case MessageContentType::LiveLocation:
|
case MessageContentType::LiveLocation:
|
||||||
case MessageContentType::Location:
|
case MessageContentType::Location:
|
||||||
case MessageContentType::Sticker:
|
case MessageContentType::Sticker:
|
||||||
@ -5674,6 +5829,8 @@ string get_message_content_search_text(const Td *td, const MessageContent *conte
|
|||||||
case MessageContentType::WebViewDataSent:
|
case MessageContentType::WebViewDataSent:
|
||||||
case MessageContentType::WebViewDataReceived:
|
case MessageContentType::WebViewDataReceived:
|
||||||
case MessageContentType::GiftPremium:
|
case MessageContentType::GiftPremium:
|
||||||
|
case MessageContentType::TopicCreate:
|
||||||
|
case MessageContentType::TopicEdit:
|
||||||
return string();
|
return string();
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -5681,6 +5838,23 @@ string get_message_content_search_text(const Td *td, const MessageContent *conte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool update_message_content_extended_media(MessageContent *content,
|
||||||
|
telegram_api::object_ptr<telegram_api::MessageExtendedMedia> extended_media,
|
||||||
|
DialogId owner_dialog_id, Td *td) {
|
||||||
|
CHECK(content != nullptr);
|
||||||
|
CHECK(content->get_type() == MessageContentType::Invoice);
|
||||||
|
return static_cast<MessageInvoice *>(content)->input_invoice.update_extended_media(std::move(extended_media),
|
||||||
|
owner_dialog_id, td);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool need_poll_message_content_extended_media(const MessageContent *content) {
|
||||||
|
CHECK(content != nullptr);
|
||||||
|
if (content->get_type() != MessageContentType::Invoice) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return static_cast<const MessageInvoice *>(content)->input_invoice.need_poll_extended_media();
|
||||||
|
}
|
||||||
|
|
||||||
void get_message_content_animated_emoji_click_sticker(const MessageContent *content, FullMessageId full_message_id,
|
void get_message_content_animated_emoji_click_sticker(const MessageContent *content, FullMessageId full_message_id,
|
||||||
Td *td, Promise<td_api::object_ptr<td_api::sticker>> &&promise) {
|
Td *td, Promise<td_api::object_ptr<td_api::sticker>> &&promise) {
|
||||||
if (content->get_type() != MessageContentType::Text) {
|
if (content->get_type() != MessageContentType::Text) {
|
||||||
@ -5718,6 +5892,10 @@ bool need_reget_message_content(const MessageContent *content) {
|
|||||||
const auto *m = static_cast<const MessageUnsupported *>(content);
|
const auto *m = static_cast<const MessageUnsupported *>(content);
|
||||||
return m->version != MessageUnsupported::CURRENT_VERSION;
|
return m->version != MessageUnsupported::CURRENT_VERSION;
|
||||||
}
|
}
|
||||||
|
case MessageContentType::Invoice: {
|
||||||
|
const auto *m = static_cast<const MessageInvoice *>(content);
|
||||||
|
return m->input_invoice.need_reget();
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -5927,6 +6105,10 @@ void add_message_content_dependencies(Dependencies &dependencies, const MessageC
|
|||||||
break;
|
break;
|
||||||
case MessageContentType::GiftPremium:
|
case MessageContentType::GiftPremium:
|
||||||
break;
|
break;
|
||||||
|
case MessageContentType::TopicCreate:
|
||||||
|
break;
|
||||||
|
case MessageContentType::TopicEdit:
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
break;
|
break;
|
||||||
@ -5934,6 +6116,21 @@ void add_message_content_dependencies(Dependencies &dependencies, const MessageC
|
|||||||
add_formatted_text_dependencies(dependencies, get_message_content_text(message_content));
|
add_formatted_text_dependencies(dependencies, get_message_content_text(message_content));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update_forum_topic_info_by_service_message_content(Td *td, const MessageContent *content, DialogId dialog_id,
|
||||||
|
MessageId top_thread_message_id) {
|
||||||
|
if (!top_thread_message_id.is_valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (content->get_type()) {
|
||||||
|
case MessageContentType::TopicEdit:
|
||||||
|
return td->forum_topic_manager_->on_forum_topic_edited(
|
||||||
|
dialog_id, top_thread_message_id, static_cast<const MessageTopicEdit *>(content)->edited_data);
|
||||||
|
default:
|
||||||
|
// nothing to do
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void on_sent_message_content(Td *td, const MessageContent *content) {
|
void on_sent_message_content(Td *td, const MessageContent *content) {
|
||||||
switch (content->get_type()) {
|
switch (content->get_type()) {
|
||||||
case MessageContentType::Animation:
|
case MessageContentType::Animation:
|
||||||
@ -5957,10 +6154,10 @@ void move_message_content_sticker_set_to_top(Td *td, const MessageContent *conte
|
|||||||
if (text == nullptr) {
|
if (text == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vector<int64> custom_emoji_ids;
|
vector<CustomEmojiId> custom_emoji_ids;
|
||||||
for (auto &entity : text->entities) {
|
for (auto &entity : text->entities) {
|
||||||
if (entity.type == MessageEntity::Type::CustomEmoji) {
|
if (entity.type == MessageEntity::Type::CustomEmoji) {
|
||||||
custom_emoji_ids.push_back(entity.document_id);
|
custom_emoji_ids.push_back(entity.custom_emoji_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!custom_emoji_ids.empty()) {
|
if (!custom_emoji_ids.empty()) {
|
||||||
@ -6017,4 +6214,28 @@ void update_used_hashtags(Td *td, const MessageContent *content) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void recognize_message_content_speech(Td *td, const MessageContent *content, FullMessageId full_message_id,
|
||||||
|
Promise<Unit> &&promise) {
|
||||||
|
switch (content->get_type()) {
|
||||||
|
case MessageContentType::VideoNote:
|
||||||
|
return td->video_notes_manager_->recognize_speech(full_message_id, std::move(promise));
|
||||||
|
case MessageContentType::VoiceNote:
|
||||||
|
return td->voice_notes_manager_->recognize_speech(full_message_id, std::move(promise));
|
||||||
|
default:
|
||||||
|
return promise.set_error(Status::Error(400, "Invalid message specified"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void rate_message_content_speech_recognition(Td *td, const MessageContent *content, FullMessageId full_message_id,
|
||||||
|
bool is_good, Promise<Unit> &&promise) {
|
||||||
|
switch (content->get_type()) {
|
||||||
|
case MessageContentType::VideoNote:
|
||||||
|
return td->video_notes_manager_->rate_speech_recognition(full_message_id, is_good, std::move(promise));
|
||||||
|
case MessageContentType::VoiceNote:
|
||||||
|
return td->voice_notes_manager_->rate_speech_recognition(full_message_id, is_good, std::move(promise));
|
||||||
|
default:
|
||||||
|
return promise.set_error(Status::Error(400, "Invalid message specified"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -216,6 +216,8 @@ int32 get_message_content_duration(const MessageContent *content, const Td *td);
|
|||||||
|
|
||||||
int32 get_message_content_media_duration(const MessageContent *content, const Td *td);
|
int32 get_message_content_media_duration(const MessageContent *content, const Td *td);
|
||||||
|
|
||||||
|
const Photo *get_message_content_photo(const MessageContent *content);
|
||||||
|
|
||||||
FileId get_message_content_upload_file_id(const MessageContent *content);
|
FileId get_message_content_upload_file_id(const MessageContent *content);
|
||||||
|
|
||||||
FileId get_message_content_any_file_id(const MessageContent *content);
|
FileId get_message_content_any_file_id(const MessageContent *content);
|
||||||
@ -228,6 +230,12 @@ vector<FileId> get_message_content_file_ids(const MessageContent *content, const
|
|||||||
|
|
||||||
string get_message_content_search_text(const Td *td, const MessageContent *content);
|
string get_message_content_search_text(const Td *td, const MessageContent *content);
|
||||||
|
|
||||||
|
bool update_message_content_extended_media(MessageContent *content,
|
||||||
|
telegram_api::object_ptr<telegram_api::MessageExtendedMedia> extended_media,
|
||||||
|
DialogId owner_dialog_id, Td *td);
|
||||||
|
|
||||||
|
bool need_poll_message_content_extended_media(const MessageContent *content);
|
||||||
|
|
||||||
void get_message_content_animated_emoji_click_sticker(const MessageContent *content, FullMessageId full_message_id,
|
void get_message_content_animated_emoji_click_sticker(const MessageContent *content, FullMessageId full_message_id,
|
||||||
Td *td, Promise<td_api::object_ptr<td_api::sticker>> &&promise);
|
Td *td, Promise<td_api::object_ptr<td_api::sticker>> &&promise);
|
||||||
|
|
||||||
@ -244,6 +252,9 @@ void update_failed_to_send_message_content(Td *td, unique_ptr<MessageContent> &c
|
|||||||
|
|
||||||
void add_message_content_dependencies(Dependencies &dependencies, const MessageContent *message_content);
|
void add_message_content_dependencies(Dependencies &dependencies, const MessageContent *message_content);
|
||||||
|
|
||||||
|
void update_forum_topic_info_by_service_message_content(Td *td, const MessageContent *content, DialogId dialog_id,
|
||||||
|
MessageId top_thread_message_id);
|
||||||
|
|
||||||
void on_sent_message_content(Td *td, const MessageContent *content);
|
void on_sent_message_content(Td *td, const MessageContent *content);
|
||||||
|
|
||||||
void move_message_content_sticker_set_to_top(Td *td, const MessageContent *content);
|
void move_message_content_sticker_set_to_top(Td *td, const MessageContent *content);
|
||||||
@ -256,4 +267,10 @@ void on_dialog_used(TopDialogCategory category, DialogId dialog_id, int32 date);
|
|||||||
|
|
||||||
void update_used_hashtags(Td *td, const MessageContent *content);
|
void update_used_hashtags(Td *td, const MessageContent *content);
|
||||||
|
|
||||||
|
void recognize_message_content_speech(Td *td, const MessageContent *content, FullMessageId full_message_id,
|
||||||
|
Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void rate_message_content_speech_recognition(Td *td, const MessageContent *content, FullMessageId full_message_id,
|
||||||
|
bool is_good, Promise<Unit> &&promise);
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -110,6 +110,10 @@ StringBuilder &operator<<(StringBuilder &string_builder, MessageContentType cont
|
|||||||
return string_builder << "WebViewDataReceived";
|
return string_builder << "WebViewDataReceived";
|
||||||
case MessageContentType::GiftPremium:
|
case MessageContentType::GiftPremium:
|
||||||
return string_builder << "GiftPremium";
|
return string_builder << "GiftPremium";
|
||||||
|
case MessageContentType::TopicCreate:
|
||||||
|
return string_builder << "TopicCreate";
|
||||||
|
case MessageContentType::TopicEdit:
|
||||||
|
return string_builder << "TopicEdit";
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return string_builder;
|
return string_builder;
|
||||||
@ -168,6 +172,8 @@ bool is_allowed_media_group_content(MessageContentType content_type) {
|
|||||||
case MessageContentType::WebViewDataSent:
|
case MessageContentType::WebViewDataSent:
|
||||||
case MessageContentType::WebViewDataReceived:
|
case MessageContentType::WebViewDataReceived:
|
||||||
case MessageContentType::GiftPremium:
|
case MessageContentType::GiftPremium:
|
||||||
|
case MessageContentType::TopicCreate:
|
||||||
|
case MessageContentType::TopicEdit:
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -234,6 +240,8 @@ bool is_secret_message_content(int32 ttl, MessageContentType content_type) {
|
|||||||
case MessageContentType::WebViewDataSent:
|
case MessageContentType::WebViewDataSent:
|
||||||
case MessageContentType::WebViewDataReceived:
|
case MessageContentType::WebViewDataReceived:
|
||||||
case MessageContentType::GiftPremium:
|
case MessageContentType::GiftPremium:
|
||||||
|
case MessageContentType::TopicCreate:
|
||||||
|
case MessageContentType::TopicEdit:
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -293,6 +301,8 @@ bool is_service_message_content(MessageContentType content_type) {
|
|||||||
case MessageContentType::WebViewDataSent:
|
case MessageContentType::WebViewDataSent:
|
||||||
case MessageContentType::WebViewDataReceived:
|
case MessageContentType::WebViewDataReceived:
|
||||||
case MessageContentType::GiftPremium:
|
case MessageContentType::GiftPremium:
|
||||||
|
case MessageContentType::TopicCreate:
|
||||||
|
case MessageContentType::TopicEdit:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -352,6 +362,8 @@ bool can_have_message_content_caption(MessageContentType content_type) {
|
|||||||
case MessageContentType::WebViewDataSent:
|
case MessageContentType::WebViewDataSent:
|
||||||
case MessageContentType::WebViewDataReceived:
|
case MessageContentType::WebViewDataReceived:
|
||||||
case MessageContentType::GiftPremium:
|
case MessageContentType::GiftPremium:
|
||||||
|
case MessageContentType::TopicCreate:
|
||||||
|
case MessageContentType::TopicEdit:
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -364,6 +376,7 @@ uint64 get_message_content_chain_id(MessageContentType content_type) {
|
|||||||
case MessageContentType::Animation:
|
case MessageContentType::Animation:
|
||||||
case MessageContentType::Audio:
|
case MessageContentType::Audio:
|
||||||
case MessageContentType::Document:
|
case MessageContentType::Document:
|
||||||
|
case MessageContentType::Invoice:
|
||||||
case MessageContentType::Photo:
|
case MessageContentType::Photo:
|
||||||
case MessageContentType::Sticker:
|
case MessageContentType::Sticker:
|
||||||
case MessageContentType::Video:
|
case MessageContentType::Video:
|
||||||
|
@ -64,7 +64,9 @@ enum class MessageContentType : int32 {
|
|||||||
ChatSetTheme,
|
ChatSetTheme,
|
||||||
WebViewDataSent,
|
WebViewDataSent,
|
||||||
WebViewDataReceived,
|
WebViewDataReceived,
|
||||||
GiftPremium
|
GiftPremium,
|
||||||
|
TopicCreate,
|
||||||
|
TopicEdit
|
||||||
};
|
};
|
||||||
|
|
||||||
StringBuilder &operator<<(StringBuilder &string_builder, MessageContentType content_type);
|
StringBuilder &operator<<(StringBuilder &string_builder, MessageContentType content_type);
|
||||||
|
@ -19,7 +19,6 @@ struct MessageCopyOptions {
|
|||||||
bool send_copy = false;
|
bool send_copy = false;
|
||||||
bool replace_caption = false;
|
bool replace_caption = false;
|
||||||
FormattedText new_caption;
|
FormattedText new_caption;
|
||||||
MessageId top_thread_message_id;
|
|
||||||
MessageId reply_to_message_id;
|
MessageId reply_to_message_id;
|
||||||
unique_ptr<ReplyMarkup> reply_markup;
|
unique_ptr<ReplyMarkup> reply_markup;
|
||||||
|
|
||||||
@ -31,8 +30,7 @@ struct MessageCopyOptions {
|
|||||||
if (!send_copy) {
|
if (!send_copy) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((replace_caption && !new_caption.text.empty()) || top_thread_message_id.is_valid() ||
|
if ((replace_caption && !new_caption.text.empty()) || reply_to_message_id.is_valid() || reply_markup != nullptr) {
|
||||||
reply_to_message_id.is_valid() || reply_markup != nullptr) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -45,9 +43,6 @@ inline StringBuilder &operator<<(StringBuilder &string_builder, MessageCopyOptio
|
|||||||
if (copy_options.replace_caption) {
|
if (copy_options.replace_caption) {
|
||||||
string_builder << ", new_caption = " << copy_options.new_caption;
|
string_builder << ", new_caption = " << copy_options.new_caption;
|
||||||
}
|
}
|
||||||
if (copy_options.top_thread_message_id.is_valid()) {
|
|
||||||
string_builder << ", in thread of " << copy_options.top_thread_message_id;
|
|
||||||
}
|
|
||||||
if (copy_options.reply_to_message_id.is_valid()) {
|
if (copy_options.reply_to_message_id.is_valid()) {
|
||||||
string_builder << ", in reply to " << copy_options.reply_to_message_id;
|
string_builder << ", in reply to " << copy_options.reply_to_message_id;
|
||||||
}
|
}
|
||||||
|
@ -122,8 +122,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, const MessageEntity &me
|
|||||||
if (message_entity.user_id.is_valid()) {
|
if (message_entity.user_id.is_valid()) {
|
||||||
string_builder << ", " << message_entity.user_id;
|
string_builder << ", " << message_entity.user_id;
|
||||||
}
|
}
|
||||||
if (message_entity.document_id != 0) {
|
if (message_entity.custom_emoji_id.is_valid()) {
|
||||||
string_builder << ", emoji = " << message_entity.document_id;
|
string_builder << ", " << message_entity.custom_emoji_id;
|
||||||
}
|
}
|
||||||
string_builder << ']';
|
string_builder << ']';
|
||||||
return string_builder;
|
return string_builder;
|
||||||
@ -173,7 +173,7 @@ tl_object_ptr<td_api::TextEntityType> MessageEntity::get_text_entity_type_object
|
|||||||
case MessageEntity::Type::Spoiler:
|
case MessageEntity::Type::Spoiler:
|
||||||
return make_tl_object<td_api::textEntityTypeSpoiler>();
|
return make_tl_object<td_api::textEntityTypeSpoiler>();
|
||||||
case MessageEntity::Type::CustomEmoji:
|
case MessageEntity::Type::CustomEmoji:
|
||||||
return make_tl_object<td_api::textEntityTypeCustomEmoji>(document_id);
|
return make_tl_object<td_api::textEntityTypeCustomEmoji>(custom_emoji_id.get());
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -1322,7 +1322,7 @@ vector<Slice> find_mentions(Slice str) {
|
|||||||
auto mentions = match_mentions(str);
|
auto mentions = match_mentions(str);
|
||||||
td::remove_if(mentions, [](Slice mention) {
|
td::remove_if(mentions, [](Slice mention) {
|
||||||
mention.remove_prefix(1);
|
mention.remove_prefix(1);
|
||||||
if (mention.size() >= 5) {
|
if (mention.size() >= 4) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto lowered_mention = to_lower(mention);
|
auto lowered_mention = to_lower(mention);
|
||||||
@ -1421,7 +1421,7 @@ void remove_empty_entities(vector<MessageEntity> &entities) {
|
|||||||
case MessageEntity::Type::MentionName:
|
case MessageEntity::Type::MentionName:
|
||||||
return !entity.user_id.is_valid();
|
return !entity.user_id.is_valid();
|
||||||
case MessageEntity::Type::CustomEmoji:
|
case MessageEntity::Type::CustomEmoji:
|
||||||
return entity.document_id == 0;
|
return !entity.custom_emoji_id.is_valid();
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1563,12 +1563,12 @@ static bool are_entities_valid(const vector<MessageEntity> &entities) {
|
|||||||
}
|
}
|
||||||
// parents are not pre after this point
|
// parents are not pre after this point
|
||||||
if (is_pre_entity(entity.type) && (nested_entity_type_mask & ~get_blockquote_entities_mask()) != 0) {
|
if (is_pre_entity(entity.type) && (nested_entity_type_mask & ~get_blockquote_entities_mask()) != 0) {
|
||||||
// Pre and Code can't be contained in other entities, except blockquote
|
// Pre and Code can't be part of other entities, except blockquote
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((is_continuous_entity(entity.type) || is_blockquote_entity(entity.type)) &&
|
if ((is_continuous_entity(entity.type) || is_blockquote_entity(entity.type)) &&
|
||||||
(nested_entity_type_mask & get_continuous_entities_mask()) != 0) {
|
(nested_entity_type_mask & get_continuous_entities_mask()) != 0) {
|
||||||
// continuous and blockquote can't be contained in continuous
|
// continuous and blockquote can't be part of other continuous entity
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((nested_entity_type_mask & get_splittable_entities_mask()) != 0) {
|
if ((nested_entity_type_mask & get_splittable_entities_mask()) != 0) {
|
||||||
@ -1793,7 +1793,7 @@ string get_first_url(const FormattedText &text) {
|
|||||||
if (entity.length <= 4) {
|
if (entity.length <= 4) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Slice url = utf8_utf16_substr(text.text, entity.offset, entity.length);
|
auto url = utf8_utf16_substr(text.text, entity.offset, entity.length);
|
||||||
string scheme = to_lower(url.substr(0, 4));
|
string scheme = to_lower(url.substr(0, 4));
|
||||||
if (scheme == "ton:" || begins_with(scheme, "tg:") || scheme == "ftp:" || is_plain_domain(url)) {
|
if (scheme == "ton:" || begins_with(scheme, "tg:") || scheme == "ftp:" || is_plain_domain(url)) {
|
||||||
continue;
|
continue;
|
||||||
@ -2126,7 +2126,7 @@ static Result<vector<MessageEntity>> do_parse_markdown_v2(CSlice text, string &r
|
|||||||
auto type = nested_entities.back().type;
|
auto type = nested_entities.back().type;
|
||||||
auto argument = std::move(nested_entities.back().argument);
|
auto argument = std::move(nested_entities.back().argument);
|
||||||
UserId user_id;
|
UserId user_id;
|
||||||
int64 document_id = 0;
|
CustomEmojiId custom_emoji_id;
|
||||||
bool skip_entity = utf16_offset == nested_entities.back().entity_offset;
|
bool skip_entity = utf16_offset == nested_entities.back().entity_offset;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case MessageEntity::Type::Bold:
|
case MessageEntity::Type::Bold:
|
||||||
@ -2192,7 +2192,7 @@ static Result<vector<MessageEntity>> do_parse_markdown_v2(CSlice text, string &r
|
|||||||
return Status::Error(400, PSLICE()
|
return Status::Error(400, PSLICE()
|
||||||
<< "Can't find end of a custom emoji URL at byte offset " << url_begin_pos);
|
<< "Can't find end of a custom emoji URL at byte offset " << url_begin_pos);
|
||||||
}
|
}
|
||||||
TRY_RESULT_ASSIGN(document_id, LinkManager::get_link_custom_emoji_document_id(url));
|
TRY_RESULT_ASSIGN(custom_emoji_id, LinkManager::get_link_custom_emoji_id(url));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -2205,8 +2205,8 @@ static Result<vector<MessageEntity>> do_parse_markdown_v2(CSlice text, string &r
|
|||||||
auto entity_length = utf16_offset - entity_offset;
|
auto entity_length = utf16_offset - entity_offset;
|
||||||
if (user_id.is_valid()) {
|
if (user_id.is_valid()) {
|
||||||
entities.emplace_back(entity_offset, entity_length, user_id);
|
entities.emplace_back(entity_offset, entity_length, user_id);
|
||||||
} else if (document_id != 0) {
|
} else if (custom_emoji_id.is_valid()) {
|
||||||
entities.emplace_back(type, entity_offset, entity_length, document_id);
|
entities.emplace_back(type, entity_offset, entity_length, custom_emoji_id);
|
||||||
} else {
|
} else {
|
||||||
entities.emplace_back(type, entity_offset, entity_length, std::move(argument));
|
entities.emplace_back(type, entity_offset, entity_length, std::move(argument));
|
||||||
}
|
}
|
||||||
@ -3170,7 +3170,8 @@ static Result<vector<MessageEntity>> do_parse_html(CSlice text, string &result)
|
|||||||
if (r_document_id.is_error() || r_document_id.ok() == 0) {
|
if (r_document_id.is_error() || r_document_id.ok() == 0) {
|
||||||
return Status::Error(400, "Invalid custom emoji identifier specified");
|
return Status::Error(400, "Invalid custom emoji identifier specified");
|
||||||
}
|
}
|
||||||
entities.emplace_back(MessageEntity::Type::CustomEmoji, entity_offset, entity_length, r_document_id.ok());
|
entities.emplace_back(MessageEntity::Type::CustomEmoji, entity_offset, entity_length,
|
||||||
|
CustomEmojiId(r_document_id.ok()));
|
||||||
} else if (tag_name == "a") {
|
} else if (tag_name == "a") {
|
||||||
auto url = std::move(nested_entities.back().argument);
|
auto url = std::move(nested_entities.back().argument);
|
||||||
if (url.empty()) {
|
if (url.empty()) {
|
||||||
@ -3308,8 +3309,8 @@ vector<tl_object_ptr<secret_api::MessageEntity>> get_input_secret_message_entiti
|
|||||||
break;
|
break;
|
||||||
case MessageEntity::Type::CustomEmoji:
|
case MessageEntity::Type::CustomEmoji:
|
||||||
if (layer >= static_cast<int32>(SecretChatLayer::SpoilerAndCustomEmojiEntities)) {
|
if (layer >= static_cast<int32>(SecretChatLayer::SpoilerAndCustomEmojiEntities)) {
|
||||||
result.push_back(
|
result.push_back(make_tl_object<secret_api::messageEntityCustomEmoji>(entity.offset, entity.length,
|
||||||
make_tl_object<secret_api::messageEntityCustomEmoji>(entity.offset, entity.length, entity.document_id));
|
entity.custom_emoji_id.get()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -3425,7 +3426,11 @@ Result<vector<MessageEntity>> get_message_entities(const ContactsManager *contac
|
|||||||
break;
|
break;
|
||||||
case td_api::textEntityTypeCustomEmoji::ID: {
|
case td_api::textEntityTypeCustomEmoji::ID: {
|
||||||
auto entity = static_cast<td_api::textEntityTypeCustomEmoji *>(input_entity->type_.get());
|
auto entity = static_cast<td_api::textEntityTypeCustomEmoji *>(input_entity->type_.get());
|
||||||
entities.emplace_back(MessageEntity::Type::CustomEmoji, offset, length, entity->custom_emoji_id_);
|
CustomEmojiId custom_emoji_id(entity->custom_emoji_id_);
|
||||||
|
if (!custom_emoji_id.is_valid()) {
|
||||||
|
return Status::Error(400, "Invalid custom emoji identifier specified");
|
||||||
|
}
|
||||||
|
entities.emplace_back(MessageEntity::Type::CustomEmoji, offset, length, custom_emoji_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -3564,7 +3569,8 @@ vector<MessageEntity> get_message_entities(const ContactsManager *contacts_manag
|
|||||||
}
|
}
|
||||||
case telegram_api::messageEntityCustomEmoji::ID: {
|
case telegram_api::messageEntityCustomEmoji::ID: {
|
||||||
auto entity = static_cast<const telegram_api::messageEntityCustomEmoji *>(server_entity.get());
|
auto entity = static_cast<const telegram_api::messageEntityCustomEmoji *>(server_entity.get());
|
||||||
entities.emplace_back(MessageEntity::Type::CustomEmoji, entity->offset_, entity->length_, entity->document_id_);
|
entities.emplace_back(MessageEntity::Type::CustomEmoji, entity->offset_, entity->length_,
|
||||||
|
CustomEmojiId(entity->document_id_));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -3580,7 +3586,7 @@ vector<MessageEntity> get_message_entities(Td *td, vector<tl_object_ptr<secret_a
|
|||||||
constexpr size_t MAX_CUSTOM_EMOJI_ENTITIES = 100;
|
constexpr size_t MAX_CUSTOM_EMOJI_ENTITIES = 100;
|
||||||
vector<MessageEntity> entities;
|
vector<MessageEntity> entities;
|
||||||
entities.reserve(secret_entities.size());
|
entities.reserve(secret_entities.size());
|
||||||
vector<int64> document_ids;
|
vector<CustomEmojiId> custom_emoji_ids;
|
||||||
for (auto &secret_entity : secret_entities) {
|
for (auto &secret_entity : secret_entities) {
|
||||||
switch (secret_entity->get_id()) {
|
switch (secret_entity->get_id()) {
|
||||||
case secret_api::messageEntityUnknown::ID:
|
case secret_api::messageEntityUnknown::ID:
|
||||||
@ -3683,11 +3689,11 @@ vector<MessageEntity> get_message_entities(Td *td, vector<tl_object_ptr<secret_a
|
|||||||
}
|
}
|
||||||
case secret_api::messageEntityCustomEmoji::ID: {
|
case secret_api::messageEntityCustomEmoji::ID: {
|
||||||
auto entity = static_cast<const secret_api::messageEntityCustomEmoji *>(secret_entity.get());
|
auto entity = static_cast<const secret_api::messageEntityCustomEmoji *>(secret_entity.get());
|
||||||
if (is_premium || !td->stickers_manager_->is_premium_custom_emoji(entity->document_id_, false)) {
|
CustomEmojiId custom_emoji_id(entity->document_id_);
|
||||||
if (document_ids.size() < MAX_CUSTOM_EMOJI_ENTITIES) {
|
if (is_premium || !td->stickers_manager_->is_premium_custom_emoji(custom_emoji_id, false)) {
|
||||||
entities.emplace_back(MessageEntity::Type::CustomEmoji, entity->offset_, entity->length_,
|
if (custom_emoji_ids.size() < MAX_CUSTOM_EMOJI_ENTITIES) {
|
||||||
entity->document_id_);
|
entities.emplace_back(MessageEntity::Type::CustomEmoji, entity->offset_, entity->length_, custom_emoji_id);
|
||||||
document_ids.push_back(entity->document_id_);
|
custom_emoji_ids.push_back(custom_emoji_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3701,10 +3707,10 @@ vector<MessageEntity> get_message_entities(Td *td, vector<tl_object_ptr<secret_a
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!document_ids.empty() && !is_premium) {
|
if (!custom_emoji_ids.empty() && !is_premium) {
|
||||||
// preload custom emoji to check that they aren't premium
|
// preload custom emoji to check that they aren't premium
|
||||||
td->stickers_manager_->get_custom_emoji_stickers(
|
td->stickers_manager_->get_custom_emoji_stickers(
|
||||||
std::move(document_ids), true,
|
std::move(custom_emoji_ids), true,
|
||||||
PromiseCreator::lambda(
|
PromiseCreator::lambda(
|
||||||
[promise = load_data_multipromise.get_promise()](td_api::object_ptr<td_api::stickers> result) mutable {
|
[promise = load_data_multipromise.get_promise()](td_api::object_ptr<td_api::stickers> result) mutable {
|
||||||
promise.set_value(Unit());
|
promise.set_value(Unit());
|
||||||
@ -4236,8 +4242,6 @@ Status fix_formatted_text(string &text, vector<MessageEntity> &entities, bool al
|
|||||||
// new whitespace-only entities could be added after splitting of entities
|
// new whitespace-only entities could be added after splitting of entities
|
||||||
remove_invalid_entities(text, entities);
|
remove_invalid_entities(text, entities);
|
||||||
|
|
||||||
// TODO MAX_MESSAGE_LENGTH and MAX_CAPTION_LENGTH
|
|
||||||
|
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4425,8 +4429,8 @@ vector<tl_object_ptr<telegram_api::MessageEntity>> get_input_message_entities(co
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MessageEntity::Type::CustomEmoji:
|
case MessageEntity::Type::CustomEmoji:
|
||||||
result.push_back(
|
result.push_back(make_tl_object<telegram_api::messageEntityCustomEmoji>(entity.offset, entity.length,
|
||||||
make_tl_object<telegram_api::messageEntityCustomEmoji>(entity.offset, entity.length, entity.document_id));
|
entity.custom_emoji_id.get()));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -4470,7 +4474,7 @@ vector<tl_object_ptr<telegram_api::MessageEntity>> get_input_message_entities(co
|
|||||||
void remove_premium_custom_emoji_entities(const Td *td, vector<MessageEntity> &entities, bool remove_unknown) {
|
void remove_premium_custom_emoji_entities(const Td *td, vector<MessageEntity> &entities, bool remove_unknown) {
|
||||||
td::remove_if(entities, [&](const MessageEntity &entity) {
|
td::remove_if(entities, [&](const MessageEntity &entity) {
|
||||||
return entity.type == MessageEntity::Type::CustomEmoji &&
|
return entity.type == MessageEntity::Type::CustomEmoji &&
|
||||||
td->stickers_manager_->is_premium_custom_emoji(entity.document_id, remove_unknown);
|
td->stickers_manager_->is_premium_custom_emoji(entity.custom_emoji_id, remove_unknown);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/CustomEmojiId.h"
|
||||||
#include "td/telegram/DialogId.h"
|
#include "td/telegram/DialogId.h"
|
||||||
#include "td/telegram/secret_api.h"
|
#include "td/telegram/secret_api.h"
|
||||||
#include "td/telegram/td_api.h"
|
#include "td/telegram/td_api.h"
|
||||||
@ -60,7 +61,7 @@ class MessageEntity {
|
|||||||
int32 media_timestamp = -1;
|
int32 media_timestamp = -1;
|
||||||
string argument;
|
string argument;
|
||||||
UserId user_id;
|
UserId user_id;
|
||||||
int64 document_id = 0;
|
CustomEmojiId custom_emoji_id;
|
||||||
|
|
||||||
MessageEntity() = default;
|
MessageEntity() = default;
|
||||||
|
|
||||||
@ -74,8 +75,8 @@ class MessageEntity {
|
|||||||
: type(type), offset(offset), length(length), media_timestamp(media_timestamp) {
|
: type(type), offset(offset), length(length), media_timestamp(media_timestamp) {
|
||||||
CHECK(type == Type::MediaTimestamp);
|
CHECK(type == Type::MediaTimestamp);
|
||||||
}
|
}
|
||||||
MessageEntity(Type type, int32 offset, int32 length, int64 document_id)
|
MessageEntity(Type type, int32 offset, int32 length, CustomEmojiId custom_emoji_id)
|
||||||
: type(type), offset(offset), length(length), document_id(document_id) {
|
: type(type), offset(offset), length(length), custom_emoji_id(custom_emoji_id) {
|
||||||
CHECK(type == Type::CustomEmoji);
|
CHECK(type == Type::CustomEmoji);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +85,7 @@ class MessageEntity {
|
|||||||
bool operator==(const MessageEntity &other) const {
|
bool operator==(const MessageEntity &other) const {
|
||||||
return offset == other.offset && length == other.length && type == other.type &&
|
return offset == other.offset && length == other.length && type == other.type &&
|
||||||
media_timestamp == other.media_timestamp && argument == other.argument && user_id == other.user_id &&
|
media_timestamp == other.media_timestamp && argument == other.argument && user_id == other.user_id &&
|
||||||
document_id == other.document_id;
|
custom_emoji_id == other.custom_emoji_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const MessageEntity &other) const {
|
bool operator<(const MessageEntity &other) const {
|
||||||
|
@ -28,7 +28,7 @@ void MessageEntity::store(StorerT &storer) const {
|
|||||||
store(media_timestamp, storer);
|
store(media_timestamp, storer);
|
||||||
}
|
}
|
||||||
if (type == Type::CustomEmoji) {
|
if (type == Type::CustomEmoji) {
|
||||||
store(document_id, storer);
|
store(custom_emoji_id, storer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ void MessageEntity::parse(ParserT &parser) {
|
|||||||
parse(media_timestamp, parser);
|
parse(media_timestamp, parser);
|
||||||
}
|
}
|
||||||
if (type == Type::CustomEmoji) {
|
if (type == Type::CustomEmoji) {
|
||||||
parse(document_id, parser);
|
parse(custom_emoji_id, parser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
328
td/telegram/MessageExtendedMedia.cpp
Normal file
328
td/telegram/MessageExtendedMedia.cpp
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#include "td/telegram/MessageExtendedMedia.h"
|
||||||
|
|
||||||
|
#include "td/telegram/Document.h"
|
||||||
|
#include "td/telegram/DocumentsManager.h"
|
||||||
|
#include "td/telegram/MessageContent.h"
|
||||||
|
#include "td/telegram/MessageContentType.h"
|
||||||
|
#include "td/telegram/PhotoSize.h"
|
||||||
|
#include "td/telegram/Td.h"
|
||||||
|
#include "td/telegram/VideosManager.h"
|
||||||
|
|
||||||
|
#include "td/utils/algorithm.h"
|
||||||
|
#include "td/utils/logging.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
MessageExtendedMedia::MessageExtendedMedia(
|
||||||
|
Td *td, telegram_api::object_ptr<telegram_api::MessageExtendedMedia> &&extended_media, FormattedText &&caption,
|
||||||
|
DialogId owner_dialog_id) {
|
||||||
|
if (extended_media == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
caption_ = std::move(caption);
|
||||||
|
|
||||||
|
switch (extended_media->get_id()) {
|
||||||
|
case telegram_api::messageExtendedMediaPreview::ID: {
|
||||||
|
auto media = move_tl_object_as<telegram_api::messageExtendedMediaPreview>(extended_media);
|
||||||
|
type_ = Type::Preview;
|
||||||
|
duration_ = media->video_duration_;
|
||||||
|
dimensions_ = get_dimensions(media->w_, media->h_, "MessageExtendedMedia");
|
||||||
|
if (media->thumb_ != nullptr) {
|
||||||
|
if (media->thumb_->get_id() == telegram_api::photoStrippedSize::ID) {
|
||||||
|
auto thumb = move_tl_object_as<telegram_api::photoStrippedSize>(media->thumb_);
|
||||||
|
minithumbnail_ = thumb->bytes_.as_slice().str();
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << "Receive " << to_string(media->thumb_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case telegram_api::messageExtendedMedia::ID: {
|
||||||
|
auto media = move_tl_object_as<telegram_api::messageExtendedMedia>(extended_media);
|
||||||
|
type_ = Type::Unsupported;
|
||||||
|
switch (media->media_->get_id()) {
|
||||||
|
case telegram_api::messageMediaPhoto::ID: {
|
||||||
|
auto photo = move_tl_object_as<telegram_api::messageMediaPhoto>(media->media_);
|
||||||
|
if (photo->photo_ == nullptr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
photo_ = get_photo(td->file_manager_.get(), std::move(photo->photo_), owner_dialog_id);
|
||||||
|
if (photo_.is_empty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
type_ = Type::Photo;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case telegram_api::messageMediaDocument::ID: {
|
||||||
|
auto document = move_tl_object_as<telegram_api::messageMediaDocument>(media->media_);
|
||||||
|
if (document->document_ == nullptr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto document_ptr = std::move(document->document_);
|
||||||
|
int32 document_id = document_ptr->get_id();
|
||||||
|
if (document_id == telegram_api::documentEmpty::ID) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
CHECK(document_id == telegram_api::document::ID);
|
||||||
|
|
||||||
|
auto parsed_document = td->documents_manager_->on_get_document(
|
||||||
|
move_tl_object_as<telegram_api::document>(document_ptr), owner_dialog_id, nullptr);
|
||||||
|
if (parsed_document.empty() || parsed_document.type != Document::Type::Video) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
CHECK(parsed_document.file_id.is_valid());
|
||||||
|
video_file_id_ = parsed_document.file_id;
|
||||||
|
type_ = Type::Video;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (type_ == Type::Unsupported) {
|
||||||
|
unsupported_version_ = CURRENT_VERSION;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<MessageExtendedMedia> MessageExtendedMedia::get_message_extended_media(
|
||||||
|
Td *td, td_api::object_ptr<td_api::InputMessageContent> &&extended_media_content, DialogId owner_dialog_id,
|
||||||
|
bool is_premium) {
|
||||||
|
if (extended_media_content == nullptr) {
|
||||||
|
return MessageExtendedMedia();
|
||||||
|
}
|
||||||
|
if (!owner_dialog_id.is_valid()) {
|
||||||
|
return Status::Error(400, "Extended media can't be added to the invoice");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto input_content_type = extended_media_content->get_id();
|
||||||
|
if (input_content_type != td_api::inputMessagePhoto::ID && input_content_type != td_api::inputMessageVideo::ID) {
|
||||||
|
return Status::Error("Invalid extended media content specified");
|
||||||
|
}
|
||||||
|
TRY_RESULT(input_message_content,
|
||||||
|
get_input_message_content(owner_dialog_id, std::move(extended_media_content), td, is_premium));
|
||||||
|
if (input_message_content.ttl != 0) {
|
||||||
|
return Status::Error("Can't use self-destructing extended media");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto content = input_message_content.content.get();
|
||||||
|
auto content_type = content->get_type();
|
||||||
|
MessageExtendedMedia result;
|
||||||
|
CHECK(content_type == MessageContentType::Photo || content_type == MessageContentType::Video);
|
||||||
|
result.caption_ = *get_message_content_caption(content);
|
||||||
|
if (content_type == MessageContentType::Photo) {
|
||||||
|
result.type_ = Type::Photo;
|
||||||
|
result.photo_ = *get_message_content_photo(content);
|
||||||
|
} else {
|
||||||
|
CHECK(content_type == MessageContentType::Video);
|
||||||
|
result.type_ = Type::Video;
|
||||||
|
result.video_file_id_ = get_message_content_upload_file_id(content);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageExtendedMedia::update_from(const MessageExtendedMedia &old_extended_media) {
|
||||||
|
if (!is_media() && old_extended_media.is_media()) {
|
||||||
|
*this = old_extended_media;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MessageExtendedMedia::update_to(Td *td,
|
||||||
|
telegram_api::object_ptr<telegram_api::MessageExtendedMedia> extended_media_ptr,
|
||||||
|
DialogId owner_dialog_id) {
|
||||||
|
MessageExtendedMedia new_extended_media(td, std::move(extended_media_ptr), FormattedText(caption_), owner_dialog_id);
|
||||||
|
if (!new_extended_media.is_media() && is_media()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (*this != new_extended_media || is_equal_but_different(new_extended_media)) {
|
||||||
|
*this = std::move(new_extended_media);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
td_api::object_ptr<td_api::MessageExtendedMedia> MessageExtendedMedia::get_message_extended_media_object(
|
||||||
|
Td *td, bool skip_bot_commands, int32 max_media_timestamp) const {
|
||||||
|
if (type_ == Type::Empty) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto caption = get_formatted_text_object(caption_, skip_bot_commands, max_media_timestamp);
|
||||||
|
switch (type_) {
|
||||||
|
case Type::Unsupported:
|
||||||
|
return td_api::make_object<td_api::messageExtendedMediaUnsupported>(std::move(caption));
|
||||||
|
case Type::Preview:
|
||||||
|
return td_api::make_object<td_api::messageExtendedMediaPreview>(dimensions_.width, dimensions_.height, duration_,
|
||||||
|
get_minithumbnail_object(minithumbnail_),
|
||||||
|
std::move(caption));
|
||||||
|
case Type::Photo: {
|
||||||
|
auto photo = get_photo_object(td->file_manager_.get(), photo_);
|
||||||
|
CHECK(photo != nullptr);
|
||||||
|
return td_api::make_object<td_api::messageExtendedMediaPhoto>(std::move(photo), std::move(caption));
|
||||||
|
}
|
||||||
|
case Type::Video:
|
||||||
|
return td_api::make_object<td_api::messageExtendedMediaVideo>(
|
||||||
|
td->videos_manager_->get_video_object(video_file_id_), std::move(caption));
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageExtendedMedia::append_file_ids(const Td *td, vector<FileId> &file_ids) const {
|
||||||
|
switch (type_) {
|
||||||
|
case Type::Empty:
|
||||||
|
case Type::Unsupported:
|
||||||
|
case Type::Preview:
|
||||||
|
break;
|
||||||
|
case Type::Photo:
|
||||||
|
append(file_ids, photo_get_file_ids(photo_));
|
||||||
|
break;
|
||||||
|
case Type::Video:
|
||||||
|
Document(Document::Type::Video, video_file_id_).append_file_ids(td, file_ids);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageExtendedMedia::delete_thumbnail(Td *td) {
|
||||||
|
switch (type_) {
|
||||||
|
case Type::Empty:
|
||||||
|
case Type::Unsupported:
|
||||||
|
case Type::Preview:
|
||||||
|
break;
|
||||||
|
case Type::Photo:
|
||||||
|
photo_delete_thumbnail(photo_);
|
||||||
|
break;
|
||||||
|
case Type::Video:
|
||||||
|
td->videos_manager_->delete_video_thumbnail(video_file_id_);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 MessageExtendedMedia::get_duration(const Td *td) const {
|
||||||
|
if (!has_media_timestamp()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return td->videos_manager_->get_video_duration(video_file_id_);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileId MessageExtendedMedia::get_upload_file_id() const {
|
||||||
|
switch (type_) {
|
||||||
|
case Type::Empty:
|
||||||
|
case Type::Unsupported:
|
||||||
|
case Type::Preview:
|
||||||
|
break;
|
||||||
|
case Type::Photo:
|
||||||
|
return get_photo_upload_file_id(photo_);
|
||||||
|
case Type::Video:
|
||||||
|
return video_file_id_;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return FileId();
|
||||||
|
}
|
||||||
|
|
||||||
|
FileId MessageExtendedMedia::get_any_file_id() const {
|
||||||
|
switch (type_) {
|
||||||
|
case Type::Empty:
|
||||||
|
case Type::Unsupported:
|
||||||
|
case Type::Preview:
|
||||||
|
break;
|
||||||
|
case Type::Photo:
|
||||||
|
return get_photo_any_file_id(photo_);
|
||||||
|
case Type::Video:
|
||||||
|
return video_file_id_;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return FileId();
|
||||||
|
}
|
||||||
|
|
||||||
|
FileId MessageExtendedMedia::get_thumbnail_file_id(const Td *td) const {
|
||||||
|
switch (type_) {
|
||||||
|
case Type::Empty:
|
||||||
|
case Type::Unsupported:
|
||||||
|
case Type::Preview:
|
||||||
|
break;
|
||||||
|
case Type::Photo:
|
||||||
|
return get_photo_thumbnail_file_id(photo_);
|
||||||
|
case Type::Video:
|
||||||
|
return td->videos_manager_->get_video_thumbnail_file_id(video_file_id_);
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return FileId();
|
||||||
|
}
|
||||||
|
|
||||||
|
telegram_api::object_ptr<telegram_api::InputMedia> MessageExtendedMedia::get_input_media(
|
||||||
|
Td *td, tl_object_ptr<telegram_api::InputFile> input_file,
|
||||||
|
tl_object_ptr<telegram_api::InputFile> input_thumbnail) const {
|
||||||
|
switch (type_) {
|
||||||
|
case Type::Empty:
|
||||||
|
case Type::Unsupported:
|
||||||
|
case Type::Preview:
|
||||||
|
break;
|
||||||
|
case Type::Photo:
|
||||||
|
return photo_get_input_media(td->file_manager_.get(), photo_, std::move(input_file), 0);
|
||||||
|
case Type::Video:
|
||||||
|
return td->videos_manager_->get_input_media(video_file_id_, std::move(input_file), std::move(input_thumbnail), 0);
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MessageExtendedMedia::is_equal_but_different(const MessageExtendedMedia &other) const {
|
||||||
|
return type_ == Type::Unsupported && other.type_ == Type::Unsupported &&
|
||||||
|
unsupported_version_ != other.unsupported_version_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const MessageExtendedMedia &lhs, const MessageExtendedMedia &rhs) {
|
||||||
|
if (lhs.type_ != rhs.type_ || lhs.caption_ != rhs.caption_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
switch (lhs.type_) {
|
||||||
|
case MessageExtendedMedia::Type::Empty:
|
||||||
|
return true;
|
||||||
|
case MessageExtendedMedia::Type::Unsupported:
|
||||||
|
// don't compare unsupported_version_
|
||||||
|
return true;
|
||||||
|
case MessageExtendedMedia::Type::Preview:
|
||||||
|
return lhs.duration_ == rhs.duration_ && lhs.dimensions_ == rhs.dimensions_ &&
|
||||||
|
lhs.minithumbnail_ == rhs.minithumbnail_;
|
||||||
|
case MessageExtendedMedia::Type::Photo:
|
||||||
|
return lhs.photo_ == rhs.photo_;
|
||||||
|
case MessageExtendedMedia::Type::Video:
|
||||||
|
return lhs.video_file_id_ == rhs.video_file_id_;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const MessageExtendedMedia &lhs, const MessageExtendedMedia &rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
118
td/telegram/MessageExtendedMedia.h
Normal file
118
td/telegram/MessageExtendedMedia.h
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/DialogId.h"
|
||||||
|
#include "td/telegram/Dimensions.h"
|
||||||
|
#include "td/telegram/files/FileId.h"
|
||||||
|
#include "td/telegram/MessageEntity.h"
|
||||||
|
#include "td/telegram/Photo.h"
|
||||||
|
#include "td/telegram/td_api.h"
|
||||||
|
#include "td/telegram/telegram_api.h"
|
||||||
|
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/Status.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class Td;
|
||||||
|
|
||||||
|
class MessageExtendedMedia {
|
||||||
|
enum class Type : int32 { Empty, Unsupported, Preview, Photo, Video };
|
||||||
|
Type type_ = Type::Empty;
|
||||||
|
FormattedText caption_;
|
||||||
|
|
||||||
|
static constexpr int32 CURRENT_VERSION = 1;
|
||||||
|
|
||||||
|
// for Unsupported
|
||||||
|
int32 unsupported_version_ = 0;
|
||||||
|
|
||||||
|
// for Preview
|
||||||
|
int32 duration_ = 0;
|
||||||
|
Dimensions dimensions_;
|
||||||
|
string minithumbnail_;
|
||||||
|
|
||||||
|
// for Photo
|
||||||
|
Photo photo_;
|
||||||
|
|
||||||
|
// for Video
|
||||||
|
FileId video_file_id_;
|
||||||
|
|
||||||
|
friend bool operator==(const MessageExtendedMedia &lhs, const MessageExtendedMedia &rhs);
|
||||||
|
|
||||||
|
bool is_media() const {
|
||||||
|
return type_ != Type::Empty && type_ != Type::Preview;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
MessageExtendedMedia() = default;
|
||||||
|
|
||||||
|
MessageExtendedMedia(Td *td, telegram_api::object_ptr<telegram_api::MessageExtendedMedia> &&extended_media,
|
||||||
|
FormattedText &&caption, DialogId owner_dialog_id);
|
||||||
|
|
||||||
|
static Result<MessageExtendedMedia> get_message_extended_media(
|
||||||
|
Td *td, td_api::object_ptr<td_api::InputMessageContent> &&extended_media_content, DialogId owner_dialog_id,
|
||||||
|
bool is_premium);
|
||||||
|
|
||||||
|
bool is_empty() const {
|
||||||
|
return type_ == Type::Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_from(const MessageExtendedMedia &old_extended_media);
|
||||||
|
|
||||||
|
bool update_to(Td *td, telegram_api::object_ptr<telegram_api::MessageExtendedMedia> extended_media_ptr,
|
||||||
|
DialogId owner_dialog_id);
|
||||||
|
|
||||||
|
td_api::object_ptr<td_api::MessageExtendedMedia> get_message_extended_media_object(Td *td, bool skip_bot_commands,
|
||||||
|
int32 max_media_timestamp) const;
|
||||||
|
|
||||||
|
void append_file_ids(const Td *td, vector<FileId> &file_ids) const;
|
||||||
|
|
||||||
|
void delete_thumbnail(Td *td);
|
||||||
|
|
||||||
|
bool need_reget() const {
|
||||||
|
return type_ == Type::Unsupported && unsupported_version_ < CURRENT_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool need_poll() const {
|
||||||
|
return type_ == Type::Preview;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_media_timestamp() const {
|
||||||
|
return type_ == Type::Video;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_equal_but_different(const MessageExtendedMedia &other) const;
|
||||||
|
|
||||||
|
int32 get_duration(const Td *td) const;
|
||||||
|
|
||||||
|
const FormattedText *get_caption() const {
|
||||||
|
return &caption_;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileId get_upload_file_id() const;
|
||||||
|
|
||||||
|
FileId get_any_file_id() const;
|
||||||
|
|
||||||
|
FileId get_thumbnail_file_id(const Td *td) const;
|
||||||
|
|
||||||
|
telegram_api::object_ptr<telegram_api::InputMedia> get_input_media(
|
||||||
|
Td *td, tl_object_ptr<telegram_api::InputFile> input_file,
|
||||||
|
tl_object_ptr<telegram_api::InputFile> input_thumbnail) const;
|
||||||
|
|
||||||
|
template <class StorerT>
|
||||||
|
void store(StorerT &storer) const;
|
||||||
|
|
||||||
|
template <class ParserT>
|
||||||
|
void parse(ParserT &parser);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(const MessageExtendedMedia &lhs, const MessageExtendedMedia &rhs);
|
||||||
|
|
||||||
|
bool operator!=(const MessageExtendedMedia &lhs, const MessageExtendedMedia &rhs);
|
||||||
|
|
||||||
|
} // namespace td
|
115
td/telegram/MessageExtendedMedia.hpp
Normal file
115
td/telegram/MessageExtendedMedia.hpp
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/MessageExtendedMedia.h"
|
||||||
|
#include "td/telegram/Photo.hpp"
|
||||||
|
#include "td/telegram/Td.h"
|
||||||
|
#include "td/telegram/VideosManager.h"
|
||||||
|
|
||||||
|
#include "td/utils/logging.h"
|
||||||
|
#include "td/utils/tl_helpers.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
template <class StorerT>
|
||||||
|
void MessageExtendedMedia::store(StorerT &storer) const {
|
||||||
|
bool has_caption = !caption_.text.empty();
|
||||||
|
bool has_unsupported_version = unsupported_version_ != 0;
|
||||||
|
bool has_duration = duration_ != 0;
|
||||||
|
bool has_dimensions = dimensions_.width != 0 || dimensions_.height != 0;
|
||||||
|
bool has_minithumbnail = !minithumbnail_.empty();
|
||||||
|
bool has_photo = !photo_.is_empty();
|
||||||
|
bool has_video = video_file_id_.is_valid();
|
||||||
|
BEGIN_STORE_FLAGS();
|
||||||
|
STORE_FLAG(has_caption);
|
||||||
|
STORE_FLAG(has_unsupported_version);
|
||||||
|
STORE_FLAG(has_duration);
|
||||||
|
STORE_FLAG(has_dimensions);
|
||||||
|
STORE_FLAG(has_minithumbnail);
|
||||||
|
STORE_FLAG(has_photo);
|
||||||
|
STORE_FLAG(has_video);
|
||||||
|
END_STORE_FLAGS();
|
||||||
|
td::store(type_, storer);
|
||||||
|
if (has_caption) {
|
||||||
|
td::store(caption_, storer);
|
||||||
|
}
|
||||||
|
if (has_unsupported_version) {
|
||||||
|
td::store(unsupported_version_, storer);
|
||||||
|
}
|
||||||
|
if (has_duration) {
|
||||||
|
td::store(duration_, storer);
|
||||||
|
}
|
||||||
|
if (has_dimensions) {
|
||||||
|
td::store(dimensions_, storer);
|
||||||
|
}
|
||||||
|
if (has_minithumbnail) {
|
||||||
|
td::store(minithumbnail_, storer);
|
||||||
|
}
|
||||||
|
if (has_photo) {
|
||||||
|
td::store(photo_, storer);
|
||||||
|
}
|
||||||
|
if (has_video) {
|
||||||
|
Td *td = storer.context()->td().get_actor_unsafe();
|
||||||
|
td->videos_manager_->store_video(video_file_id_, storer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ParserT>
|
||||||
|
void MessageExtendedMedia::parse(ParserT &parser) {
|
||||||
|
bool has_caption;
|
||||||
|
bool has_unsupported_version;
|
||||||
|
bool has_duration;
|
||||||
|
bool has_dimensions;
|
||||||
|
bool has_minithumbnail;
|
||||||
|
bool has_photo;
|
||||||
|
bool has_video;
|
||||||
|
BEGIN_PARSE_FLAGS();
|
||||||
|
PARSE_FLAG(has_caption);
|
||||||
|
PARSE_FLAG(has_unsupported_version);
|
||||||
|
PARSE_FLAG(has_duration);
|
||||||
|
PARSE_FLAG(has_dimensions);
|
||||||
|
PARSE_FLAG(has_minithumbnail);
|
||||||
|
PARSE_FLAG(has_photo);
|
||||||
|
PARSE_FLAG(has_video);
|
||||||
|
END_PARSE_FLAGS();
|
||||||
|
td::parse(type_, parser);
|
||||||
|
if (has_caption) {
|
||||||
|
td::parse(caption_, parser);
|
||||||
|
}
|
||||||
|
if (has_unsupported_version) {
|
||||||
|
td::parse(unsupported_version_, parser);
|
||||||
|
}
|
||||||
|
if (has_duration) {
|
||||||
|
td::parse(duration_, parser);
|
||||||
|
}
|
||||||
|
if (has_dimensions) {
|
||||||
|
td::parse(dimensions_, parser);
|
||||||
|
}
|
||||||
|
if (has_minithumbnail) {
|
||||||
|
td::parse(minithumbnail_, parser);
|
||||||
|
}
|
||||||
|
bool is_bad = false;
|
||||||
|
if (has_photo) {
|
||||||
|
td::parse(photo_, parser);
|
||||||
|
is_bad = photo_.is_bad();
|
||||||
|
}
|
||||||
|
if (has_video) {
|
||||||
|
Td *td = parser.context()->td().get_actor_unsafe();
|
||||||
|
video_file_id_ = td->videos_manager_->parse_video(parser);
|
||||||
|
is_bad = !video_file_id_.is_valid();
|
||||||
|
}
|
||||||
|
if (is_bad) {
|
||||||
|
LOG(ERROR) << "Failed to parse MessageExtendedMedia";
|
||||||
|
photo_ = Photo();
|
||||||
|
video_file_id_ = FileId();
|
||||||
|
type_ = Type::Unsupported;
|
||||||
|
unsupported_version_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
@ -23,6 +23,8 @@ struct MessageLinkInfo {
|
|||||||
bool is_single = false;
|
bool is_single = false;
|
||||||
int32 media_timestamp = 0;
|
int32 media_timestamp = 0;
|
||||||
|
|
||||||
|
MessageId top_thread_message_id;
|
||||||
|
|
||||||
DialogId comment_dialog_id;
|
DialogId comment_dialog_id;
|
||||||
MessageId comment_message_id;
|
MessageId comment_message_id;
|
||||||
bool for_comment = false;
|
bool for_comment = false;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "td/telegram/AccessRights.h"
|
#include "td/telegram/AccessRights.h"
|
||||||
#include "td/telegram/ConfigManager.h"
|
#include "td/telegram/ConfigManager.h"
|
||||||
#include "td/telegram/ContactsManager.h"
|
#include "td/telegram/ContactsManager.h"
|
||||||
|
#include "td/telegram/Dependencies.h"
|
||||||
#include "td/telegram/Global.h"
|
#include "td/telegram/Global.h"
|
||||||
#include "td/telegram/MessageSender.h"
|
#include "td/telegram/MessageSender.h"
|
||||||
#include "td/telegram/MessagesManager.h"
|
#include "td/telegram/MessagesManager.h"
|
||||||
@ -29,6 +30,8 @@
|
|||||||
#include "td/utils/emoji.h"
|
#include "td/utils/emoji.h"
|
||||||
#include "td/utils/FlatHashSet.h"
|
#include "td/utils/FlatHashSet.h"
|
||||||
#include "td/utils/logging.h"
|
#include "td/utils/logging.h"
|
||||||
|
#include "td/utils/Slice.h"
|
||||||
|
#include "td/utils/SliceBuilder.h"
|
||||||
#include "td/utils/Status.h"
|
#include "td/utils/Status.h"
|
||||||
#include "td/utils/utf8.h"
|
#include "td/utils/utf8.h"
|
||||||
|
|
||||||
@ -219,6 +222,9 @@ class SendReactionQuery final : public Td::ResultHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void on_error(Status status) final {
|
void on_error(Status status) final {
|
||||||
|
if (status.message() == "MESSAGE_NOT_MODIFIED") {
|
||||||
|
return promise_.set_value(Unit());
|
||||||
|
}
|
||||||
td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SendReactionQuery");
|
td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SendReactionQuery");
|
||||||
promise_.set_error(std::move(status));
|
promise_.set_error(std::move(status));
|
||||||
}
|
}
|
||||||
@ -550,19 +556,19 @@ unique_ptr<MessageReactions> MessageReactions::get_message_reactions(
|
|||||||
if (dialog_type == DialogType::User) {
|
if (dialog_type == DialogType::User) {
|
||||||
auto user_id = dialog_id.get_user_id();
|
auto user_id = dialog_id.get_user_id();
|
||||||
if (!td->contacts_manager_->have_min_user(user_id)) {
|
if (!td->contacts_manager_->have_min_user(user_id)) {
|
||||||
LOG(ERROR) << "Have no info about " << user_id;
|
LOG(ERROR) << "Receive unknown " << user_id;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (dialog_type == DialogType::Channel) {
|
} else if (dialog_type == DialogType::Channel) {
|
||||||
auto channel_id = dialog_id.get_channel_id();
|
auto channel_id = dialog_id.get_channel_id();
|
||||||
auto min_channel = td->contacts_manager_->get_min_channel(channel_id);
|
auto min_channel = td->contacts_manager_->get_min_channel(channel_id);
|
||||||
if (min_channel == nullptr) {
|
if (min_channel == nullptr) {
|
||||||
LOG(ERROR) << "Have no info about reacted " << channel_id;
|
LOG(ERROR) << "Receive unknown reacted " << channel_id;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
recent_chooser_min_channels.emplace_back(channel_id, *min_channel);
|
recent_chooser_min_channels.emplace_back(channel_id, *min_channel);
|
||||||
} else {
|
} else {
|
||||||
LOG(ERROR) << "Have no info about reacted " << dialog_id;
|
LOG(ERROR) << "Receive unknown reacted " << dialog_id;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -762,6 +768,69 @@ vector<string> MessageReactions::get_chosen_reactions() const {
|
|||||||
return reaction_order;
|
return reaction_order;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MessageReactions::are_consistent_with_list(const string &reaction, FlatHashMap<string, vector<DialogId>> reactions,
|
||||||
|
int32 total_count) const {
|
||||||
|
auto are_consistent = [](const vector<DialogId> &lhs, const vector<DialogId> &rhs) {
|
||||||
|
size_t i = 0;
|
||||||
|
size_t max_i = td::min(lhs.size(), rhs.size());
|
||||||
|
while (i < max_i && lhs[i] == rhs[i]) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return i == max_i;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (reaction.empty()) {
|
||||||
|
// received list and total_count for all reactions
|
||||||
|
int32 old_total_count = 0;
|
||||||
|
for (const auto &message_reaction : reactions_) {
|
||||||
|
CHECK(!message_reaction.get_reaction().empty());
|
||||||
|
if (!are_consistent(reactions[message_reaction.get_reaction()],
|
||||||
|
message_reaction.get_recent_chooser_dialog_ids())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
old_total_count += message_reaction.get_choose_count();
|
||||||
|
reactions.erase(message_reaction.get_reaction());
|
||||||
|
}
|
||||||
|
return old_total_count == total_count && reactions.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// received list and total_count for a single reaction
|
||||||
|
const auto *message_reaction = get_reaction(reaction);
|
||||||
|
if (message_reaction == nullptr) {
|
||||||
|
return reactions.count(reaction) == 0 && total_count == 0;
|
||||||
|
} else {
|
||||||
|
return are_consistent(reactions[reaction], message_reaction->get_recent_chooser_dialog_ids()) &&
|
||||||
|
message_reaction->get_choose_count() == total_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<td_api::object_ptr<td_api::messageReaction>> MessageReactions::get_message_reactions_object(
|
||||||
|
Td *td, UserId my_user_id, UserId peer_user_id) const {
|
||||||
|
return transform(reactions_, [td, my_user_id, peer_user_id](const MessageReaction &reaction) {
|
||||||
|
return reaction.get_message_reaction_object(td, my_user_id, peer_user_id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageReactions::add_min_channels(Td *td) const {
|
||||||
|
for (const auto &reaction : reactions_) {
|
||||||
|
for (const auto &recent_chooser_min_channel : reaction.get_recent_chooser_min_channels()) {
|
||||||
|
LOG(INFO) << "Add min reacted " << recent_chooser_min_channel.first;
|
||||||
|
td->contacts_manager_->add_min_channel(recent_chooser_min_channel.first, recent_chooser_min_channel.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageReactions::add_dependencies(Dependencies &dependencies) const {
|
||||||
|
for (const auto &reaction : reactions_) {
|
||||||
|
const auto &dialog_ids = reaction.get_recent_chooser_dialog_ids();
|
||||||
|
for (auto dialog_id : dialog_ids) {
|
||||||
|
// don't load the dialog itself
|
||||||
|
// it will be created in get_message_reaction_object if needed
|
||||||
|
dependencies.add_dialog_dependencies(dialog_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool MessageReactions::need_update_message_reactions(const MessageReactions *old_reactions,
|
bool MessageReactions::need_update_message_reactions(const MessageReactions *old_reactions,
|
||||||
const MessageReactions *new_reactions) {
|
const MessageReactions *new_reactions) {
|
||||||
if (old_reactions == nullptr) {
|
if (old_reactions == nullptr) {
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "td/telegram/MinChannel.h"
|
#include "td/telegram/MinChannel.h"
|
||||||
#include "td/telegram/td_api.h"
|
#include "td/telegram/td_api.h"
|
||||||
#include "td/telegram/telegram_api.h"
|
#include "td/telegram/telegram_api.h"
|
||||||
|
#include "td/telegram/UserId.h"
|
||||||
|
|
||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
#include "td/utils/FlatHashMap.h"
|
#include "td/utils/FlatHashMap.h"
|
||||||
@ -23,9 +24,15 @@
|
|||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
|
class Dependencies;
|
||||||
|
|
||||||
class Td;
|
class Td;
|
||||||
|
|
||||||
class MessageReaction {
|
class MessageReaction {
|
||||||
|
static constexpr int32 MAX_CHOOSE_COUNT = 2147483640;
|
||||||
|
|
||||||
|
static constexpr size_t MAX_RECENT_CHOOSERS = 3;
|
||||||
|
|
||||||
string reaction_;
|
string reaction_;
|
||||||
int32 choose_count_ = 0;
|
int32 choose_count_ = 0;
|
||||||
bool is_chosen_ = false;
|
bool is_chosen_ = false;
|
||||||
@ -63,16 +70,6 @@ class MessageReaction {
|
|||||||
|
|
||||||
void update_recent_chooser_dialog_ids(const MessageReaction &old_reaction);
|
void update_recent_chooser_dialog_ids(const MessageReaction &old_reaction);
|
||||||
|
|
||||||
public:
|
|
||||||
static constexpr size_t MAX_RECENT_CHOOSERS = 3;
|
|
||||||
static constexpr int32 MAX_CHOOSE_COUNT = 2147483640;
|
|
||||||
|
|
||||||
MessageReaction() = default;
|
|
||||||
|
|
||||||
const string &get_reaction() const {
|
|
||||||
return reaction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 get_choose_count() const {
|
int32 get_choose_count() const {
|
||||||
return choose_count_;
|
return choose_count_;
|
||||||
}
|
}
|
||||||
@ -88,6 +85,13 @@ class MessageReaction {
|
|||||||
td_api::object_ptr<td_api::messageReaction> get_message_reaction_object(Td *td, UserId my_user_id,
|
td_api::object_ptr<td_api::messageReaction> get_message_reaction_object(Td *td, UserId my_user_id,
|
||||||
UserId peer_user_id) const;
|
UserId peer_user_id) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MessageReaction() = default;
|
||||||
|
|
||||||
|
const string &get_reaction() const {
|
||||||
|
return reaction_;
|
||||||
|
}
|
||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
void store(StorerT &storer) const;
|
void store(StorerT &storer) const;
|
||||||
|
|
||||||
@ -166,6 +170,16 @@ struct MessageReactions {
|
|||||||
|
|
||||||
vector<string> get_chosen_reactions() const;
|
vector<string> get_chosen_reactions() const;
|
||||||
|
|
||||||
|
bool are_consistent_with_list(const string &reaction, FlatHashMap<string, vector<DialogId>> reactions,
|
||||||
|
int32 total_count) const;
|
||||||
|
|
||||||
|
vector<td_api::object_ptr<td_api::messageReaction>> get_message_reactions_object(Td *td, UserId my_user_id,
|
||||||
|
UserId peer_user_id) const;
|
||||||
|
|
||||||
|
void add_min_channels(Td *td) const;
|
||||||
|
|
||||||
|
void add_dependencies(Dependencies &dependencies) const;
|
||||||
|
|
||||||
static bool need_update_message_reactions(const MessageReactions *old_reactions,
|
static bool need_update_message_reactions(const MessageReactions *old_reactions,
|
||||||
const MessageReactions *new_reactions);
|
const MessageReactions *new_reactions);
|
||||||
|
|
||||||
|
62
td/telegram/MessageReplyHeader.cpp
Normal file
62
td/telegram/MessageReplyHeader.cpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#include "td/telegram/MessageReplyHeader.h"
|
||||||
|
|
||||||
|
#include "td/telegram/FullMessageId.h"
|
||||||
|
#include "td/telegram/ScheduledServerMessageId.h"
|
||||||
|
#include "td/telegram/ServerMessageId.h"
|
||||||
|
|
||||||
|
#include "td/utils/logging.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
MessageReplyHeader::MessageReplyHeader(tl_object_ptr<telegram_api::messageReplyHeader> &&reply_header,
|
||||||
|
DialogId dialog_id, MessageId message_id, int32 date, bool can_have_thread) {
|
||||||
|
if (reply_header == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (reply_header->reply_to_scheduled_) {
|
||||||
|
reply_to_message_id = MessageId(ScheduledServerMessageId(reply_header->reply_to_msg_id_), date);
|
||||||
|
if (message_id.is_scheduled()) {
|
||||||
|
auto reply_to_peer_id = std::move(reply_header->reply_to_peer_id_);
|
||||||
|
if (reply_to_peer_id != nullptr) {
|
||||||
|
reply_in_dialog_id = DialogId(reply_to_peer_id);
|
||||||
|
LOG(ERROR) << "Receive reply to " << FullMessageId{reply_in_dialog_id, reply_to_message_id} << " in "
|
||||||
|
<< FullMessageId{dialog_id, message_id};
|
||||||
|
reply_to_message_id = MessageId();
|
||||||
|
reply_in_dialog_id = DialogId();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << "Receive reply to " << reply_to_message_id << " in " << FullMessageId{dialog_id, message_id};
|
||||||
|
reply_to_message_id = MessageId();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reply_to_message_id = MessageId(ServerMessageId(reply_header->reply_to_msg_id_));
|
||||||
|
auto reply_to_peer_id = std::move(reply_header->reply_to_peer_id_);
|
||||||
|
if (reply_to_peer_id != nullptr) {
|
||||||
|
reply_in_dialog_id = DialogId(reply_to_peer_id);
|
||||||
|
if (!reply_in_dialog_id.is_valid()) {
|
||||||
|
LOG(ERROR) << "Receive reply in invalid " << to_string(reply_to_peer_id);
|
||||||
|
reply_to_message_id = MessageId();
|
||||||
|
reply_in_dialog_id = DialogId();
|
||||||
|
}
|
||||||
|
if (reply_in_dialog_id == dialog_id) {
|
||||||
|
reply_in_dialog_id = DialogId(); // just in case
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reply_to_message_id.is_valid() && !message_id.is_scheduled() && !reply_in_dialog_id.is_valid()) {
|
||||||
|
if ((reply_header->flags_ & telegram_api::messageReplyHeader::REPLY_TO_TOP_ID_MASK) != 0) {
|
||||||
|
top_thread_message_id = MessageId(ServerMessageId(reply_header->reply_to_top_id_));
|
||||||
|
} else if (can_have_thread) {
|
||||||
|
top_thread_message_id = reply_to_message_id;
|
||||||
|
}
|
||||||
|
is_topic_message = reply_header->forum_topic_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
29
td/telegram/MessageReplyHeader.h
Normal file
29
td/telegram/MessageReplyHeader.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/DialogId.h"
|
||||||
|
#include "td/telegram/MessageId.h"
|
||||||
|
#include "td/telegram/telegram_api.h"
|
||||||
|
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
struct MessageReplyHeader {
|
||||||
|
MessageId reply_to_message_id;
|
||||||
|
DialogId reply_in_dialog_id;
|
||||||
|
MessageId top_thread_message_id;
|
||||||
|
bool is_topic_message = false;
|
||||||
|
|
||||||
|
MessageReplyHeader() = default;
|
||||||
|
|
||||||
|
MessageReplyHeader(tl_object_ptr<telegram_api::messageReplyHeader> &&reply_header, DialogId dialog_id,
|
||||||
|
MessageId message_id, int32 date, bool can_have_thread);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace td
|
@ -19,13 +19,17 @@
|
|||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
MessageReplyInfo::MessageReplyInfo(Td *td, tl_object_ptr<telegram_api::messageReplies> &&reply_info, bool is_bot) {
|
MessageReplyInfo::MessageReplyInfo(Td *td, tl_object_ptr<telegram_api::messageReplies> &&reply_info, bool is_bot) {
|
||||||
if (reply_info == nullptr || is_bot || reply_info->channel_id_ == 777) {
|
if (reply_info == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (reply_info->replies_ < 0) {
|
if (reply_info->replies_ < 0) {
|
||||||
LOG(ERROR) << "Receive wrong " << to_string(reply_info);
|
LOG(ERROR) << "Receive wrong " << to_string(reply_info);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (is_bot || reply_info->channel_id_ == 777) {
|
||||||
|
is_dropped = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
reply_count = reply_info->replies_;
|
reply_count = reply_info->replies_;
|
||||||
pts = reply_info->replies_pts_;
|
pts = reply_info->replies_pts_;
|
||||||
|
|
||||||
@ -56,19 +60,19 @@ MessageReplyInfo::MessageReplyInfo(Td *td, tl_object_ptr<telegram_api::messageRe
|
|||||||
if (dialog_type == DialogType::User) {
|
if (dialog_type == DialogType::User) {
|
||||||
auto replier_user_id = dialog_id.get_user_id();
|
auto replier_user_id = dialog_id.get_user_id();
|
||||||
if (!td->contacts_manager_->have_min_user(replier_user_id)) {
|
if (!td->contacts_manager_->have_min_user(replier_user_id)) {
|
||||||
LOG(ERROR) << "Have no info about replied " << replier_user_id;
|
LOG(ERROR) << "Receive unknown replied " << replier_user_id;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (dialog_type == DialogType::Channel) {
|
} else if (dialog_type == DialogType::Channel) {
|
||||||
auto replier_channel_id = dialog_id.get_channel_id();
|
auto replier_channel_id = dialog_id.get_channel_id();
|
||||||
auto min_channel = td->contacts_manager_->get_min_channel(replier_channel_id);
|
auto min_channel = td->contacts_manager_->get_min_channel(replier_channel_id);
|
||||||
if (min_channel == nullptr) {
|
if (min_channel == nullptr) {
|
||||||
LOG(ERROR) << "Have no info about replied " << replier_channel_id;
|
LOG(ERROR) << "Receive unknown replied " << replier_channel_id;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
replier_min_channels.emplace_back(replier_channel_id, *min_channel);
|
replier_min_channels.emplace_back(replier_channel_id, *min_channel);
|
||||||
} else {
|
} else {
|
||||||
LOG(ERROR) << "Have no info about replied " << dialog_id;
|
LOG(ERROR) << "Receive unknown replied " << dialog_id;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ struct MessageReplyInfo {
|
|||||||
MessageId last_read_inbox_message_id;
|
MessageId last_read_inbox_message_id;
|
||||||
MessageId last_read_outbox_message_id;
|
MessageId last_read_outbox_message_id;
|
||||||
bool is_comment = false;
|
bool is_comment = false;
|
||||||
|
bool is_dropped = false;
|
||||||
|
|
||||||
static constexpr size_t MAX_RECENT_REPLIERS = 3;
|
static constexpr size_t MAX_RECENT_REPLIERS = 3;
|
||||||
|
|
||||||
@ -43,6 +44,10 @@ struct MessageReplyInfo {
|
|||||||
return reply_count < 0;
|
return reply_count < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool was_dropped() const {
|
||||||
|
return is_dropped;
|
||||||
|
}
|
||||||
|
|
||||||
bool need_update_to(const MessageReplyInfo &other) const;
|
bool need_update_to(const MessageReplyInfo &other) const;
|
||||||
|
|
||||||
bool update_max_message_ids(MessageId other_max_message_id, MessageId other_last_read_inbox_message_id,
|
bool update_max_message_ids(MessageId other_max_message_id, MessageId other_last_read_inbox_message_id,
|
||||||
|
@ -94,7 +94,7 @@ vector<DialogId> get_message_sender_dialog_ids(Td *td,
|
|||||||
}
|
}
|
||||||
if (dialog_id.get_type() == DialogType::User) {
|
if (dialog_id.get_type() == DialogType::User) {
|
||||||
if (!td->contacts_manager_->have_user(dialog_id.get_user_id())) {
|
if (!td->contacts_manager_->have_user(dialog_id.get_user_id())) {
|
||||||
LOG(ERROR) << "Have no info about " << dialog_id.get_user_id();
|
LOG(ERROR) << "Receive unknown " << dialog_id.get_user_id();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "td/telegram/MessagesDb.h"
|
#include "td/telegram/MessagesDb.h"
|
||||||
|
|
||||||
#include "td/telegram/logevent/LogEvent.h"
|
#include "td/telegram/logevent/LogEvent.h"
|
||||||
|
#include "td/telegram/UserId.h"
|
||||||
#include "td/telegram/Version.h"
|
#include "td/telegram/Version.h"
|
||||||
|
|
||||||
#include "td/db/SqliteConnectionSafe.h"
|
#include "td/db/SqliteConnectionSafe.h"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -17,6 +17,7 @@
|
|||||||
#include "td/telegram/DialogId.h"
|
#include "td/telegram/DialogId.h"
|
||||||
#include "td/telegram/DialogListId.h"
|
#include "td/telegram/DialogListId.h"
|
||||||
#include "td/telegram/DialogLocation.h"
|
#include "td/telegram/DialogLocation.h"
|
||||||
|
#include "td/telegram/DialogNotificationSettings.h"
|
||||||
#include "td/telegram/DialogParticipant.h"
|
#include "td/telegram/DialogParticipant.h"
|
||||||
#include "td/telegram/DialogSource.h"
|
#include "td/telegram/DialogSource.h"
|
||||||
#include "td/telegram/EncryptedFile.h"
|
#include "td/telegram/EncryptedFile.h"
|
||||||
@ -32,6 +33,7 @@
|
|||||||
#include "td/telegram/MessageCopyOptions.h"
|
#include "td/telegram/MessageCopyOptions.h"
|
||||||
#include "td/telegram/MessageId.h"
|
#include "td/telegram/MessageId.h"
|
||||||
#include "td/telegram/MessageLinkInfo.h"
|
#include "td/telegram/MessageLinkInfo.h"
|
||||||
|
#include "td/telegram/MessageReplyHeader.h"
|
||||||
#include "td/telegram/MessageReplyInfo.h"
|
#include "td/telegram/MessageReplyInfo.h"
|
||||||
#include "td/telegram/MessagesDb.h"
|
#include "td/telegram/MessagesDb.h"
|
||||||
#include "td/telegram/MessageSearchFilter.h"
|
#include "td/telegram/MessageSearchFilter.h"
|
||||||
@ -44,7 +46,7 @@
|
|||||||
#include "td/telegram/NotificationGroupKey.h"
|
#include "td/telegram/NotificationGroupKey.h"
|
||||||
#include "td/telegram/NotificationGroupType.h"
|
#include "td/telegram/NotificationGroupType.h"
|
||||||
#include "td/telegram/NotificationId.h"
|
#include "td/telegram/NotificationId.h"
|
||||||
#include "td/telegram/NotificationSettings.h"
|
#include "td/telegram/NotificationSettingsScope.h"
|
||||||
#include "td/telegram/Photo.h"
|
#include "td/telegram/Photo.h"
|
||||||
#include "td/telegram/RecentDialogList.h"
|
#include "td/telegram/RecentDialogList.h"
|
||||||
#include "td/telegram/ReplyMarkup.h"
|
#include "td/telegram/ReplyMarkup.h"
|
||||||
@ -58,6 +60,7 @@
|
|||||||
#include "td/telegram/td_api.h"
|
#include "td/telegram/td_api.h"
|
||||||
#include "td/telegram/telegram_api.h"
|
#include "td/telegram/telegram_api.h"
|
||||||
#include "td/telegram/UserId.h"
|
#include "td/telegram/UserId.h"
|
||||||
|
#include "td/telegram/Usernames.h"
|
||||||
|
|
||||||
#include "td/actor/actor.h"
|
#include "td/actor/actor.h"
|
||||||
#include "td/actor/MultiPromise.h"
|
#include "td/actor/MultiPromise.h"
|
||||||
@ -139,7 +142,7 @@ class MessagesManager final : public Actor {
|
|||||||
static constexpr int32 SEND_MESSAGE_FLAG_FROM_BACKGROUND = 1 << 6;
|
static constexpr int32 SEND_MESSAGE_FLAG_FROM_BACKGROUND = 1 << 6;
|
||||||
static constexpr int32 SEND_MESSAGE_FLAG_CLEAR_DRAFT = 1 << 7;
|
static constexpr int32 SEND_MESSAGE_FLAG_CLEAR_DRAFT = 1 << 7;
|
||||||
static constexpr int32 SEND_MESSAGE_FLAG_WITH_MY_SCORE = 1 << 8;
|
static constexpr int32 SEND_MESSAGE_FLAG_WITH_MY_SCORE = 1 << 8;
|
||||||
static constexpr int32 SEND_MESSAGE_FLAG_GROUP_MEDIA = 1 << 9;
|
static constexpr int32 SEND_MESSAGE_FLAG_IS_FROM_THREAD = 1 << 9;
|
||||||
static constexpr int32 SEND_MESSAGE_FLAG_HAS_SCHEDULE_DATE = 1 << 10;
|
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_MESSAGE = 1 << 11;
|
||||||
static constexpr int32 SEND_MESSAGE_FLAG_HAS_SEND_AS = 1 << 13;
|
static constexpr int32 SEND_MESSAGE_FLAG_HAS_SEND_AS = 1 << 13;
|
||||||
@ -254,16 +257,16 @@ class MessagesManager final : public Actor {
|
|||||||
bool is_channel_message, bool is_scheduled, bool have_previous, bool have_next,
|
bool is_channel_message, bool is_scheduled, bool have_previous, bool have_next,
|
||||||
const char *source);
|
const char *source);
|
||||||
|
|
||||||
void open_secret_message(SecretChatId secret_chat_id, int64 random_id, Promise<>);
|
void open_secret_message(SecretChatId secret_chat_id, int64 random_id, Promise<Unit>);
|
||||||
|
|
||||||
void on_send_secret_message_success(int64 random_id, MessageId message_id, int32 date, unique_ptr<EncryptedFile> file,
|
void on_send_secret_message_success(int64 random_id, MessageId message_id, int32 date, unique_ptr<EncryptedFile> file,
|
||||||
Promise<> promise);
|
Promise<Unit> promise);
|
||||||
void on_send_secret_message_error(int64 random_id, Status error, Promise<> promise);
|
void on_send_secret_message_error(int64 random_id, Status error, Promise<Unit> promise);
|
||||||
|
|
||||||
void delete_secret_messages(SecretChatId secret_chat_id, std::vector<int64> random_ids, Promise<> promise);
|
void delete_secret_messages(SecretChatId secret_chat_id, std::vector<int64> random_ids, Promise<Unit> promise);
|
||||||
|
|
||||||
void delete_secret_chat_history(SecretChatId secret_chat_id, bool remove_from_dialog_list, MessageId last_message_id,
|
void delete_secret_chat_history(SecretChatId secret_chat_id, bool remove_from_dialog_list, MessageId last_message_id,
|
||||||
Promise<> promise);
|
Promise<Unit> promise);
|
||||||
|
|
||||||
void read_secret_chat_outbox(SecretChatId secret_chat_id, int32 up_to_date, int32 read_date);
|
void read_secret_chat_outbox(SecretChatId secret_chat_id, int32 up_to_date, int32 read_date);
|
||||||
|
|
||||||
@ -271,13 +274,13 @@ class MessagesManager final : public Actor {
|
|||||||
|
|
||||||
void on_get_secret_message(SecretChatId secret_chat_id, UserId user_id, MessageId message_id, int32 date,
|
void on_get_secret_message(SecretChatId secret_chat_id, UserId user_id, MessageId message_id, int32 date,
|
||||||
unique_ptr<EncryptedFile> file, tl_object_ptr<secret_api::decryptedMessage> message,
|
unique_ptr<EncryptedFile> file, tl_object_ptr<secret_api::decryptedMessage> message,
|
||||||
Promise<> promise);
|
Promise<Unit> promise);
|
||||||
|
|
||||||
void on_secret_chat_screenshot_taken(SecretChatId secret_chat_id, UserId user_id, MessageId message_id, int32 date,
|
void on_secret_chat_screenshot_taken(SecretChatId secret_chat_id, UserId user_id, MessageId message_id, int32 date,
|
||||||
int64 random_id, Promise<> promise);
|
int64 random_id, Promise<Unit> promise);
|
||||||
|
|
||||||
void on_secret_chat_ttl_changed(SecretChatId secret_chat_id, UserId user_id, MessageId message_id, int32 date,
|
void on_secret_chat_ttl_changed(SecretChatId secret_chat_id, UserId user_id, MessageId message_id, int32 date,
|
||||||
int32 ttl, int64 random_id, Promise<> promise);
|
int32 ttl, int64 random_id, Promise<Unit> promise);
|
||||||
|
|
||||||
void on_update_sent_text_message(int64 random_id, tl_object_ptr<telegram_api::MessageMedia> message_media,
|
void on_update_sent_text_message(int64 random_id, tl_object_ptr<telegram_api::MessageMedia> message_media,
|
||||||
vector<tl_object_ptr<telegram_api::MessageEntity>> &&entities);
|
vector<tl_object_ptr<telegram_api::MessageEntity>> &&entities);
|
||||||
@ -293,7 +296,8 @@ class MessagesManager final : public Actor {
|
|||||||
|
|
||||||
bool on_update_message_id(int64 random_id, MessageId new_message_id, const string &source);
|
bool on_update_message_id(int64 random_id, MessageId new_message_id, const string &source);
|
||||||
|
|
||||||
void on_update_dialog_draft_message(DialogId dialog_id, tl_object_ptr<telegram_api::DraftMessage> &&draft_message);
|
void on_update_dialog_draft_message(DialogId dialog_id, MessageId top_thread_message_id,
|
||||||
|
tl_object_ptr<telegram_api::DraftMessage> &&draft_message);
|
||||||
|
|
||||||
void on_update_dialog_is_pinned(FolderId folder_id, DialogId dialog_id, bool is_pinned);
|
void on_update_dialog_is_pinned(FolderId folder_id, DialogId dialog_id, bool is_pinned);
|
||||||
|
|
||||||
@ -366,6 +370,9 @@ class MessagesManager final : public Actor {
|
|||||||
|
|
||||||
void on_update_some_live_location_viewed(Promise<Unit> &&promise);
|
void on_update_some_live_location_viewed(Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void on_update_message_extended_media(FullMessageId full_message_id,
|
||||||
|
telegram_api::object_ptr<telegram_api::MessageExtendedMedia> extended_media);
|
||||||
|
|
||||||
void on_external_update_message_content(FullMessageId full_message_id);
|
void on_external_update_message_content(FullMessageId full_message_id);
|
||||||
|
|
||||||
void on_update_message_content(FullMessageId full_message_id);
|
void on_update_message_content(FullMessageId full_message_id);
|
||||||
@ -397,6 +404,8 @@ class MessagesManager final : public Actor {
|
|||||||
|
|
||||||
void delete_dialog_history(DialogId dialog_id, bool remove_from_dialog_list, bool revoke, Promise<Unit> &&promise);
|
void delete_dialog_history(DialogId dialog_id, bool remove_from_dialog_list, bool revoke, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void delete_topic_history(DialogId dialog_id, MessageId top_thread_message_id, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void delete_all_call_messages(bool revoke, Promise<Unit> &&promise);
|
void delete_all_call_messages(bool revoke, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void delete_dialog_messages_by_sender(DialogId dialog_id, DialogId sender_dialog_id, Promise<Unit> &&promise);
|
void delete_dialog_messages_by_sender(DialogId dialog_id, DialogId sender_dialog_id, Promise<Unit> &&promise);
|
||||||
@ -408,9 +417,9 @@ class MessagesManager final : public Actor {
|
|||||||
|
|
||||||
void on_update_dialog_group_call_rights(DialogId dialog_id);
|
void on_update_dialog_group_call_rights(DialogId dialog_id);
|
||||||
|
|
||||||
void read_all_dialog_mentions(DialogId dialog_id, Promise<Unit> &&promise);
|
void read_all_dialog_mentions(DialogId dialog_id, MessageId top_thread_message_id, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void read_all_dialog_reactions(DialogId dialog_id, Promise<Unit> &&promise);
|
void read_all_dialog_reactions(DialogId dialog_id, MessageId top_thread_message_id, Promise<Unit> &&promise);
|
||||||
|
|
||||||
Status add_recently_found_dialog(DialogId dialog_id) TD_WARN_UNUSED_RESULT;
|
Status add_recently_found_dialog(DialogId dialog_id) TD_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
@ -427,7 +436,7 @@ class MessagesManager final : public Actor {
|
|||||||
void reload_voice_chat_on_search(const string &username);
|
void reload_voice_chat_on_search(const string &username);
|
||||||
|
|
||||||
void get_dialog_send_message_as_dialog_ids(DialogId dialog_id,
|
void get_dialog_send_message_as_dialog_ids(DialogId dialog_id,
|
||||||
Promise<td_api::object_ptr<td_api::messageSenders>> &&promise,
|
Promise<td_api::object_ptr<td_api::chatMessageSenders>> &&promise,
|
||||||
bool is_recursive = false);
|
bool is_recursive = false);
|
||||||
|
|
||||||
void set_dialog_default_send_message_as_dialog_id(DialogId dialog_id, DialogId message_sender_dialog_id,
|
void set_dialog_default_send_message_as_dialog_id(DialogId dialog_id, DialogId message_sender_dialog_id,
|
||||||
@ -457,8 +466,8 @@ class MessagesManager final : public Actor {
|
|||||||
int64 query_id, const string &result_id,
|
int64 query_id, const string &result_id,
|
||||||
bool hide_via_bot) TD_WARN_UNUSED_RESULT;
|
bool hide_via_bot) TD_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
Result<td_api::object_ptr<td_api::messages>> forward_messages(DialogId to_dialog_id, DialogId from_dialog_id,
|
Result<td_api::object_ptr<td_api::messages>> forward_messages(DialogId to_dialog_id, MessageId top_thread_message_id,
|
||||||
vector<MessageId> message_ids,
|
DialogId from_dialog_id, vector<MessageId> message_ids,
|
||||||
tl_object_ptr<td_api::messageSendOptions> &&options,
|
tl_object_ptr<td_api::messageSendOptions> &&options,
|
||||||
bool in_game_share,
|
bool in_game_share,
|
||||||
vector<MessageCopyOptions> &©_options,
|
vector<MessageCopyOptions> &©_options,
|
||||||
@ -557,7 +566,7 @@ class MessagesManager final : public Actor {
|
|||||||
void pin_dialog_message(DialogId dialog_id, MessageId message_id, bool disable_notification, bool only_for_self,
|
void pin_dialog_message(DialogId dialog_id, MessageId message_id, bool disable_notification, bool only_for_self,
|
||||||
bool is_unpin, Promise<Unit> &&promise);
|
bool is_unpin, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void unpin_all_dialog_messages(DialogId dialog_id, Promise<Unit> &&promise);
|
void unpin_all_dialog_messages(DialogId dialog_id, MessageId top_thread_message_id, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void get_dialog_info_full(DialogId dialog_id, Promise<Unit> &&promise, const char *source);
|
void get_dialog_info_full(DialogId dialog_id, Promise<Unit> &&promise, const char *source);
|
||||||
|
|
||||||
@ -645,12 +654,16 @@ class MessagesManager final : public Actor {
|
|||||||
void translate_text(const string &text, const string &from_language_code, const string &to_language_code,
|
void translate_text(const string &text, const string &from_language_code, const string &to_language_code,
|
||||||
Promise<td_api::object_ptr<td_api::text>> &&promise);
|
Promise<td_api::object_ptr<td_api::text>> &&promise);
|
||||||
|
|
||||||
|
void recognize_speech(FullMessageId full_message_id, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void rate_speech_recognition(FullMessageId full_message_id, bool is_good, Promise<Unit> &&promise);
|
||||||
|
|
||||||
bool is_message_edited_recently(FullMessageId full_message_id, int32 seconds);
|
bool is_message_edited_recently(FullMessageId full_message_id, int32 seconds);
|
||||||
|
|
||||||
bool is_deleted_secret_chat(DialogId dialog_id) const;
|
bool is_deleted_secret_chat(DialogId dialog_id) const;
|
||||||
|
|
||||||
Result<std::pair<string, bool>> get_message_link(FullMessageId full_message_id, int32 media_timestamp, bool for_group,
|
Result<std::pair<string, bool>> get_message_link(FullMessageId full_message_id, int32 media_timestamp, bool for_group,
|
||||||
bool for_comment);
|
bool in_message_thread);
|
||||||
|
|
||||||
string get_message_embedding_code(FullMessageId full_message_id, bool for_group, Promise<Unit> &&promise);
|
string get_message_embedding_code(FullMessageId full_message_id, bool for_group, Promise<Unit> &&promise);
|
||||||
|
|
||||||
@ -715,6 +728,8 @@ class MessagesManager final : public Actor {
|
|||||||
|
|
||||||
void finish_get_message_views(DialogId dialog_id, const vector<MessageId> &message_ids);
|
void finish_get_message_views(DialogId dialog_id, const vector<MessageId> &message_ids);
|
||||||
|
|
||||||
|
void finish_get_message_extended_media(DialogId dialog_id, const vector<MessageId> &message_ids);
|
||||||
|
|
||||||
Status open_message_content(FullMessageId full_message_id) TD_WARN_UNUSED_RESULT;
|
Status open_message_content(FullMessageId full_message_id) TD_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
void click_animated_emoji_message(FullMessageId full_message_id,
|
void click_animated_emoji_message(FullMessageId full_message_id,
|
||||||
@ -767,7 +782,7 @@ class MessagesManager final : public Actor {
|
|||||||
const char *source);
|
const char *source);
|
||||||
|
|
||||||
FoundMessages offline_search_messages(DialogId dialog_id, const string &query, string offset, int32 limit,
|
FoundMessages offline_search_messages(DialogId dialog_id, const string &query, string offset, int32 limit,
|
||||||
MessageSearchFilter filter, int64 &random_id, Promise<> &&promise);
|
MessageSearchFilter filter, int64 &random_id, Promise<Unit> &&promise);
|
||||||
|
|
||||||
std::pair<int32, vector<FullMessageId>> search_messages(FolderId folder_id, bool ignore_folder_id,
|
std::pair<int32, vector<FullMessageId>> search_messages(FolderId folder_id, bool ignore_folder_id,
|
||||||
const string &query, int32 offset_date,
|
const string &query, int32 offset_date,
|
||||||
@ -806,6 +821,9 @@ class MessagesManager final : public Actor {
|
|||||||
void get_dialog_message_count(DialogId dialog_id, MessageSearchFilter filter, bool return_local,
|
void get_dialog_message_count(DialogId dialog_id, MessageSearchFilter filter, bool return_local,
|
||||||
Promise<int32> &&promise);
|
Promise<int32> &&promise);
|
||||||
|
|
||||||
|
void get_dialog_message_position(FullMessageId full_message_id, MessageSearchFilter filter,
|
||||||
|
MessageId top_thread_message_id, Promise<int32> &&promise);
|
||||||
|
|
||||||
vector<MessageId> get_dialog_scheduled_messages(DialogId dialog_id, bool force, bool ignore_result,
|
vector<MessageId> get_dialog_scheduled_messages(DialogId dialog_id, bool force, bool ignore_result,
|
||||||
Promise<Unit> &&promise);
|
Promise<Unit> &&promise);
|
||||||
|
|
||||||
@ -845,13 +863,11 @@ class MessagesManager final : public Actor {
|
|||||||
|
|
||||||
bool is_old_channel_update(DialogId dialog_id, int32 new_pts);
|
bool is_old_channel_update(DialogId dialog_id, int32 new_pts);
|
||||||
|
|
||||||
bool is_update_about_username_change_received(DialogId dialog_id) const;
|
|
||||||
|
|
||||||
void on_dialog_bots_updated(DialogId dialog_id, vector<UserId> bot_user_ids, bool from_database);
|
void on_dialog_bots_updated(DialogId dialog_id, vector<UserId> bot_user_ids, bool from_database);
|
||||||
|
|
||||||
void on_dialog_photo_updated(DialogId dialog_id);
|
void on_dialog_photo_updated(DialogId dialog_id);
|
||||||
void on_dialog_title_updated(DialogId dialog_id);
|
void on_dialog_title_updated(DialogId dialog_id);
|
||||||
void on_dialog_username_updated(DialogId dialog_id, const string &old_username, const string &new_username);
|
void on_dialog_usernames_updated(DialogId dialog_id, const Usernames &old_usernames, const Usernames &new_usernames);
|
||||||
void on_dialog_default_permissions_updated(DialogId dialog_id);
|
void on_dialog_default_permissions_updated(DialogId dialog_id);
|
||||||
void on_dialog_has_protected_content_updated(DialogId dialog_id);
|
void on_dialog_has_protected_content_updated(DialogId dialog_id);
|
||||||
|
|
||||||
@ -1030,8 +1046,7 @@ class MessagesManager final : public Actor {
|
|||||||
bool disable_web_page_preview = false;
|
bool disable_web_page_preview = false;
|
||||||
int64 random_id = 0;
|
int64 random_id = 0;
|
||||||
tl_object_ptr<telegram_api::messageFwdHeader> forward_header;
|
tl_object_ptr<telegram_api::messageFwdHeader> forward_header;
|
||||||
MessageId reply_to_message_id;
|
MessageReplyHeader reply_header;
|
||||||
tl_object_ptr<telegram_api::messageReplyHeader> reply_header;
|
|
||||||
UserId via_bot_user_id;
|
UserId via_bot_user_id;
|
||||||
int32 view_count = 0;
|
int32 view_count = 0;
|
||||||
int32 forward_count = 0;
|
int32 forward_count = 0;
|
||||||
@ -1140,6 +1155,7 @@ class MessagesManager final : public Actor {
|
|||||||
string author_signature;
|
string author_signature;
|
||||||
|
|
||||||
bool is_channel_post = false;
|
bool is_channel_post = false;
|
||||||
|
bool is_topic_message = false;
|
||||||
bool is_outgoing = false;
|
bool is_outgoing = false;
|
||||||
bool is_failed_to_send = false;
|
bool is_failed_to_send = false;
|
||||||
bool disable_notification = false;
|
bool disable_notification = false;
|
||||||
@ -1172,6 +1188,8 @@ class MessagesManager final : public Actor {
|
|||||||
bool has_get_message_views_query = false;
|
bool has_get_message_views_query = false;
|
||||||
bool need_view_counter_increment = false;
|
bool need_view_counter_increment = false;
|
||||||
|
|
||||||
|
bool has_get_extended_media_query = false;
|
||||||
|
|
||||||
DialogId real_forward_from_dialog_id; // for resend_message
|
DialogId real_forward_from_dialog_id; // for resend_message
|
||||||
MessageId real_forward_from_message_id; // for resend_message
|
MessageId real_forward_from_message_id; // for resend_message
|
||||||
|
|
||||||
@ -1414,7 +1432,7 @@ class MessagesManager final : public Actor {
|
|||||||
MessageId suffix_load_first_message_id_; // identifier of some message such all suffix messages in range
|
MessageId suffix_load_first_message_id_; // identifier of some message such all suffix messages in range
|
||||||
// [suffix_load_first_message_id_, last_message_id] are loaded
|
// [suffix_load_first_message_id_, last_message_id] are loaded
|
||||||
MessageId suffix_load_query_message_id_;
|
MessageId suffix_load_query_message_id_;
|
||||||
std::vector<std::pair<Promise<>, std::function<bool(const Message *)>>> suffix_load_queries_;
|
std::vector<std::pair<Promise<Unit>, std::function<bool(const Message *)>>> suffix_load_queries_;
|
||||||
|
|
||||||
FlatHashMap<MessageId, int64, MessageIdHash> pending_viewed_live_locations; // message_id -> task_id
|
FlatHashMap<MessageId, int64, MessageIdHash> pending_viewed_live_locations; // message_id -> task_id
|
||||||
FlatHashSet<MessageId, MessageIdHash> pending_viewed_message_ids;
|
FlatHashSet<MessageId, MessageIdHash> pending_viewed_message_ids;
|
||||||
@ -1724,7 +1742,7 @@ class MessagesManager final : public Actor {
|
|||||||
MessageId last_message_id;
|
MessageId last_message_id;
|
||||||
bool remove_from_dialog_list = false;
|
bool remove_from_dialog_list = false;
|
||||||
|
|
||||||
Promise<> success_promise;
|
Promise<Unit> success_promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MessageSendOptions {
|
struct MessageSendOptions {
|
||||||
@ -1753,6 +1771,7 @@ class MessagesManager final : public Actor {
|
|||||||
class DeleteMessageLogEvent;
|
class DeleteMessageLogEvent;
|
||||||
class DeleteMessagesOnServerLogEvent;
|
class DeleteMessagesOnServerLogEvent;
|
||||||
class DeleteScheduledMessagesOnServerLogEvent;
|
class DeleteScheduledMessagesOnServerLogEvent;
|
||||||
|
class DeleteTopicHistoryOnServerLogEvent;
|
||||||
class ForwardMessagesLogEvent;
|
class ForwardMessagesLogEvent;
|
||||||
class GetChannelDifferenceLogEvent;
|
class GetChannelDifferenceLogEvent;
|
||||||
class ReadAllDialogMentionsOnServerLogEvent;
|
class ReadAllDialogMentionsOnServerLogEvent;
|
||||||
@ -1793,6 +1812,7 @@ class MessagesManager final : public Actor {
|
|||||||
static constexpr size_t MAX_DIALOG_FILTER_TITLE_LENGTH = 12; // server side limit for dialog filter title
|
static constexpr size_t MAX_DIALOG_FILTER_TITLE_LENGTH = 12; // server side limit for dialog filter title
|
||||||
static constexpr int32 MAX_PRIVATE_MESSAGE_TTL = 60; // server side limit
|
static constexpr int32 MAX_PRIVATE_MESSAGE_TTL = 60; // server side limit
|
||||||
static constexpr int32 DIALOG_FILTERS_CACHE_TIME = 86400;
|
static constexpr int32 DIALOG_FILTERS_CACHE_TIME = 86400;
|
||||||
|
static constexpr size_t MIN_DELETED_ASYNCHRONOUSLY_MESSAGES = 10u;
|
||||||
|
|
||||||
static constexpr int64 SPONSORED_DIALOG_ORDER = static_cast<int64>(2147483647) << 32;
|
static constexpr int64 SPONSORED_DIALOG_ORDER = static_cast<int64>(2147483647) << 32;
|
||||||
static constexpr int32 MIN_PINNED_DIALOG_DATE = 2147000000; // some big date
|
static constexpr int32 MIN_PINNED_DIALOG_DATE = 2147000000; // some big date
|
||||||
@ -1817,8 +1837,7 @@ class MessagesManager final : public Actor {
|
|||||||
static constexpr int32 LIVE_LOCATION_VIEW_PERIOD = 60; // seconds, server-side limit
|
static constexpr int32 LIVE_LOCATION_VIEW_PERIOD = 60; // seconds, server-side limit
|
||||||
static constexpr int32 UPDATE_VIEWED_MESSAGES_PERIOD = 15; // seconds
|
static constexpr int32 UPDATE_VIEWED_MESSAGES_PERIOD = 15; // seconds
|
||||||
|
|
||||||
static constexpr int32 USERNAME_CACHE_EXPIRE_TIME = 3 * 86400;
|
static constexpr int32 USERNAME_CACHE_EXPIRE_TIME = 86400;
|
||||||
static constexpr int32 USERNAME_CACHE_EXPIRE_TIME_SHORT = 900;
|
|
||||||
static constexpr int32 AUTH_NOTIFICATION_ID_CACHE_TIME = 7 * 86400;
|
static constexpr int32 AUTH_NOTIFICATION_ID_CACHE_TIME = 7 * 86400;
|
||||||
static constexpr size_t MAX_SAVED_AUTH_NOTIFICATION_IDS = 100;
|
static constexpr size_t MAX_SAVED_AUTH_NOTIFICATION_IDS = 100;
|
||||||
|
|
||||||
@ -1867,10 +1886,10 @@ class MessagesManager final : public Actor {
|
|||||||
|
|
||||||
void finish_add_secret_message(unique_ptr<PendingSecretMessage> pending_secret_message);
|
void finish_add_secret_message(unique_ptr<PendingSecretMessage> pending_secret_message);
|
||||||
|
|
||||||
void finish_delete_secret_messages(DialogId dialog_id, std::vector<int64> random_ids, Promise<> promise);
|
void finish_delete_secret_messages(DialogId dialog_id, std::vector<int64> random_ids, Promise<Unit> promise);
|
||||||
|
|
||||||
void finish_delete_secret_chat_history(DialogId dialog_id, bool remove_from_dialog_list, MessageId last_message_id,
|
void finish_delete_secret_chat_history(DialogId dialog_id, bool remove_from_dialog_list, MessageId last_message_id,
|
||||||
Promise<> promise);
|
Promise<Unit> promise);
|
||||||
|
|
||||||
MessageInfo parse_telegram_api_message(tl_object_ptr<telegram_api::Message> message_ptr, bool is_scheduled,
|
MessageInfo parse_telegram_api_message(tl_object_ptr<telegram_api::Message> message_ptr, bool is_scheduled,
|
||||||
const char *source) const;
|
const char *source) const;
|
||||||
@ -1959,14 +1978,17 @@ class MessagesManager final : public Actor {
|
|||||||
void add_postponed_channel_update(DialogId dialog_id, tl_object_ptr<telegram_api::Update> &&update, int32 new_pts,
|
void add_postponed_channel_update(DialogId dialog_id, tl_object_ptr<telegram_api::Update> &&update, int32 new_pts,
|
||||||
int32 pts_count, Promise<Unit> &&promise);
|
int32 pts_count, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void process_channel_update(tl_object_ptr<telegram_api::Update> &&update_ptr);
|
bool process_channel_update(tl_object_ptr<telegram_api::Update> &&update_ptr);
|
||||||
|
|
||||||
void on_message_edited(FullMessageId full_message_id, int32 pts, bool had_message);
|
void on_message_edited(FullMessageId full_message_id, int32 pts, bool had_message);
|
||||||
|
|
||||||
void delete_messages_from_updates(const vector<MessageId> &message_ids);
|
void delete_messages_from_updates(const vector<MessageId> &message_ids);
|
||||||
|
|
||||||
void delete_dialog_messages(DialogId dialog_id, const vector<MessageId> &message_ids, bool from_updates,
|
void delete_dialog_messages(DialogId dialog_id, const vector<MessageId> &message_ids,
|
||||||
bool skip_update_for_not_found_messages, const char *source);
|
bool force_update_for_not_found_messages, const char *source);
|
||||||
|
|
||||||
|
void delete_dialog_messages(Dialog *d, const vector<MessageId> &message_ids, bool force_update_for_not_found_messages,
|
||||||
|
const char *source);
|
||||||
|
|
||||||
void update_dialog_pinned_messages_from_updates(DialogId dialog_id, const vector<MessageId> &message_ids,
|
void update_dialog_pinned_messages_from_updates(DialogId dialog_id, const vector<MessageId> &message_ids,
|
||||||
bool is_pin);
|
bool is_pin);
|
||||||
@ -1977,12 +1999,13 @@ class MessagesManager final : public Actor {
|
|||||||
const vector<MessageId> &message_ids, bool drop_author, bool drop_media_captions,
|
const vector<MessageId> &message_ids, bool drop_author, bool drop_media_captions,
|
||||||
uint64 log_event_id);
|
uint64 log_event_id);
|
||||||
|
|
||||||
void send_forward_message_query(int32 flags, DialogId to_dialog_id, DialogId from_dialog_id,
|
void send_forward_message_query(int32 flags, DialogId to_dialog_id, MessageId top_thread_message_id,
|
||||||
tl_object_ptr<telegram_api::InputPeer> as_input_peer, vector<MessageId> message_ids,
|
DialogId from_dialog_id, tl_object_ptr<telegram_api::InputPeer> as_input_peer,
|
||||||
vector<int64> random_ids, int32 schedule_date, Promise<Unit> promise);
|
vector<MessageId> message_ids, vector<int64> random_ids, int32 schedule_date,
|
||||||
|
Promise<Unit> promise);
|
||||||
|
|
||||||
Result<td_api::object_ptr<td_api::message>> forward_message(DialogId to_dialog_id, DialogId from_dialog_id,
|
Result<td_api::object_ptr<td_api::message>> forward_message(DialogId to_dialog_id, MessageId top_thread_message_id,
|
||||||
MessageId message_id,
|
DialogId from_dialog_id, MessageId message_id,
|
||||||
tl_object_ptr<td_api::messageSendOptions> &&options,
|
tl_object_ptr<td_api::messageSendOptions> &&options,
|
||||||
bool in_game_share,
|
bool in_game_share,
|
||||||
MessageCopyOptions &©_options) TD_WARN_UNUSED_RESULT;
|
MessageCopyOptions &©_options) TD_WARN_UNUSED_RESULT;
|
||||||
@ -1996,7 +2019,6 @@ class MessagesManager final : public Actor {
|
|||||||
struct ForwardedMessages {
|
struct ForwardedMessages {
|
||||||
struct CopiedMessage {
|
struct CopiedMessage {
|
||||||
unique_ptr<MessageContent> content;
|
unique_ptr<MessageContent> content;
|
||||||
MessageId top_thread_message_id;
|
|
||||||
MessageId reply_to_message_id;
|
MessageId reply_to_message_id;
|
||||||
MessageId original_message_id;
|
MessageId original_message_id;
|
||||||
MessageId original_reply_to_message_id;
|
MessageId original_reply_to_message_id;
|
||||||
@ -2017,12 +2039,13 @@ class MessagesManager final : public Actor {
|
|||||||
bool drop_media_captions = false;
|
bool drop_media_captions = false;
|
||||||
|
|
||||||
Dialog *from_dialog;
|
Dialog *from_dialog;
|
||||||
|
MessageId top_thread_message_id;
|
||||||
Dialog *to_dialog;
|
Dialog *to_dialog;
|
||||||
MessageSendOptions message_send_options;
|
MessageSendOptions message_send_options;
|
||||||
};
|
};
|
||||||
|
|
||||||
Result<ForwardedMessages> get_forwarded_messages(DialogId to_dialog_id, DialogId from_dialog_id,
|
Result<ForwardedMessages> get_forwarded_messages(DialogId to_dialog_id, MessageId top_thread_message_id,
|
||||||
const vector<MessageId> &message_ids,
|
DialogId from_dialog_id, const vector<MessageId> &message_ids,
|
||||||
tl_object_ptr<td_api::messageSendOptions> &&options,
|
tl_object_ptr<td_api::messageSendOptions> &&options,
|
||||||
bool in_game_share, vector<MessageCopyOptions> &©_options);
|
bool in_game_share, vector<MessageCopyOptions> &©_options);
|
||||||
|
|
||||||
@ -2101,7 +2124,7 @@ class MessagesManager final : public Actor {
|
|||||||
|
|
||||||
bool can_unload_message(const Dialog *d, const Message *m) const;
|
bool can_unload_message(const Dialog *d, const Message *m) const;
|
||||||
|
|
||||||
void unload_message(Dialog *d, MessageId message_id);
|
unique_ptr<Message> unload_message(Dialog *d, MessageId message_id);
|
||||||
|
|
||||||
unique_ptr<Message> delete_message(Dialog *d, MessageId message_id, bool is_permanently_deleted,
|
unique_ptr<Message> delete_message(Dialog *d, MessageId message_id, bool is_permanently_deleted,
|
||||||
bool *need_update_dialog_pos, const char *source);
|
bool *need_update_dialog_pos, const char *source);
|
||||||
@ -2140,6 +2163,9 @@ class MessagesManager final : public Actor {
|
|||||||
void delete_dialog_history_on_server(DialogId dialog_id, MessageId max_message_id, bool remove_from_dialog_list,
|
void delete_dialog_history_on_server(DialogId dialog_id, MessageId max_message_id, bool remove_from_dialog_list,
|
||||||
bool revoke, bool allow_error, uint64 log_event_id, Promise<Unit> &&promise);
|
bool revoke, bool allow_error, uint64 log_event_id, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void delete_topic_history_on_server(DialogId dialog_id, MessageId top_thread_message_id, uint64 log_event_id,
|
||||||
|
Promise<Unit> &&promise);
|
||||||
|
|
||||||
void delete_all_call_messages_on_server(bool revoke, uint64 log_event_id, Promise<Unit> &&promise);
|
void delete_all_call_messages_on_server(bool revoke, uint64 log_event_id, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void block_message_sender_from_replies_on_server(MessageId message_id, bool need_delete_message,
|
void block_message_sender_from_replies_on_server(MessageId message_id, bool need_delete_message,
|
||||||
@ -2186,7 +2212,12 @@ class MessagesManager final : public Actor {
|
|||||||
bool has_reply_info, tl_object_ptr<telegram_api::messageReplies> &&reply_info,
|
bool has_reply_info, tl_object_ptr<telegram_api::messageReplies> &&reply_info,
|
||||||
bool has_reactions, unique_ptr<MessageReactions> &&reactions);
|
bool has_reactions, unique_ptr<MessageReactions> &&reactions);
|
||||||
|
|
||||||
bool is_active_message_reply_info(DialogId dialog_id, const MessageReplyInfo &info) const;
|
bool is_thread_message(DialogId dialog_id, const Message *m) const;
|
||||||
|
|
||||||
|
bool is_thread_message(DialogId dialog_id, MessageId message_id, const MessageReplyInfo &reply_info,
|
||||||
|
MessageContentType content_type) const;
|
||||||
|
|
||||||
|
bool is_active_message_reply_info(DialogId dialog_id, const MessageReplyInfo &reply_info) const;
|
||||||
|
|
||||||
bool is_visible_message_reply_info(DialogId dialog_id, const Message *m) const;
|
bool is_visible_message_reply_info(DialogId dialog_id, const Message *m) const;
|
||||||
|
|
||||||
@ -2841,7 +2872,7 @@ class MessagesManager final : public Actor {
|
|||||||
|
|
||||||
void edit_dialog_filter(unique_ptr<DialogFilter> new_dialog_filter, const char *source);
|
void edit_dialog_filter(unique_ptr<DialogFilter> new_dialog_filter, const char *source);
|
||||||
|
|
||||||
void delete_dialog_filter(DialogFilterId dialog_filter_id, const char *source);
|
int32 delete_dialog_filter(DialogFilterId dialog_filter_id, const char *source);
|
||||||
|
|
||||||
static bool set_dialog_filters_order(vector<unique_ptr<DialogFilter>> &dialog_filters,
|
static bool set_dialog_filters_order(vector<unique_ptr<DialogFilter>> &dialog_filters,
|
||||||
vector<DialogFilterId> dialog_filter_ids);
|
vector<DialogFilterId> dialog_filter_ids);
|
||||||
@ -2853,7 +2884,8 @@ class MessagesManager final : public Actor {
|
|||||||
|
|
||||||
int32 get_server_main_dialog_list_position() const;
|
int32 get_server_main_dialog_list_position() const;
|
||||||
|
|
||||||
static vector<DialogFilterId> get_dialog_filter_ids(const vector<unique_ptr<DialogFilter>> &dialog_filters);
|
static vector<DialogFilterId> get_dialog_filter_ids(const vector<unique_ptr<DialogFilter>> &dialog_filters,
|
||||||
|
int32 main_dialog_list_position);
|
||||||
|
|
||||||
static vector<FolderId> get_dialog_filter_folder_ids(const DialogFilter *filter);
|
static vector<FolderId> get_dialog_filter_folder_ids(const DialogFilter *filter);
|
||||||
|
|
||||||
@ -3068,8 +3100,6 @@ class MessagesManager final : public Actor {
|
|||||||
|
|
||||||
const DialogPhoto *get_dialog_photo(DialogId dialog_id) const;
|
const DialogPhoto *get_dialog_photo(DialogId dialog_id) const;
|
||||||
|
|
||||||
string get_dialog_username(DialogId dialog_id) const;
|
|
||||||
|
|
||||||
RestrictedRights get_dialog_default_permissions(DialogId dialog_id) const;
|
RestrictedRights get_dialog_default_permissions(DialogId dialog_id) const;
|
||||||
|
|
||||||
bool get_dialog_has_protected_content(DialogId dialog_id) const;
|
bool get_dialog_has_protected_content(DialogId dialog_id) const;
|
||||||
@ -3293,6 +3323,8 @@ class MessagesManager final : public Actor {
|
|||||||
static uint64 save_delete_dialog_history_on_server_log_event(DialogId dialog_id, MessageId max_message_id,
|
static uint64 save_delete_dialog_history_on_server_log_event(DialogId dialog_id, MessageId max_message_id,
|
||||||
bool remove_from_dialog_list, bool revoke);
|
bool remove_from_dialog_list, bool revoke);
|
||||||
|
|
||||||
|
static uint64 save_delete_topic_history_on_server_log_event(DialogId dialog_id, MessageId top_thread_message_id);
|
||||||
|
|
||||||
static uint64 save_delete_all_call_messages_on_server_log_event(bool revoke);
|
static uint64 save_delete_all_call_messages_on_server_log_event(bool revoke);
|
||||||
|
|
||||||
static uint64 save_block_message_sender_from_replies_on_server_log_event(MessageId message_id,
|
static uint64 save_block_message_sender_from_replies_on_server_log_event(MessageId message_id,
|
||||||
@ -3335,9 +3367,9 @@ class MessagesManager final : public Actor {
|
|||||||
void suffix_load_loop(Dialog *d);
|
void suffix_load_loop(Dialog *d);
|
||||||
static void suffix_load_update_first_message_id(Dialog *d);
|
static void suffix_load_update_first_message_id(Dialog *d);
|
||||||
void suffix_load_query_ready(DialogId dialog_id);
|
void suffix_load_query_ready(DialogId dialog_id);
|
||||||
void suffix_load_add_query(Dialog *d, std::pair<Promise<>, std::function<bool(const Message *)>> query);
|
void suffix_load_add_query(Dialog *d, std::pair<Promise<Unit>, std::function<bool(const Message *)>> query);
|
||||||
void suffix_load_till_date(Dialog *d, int32 date, Promise<> promise);
|
void suffix_load_till_date(Dialog *d, int32 date, Promise<Unit> promise);
|
||||||
void suffix_load_till_message_id(Dialog *d, MessageId message_id, Promise<> promise);
|
void suffix_load_till_message_id(Dialog *d, MessageId message_id, Promise<Unit> promise);
|
||||||
|
|
||||||
bool is_group_dialog(DialogId dialog_id) const;
|
bool is_group_dialog(DialogId dialog_id) const;
|
||||||
|
|
||||||
@ -3512,17 +3544,6 @@ class MessagesManager final : public Actor {
|
|||||||
|
|
||||||
FlatHashSet<DialogId, DialogIdHash> postponed_chat_read_inbox_updates_;
|
FlatHashSet<DialogId, DialogIdHash> postponed_chat_read_inbox_updates_;
|
||||||
|
|
||||||
struct PendingGetMessageRequest {
|
|
||||||
MessageId message_id;
|
|
||||||
Promise<Unit> promise;
|
|
||||||
tl_object_ptr<telegram_api::InputMessage> input_message;
|
|
||||||
|
|
||||||
PendingGetMessageRequest(MessageId message_id, Promise<Unit> promise,
|
|
||||||
tl_object_ptr<telegram_api::InputMessage> input_message)
|
|
||||||
: message_id(message_id), promise(std::move(promise)), input_message(std::move(input_message)) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
FlatHashMap<string, vector<Promise<Unit>>> search_public_dialogs_queries_;
|
FlatHashMap<string, vector<Promise<Unit>>> search_public_dialogs_queries_;
|
||||||
FlatHashMap<string, vector<DialogId>> found_public_dialogs_; // TODO time bound cache
|
FlatHashMap<string, vector<DialogId>> found_public_dialogs_; // TODO time bound cache
|
||||||
FlatHashMap<string, vector<DialogId>> found_on_server_dialogs_; // TODO time bound cache
|
FlatHashMap<string, vector<DialogId>> found_on_server_dialogs_; // TODO time bound cache
|
||||||
@ -3628,7 +3649,7 @@ class MessagesManager final : public Actor {
|
|||||||
|
|
||||||
Timeout reload_dialog_filters_timeout_;
|
Timeout reload_dialog_filters_timeout_;
|
||||||
|
|
||||||
Hints dialogs_hints_; // search dialogs by title and username
|
Hints dialogs_hints_; // search dialogs by title and usernames
|
||||||
|
|
||||||
FlatHashSet<FullMessageId, FullMessageIdHash> active_live_location_full_message_ids_;
|
FlatHashSet<FullMessageId, FullMessageIdHash> active_live_location_full_message_ids_;
|
||||||
bool are_active_live_location_messages_loaded_ = false;
|
bool are_active_live_location_messages_loaded_ = false;
|
||||||
@ -3638,11 +3659,15 @@ class MessagesManager final : public Actor {
|
|||||||
|
|
||||||
struct ResolvedUsername {
|
struct ResolvedUsername {
|
||||||
DialogId dialog_id;
|
DialogId dialog_id;
|
||||||
double expires_at;
|
double expires_at = 0.0;
|
||||||
|
|
||||||
|
ResolvedUsername() = default;
|
||||||
|
ResolvedUsername(DialogId dialog_id, double expires_at) : dialog_id(dialog_id), expires_at(expires_at) {
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
FlatHashMap<string, ResolvedUsername> resolved_usernames_;
|
WaitFreeHashMap<string, ResolvedUsername> resolved_usernames_;
|
||||||
FlatHashMap<string, DialogId> inaccessible_resolved_usernames_;
|
WaitFreeHashMap<string, DialogId> inaccessible_resolved_usernames_;
|
||||||
FlatHashSet<string> reload_voice_chat_on_search_usernames_;
|
FlatHashSet<string> reload_voice_chat_on_search_usernames_;
|
||||||
|
|
||||||
struct GetDialogsTask {
|
struct GetDialogsTask {
|
||||||
|
@ -2685,7 +2685,7 @@ void NotificationManager::process_push_notification(string payload, Promise<Unit
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto receiver_id = r_receiver_id.move_as_ok();
|
auto receiver_id = r_receiver_id.move_as_ok();
|
||||||
auto encryption_keys = td_->device_token_manager_->get_actor_unsafe()->get_encryption_keys();
|
auto encryption_keys = td_->device_token_manager_.get_actor_unsafe()->get_encryption_keys();
|
||||||
VLOG(notifications) << "Process push notification \"" << format::escaped(payload)
|
VLOG(notifications) << "Process push notification \"" << format::escaped(payload)
|
||||||
<< "\" with receiver_id = " << receiver_id << " and " << encryption_keys.size()
|
<< "\" with receiver_id = " << receiver_id << " and " << encryption_keys.size()
|
||||||
<< " encryption keys";
|
<< " encryption keys";
|
||||||
@ -3261,7 +3261,7 @@ Status NotificationManager::process_push_notification_payload(string payload, bo
|
|||||||
return Status::Error(406, "Phone call notification is not supported");
|
return Status::Error(406, "Phone call notification is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (begins_with(loc_key, "REACT_")) {
|
if (begins_with(loc_key, "REACT_") || loc_key == "READ_REACTION") {
|
||||||
// TODO REACT_* notifications
|
// TODO REACT_* notifications
|
||||||
return Status::Error(406, "Reaction notifications are unsupported");
|
return Status::Error(406, "Reaction notifications are unsupported");
|
||||||
}
|
}
|
||||||
@ -3331,8 +3331,9 @@ Status NotificationManager::process_push_notification_payload(string payload, bo
|
|||||||
flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
||||||
false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
||||||
false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
||||||
false /*ignored*/, false /*ignored*/, false /*ignored*/, sender_user_id.get(), sender_access_hash, user_name,
|
false /*ignored*/, false /*ignored*/, false /*ignored*/, 0, sender_user_id.get(), sender_access_hash, user_name,
|
||||||
string(), string(), string(), std::move(sender_photo), nullptr, 0, Auto(), string(), string(), nullptr);
|
string(), string(), string(), std::move(sender_photo), nullptr, 0, Auto(), string(), string(), nullptr,
|
||||||
|
vector<telegram_api::object_ptr<telegram_api::username>>());
|
||||||
td_->contacts_manager_->on_get_user(std::move(user), "process_push_notification_payload");
|
td_->contacts_manager_->on_get_user(std::move(user), "process_push_notification_payload");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3689,8 +3690,9 @@ void NotificationManager::add_message_push_notification(DialogId dialog_id, Mess
|
|||||||
flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
||||||
false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
||||||
false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
|
||||||
false /*ignored*/, false /*ignored*/, false /*ignored*/, sender_user_id.get(), 0, user_name, string(), string(),
|
false /*ignored*/, false /*ignored*/, false /*ignored*/, 0, sender_user_id.get(), 0, user_name, string(),
|
||||||
string(), nullptr, nullptr, 0, Auto(), string(), string(), nullptr);
|
string(), string(), nullptr, nullptr, 0, Auto(), string(), string(), nullptr,
|
||||||
|
vector<telegram_api::object_ptr<telegram_api::username>>());
|
||||||
td_->contacts_manager_->on_get_user(std::move(user), "add_message_push_notification");
|
td_->contacts_manager_->on_get_user(std::move(user), "add_message_push_notification");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "td/telegram/NotificationType.h"
|
#include "td/telegram/NotificationType.h"
|
||||||
#include "td/telegram/Photo.h"
|
#include "td/telegram/Photo.h"
|
||||||
#include "td/telegram/td_api.h"
|
#include "td/telegram/td_api.h"
|
||||||
|
#include "td/telegram/UserId.h"
|
||||||
|
|
||||||
#include "td/actor/actor.h"
|
#include "td/actor/actor.h"
|
||||||
#include "td/actor/MultiTimeout.h"
|
#include "td/actor/MultiTimeout.h"
|
||||||
|
@ -1,221 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
#include "td/telegram/NotificationSettings.h"
|
|
||||||
|
|
||||||
#include "td/telegram/Global.h"
|
|
||||||
|
|
||||||
#include "td/utils/common.h"
|
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
|
|
||||||
StringBuilder &operator<<(StringBuilder &string_builder, const DialogNotificationSettings ¬ification_settings) {
|
|
||||||
return string_builder << "[" << notification_settings.mute_until << ", " << notification_settings.sound << ", "
|
|
||||||
<< notification_settings.show_preview << ", " << notification_settings.silent_send_message
|
|
||||||
<< ", " << notification_settings.disable_pinned_message_notifications << ", "
|
|
||||||
<< notification_settings.disable_mention_notifications << ", "
|
|
||||||
<< notification_settings.use_default_mute_until << ", "
|
|
||||||
<< notification_settings.use_default_show_preview << ", "
|
|
||||||
<< notification_settings.use_default_disable_pinned_message_notifications << ", "
|
|
||||||
<< notification_settings.use_default_disable_mention_notifications << ", "
|
|
||||||
<< notification_settings.is_synchronized << "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder &operator<<(StringBuilder &string_builder, NotificationSettingsScope scope) {
|
|
||||||
switch (scope) {
|
|
||||||
case NotificationSettingsScope::Private:
|
|
||||||
return string_builder << "notification settings for private chats";
|
|
||||||
case NotificationSettingsScope::Group:
|
|
||||||
return string_builder << "notification settings for group chats";
|
|
||||||
case NotificationSettingsScope::Channel:
|
|
||||||
return string_builder << "notification settings for channel chats";
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
return string_builder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder &operator<<(StringBuilder &string_builder, const ScopeNotificationSettings ¬ification_settings) {
|
|
||||||
return string_builder << "[" << notification_settings.mute_until << ", " << notification_settings.sound << ", "
|
|
||||||
<< notification_settings.show_preview << ", " << notification_settings.is_synchronized << ", "
|
|
||||||
<< notification_settings.disable_pinned_message_notifications << ", "
|
|
||||||
<< notification_settings.disable_mention_notifications << "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
td_api::object_ptr<td_api::NotificationSettingsScope> get_notification_settings_scope_object(
|
|
||||||
NotificationSettingsScope scope) {
|
|
||||||
switch (scope) {
|
|
||||||
case NotificationSettingsScope::Private:
|
|
||||||
return td_api::make_object<td_api::notificationSettingsScopePrivateChats>();
|
|
||||||
case NotificationSettingsScope::Group:
|
|
||||||
return td_api::make_object<td_api::notificationSettingsScopeGroupChats>();
|
|
||||||
case NotificationSettingsScope::Channel:
|
|
||||||
return td_api::make_object<td_api::notificationSettingsScopeChannelChats>();
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
td_api::object_ptr<td_api::chatNotificationSettings> get_chat_notification_settings_object(
|
|
||||||
const DialogNotificationSettings *notification_settings) {
|
|
||||||
CHECK(notification_settings != nullptr);
|
|
||||||
return td_api::make_object<td_api::chatNotificationSettings>(
|
|
||||||
notification_settings->use_default_mute_until, max(0, notification_settings->mute_until - G()->unix_time()),
|
|
||||||
is_notification_sound_default(notification_settings->sound),
|
|
||||||
get_notification_sound_ringtone_id(notification_settings->sound), notification_settings->use_default_show_preview,
|
|
||||||
notification_settings->show_preview, notification_settings->use_default_disable_pinned_message_notifications,
|
|
||||||
notification_settings->disable_pinned_message_notifications,
|
|
||||||
notification_settings->use_default_disable_mention_notifications,
|
|
||||||
notification_settings->disable_mention_notifications);
|
|
||||||
}
|
|
||||||
|
|
||||||
td_api::object_ptr<td_api::scopeNotificationSettings> get_scope_notification_settings_object(
|
|
||||||
const ScopeNotificationSettings *notification_settings) {
|
|
||||||
CHECK(notification_settings != nullptr);
|
|
||||||
return td_api::make_object<td_api::scopeNotificationSettings>(
|
|
||||||
max(0, notification_settings->mute_until - G()->unix_time()),
|
|
||||||
get_notification_sound_ringtone_id(notification_settings->sound), notification_settings->show_preview,
|
|
||||||
notification_settings->disable_pinned_message_notifications,
|
|
||||||
notification_settings->disable_mention_notifications);
|
|
||||||
}
|
|
||||||
|
|
||||||
telegram_api::object_ptr<telegram_api::InputNotifyPeer> get_input_notify_peer(NotificationSettingsScope scope) {
|
|
||||||
switch (scope) {
|
|
||||||
case NotificationSettingsScope::Private:
|
|
||||||
return telegram_api::make_object<telegram_api::inputNotifyUsers>();
|
|
||||||
case NotificationSettingsScope::Group:
|
|
||||||
return telegram_api::make_object<telegram_api::inputNotifyChats>();
|
|
||||||
case NotificationSettingsScope::Channel:
|
|
||||||
return telegram_api::make_object<telegram_api::inputNotifyBroadcasts>();
|
|
||||||
default:
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationSettingsScope get_notification_settings_scope(
|
|
||||||
const td_api::object_ptr<td_api::NotificationSettingsScope> &scope) {
|
|
||||||
CHECK(scope != nullptr);
|
|
||||||
switch (scope->get_id()) {
|
|
||||||
case td_api::notificationSettingsScopePrivateChats::ID:
|
|
||||||
return NotificationSettingsScope::Private;
|
|
||||||
case td_api::notificationSettingsScopeGroupChats::ID:
|
|
||||||
return NotificationSettingsScope::Group;
|
|
||||||
case td_api::notificationSettingsScopeChannelChats::ID:
|
|
||||||
return NotificationSettingsScope::Channel;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
return NotificationSettingsScope::Private;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32 get_mute_until(int32 mute_for) {
|
|
||||||
if (mute_for <= 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int32 MAX_PRECISE_MUTE_FOR = 366 * 86400;
|
|
||||||
int32 current_time = G()->unix_time();
|
|
||||||
if (mute_for > MAX_PRECISE_MUTE_FOR || mute_for >= std::numeric_limits<int32>::max() - current_time) {
|
|
||||||
return std::numeric_limits<int32>::max();
|
|
||||||
}
|
|
||||||
return mute_for + current_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result<DialogNotificationSettings> get_dialog_notification_settings(
|
|
||||||
td_api::object_ptr<td_api::chatNotificationSettings> &¬ification_settings, bool old_silent_send_message) {
|
|
||||||
if (notification_settings == nullptr) {
|
|
||||||
return Status::Error(400, "New notification settings must be non-empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 mute_until =
|
|
||||||
notification_settings->use_default_mute_for_ ? 0 : get_mute_until(notification_settings->mute_for_);
|
|
||||||
return DialogNotificationSettings(
|
|
||||||
notification_settings->use_default_mute_for_, mute_until,
|
|
||||||
get_notification_sound(notification_settings->use_default_sound_, notification_settings->sound_id_),
|
|
||||||
notification_settings->use_default_show_preview_, notification_settings->show_preview_, old_silent_send_message,
|
|
||||||
notification_settings->use_default_disable_pinned_message_notifications_,
|
|
||||||
notification_settings->disable_pinned_message_notifications_,
|
|
||||||
notification_settings->use_default_disable_mention_notifications_,
|
|
||||||
notification_settings->disable_mention_notifications_);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result<ScopeNotificationSettings> get_scope_notification_settings(
|
|
||||||
td_api::object_ptr<td_api::scopeNotificationSettings> &¬ification_settings) {
|
|
||||||
if (notification_settings == nullptr) {
|
|
||||||
return Status::Error(400, "New notification settings must be non-empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto mute_until = get_mute_until(notification_settings->mute_for_);
|
|
||||||
return ScopeNotificationSettings(mute_until, get_notification_sound(false, notification_settings->sound_id_),
|
|
||||||
notification_settings->show_preview_,
|
|
||||||
notification_settings->disable_pinned_message_notifications_,
|
|
||||||
notification_settings->disable_mention_notifications_);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unique_ptr<NotificationSound> get_peer_notification_sound(
|
|
||||||
tl_object_ptr<telegram_api::peerNotifySettings> &settings) {
|
|
||||||
telegram_api::NotificationSound *sound =
|
|
||||||
#if TD_ANDROID
|
|
||||||
settings->android_sound_.get();
|
|
||||||
#elif TD_DARWIN_IOS || TD_DARWIN_TV_OS || TD_DARWIN_WATCH_OS
|
|
||||||
settings->ios_sound_.get();
|
|
||||||
#else
|
|
||||||
settings->other_sound_.get();
|
|
||||||
#endif
|
|
||||||
return get_notification_sound(sound);
|
|
||||||
}
|
|
||||||
|
|
||||||
DialogNotificationSettings get_dialog_notification_settings(tl_object_ptr<telegram_api::peerNotifySettings> &&settings,
|
|
||||||
bool old_use_default_disable_pinned_message_notifications,
|
|
||||||
bool old_disable_pinned_message_notifications,
|
|
||||||
bool old_use_default_disable_mention_notifications,
|
|
||||||
bool old_disable_mention_notifications) {
|
|
||||||
if (settings == nullptr) {
|
|
||||||
return DialogNotificationSettings();
|
|
||||||
}
|
|
||||||
bool use_default_mute_until = (settings->flags_ & telegram_api::peerNotifySettings::MUTE_UNTIL_MASK) == 0;
|
|
||||||
bool use_default_show_preview = (settings->flags_ & telegram_api::peerNotifySettings::SHOW_PREVIEWS_MASK) == 0;
|
|
||||||
auto mute_until = use_default_mute_until || settings->mute_until_ <= G()->unix_time() ? 0 : settings->mute_until_;
|
|
||||||
bool silent_send_message =
|
|
||||||
(settings->flags_ & telegram_api::peerNotifySettings::SILENT_MASK) == 0 ? false : settings->silent_;
|
|
||||||
return {use_default_mute_until,
|
|
||||||
mute_until,
|
|
||||||
get_peer_notification_sound(settings),
|
|
||||||
use_default_show_preview,
|
|
||||||
settings->show_previews_,
|
|
||||||
silent_send_message,
|
|
||||||
old_use_default_disable_pinned_message_notifications,
|
|
||||||
old_disable_pinned_message_notifications,
|
|
||||||
old_use_default_disable_mention_notifications,
|
|
||||||
old_disable_mention_notifications};
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopeNotificationSettings get_scope_notification_settings(tl_object_ptr<telegram_api::peerNotifySettings> &&settings,
|
|
||||||
bool old_disable_pinned_message_notifications,
|
|
||||||
bool old_disable_mention_notifications) {
|
|
||||||
if (settings == nullptr) {
|
|
||||||
return ScopeNotificationSettings();
|
|
||||||
}
|
|
||||||
auto mute_until = (settings->flags_ & telegram_api::peerNotifySettings::MUTE_UNTIL_MASK) == 0 ||
|
|
||||||
settings->mute_until_ <= G()->unix_time()
|
|
||||||
? 0
|
|
||||||
: settings->mute_until_;
|
|
||||||
auto show_preview =
|
|
||||||
(settings->flags_ & telegram_api::peerNotifySettings::SHOW_PREVIEWS_MASK) == 0 ? false : settings->show_previews_;
|
|
||||||
return {mute_until, get_peer_notification_sound(settings), show_preview, old_disable_pinned_message_notifications,
|
|
||||||
old_disable_mention_notifications};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool are_default_dialog_notification_settings(const DialogNotificationSettings &settings, bool compare_sound) {
|
|
||||||
return settings.use_default_mute_until && (!compare_sound || is_notification_sound_default(settings.sound)) &&
|
|
||||||
settings.use_default_show_preview && settings.use_default_disable_pinned_message_notifications &&
|
|
||||||
settings.use_default_disable_mention_notifications;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace td
|
|
@ -22,9 +22,9 @@
|
|||||||
#include "td/telegram/logevent/LogEventHelper.h"
|
#include "td/telegram/logevent/LogEventHelper.h"
|
||||||
#include "td/telegram/MessagesManager.h"
|
#include "td/telegram/MessagesManager.h"
|
||||||
#include "td/telegram/NotificationManager.h"
|
#include "td/telegram/NotificationManager.h"
|
||||||
#include "td/telegram/NotificationSettings.hpp"
|
|
||||||
#include "td/telegram/NotificationSound.h"
|
#include "td/telegram/NotificationSound.h"
|
||||||
#include "td/telegram/OptionManager.h"
|
#include "td/telegram/OptionManager.h"
|
||||||
|
#include "td/telegram/ScopeNotificationSettings.hpp"
|
||||||
#include "td/telegram/Td.h"
|
#include "td/telegram/Td.h"
|
||||||
#include "td/telegram/TdDb.h"
|
#include "td/telegram/TdDb.h"
|
||||||
#include "td/telegram/telegram_api.h"
|
#include "td/telegram/telegram_api.h"
|
||||||
|
@ -7,9 +7,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "td/telegram/DialogId.h"
|
#include "td/telegram/DialogId.h"
|
||||||
|
#include "td/telegram/DialogNotificationSettings.h"
|
||||||
#include "td/telegram/files/FileId.h"
|
#include "td/telegram/files/FileId.h"
|
||||||
#include "td/telegram/files/FileSourceId.h"
|
#include "td/telegram/files/FileSourceId.h"
|
||||||
#include "td/telegram/NotificationSettings.h"
|
#include "td/telegram/NotificationSettingsScope.h"
|
||||||
|
#include "td/telegram/ScopeNotificationSettings.h"
|
||||||
#include "td/telegram/td_api.h"
|
#include "td/telegram/td_api.h"
|
||||||
#include "td/telegram/telegram_api.h"
|
#include "td/telegram/telegram_api.h"
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user