Improve chat statistics.

GitOrigin-RevId: a55d3a62bbeded1000f58a348c1ab7225b85d39a
This commit is contained in:
levlam 2020-04-03 03:53:33 +03:00
parent 81babdf915
commit 3b2c06e520
7 changed files with 188 additions and 99 deletions

View File

@ -2734,7 +2734,7 @@ textParseModeHTML = TextParseMode;
//@description A SOCKS5 proxy server @username Username for logging in; may be empty @password Password for logging in; may be empty //@description A SOCKS5 proxy server @username Username for logging in; may be empty @password Password for logging in; may be empty
proxyTypeSocks5 username:string password:string = ProxyType; proxyTypeSocks5 username:string password:string = ProxyType;
//@description A HTTP transparent proxy server @username Username for logging in; may be empty @password Password for logging in; may be empty @http_only Pass true, if the proxy supports only HTTP requests and doesn't support transparent TCP connections via HTTP CONNECT method //@description A HTTP transparent proxy server @username Username for logging in; may be empty @password Password for logging in; may be empty @http_only Pass true if the proxy supports only HTTP requests and doesn't support transparent TCP connections via HTTP CONNECT method
proxyTypeHttp username:string password:string http_only:Bool = ProxyType; proxyTypeHttp username:string password:string http_only:Bool = ProxyType;
//@description An MTProto proxy server @secret The proxy's secret in hexadecimal encoding //@description An MTProto proxy server @secret The proxy's secret in hexadecimal encoding
@ -2762,51 +2762,50 @@ inputStickerStatic sticker:InputFile emojis:string mask_position:maskPosition =
inputStickerAnimated sticker:InputFile emojis:string = InputSticker; inputStickerAnimated sticker:InputFile emojis:string = InputSticker;
//@description chatStatisticsDateRange //@description Represents a date range @start_date Point in time (Unix timestamp) at which the date range begins @end_date Point in time (Unix timestamp) at which the date range ends
//@min_date min_date dateRange start_date:int32 end_date:int32 = DateRange;
//@max_date max_date
chatStatisticsDateRange min_date:int32 max_date:int32 = ChatStatisticsDateRange;
//@description chatStatisticsAbsoluteValue
//@current current
//@previous previous
chatStatisticsAbsoluteValue current:double previous:double = ChatStatisticsAbsoluteValue;
//@description chatStatisticsRelativeValue
//@part part
//@total total
chatStatisticsRelativeValue part:double total:double = ChatStatisticsRelativeValue;
//@class ChatStatisticsGraph @description ChatStatisticsGraph //@description A statistics value @value The value @previous_value The value for the previous day @growth_rate_percentage The growth rate of the value, as a percentage
statisticsValue value:double previous_value:double growth_rate_percentage:double = StatisticsValue;
//@description chatStatisticsGraphAsync
//@token token
chatStatisticsGraphAsync token:string = ChatStatisticsGraph;
//@description chatStatisticsGraphError
//@error_message error_message
chatStatisticsGraphError error_message:string = ChatStatisticsGraph;
//@description chatStatisticsGraphData
//@json json
//@zoom_token zoom_token
chatStatisticsGraphData json:string zoom_token:string = ChatStatisticsGraph;
//@description chatStatisticsMessageInteractionCounters //@class StatisticsGraph @description Descrbes a statistics graph
//@message_id message_id
//@views views //@description A graph data @json_data Graph data in JSON format @zoom_token If non-empty, a token which can be used to receive a zoomed in graph
//@forwards forwards statisticsGraphData json_data:string zoom_token:string = StatisticsGraph;
chatStatisticsMessageInteractionCounters message_id:int32 views:int32 forwards:int32 = ChatStatisticsMessageInteractionCounters;
//@description The graph data to be asynchronously loaded through getChatStatisticsGraph @token The token to use for data loading
statisticsGraphAsync token:string = StatisticsGraph;
//@description An error message to be shown to the user instead of the graph @error_message The error message
statisticsGraphError error_message:string = StatisticsGraph;
//@description chatStatistics //@description Contains statistics about interactions with a message
//@period period @followers followers @views_per_post views_per_post @shares_per_post shares_per_post @enabled_notifications enabled_notifications //@message_id Message identifier
//@growth_graph growth_graph @followers_graph followers_graph @mute_graph mute_graph @top_hours_graph top_hours_graph @interactions_graph interactions_graph //@view_count Number of times the message was viewed
//@iv_interactions_graph iv_interactions_graph @views_by_source_graph views_by_source_graph @new_followers_by_source_graph new_followers_by_source_graph //@forward_count Number of times the message was forwarded
//@languages_graph languages_graph @recent_message_interactions recent_message_interactions chatStatisticsMessageInteractionCounters message_id:int53 view_count:int32 forward_count:int32 = ChatStatisticsMessageInteractionCounters;
chatStatistics period:ChatStatisticsDateRange followers:ChatStatisticsAbsoluteValue views_per_post:ChatStatisticsAbsoluteValue shares_per_post:ChatStatisticsAbsoluteValue enabled_notifications:ChatStatisticsRelativeValue growth_graph:ChatStatisticsGraph followers_graph:ChatStatisticsGraph mute_graph:ChatStatisticsGraph top_hours_graph:ChatStatisticsGraph interactions_graph:ChatStatisticsGraph iv_interactions_graph:ChatStatisticsGraph views_by_source_graph:ChatStatisticsGraph new_followers_by_source_graph:ChatStatisticsGraph languages_graph:ChatStatisticsGraph recent_message_interactions:Vector<ChatStatisticsMessageInteractionCounters> = ChatStatistics;
//@description A detailed statistics about a chat
//@period A period to which the statistics applies
//@member_count Number of members in the chat
//@mean_view_count Mean number of times the recently sent messages was viewed
//@mean_share_count Mean number of times the recently sent messages was shared
//@enabled_notifications_percentage A percentage of users with enabled notifications for the chat
//@member_count_graph A graph containing number of members in the chat
//@join_graph A graph containing number of members joined and left the chat
//@mute_graph A graph containing number of members muted and unmuted the chat
//@view_count_by_hour_graph A graph containing number of message views in a given hour in the last two weeks
//@view_count_by_source_graph A graph containing number of message views per source
//@join_by_source_graph A graph containing number of new member joins per source
//@language_graph A graph containing number of users viewed chat messages per language
//@message_interaction_graph A graph containing number of chat message views and shares
//@instant_view_interaction_graph A graph containing number of views of associated with the chat instant views
//@recent_message_interactions Detailed statistics about number of views and shares of recently sent messages
chatStatistics period:dateRange member_count:statisticsValue mean_view_count:statisticsValue mean_share_count:statisticsValue enabled_notifications_percentage:double member_count_graph:StatisticsGraph join_graph:StatisticsGraph mute_graph:StatisticsGraph view_count_by_hour_graph:StatisticsGraph view_count_by_source_graph:StatisticsGraph join_by_source_graph:StatisticsGraph language_graph:StatisticsGraph message_interaction_graph:StatisticsGraph instant_view_interaction_graph:StatisticsGraph recent_message_interactions:vector<chatStatisticsMessageInteractionCounters> = ChatStatistics;
//@class Update @description Contains notifications about data changes //@class Update @description Contains notifications about data changes
@ -4187,11 +4186,11 @@ reportChat chat_id:int53 reason:ChatReportReason message_ids:vector<int53> = Ok;
//@description Returns an HTTP URL with the chat statistics. Currently this method of getting the statistics is disabled and can be deleted in the future @chat_id Chat identifier @parameters Parameters from "tg://statsrefresh?params=******" link @is_dark Pass true if a URL with the dark theme must be returned //@description Returns an HTTP URL with the chat statistics. Currently this method of getting the statistics is disabled and can be deleted in the future @chat_id Chat identifier @parameters Parameters from "tg://statsrefresh?params=******" link @is_dark Pass true if a URL with the dark theme must be returned
getChatStatisticsUrl chat_id:int53 parameters:string is_dark:Bool = HttpUrl; getChatStatisticsUrl chat_id:int53 parameters:string is_dark:Bool = HttpUrl;
//@description Retrieve specified channel statistics @chat_id supergroup id @is_dark is dark //@description Returns detailed statistics about a chat. Currently this method can be used only for channels. Requires administrator rights in the channel @chat_id Chat identifier @is_dark Pass true if a dark theme is used by the app
getChatStatistics chat_id:int53 is_dark:Bool = ChatStatistics; getChatStatistics chat_id:int53 is_dark:Bool = ChatStatistics;
//@description Load async stats @token token @x zoom //@description Loads asynchronous or zoomed in chat statistics graph @chat_id Chat identifer @token The token for graph loading @x X-value for zoomed in graph or 0 otherwise
getChatStatisticsGraph token:string x:int53 = ChatStatisticsGraph; getChatStatisticsGraph chat_id:int53 token:string x:int53 = StatisticsGraph;
//@description Returns storage usage statistics. Can be called before authorization @chat_limit The 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 //@description Returns storage usage statistics. Can be called before authorization @chat_limit The 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
@ -4211,7 +4210,7 @@ getDatabaseStatistics = DatabaseStatistics;
//@file_types If not empty, only files with the given type(s) are considered. By default, all types except thumbnails, profile photos, stickers and wallpapers are deleted //@file_types If not empty, only files with the given type(s) are considered. By default, all types except thumbnails, profile photos, stickers and wallpapers are deleted
//@chat_ids If not empty, only files from the given chats are considered. Use 0 as chat identifier to delete files not belonging to any chat (e.g., profile photos) //@chat_ids If not empty, only files from the given chats are considered. Use 0 as chat identifier to delete files not belonging to any chat (e.g., profile photos)
//@exclude_chat_ids If not empty, files from the given chats are excluded. Use 0 as chat identifier to exclude all files not belonging to any chat (e.g., profile photos) //@exclude_chat_ids If not empty, files from the given chats are excluded. Use 0 as chat identifier to exclude all files not belonging to any chat (e.g., profile photos)
//@return_deleted_file_statistics Pass true, if deleted file statistics needs to be returned instead of the whole storage usage statistics. Affects only returned statistics //@return_deleted_file_statistics Pass true if deleted file statistics needs to be returned instead of the whole storage usage statistics. Affects only returned statistics
//@chat_limit Same as in getStorageStatistics. Affects only returned statistics //@chat_limit Same as in getStorageStatistics. Affects only returned statistics
optimizeStorage size:int53 ttl:int32 count:int32 immunity_delay:int32 file_types:vector<FileType> chat_ids:vector<int53> exclude_chat_ids:vector<int53> return_deleted_file_statistics:Bool chat_limit:int32 = StorageStatistics; optimizeStorage size:int53 ttl:int32 count:int32 immunity_delay:int32 file_types:vector<FileType> chat_ids:vector<int53> exclude_chat_ids:vector<int53> return_deleted_file_statistics:Bool chat_limit:int32 = StorageStatistics;

Binary file not shown.

View File

@ -2660,21 +2660,22 @@ class GetSupportUserQuery : public Td::ResultHandler {
} }
}; };
static tl_object_ptr<td_api::ChatStatisticsGraph> convert_stats_graph(tl_object_ptr<telegram_api::StatsGraph> obj) { tl_object_ptr<td_api::StatisticsGraph> ContactsManager::convert_stats_graph(
tl_object_ptr<telegram_api::StatsGraph> obj) {
CHECK(obj != nullptr); CHECK(obj != nullptr);
switch (obj->get_id()) { switch (obj->get_id()) {
case telegram_api::statsGraphAsync::ID: { case telegram_api::statsGraphAsync::ID: {
auto graph = move_tl_object_as<telegram_api::statsGraphAsync>(obj); auto graph = move_tl_object_as<telegram_api::statsGraphAsync>(obj);
return make_tl_object<td_api::chatStatisticsGraphAsync>(std::move(graph->token_)); return make_tl_object<td_api::statisticsGraphAsync>(std::move(graph->token_));
} }
case telegram_api::statsGraphError::ID: { case telegram_api::statsGraphError::ID: {
auto graph = move_tl_object_as<telegram_api::statsGraphError>(obj); auto graph = move_tl_object_as<telegram_api::statsGraphError>(obj);
return make_tl_object<td_api::chatStatisticsGraphError>(std::move(graph->error_)); return make_tl_object<td_api::statisticsGraphError>(std::move(graph->error_));
} }
case telegram_api::statsGraph::ID: { case telegram_api::statsGraph::ID: {
auto graph = move_tl_object_as<telegram_api::statsGraph>(obj); auto graph = move_tl_object_as<telegram_api::statsGraph>(obj);
return make_tl_object<td_api::chatStatisticsGraphData>(std::move(graph->json_->data_), std::move(graph->zoom_token_)); return make_tl_object<td_api::statisticsGraphData>(std::move(graph->json_->data_), std::move(graph->zoom_token_));
} }
default: default:
UNREACHABLE(); UNREACHABLE();
@ -2682,33 +2683,45 @@ static tl_object_ptr<td_api::ChatStatisticsGraph> convert_stats_graph(tl_object_
} }
} }
static tl_object_ptr<td_api::chatStatistics> convert_stats_broadcast_stats(tl_object_ptr<telegram_api::stats_broadcastStats> obj) { double ContactsManager::get_percentage_value(double part, double total) {
CHECK(obj != nullptr); if (total < 1e-6 && total > -1e-6) {
if (part < 1e-6 && part > -1e-6) {
vector<tl_object_ptr<td_api::chatStatisticsMessageInteractionCounters>> recent_message_interactions; return 0.0;
recent_message_interactions.reserve(obj->recent_message_interactions_.size()); }
for (auto& interaction : obj->recent_message_interactions_) { return 100.0;
recent_message_interactions.push_back( }
make_tl_object<td_api::chatStatisticsMessageInteractionCounters>(interaction->msg_id_, interaction->views_, interaction->forwards_)); if (part > 1e20) {
return 100.0;
}
return part / total * 100;
} }
tl_object_ptr<td_api::statisticsValue> ContactsManager::convert_stats_absolute_value(
const tl_object_ptr<telegram_api::statsAbsValueAndPrev> &obj) {
return make_tl_object<td_api::statisticsValue>(obj->current_, obj->previous_,
get_percentage_value(obj->current_ - obj->previous_, obj->previous_));
}
tl_object_ptr<td_api::chatStatistics> ContactsManager::convert_broadcast_stats(
tl_object_ptr<telegram_api::stats_broadcastStats> obj) {
CHECK(obj != nullptr);
auto recent_message_interactions = transform(std::move(obj->recent_message_interactions_), [](auto &&interaction) {
return make_tl_object<td_api::chatStatisticsMessageInteractionCounters>(
MessageId(ServerMessageId(interaction->msg_id_)).get(), interaction->views_, interaction->forwards_);
});
return make_tl_object<td_api::chatStatistics>( return make_tl_object<td_api::chatStatistics>(
make_tl_object<td_api::chatStatisticsDateRange>(obj->period_->min_date_, obj->period_->max_date_), make_tl_object<td_api::dateRange>(obj->period_->min_date_, obj->period_->max_date_),
make_tl_object<td_api::chatStatisticsAbsoluteValue>(obj->followers_->current_, obj->followers_->previous_), convert_stats_absolute_value(obj->followers_), convert_stats_absolute_value(obj->views_per_post_),
make_tl_object<td_api::chatStatisticsAbsoluteValue>(obj->views_per_post_->current_, obj->views_per_post_->previous_), convert_stats_absolute_value(obj->shares_per_post_),
make_tl_object<td_api::chatStatisticsAbsoluteValue>(obj->shares_per_post_->current_, obj->shares_per_post_->previous_), get_percentage_value(obj->enabled_notifications_->part_, obj->enabled_notifications_->total_),
make_tl_object<td_api::chatStatisticsRelativeValue>(obj->enabled_notifications_->part_, obj->enabled_notifications_->total_), convert_stats_graph(std::move(obj->growth_graph_)), convert_stats_graph(std::move(obj->followers_graph_)),
convert_stats_graph(std::move(obj->growth_graph_)), convert_stats_graph(std::move(obj->mute_graph_)), convert_stats_graph(std::move(obj->top_hours_graph_)),
convert_stats_graph(std::move(obj->followers_graph_)),
convert_stats_graph(std::move(obj->mute_graph_)),
convert_stats_graph(std::move(obj->top_hours_graph_)),
convert_stats_graph(std::move(obj->interactions_graph_)),
convert_stats_graph(std::move(obj->iv_interactions_graph_)),
convert_stats_graph(std::move(obj->views_by_source_graph_)), convert_stats_graph(std::move(obj->views_by_source_graph_)),
convert_stats_graph(std::move(obj->new_followers_by_source_graph_)), convert_stats_graph(std::move(obj->new_followers_by_source_graph_)),
convert_stats_graph(std::move(obj->languages_graph_)), convert_stats_graph(std::move(obj->languages_graph_)), convert_stats_graph(std::move(obj->interactions_graph_)),
std::move(recent_message_interactions) convert_stats_graph(std::move(obj->iv_interactions_graph_)), std::move(recent_message_interactions));
);
} }
class GetBroadcastStatsQuery : public Td::ResultHandler { class GetBroadcastStatsQuery : public Td::ResultHandler {
@ -2716,7 +2729,8 @@ class GetBroadcastStatsQuery : public Td::ResultHandler {
ChannelId channel_id_; ChannelId channel_id_;
public: public:
explicit GetBroadcastStatsQuery(Promise<td_api::object_ptr<td_api::chatStatistics>> &&promise) : promise_(std::move(promise)) { explicit GetBroadcastStatsQuery(Promise<td_api::object_ptr<td_api::chatStatistics>> &&promise)
: promise_(std::move(promise)) {
} }
void send(ChannelId channel_id, bool is_dark, DcId dc_id) { void send(ChannelId channel_id, bool is_dark, DcId dc_id) {
@ -2740,7 +2754,7 @@ class GetBroadcastStatsQuery : public Td::ResultHandler {
} }
auto result = result_ptr.move_as_ok(); auto result = result_ptr.move_as_ok();
promise_.set_value(convert_stats_broadcast_stats(std::move(result))); promise_.set_value(ContactsManager::convert_broadcast_stats(std::move(result)));
} }
void on_error(uint64 id, Status status) override { void on_error(uint64 id, Status status) override {
@ -2749,20 +2763,20 @@ class GetBroadcastStatsQuery : public Td::ResultHandler {
} }
}; };
class LoadAyncGraphQuery : public Td::ResultHandler { class LoadAsyncGraphQuery : public Td::ResultHandler {
Promise<td_api::object_ptr<td_api::ChatStatisticsGraph>> promise_; Promise<td_api::object_ptr<td_api::StatisticsGraph>> promise_;
public: public:
explicit LoadAyncGraphQuery(Promise<td_api::object_ptr<td_api::ChatStatisticsGraph>> &&promise) : promise_(std::move(promise)) { explicit LoadAsyncGraphQuery(Promise<td_api::object_ptr<td_api::StatisticsGraph>> &&promise)
: promise_(std::move(promise)) {
} }
void send(const string& token, int64 x) { void send(const string &token, int64 x, DcId dc_id) {
int32 flags = 0; int32 flags = 0;
if (x != 0) { if (x != 0) {
flags |= telegram_api::stats_loadAsyncGraph::X_MASK; flags |= telegram_api::stats_loadAsyncGraph::X_MASK;
} }
send_query(G()->net_query_creator().create( send_query(G()->net_query_creator().create(telegram_api::stats_loadAsyncGraph(flags, token, x), dc_id));
telegram_api::stats_loadAsyncGraph(flags, token, x)));
} }
void on_result(uint64 id, BufferSlice packet) override { void on_result(uint64 id, BufferSlice packet) override {
@ -2772,7 +2786,7 @@ class LoadAyncGraphQuery : public Td::ResultHandler {
} }
auto result = result_ptr.move_as_ok(); auto result = result_ptr.move_as_ok();
promise_.set_value(convert_stats_graph(std::move(result))); promise_.set_value(ContactsManager::convert_stats_graph(std::move(result)));
} }
void on_error(uint64 id, Status status) override { void on_error(uint64 id, Status status) override {
@ -5634,7 +5648,7 @@ void ContactsManager::set_channel_location(DialogId dialog_id, const DialogLocat
} }
if (!dialog_id.is_valid()) { if (!dialog_id.is_valid()) {
return promise.set_error(Status::Error(400, "Invalid chat specified")); return promise.set_error(Status::Error(400, "Invalid chat identifier specified"));
} }
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id)) {
return promise.set_error(Status::Error(400, "Chat not found")); return promise.set_error(Status::Error(400, "Chat not found"));
@ -5666,7 +5680,7 @@ void ContactsManager::set_channel_slow_mode_delay(DialogId dialog_id, int32 slow
} }
if (!dialog_id.is_valid()) { if (!dialog_id.is_valid()) {
return promise.set_error(Status::Error(400, "Invalid chat specified")); return promise.set_error(Status::Error(400, "Invalid chat identifier specified"));
} }
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id)) {
return promise.set_error(Status::Error(400, "Chat not found")); return promise.set_error(Status::Error(400, "Chat not found"));
@ -5691,10 +5705,9 @@ void ContactsManager::set_channel_slow_mode_delay(DialogId dialog_id, int32 slow
td_->create_handler<ToggleSlowModeQuery>(std::move(promise))->send(channel_id, slow_mode_delay); td_->create_handler<ToggleSlowModeQuery>(std::move(promise))->send(channel_id, slow_mode_delay);
} }
void ContactsManager::get_broadcast_stats(DialogId dialog_id, bool is_dark, void ContactsManager::get_channel_statistics_dc_id(DialogId dialog_id, Promise<DcId> &&promise) {
Promise<td_api::object_ptr<td_api::chatStatistics>> &&promise) {
if (!dialog_id.is_valid()) { if (!dialog_id.is_valid()) {
return promise.set_error(Status::Error(400, "Invalid chat specified")); return promise.set_error(Status::Error(400, "Invalid chat identifier specified"));
} }
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id)) {
return promise.set_error(Status::Error(400, "Chat not found")); return promise.set_error(Status::Error(400, "Chat not found"));
@ -5713,17 +5726,60 @@ void ContactsManager::get_broadcast_stats(DialogId dialog_id, bool is_dark,
return promise.set_error(Status::Error(400, "Chat is not a channel")); return promise.set_error(Status::Error(400, "Chat is not a channel"));
} }
const ChannelFull* c_full = get_channel_full(channel_id, "get_broadcast_stats"); auto channel_full = get_channel_full_force(channel_id);
if (c_full == nullptr) { if (channel_full == nullptr) {
return promise.set_error(Status::Error(400, "Chat info not found")); return promise.set_error(Status::Error(400, "Chat full info not found"));
} }
td_->create_handler<GetBroadcastStatsQuery>(std::move(promise))->send(channel_id, is_dark, c_full->stats_dc_id); if (!channel_full->stats_dc_id.is_exact()) {
return promise.set_error(Status::Error(400, "Chat statistics is not available"));
} }
void ContactsManager::load_async_graph(const string& token, int64 x, Promise<td_api::object_ptr<td_api::ChatStatisticsGraph>> &&promise) promise.set_value(DcId(channel_full->stats_dc_id));
{ }
td_->create_handler<LoadAyncGraphQuery>(std::move(promise))->send(token, x);
void ContactsManager::get_channel_statistics(DialogId dialog_id, bool is_dark,
Promise<td_api::object_ptr<td_api::chatStatistics>> &&promise) {
auto dc_id_promise = PromiseCreator::lambda(
[actor_id = actor_id(this), dialog_id, is_dark, promise = std::move(promise)](Result<DcId> r_dc_id) mutable {
if (r_dc_id.is_error()) {
return promise.set_error(r_dc_id.move_as_error());
}
send_closure(actor_id, &ContactsManager::send_get_broadcast_stats_query, r_dc_id.move_as_ok(),
dialog_id.get_channel_id(), is_dark, std::move(promise));
});
get_channel_statistics_dc_id(dialog_id, std::move(dc_id_promise));
}
void ContactsManager::send_get_broadcast_stats_query(DcId dc_id, ChannelId channel_id, bool is_dark,
Promise<td_api::object_ptr<td_api::chatStatistics>> &&promise) {
if (G()->close_flag()) {
return promise.set_error(Status::Error(500, "Request aborted"));
}
td_->create_handler<GetBroadcastStatsQuery>(std::move(promise))->send(channel_id, is_dark, dc_id);
}
void ContactsManager::load_statistics_graph(DialogId dialog_id, const string &token, int64 x,
Promise<td_api::object_ptr<td_api::StatisticsGraph>> &&promise) {
auto dc_id_promise = PromiseCreator::lambda(
[actor_id = actor_id(this), token, x, promise = std::move(promise)](Result<DcId> r_dc_id) mutable {
if (r_dc_id.is_error()) {
return promise.set_error(r_dc_id.move_as_error());
}
send_closure(actor_id, &ContactsManager::send_load_async_graph_query, r_dc_id.move_as_ok(), std::move(token), x,
std::move(promise));
});
get_channel_statistics_dc_id(dialog_id, std::move(dc_id_promise));
}
void ContactsManager::send_load_async_graph_query(DcId dc_id, string token, int64 x,
Promise<td_api::object_ptr<td_api::StatisticsGraph>> &&promise) {
if (G()->close_flag()) {
return promise.set_error(Status::Error(500, "Request aborted"));
}
td_->create_handler<LoadAsyncGraphQuery>(std::move(promise))->send(token, x, dc_id);
} }
void ContactsManager::report_channel_spam(ChannelId channel_id, UserId user_id, const vector<MessageId> &message_ids, void ContactsManager::report_channel_spam(ChannelId channel_id, UserId user_id, const vector<MessageId> &message_ids,

View File

@ -357,10 +357,11 @@ class ContactsManager : public Actor {
void delete_channel(ChannelId channel_id, Promise<Unit> &&promise); void delete_channel(ChannelId channel_id, Promise<Unit> &&promise);
void get_broadcast_stats(DialogId dialog_id, bool is_dark, void get_channel_statistics(DialogId dialog_id, bool is_dark,
Promise<td_api::object_ptr<td_api::chatStatistics>> &&promise); Promise<td_api::object_ptr<td_api::chatStatistics>> &&promise);
void load_async_graph(const string& token, int64 x, Promise<td_api::object_ptr<td_api::ChatStatisticsGraph>> &&promise); void load_statistics_graph(DialogId dialog_id, const string &token, int64 x,
Promise<td_api::object_ptr<td_api::StatisticsGraph>> &&promise);
void add_chat_participant(ChatId chat_id, UserId user_id, int32 forward_limit, Promise<Unit> &&promise); void add_chat_participant(ChatId chat_id, UserId user_id, int32 forward_limit, Promise<Unit> &&promise);
@ -538,6 +539,16 @@ class ContactsManager : public Actor {
void get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const; void get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const;
static tl_object_ptr<td_api::StatisticsGraph> convert_stats_graph(tl_object_ptr<telegram_api::StatsGraph> obj);
static double get_percentage_value(double new_value, double old_value);
static tl_object_ptr<td_api::statisticsValue> convert_stats_absolute_value(
const tl_object_ptr<telegram_api::statsAbsValueAndPrev> &obj);
static tl_object_ptr<td_api::chatStatistics> convert_broadcast_stats(
tl_object_ptr<telegram_api::stats_broadcastStats> obj);
private: private:
struct User { struct User {
string first_name; string first_name;
@ -1327,6 +1338,14 @@ class ContactsManager : public Actor {
tl_object_ptr<telegram_api::InputCheckPasswordSRP> input_check_password, tl_object_ptr<telegram_api::InputCheckPasswordSRP> input_check_password,
Promise<Unit> &&promise); Promise<Unit> &&promise);
void get_channel_statistics_dc_id(DialogId dialog_id, Promise<DcId> &&promise);
void send_get_broadcast_stats_query(DcId dc_id, ChannelId channel_id, bool is_dark,
Promise<td_api::object_ptr<td_api::chatStatistics>> &&promise);
void send_load_async_graph_query(DcId dc_id, string token, int64 x,
Promise<td_api::object_ptr<td_api::StatisticsGraph>> &&promise);
static void on_user_online_timeout_callback(void *contacts_manager_ptr, int64 user_id_long); static void on_user_online_timeout_callback(void *contacts_manager_ptr, int64 user_id_long);
static void on_channel_unban_timeout_callback(void *contacts_manager_ptr, int64 channel_id_long); static void on_channel_unban_timeout_callback(void *contacts_manager_ptr, int64 channel_id_long);

View File

@ -6494,18 +6494,17 @@ void Td::on_request(uint64 id, td_api::getChatStatisticsUrl &request) {
std::move(promise)); std::move(promise));
} }
void Td::on_request(uint64 id, td_api::getChatStatistics &request) { void Td::on_request(uint64 id, const td_api::getChatStatistics &request) {
CHECK_IS_USER(); CHECK_IS_USER();
CREATE_REQUEST_PROMISE(); CREATE_REQUEST_PROMISE();
contacts_manager_->get_broadcast_stats(DialogId(request.chat_id_), request.is_dark_, contacts_manager_->get_channel_statistics(DialogId(request.chat_id_), request.is_dark_, std::move(promise));
std::move(promise));
} }
void Td::on_request(uint64 id, td_api::getChatStatisticsGraph &request) { void Td::on_request(uint64 id, td_api::getChatStatisticsGraph &request) {
CHECK_IS_USER(); CHECK_IS_USER();
CREATE_REQUEST_PROMISE(); CREATE_REQUEST_PROMISE();
CLEAN_INPUT_STRING(request.token_); CLEAN_INPUT_STRING(request.token_);
contacts_manager_->load_async_graph(request.token_, request.x_, std::move(promise)); contacts_manager_->load_statistics_graph(DialogId(request.chat_id_), request.token_, request.x_, std::move(promise));
} }
void Td::on_request(uint64 id, td_api::setChatNotificationSettings &request) { void Td::on_request(uint64 id, td_api::setChatNotificationSettings &request) {

View File

@ -887,7 +887,7 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, td_api::getChatStatisticsUrl &request); void on_request(uint64 id, td_api::getChatStatisticsUrl &request);
void on_request(uint64 id, td_api::getChatStatistics &request); void on_request(uint64 id, const td_api::getChatStatistics &request);
void on_request(uint64 id, td_api::getChatStatisticsGraph &request); void on_request(uint64 id, td_api::getChatStatisticsGraph &request);

View File

@ -3869,7 +3869,23 @@ class CliClient final : public Actor {
std::tie(chat_id, args) = split(args); std::tie(chat_id, args) = split(args);
std::tie(parameters, is_dark) = split(args); std::tie(parameters, is_dark) = split(args);
send_request(td_api::make_object<td_api::getChatStatisticsUrl>(as_chat_id(args), parameters, as_bool(is_dark))); send_request(
td_api::make_object<td_api::getChatStatisticsUrl>(as_chat_id(chat_id), parameters, as_bool(is_dark)));
} else if (op == "gcst") {
string chat_id;
string is_dark;
std::tie(chat_id, is_dark) = split(args);
send_request(td_api::make_object<td_api::getChatStatistics>(as_chat_id(chat_id), as_bool(is_dark)));
} else if (op == "gcstg") {
string chat_id;
string token;
string x;
std::tie(chat_id, args) = split(args);
std::tie(token, x) = split(args);
send_request(
td_api::make_object<td_api::getChatStatisticsGraph>(as_chat_id(chat_id), token, to_integer<int64>(x)));
} else if (op == "glui" || op == "glu" || op == "glua") { } else if (op == "glui" || op == "glu" || op == "glua") {
string chat_id; string chat_id;
string message_id; string message_id;