From bb5ffc0c8cce2796b10c0a3574afe352cbc8e001 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 26 Feb 2019 23:37:59 +0300 Subject: [PATCH] Channel statistics support. GitOrigin-RevId: 39d17de81087c9789b6c717cf1ed5f01edc6360b --- td/generate/scheme/td_api.tl | 11 ++++++- td/generate/scheme/td_api.tlo | Bin 146128 -> 146440 bytes td/telegram/ContactsManager.cpp | 9 ++++-- td/telegram/ContactsManager.h | 1 + td/telegram/MessagesManager.cpp | 52 ++++++++++++++++++++++++++++++-- td/telegram/MessagesManager.h | 3 ++ td/telegram/Td.cpp | 7 +++++ td/telegram/Td.h | 2 ++ td/telegram/cli.cpp | 6 ++++ 9 files changed, 85 insertions(+), 6 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 6a828204b..8fca74d88 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -430,12 +430,13 @@ supergroup id:int32 username:string date:int32 status:ChatMemberStatus member_co //@can_get_members True, if members of the chat can be retrieved //@can_set_username True, if the chat can be made public //@can_set_sticker_set True, if the supergroup sticker set can be changed +//@can_view_statistics True, if the channel statistics is available through getChatStatisticsUrl //@is_all_history_available True, if new chat members will have access to old messages. In public supergroups and both public and private channels, old messages are always available, so this option affects only private supergroups. The value of this field is only available for chat administrators //@sticker_set_id Identifier of the supergroup sticker set; 0 if none //@invite_link Invite link for this chat //@upgraded_from_basic_group_id Identifier of the basic group from which supergroup was upgraded; 0 if none //@upgraded_from_max_message_id Identifier of the last message in the basic group from which supergroup was upgraded; 0 if none -supergroupFullInfo description:string member_count:int32 administrator_count:int32 restricted_count:int32 banned_count:int32 can_get_members:Bool can_set_username:Bool can_set_sticker_set:Bool is_all_history_available:Bool sticker_set_id:int64 invite_link:string upgraded_from_basic_group_id:int32 upgraded_from_max_message_id:int53 = SupergroupFullInfo; +supergroupFullInfo description:string member_count:int32 administrator_count:int32 restricted_count:int32 banned_count:int32 can_get_members:Bool can_set_username:Bool can_set_sticker_set:Bool can_view_statistics:Bool is_all_history_available:Bool sticker_set_id:int64 invite_link:string upgraded_from_basic_group_id:int32 upgraded_from_max_message_id:int53 = SupergroupFullInfo; //@class SecretChatState @description Describes the current secret chat state @@ -1594,6 +1595,10 @@ animations animations:vector = Animations; importedContacts user_ids:vector importer_count:vector = ImportedContacts; +//@description Contains a link to chat statistics @url The URL containing chat statistics +chatStatisticsUrl url:string = ChatStatisticsUrl; + + //@class InputInlineQueryResult @description Represents a single result of an inline query; for bots only //@description Represents a link to an animated GIF @id Unique identifier of the query result @title Title of the query result @thumbnail_url URL of the static result thumbnail (JPEG or GIF), if it exists @@ -3486,6 +3491,10 @@ changeChatReportSpamState chat_id:int53 is_spam_chat:Bool = Ok; reportChat chat_id:int53 reason:ChatReportReason message_ids:vector = Ok; +//@description Returns URL with chat statistics. Currently this method can be used only for channels @chat_id Chat identifier @parameters Parameters from "tg://statsrefresh?params=******" link +getChatStatisticsUrl chat_id:int53 parameters:string = ChatStatisticsUrl; + + //@description Returns storage usage statistics. Can be called before authorization @chat_limit Maximum number of chats with the largest storage usage for which separate statistics should be returned. All other chats will be grouped in entries with chat_id == 0. If the chat info database is not used, the chat_limit is ignored and is always set to 0 getStorageStatistics chat_limit:int32 = StorageStatistics; diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index df7cba0286c8288b1f387fe8fe9223ca65eb4ce6..0e8c9823a214c456cbba524e4ea07e06f634e1cb 100644 GIT binary patch delta 316 zcmcccm80Va2k)cV`c@23@Ngq;CuxhFtld5sGr8T~?o&&lN?8NCCVi|R(9~EFy2fK9piHnR5QecxOU$|`nvBKjGV}~CA&GUWP delta 164 zcmeD9!Exa$2k)cV`c@23@L(fvH{0eDY$qhRPZ(Bi7YZ&dNG(dAyq{5Z^8tAgcE)*| zud4N%ZQc`m<(VQ_K`~fCQGRKGTWL;?XI@%914#VlF(Dt`?HgSfgBhnAxG{cV0SRu` taA*9Y1z{=_F &&c auto can_get_participants = (channel_full->flags_ & CHANNEL_FULL_FLAG_CAN_GET_PARTICIPANTS) != 0; auto can_set_username = (channel_full->flags_ & CHANNEL_FULL_FLAG_CAN_SET_USERNAME) != 0; auto can_set_sticker_set = (channel_full->flags_ & CHANNEL_FULL_FLAG_CAN_SET_STICKERS) != 0; + auto can_view_statistics = (channel_full->flags_ & CHANNEL_FULL_FLAG_CAN_VIEW_STATISTICS) != 0; auto is_all_history_available = (channel_full->flags_ & CHANNEL_FULL_FLAG_IS_ALL_HISTORY_HIDDEN) == 0; int64 sticker_set_id = channel_full->stickerset_ == nullptr ? 0 @@ -6698,7 +6699,8 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c channel->administrator_count != administrator_count || channel->restricted_count != restricted_count || channel->banned_count != banned_count || channel->can_get_participants != can_get_participants || channel->can_set_username != can_set_username || channel->can_set_sticker_set != can_set_sticker_set || - channel->sticker_set_id != sticker_set_id || channel->is_all_history_available != is_all_history_available) { + channel->can_view_statistics != can_view_statistics || channel->sticker_set_id != sticker_set_id || + channel->is_all_history_available != is_all_history_available) { channel->description = std::move(channel_full->about_); channel->participant_count = participant_count; channel->administrator_count = administrator_count; @@ -6707,6 +6709,7 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c channel->can_get_participants = can_get_participants; channel->can_set_username = can_set_username; channel->can_set_sticker_set = can_set_sticker_set; + channel->can_view_statistics = can_view_statistics; channel->sticker_set_id = sticker_set_id; channel->is_all_history_available = is_all_history_available; @@ -9911,8 +9914,8 @@ tl_object_ptr ContactsManager::get_supergroup_full_i return make_tl_object( channel_full->description, channel_full->participant_count, channel_full->administrator_count, channel_full->restricted_count, channel_full->banned_count, channel_full->can_get_participants, - channel_full->can_set_username, channel_full->can_set_sticker_set, channel_full->is_all_history_available, - channel_full->sticker_set_id, channel_full->invite_link, + channel_full->can_set_username, channel_full->can_set_sticker_set, channel_full->can_view_statistics, + channel_full->is_all_history_available, channel_full->sticker_set_id, channel_full->invite_link, get_basic_group_id_object(channel_full->migrated_from_chat_id, "get_supergroup_full_info_object"), channel_full->migrated_from_max_message_id.get()); } diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 8d88cc57f..fba1d522c 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -642,6 +642,7 @@ class ContactsManager : public Actor { bool can_get_participants = false; bool can_set_username = false; bool can_set_sticker_set = false; + bool can_view_statistics = false; bool is_all_history_available = true; bool is_changed = true; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 3f2f4194a..07f3eaab0 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -2874,8 +2874,6 @@ class GetNotifySettingsExceptionsQuery : public Td::ResultHandler { } void send(NotificationSettingsScope scope, bool filter_scope, bool compare_sound) { - // +account.getNotifyExceptions flags:# compare_sound:flags.1?true peer:flags.0?InputNotifyPeer = Updates; - int32 flags = 0; tl_object_ptr input_notify_peer; if (filter_scope) { @@ -3275,6 +3273,39 @@ class ReportPeerQuery : public Td::ResultHandler { } }; +class GetStatsUrlQuery : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + + public: + explicit GetStatsUrlQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, const string ¶meters) { + dialog_id_ = dialog_id; + auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + CHECK(input_peer != nullptr); + send_query( + G()->net_query_creator().create(create_storer(telegram_api::messages_getStatsURL(std::move(input_peer))))); + } + + void on_result(uint64 id, BufferSlice packet) override { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(id, result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + promise_.set_value(td_api::make_object(result->url_)); + } + + void on_error(uint64 id, Status status) override { + td->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetStatsUrlQuery"); + promise_.set_error(std::move(status)); + } +}; + class GetChannelDifferenceQuery : public Td::ResultHandler { DialogId dialog_id_; int32 pts_; @@ -6180,6 +6211,23 @@ void MessagesManager::on_get_peer_settings(DialogId dialog_id, on_dialog_updated(dialog_id, "can_report_spam"); } +void MessagesManager::get_dialog_statistics_url(DialogId dialog_id, const string ¶meters, + Promise> &&promise) { + Dialog *d = get_dialog_force(dialog_id); + if (d == nullptr) { + return promise.set_error(Status::Error(3, "Chat not found")); + } + + if (!have_input_peer(dialog_id, AccessRights::Read)) { + return promise.set_error(Status::Error(3, "Can't access the chat")); + } + if (dialog_id.get_type() == DialogType::SecretChat) { + return promise.set_error(Status::Error(500, "There is no statistics for secret chats")); + } + + td_->create_handler(std::move(promise))->send(dialog_id, parameters); +} + void MessagesManager::load_secret_thumbnail(FileId thumbnail_file_id) { class Callback : public FileManager::DownloadCallback { public: diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 956606172..832e24e0f 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -628,6 +628,9 @@ class MessagesManager : public Actor { void report_dialog(DialogId dialog_id, const tl_object_ptr &reason, const vector &message_ids, Promise &&promise); + void get_dialog_statistics_url(DialogId dialog_id, const string ¶meters, + Promise> &&promise); + void on_get_peer_settings(DialogId dialog_id, tl_object_ptr &&peer_settings); void before_get_difference(); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 07b764d9e..c4506780a 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6206,6 +6206,13 @@ void Td::on_request(uint64 id, td_api::reportChat &request) { MessagesManager::get_message_ids(request.message_ids_), std::move(promise)); } +void Td::on_request(uint64 id, td_api::getChatStatisticsUrl &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + CLEAN_INPUT_STRING(request.parameters_); + messages_manager_->get_dialog_statistics_url(DialogId(request.chat_id_), request.parameters_, std::move(promise)); +} + void Td::on_request(uint64 id, td_api::setChatNotificationSettings &request) { CHECK_IS_USER(); answer_ok_query(id, messages_manager_->set_dialog_notification_settings(DialogId(request.chat_id_), diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 78ba1785c..6fc843ac1 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -808,6 +808,8 @@ class Td final : public NetQueryCallback { void on_request(uint64 id, td_api::reportChat &request); + void on_request(uint64 id, td_api::getChatStatisticsUrl &request); + void on_request(uint64 id, const td_api::getMapThumbnailFile &request); void on_request(uint64 id, const td_api::getLocalizationTargetInfo &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 8ec10d1a6..39765f401 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3531,6 +3531,12 @@ class CliClient final : public Actor { send_request( td_api::make_object(as_chat_id(chat_id), std::move(reason), as_message_ids(message_ids))); + } else if (op == "gcsu") { + string chat_id; + string parameters; + std::tie(chat_id, parameters) = split(args); + + send_request(td_api::make_object(as_chat_id(args), parameters)); } else if (op == "rsgs" || op == "rchs") { string supergroup_id; string user_id;