Implemented chat statistics (#981)

This commit is contained in:
Fela Ameghino 2020-04-02 15:06:05 +02:00 committed by GitHub
parent f9e8bbdff4
commit 81babdf915
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 231 additions and 0 deletions

View File

@ -2762,6 +2762,53 @@ inputStickerStatic sticker:InputFile emojis:string mask_position:maskPosition =
inputStickerAnimated sticker:InputFile emojis:string = InputSticker;
//@description chatStatisticsDateRange
//@min_date min_date
//@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 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
//@message_id message_id
//@views views
//@forwards forwards
chatStatisticsMessageInteractionCounters message_id:int32 views:int32 forwards:int32 = ChatStatisticsMessageInteractionCounters;
//@description chatStatistics
//@period period @followers followers @views_per_post views_per_post @shares_per_post shares_per_post @enabled_notifications enabled_notifications
//@growth_graph growth_graph @followers_graph followers_graph @mute_graph mute_graph @top_hours_graph top_hours_graph @interactions_graph interactions_graph
//@iv_interactions_graph iv_interactions_graph @views_by_source_graph views_by_source_graph @new_followers_by_source_graph new_followers_by_source_graph
//@languages_graph languages_graph @recent_message_interactions recent_message_interactions
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;
//@class Update @description Contains notifications about data changes
//@description The user authorization state has changed @authorization_state New authorization state
@ -4140,6 +4187,12 @@ 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
getChatStatisticsUrl chat_id:int53 parameters:string is_dark:Bool = HttpUrl;
//@description Retrieve specified channel statistics @chat_id supergroup id @is_dark is dark
getChatStatistics chat_id:int53 is_dark:Bool = ChatStatistics;
//@description Load async stats @token token @x zoom
getChatStatisticsGraph token:string x:int53 = ChatStatisticsGraph;
//@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
getStorageStatistics chat_limit:int32 = StorageStatistics;

Binary file not shown.

View File

@ -2660,6 +2660,126 @@ class GetSupportUserQuery : public Td::ResultHandler {
}
};
static tl_object_ptr<td_api::ChatStatisticsGraph> convert_stats_graph(tl_object_ptr<telegram_api::StatsGraph> obj) {
CHECK(obj != nullptr);
switch (obj->get_id()) {
case telegram_api::statsGraphAsync::ID: {
auto graph = move_tl_object_as<telegram_api::statsGraphAsync>(obj);
return make_tl_object<td_api::chatStatisticsGraphAsync>(std::move(graph->token_));
}
case telegram_api::statsGraphError::ID: {
auto graph = move_tl_object_as<telegram_api::statsGraphError>(obj);
return make_tl_object<td_api::chatStatisticsGraphError>(std::move(graph->error_));
}
case telegram_api::statsGraph::ID: {
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_));
}
default:
UNREACHABLE();
return nullptr;
}
}
static tl_object_ptr<td_api::chatStatistics> convert_stats_broadcast_stats(tl_object_ptr<telegram_api::stats_broadcastStats> obj) {
CHECK(obj != nullptr);
vector<tl_object_ptr<td_api::chatStatisticsMessageInteractionCounters>> recent_message_interactions;
recent_message_interactions.reserve(obj->recent_message_interactions_.size());
for (auto& interaction : obj->recent_message_interactions_) {
recent_message_interactions.push_back(
make_tl_object<td_api::chatStatisticsMessageInteractionCounters>(interaction->msg_id_, interaction->views_, interaction->forwards_));
}
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::chatStatisticsAbsoluteValue>(obj->followers_->current_, obj->followers_->previous_),
make_tl_object<td_api::chatStatisticsAbsoluteValue>(obj->views_per_post_->current_, obj->views_per_post_->previous_),
make_tl_object<td_api::chatStatisticsAbsoluteValue>(obj->shares_per_post_->current_, obj->shares_per_post_->previous_),
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->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->new_followers_by_source_graph_)),
convert_stats_graph(std::move(obj->languages_graph_)),
std::move(recent_message_interactions)
);
}
class GetBroadcastStatsQuery : public Td::ResultHandler {
Promise<td_api::object_ptr<td_api::chatStatistics>> promise_;
ChannelId channel_id_;
public:
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) {
channel_id_ = channel_id;
auto input_channel = td->contacts_manager_->get_input_channel(channel_id);
CHECK(input_channel != nullptr);
int32 flags = 0;
if (is_dark) {
flags |= telegram_api::stats_getBroadcastStats::DARK_MASK;
}
send_query(G()->net_query_creator().create(
telegram_api::stats_getBroadcastStats(flags, false /*ignored*/, std::move(input_channel)), dc_id));
}
void on_result(uint64 id, BufferSlice packet) override {
auto result_ptr = fetch_result<telegram_api::stats_getBroadcastStats>(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(convert_stats_broadcast_stats(std::move(result)));
}
void on_error(uint64 id, Status status) override {
td->contacts_manager_->on_get_channel_error(channel_id_, status, "GetBroadcastStatsQuery");
promise_.set_error(std::move(status));
}
};
class LoadAyncGraphQuery : public Td::ResultHandler {
Promise<td_api::object_ptr<td_api::ChatStatisticsGraph>> promise_;
public:
explicit LoadAyncGraphQuery(Promise<td_api::object_ptr<td_api::ChatStatisticsGraph>> &&promise) : promise_(std::move(promise)) {
}
void send(const string& token, int64 x) {
int32 flags = 0;
if (x != 0) {
flags |= telegram_api::stats_loadAsyncGraph::X_MASK;
}
send_query(G()->net_query_creator().create(
telegram_api::stats_loadAsyncGraph(flags, token, x)));
}
void on_result(uint64 id, BufferSlice packet) override {
auto result_ptr = fetch_result<telegram_api::stats_loadAsyncGraph>(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(convert_stats_graph(std::move(result)));
}
void on_error(uint64 id, Status status) override {
promise_.set_error(std::move(status));
}
};
bool ContactsManager::UserFull::is_expired() const {
return expires_at < Time::now();
}
@ -5571,6 +5691,41 @@ 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);
}
void ContactsManager::get_broadcast_stats(DialogId dialog_id, bool is_dark,
Promise<td_api::object_ptr<td_api::chatStatistics>> &&promise) {
if (!dialog_id.is_valid()) {
return promise.set_error(Status::Error(400, "Invalid chat specified"));
}
if (!td_->messages_manager_->have_dialog_force(dialog_id)) {
return promise.set_error(Status::Error(400, "Chat not found"));
}
if (dialog_id.get_type() != DialogType::Channel) {
return promise.set_error(Status::Error(400, "Chat is not a channel"));
}
auto channel_id = dialog_id.get_channel_id();
const Channel *c = get_channel(channel_id);
if (c == nullptr) {
return promise.set_error(Status::Error(400, "Chat info not found"));
}
if (c->is_megagroup) {
return promise.set_error(Status::Error(400, "Chat is not a channel"));
}
const ChannelFull* c_full = get_channel_full(channel_id, "get_broadcast_stats");
if (c_full == nullptr) {
return promise.set_error(Status::Error(400, "Chat info not found"));
}
td_->create_handler<GetBroadcastStatsQuery>(std::move(promise))->send(channel_id, is_dark, c_full->stats_dc_id);
}
void ContactsManager::load_async_graph(const string& token, int64 x, Promise<td_api::object_ptr<td_api::ChatStatisticsGraph>> &&promise)
{
td_->create_handler<LoadAyncGraphQuery>(std::move(promise))->send(token, x);
}
void ContactsManager::report_channel_spam(ChannelId channel_id, UserId user_id, const vector<MessageId> &message_ids,
Promise<Unit> &&promise) {
auto c = get_channel(channel_id);

View File

@ -357,6 +357,11 @@ class ContactsManager : public Actor {
void delete_channel(ChannelId channel_id, Promise<Unit> &&promise);
void get_broadcast_stats(DialogId dialog_id, bool is_dark,
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 add_chat_participant(ChatId chat_id, UserId user_id, int32 forward_limit, Promise<Unit> &&promise);
void add_channel_participant(ChannelId channel_id, UserId user_id, Promise<Unit> &&promise,

View File

@ -6494,6 +6494,20 @@ void Td::on_request(uint64 id, td_api::getChatStatisticsUrl &request) {
std::move(promise));
}
void Td::on_request(uint64 id, td_api::getChatStatistics &request) {
CHECK_IS_USER();
CREATE_REQUEST_PROMISE();
contacts_manager_->get_broadcast_stats(DialogId(request.chat_id_), request.is_dark_,
std::move(promise));
}
void Td::on_request(uint64 id, td_api::getChatStatisticsGraph &request) {
CHECK_IS_USER();
CREATE_REQUEST_PROMISE();
CLEAN_INPUT_STRING(request.token_);
contacts_manager_->load_async_graph(request.token_, request.x_, 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_),

View File

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