Apply information about forum topics from messages.channelMessages.

This commit is contained in:
levlam 2022-11-15 16:00:19 +03:00
parent b2aef90b1a
commit 0f357cdb95
6 changed files with 90 additions and 21 deletions

View File

@ -62,6 +62,17 @@ td_api::object_ptr<td_api::forumTopicInfo> ForumTopicInfo::get_forum_topic_info_
std::move(creator_id), is_outgoing_, is_closed_); std::move(creator_id), is_outgoing_, is_closed_);
} }
bool operator==(const ForumTopicInfo &lhs, const ForumTopicInfo &rhs) {
return lhs.top_thread_message_id_ == rhs.top_thread_message_id_ && lhs.title_ == rhs.title_ &&
lhs.icon_ == rhs.icon_ && lhs.creation_date_ == rhs.creation_date_ &&
lhs.creator_dialog_id_ == rhs.creator_dialog_id_ && lhs.is_outgoing_ == rhs.is_outgoing_ &&
lhs.is_closed_ == rhs.is_closed_;
}
bool operator!=(const ForumTopicInfo &lhs, const ForumTopicInfo &rhs) {
return !(lhs == rhs);
}
StringBuilder &operator<<(StringBuilder &string_builder, const ForumTopicInfo &topic_info) { StringBuilder &operator<<(StringBuilder &string_builder, const ForumTopicInfo &topic_info) {
return string_builder << "Forum topic " << topic_info.top_thread_message_id_.get() << '/' << topic_info.title_ 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_; << " by " << topic_info.creator_dialog_id_ << " with " << topic_info.icon_;

View File

@ -29,6 +29,9 @@ class ForumTopicInfo {
bool is_outgoing_ = false; bool is_outgoing_ = false;
bool is_closed_ = false; bool is_closed_ = false;
friend bool operator==(const ForumTopicInfo &lhs, const ForumTopicInfo &rhs);
friend bool operator!=(const ForumTopicInfo &lhs, const ForumTopicInfo &rhs);
friend StringBuilder &operator<<(StringBuilder &string_builder, const ForumTopicInfo &topic_info); friend StringBuilder &operator<<(StringBuilder &string_builder, const ForumTopicInfo &topic_info);
public: public:
@ -72,6 +75,9 @@ class ForumTopicInfo {
td_api::object_ptr<td_api::forumTopicInfo> get_forum_topic_info_object(Td *td) const; td_api::object_ptr<td_api::forumTopicInfo> get_forum_topic_info_object(Td *td) const;
}; };
bool operator==(const ForumTopicInfo &lhs, const ForumTopicInfo &rhs);
bool operator!=(const ForumTopicInfo &lhs, const ForumTopicInfo &rhs);
StringBuilder &operator<<(StringBuilder &string_builder, const ForumTopicInfo &topic_info); StringBuilder &operator<<(StringBuilder &string_builder, const ForumTopicInfo &topic_info);
} // namespace td } // namespace td

View File

@ -295,6 +295,36 @@ void ForumTopicManager::on_forum_topic_edited(DialogId dialog_id, MessageId top_
} }
} }
void ForumTopicManager::on_get_forum_topics(DialogId dialog_id,
vector<tl_object_ptr<telegram_api::ForumTopic>> &&forum_topics,
const char *source) {
if (forum_topics.empty()) {
return;
}
if (dialog_id.get_type() != DialogType::Channel ||
!td_->contacts_manager_->is_megagroup_channel(dialog_id.get_channel_id())) {
LOG(ERROR) << "Receive forum topics in " << dialog_id << " from " << source;
return;
}
auto dialog_topics = add_dialog_topics(dialog_id);
CHECK(dialog_topics != nullptr);
for (auto &forum_topic : forum_topics) {
auto forum_topic_info = td::make_unique<ForumTopicInfo>(forum_topic);
MessageId top_thread_message_id = forum_topic_info->get_top_thread_message_id();
if (!top_thread_message_id.is_valid()) {
continue;
}
auto topic_info = dialog_topics->topic_infos_.get_pointer(top_thread_message_id);
if (topic_info == nullptr || *topic_info != *forum_topic_info) {
dialog_topics->topic_infos_.set(top_thread_message_id, std::move(forum_topic_info));
topic_info = dialog_topics->topic_infos_.get_pointer(top_thread_message_id);
CHECK(topic_info != nullptr);
send_update_forum_topic_info(dialog_id, topic_info);
}
}
}
Status ForumTopicManager::is_forum(DialogId dialog_id) { Status ForumTopicManager::is_forum(DialogId dialog_id) {
if (!td_->messages_manager_->have_dialog_force(dialog_id, "ForumTopicManager::is_forum")) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "ForumTopicManager::is_forum")) {
return Status::Error(400, "Chat not found"); return Status::Error(400, "Chat not found");
@ -306,20 +336,24 @@ Status ForumTopicManager::is_forum(DialogId dialog_id) {
return Status::OK(); return Status::OK();
} }
ForumTopicInfo *ForumTopicManager::add_topic_info(DialogId dialog_id, unique_ptr<ForumTopicInfo> &&forum_topic_info) { ForumTopicManager::DialogTopics *ForumTopicManager::add_dialog_topics(DialogId dialog_id) {
CHECK(forum_topic_info != nullptr); auto *dialog_topics = dialog_topics_.get_pointer(dialog_id);
auto *dialog_info = dialog_topics_.get_pointer(dialog_id); if (dialog_topics != nullptr) {
if (dialog_info == nullptr) { return dialog_topics;
}
dialog_topics_.set(dialog_id, make_unique<DialogTopics>()); dialog_topics_.set(dialog_id, make_unique<DialogTopics>());
dialog_info = dialog_topics_.get_pointer(dialog_id); return dialog_topics_.get_pointer(dialog_id);
CHECK(dialog_info != nullptr);
} }
ForumTopicInfo *ForumTopicManager::add_topic_info(DialogId dialog_id, unique_ptr<ForumTopicInfo> &&forum_topic_info) {
auto *dialog_info = add_dialog_topics(dialog_id);
CHECK(forum_topic_info != nullptr);
MessageId top_thread_message_id = forum_topic_info->get_top_thread_message_id(); 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); auto topic_info = dialog_info->topic_infos_.get_pointer(top_thread_message_id);
if (topic_info == nullptr) { if (topic_info == nullptr) {
dialog_info->topic_infos_.set(top_thread_message_id, std::move(forum_topic_info)); 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); topic_info = dialog_info->topic_infos_.get_pointer(top_thread_message_id);
CHECK(topic_info != nullptr); CHECK(topic_info != nullptr);
send_update_forum_topic_info(dialog_id, topic_info); send_update_forum_topic_info(dialog_id, topic_info);
} }

View File

@ -12,6 +12,7 @@
#include "td/telegram/ForumTopicInfo.h" #include "td/telegram/ForumTopicInfo.h"
#include "td/telegram/MessageId.h" #include "td/telegram/MessageId.h"
#include "td/telegram/td_api.h" #include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h"
#include "td/actor/actor.h" #include "td/actor/actor.h"
@ -50,6 +51,9 @@ class ForumTopicManager final : public Actor {
void on_forum_topic_edited(DialogId dialog_id, MessageId top_thread_message_id, void on_forum_topic_edited(DialogId dialog_id, MessageId top_thread_message_id,
const ForumTopicEditedData &edited_data); const ForumTopicEditedData &edited_data);
void on_get_forum_topics(DialogId dialog_id, vector<tl_object_ptr<telegram_api::ForumTopic>> &&forum_topics,
const char *source);
private: private:
static constexpr size_t MAX_FORUM_TOPIC_TITLE_LENGTH = 128; // server side limit for forum topic title static constexpr size_t MAX_FORUM_TOPIC_TITLE_LENGTH = 128; // server side limit for forum topic title
@ -61,6 +65,8 @@ class ForumTopicManager final : public Actor {
Status is_forum(DialogId dialog_id); Status is_forum(DialogId dialog_id);
DialogTopics *ForumTopicManager::add_dialog_topics(DialogId dialog_id);
ForumTopicInfo *add_topic_info(DialogId dialog_id, unique_ptr<ForumTopicInfo> &&forum_topic_info); 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); ForumTopicInfo *get_topic_info(DialogId dialog_id, MessageId top_thread_message_id);

View File

@ -26,6 +26,7 @@
#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/ForumTopicManager.h"
#include "td/telegram/Global.h" #include "td/telegram/Global.h"
#include "td/telegram/GroupCallManager.h" #include "td/telegram/GroupCallManager.h"
#include "td/telegram/InlineQueriesManager.h" #include "td/telegram/InlineQueriesManager.h"
@ -468,7 +469,7 @@ class GetMessagesQuery final : public Td::ResultHandler {
return on_error(result_ptr.move_as_error()); return on_error(result_ptr.move_as_error());
} }
auto info = td_->messages_manager_->get_messages_info(result_ptr.move_as_ok(), "GetMessagesQuery"); auto info = td_->messages_manager_->get_messages_info(DialogId(), result_ptr.move_as_ok(), "GetMessagesQuery");
LOG_IF(ERROR, info.is_channel_messages) << "Receive channel messages in GetMessagesQuery"; LOG_IF(ERROR, info.is_channel_messages) << "Receive channel messages in GetMessagesQuery";
td_->messages_manager_->on_get_messages(std::move(info.messages), info.is_channel_messages, false, td_->messages_manager_->on_get_messages(std::move(info.messages), info.is_channel_messages, false,
std::move(promise_), "GetMessagesQuery"); std::move(promise_), "GetMessagesQuery");
@ -509,7 +510,8 @@ class GetChannelMessagesQuery final : public Td::ResultHandler {
return on_error(result_ptr.move_as_error()); return on_error(result_ptr.move_as_error());
} }
auto info = td_->messages_manager_->get_messages_info(result_ptr.move_as_ok(), "GetChannelMessagesQuery"); auto info = td_->messages_manager_->get_messages_info(DialogId(channel_id_), result_ptr.move_as_ok(),
"GetChannelMessagesQuery");
LOG_IF(ERROR, !info.is_channel_messages) << "Receive ordinary messages in GetChannelMessagesQuery"; LOG_IF(ERROR, !info.is_channel_messages) << "Receive ordinary messages in GetChannelMessagesQuery";
// messages with invalid big identifiers can be received as messageEmpty // messages with invalid big identifiers can be received as messageEmpty
// bots can receive messageEmpty because of their privacy mode // bots can receive messageEmpty because of their privacy mode
@ -571,7 +573,8 @@ class GetScheduledMessagesQuery final : public Td::ResultHandler {
return on_error(result_ptr.move_as_error()); return on_error(result_ptr.move_as_error());
} }
auto info = td_->messages_manager_->get_messages_info(result_ptr.move_as_ok(), "GetScheduledMessagesQuery"); auto info =
td_->messages_manager_->get_messages_info(dialog_id_, result_ptr.move_as_ok(), "GetScheduledMessagesQuery");
LOG_IF(ERROR, info.is_channel_messages != (dialog_id_.get_type() == DialogType::Channel)) LOG_IF(ERROR, info.is_channel_messages != (dialog_id_.get_type() == DialogType::Channel))
<< "Receive wrong messages constructor in GetScheduledMessagesQuery"; << "Receive wrong messages constructor in GetScheduledMessagesQuery";
td_->messages_manager_->on_get_messages(std::move(info.messages), info.is_channel_messages, true, td_->messages_manager_->on_get_messages(std::move(info.messages), info.is_channel_messages, true,
@ -2110,7 +2113,8 @@ class GetDialogMessageByDateQuery final : public Td::ResultHandler {
return on_error(result_ptr.move_as_error()); return on_error(result_ptr.move_as_error());
} }
auto info = td_->messages_manager_->get_messages_info(result_ptr.move_as_ok(), "GetDialogMessageByDateQuery"); auto info =
td_->messages_manager_->get_messages_info(dialog_id_, result_ptr.move_as_ok(), "GetDialogMessageByDateQuery");
td_->messages_manager_->get_channel_difference_if_needed( td_->messages_manager_->get_channel_difference_if_needed(
dialog_id_, std::move(info), dialog_id_, std::move(info),
PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), dialog_id = dialog_id_, date = date_, PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), dialog_id = dialog_id_, date = date_,
@ -2187,7 +2191,7 @@ class GetHistoryQuery final : public Td::ResultHandler {
return on_error(result_ptr.move_as_error()); return on_error(result_ptr.move_as_error());
} }
auto info = td_->messages_manager_->get_messages_info(result_ptr.move_as_ok(), "GetHistoryQuery"); auto info = td_->messages_manager_->get_messages_info(dialog_id_, result_ptr.move_as_ok(), "GetHistoryQuery");
td_->messages_manager_->get_channel_difference_if_needed( td_->messages_manager_->get_channel_difference_if_needed(
dialog_id_, std::move(info), dialog_id_, std::move(info),
PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), dialog_id = dialog_id_, PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), dialog_id = dialog_id_,
@ -2574,7 +2578,7 @@ class SearchMessagesQuery final : public Td::ResultHandler {
return on_error(result_ptr.move_as_error()); return on_error(result_ptr.move_as_error());
} }
auto info = td_->messages_manager_->get_messages_info(result_ptr.move_as_ok(), "SearchMessagesQuery"); auto info = td_->messages_manager_->get_messages_info(dialog_id_, result_ptr.move_as_ok(), "SearchMessagesQuery");
td_->messages_manager_->get_channel_difference_if_needed( td_->messages_manager_->get_channel_difference_if_needed(
dialog_id_, std::move(info), dialog_id_, std::move(info),
PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), dialog_id = dialog_id_, PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), dialog_id = dialog_id_,
@ -2740,7 +2744,8 @@ class SearchMessagesGlobalQuery final : public Td::ResultHandler {
return on_error(result_ptr.move_as_error()); return on_error(result_ptr.move_as_error());
} }
auto info = td_->messages_manager_->get_messages_info(result_ptr.move_as_ok(), "SearchMessagesGlobalQuery"); auto info =
td_->messages_manager_->get_messages_info(DialogId(), result_ptr.move_as_ok(), "SearchMessagesGlobalQuery");
td_->messages_manager_->get_channel_differences_if_needed( td_->messages_manager_->get_channel_differences_if_needed(
std::move(info), std::move(info),
PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), query = std::move(query_), PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), query = std::move(query_),
@ -2794,7 +2799,8 @@ class GetAllScheduledMessagesQuery final : public Td::ResultHandler {
if (result_ptr.ok()->get_id() == telegram_api::messages_messagesNotModified::ID) { if (result_ptr.ok()->get_id() == telegram_api::messages_messagesNotModified::ID) {
td_->messages_manager_->on_get_scheduled_server_messages(dialog_id_, generation_, Auto(), true); td_->messages_manager_->on_get_scheduled_server_messages(dialog_id_, generation_, Auto(), true);
} else { } else {
auto info = td_->messages_manager_->get_messages_info(result_ptr.move_as_ok(), "GetAllScheduledMessagesQuery"); auto info = td_->messages_manager_->get_messages_info(dialog_id_, result_ptr.move_as_ok(),
"GetAllScheduledMessagesQuery");
td_->messages_manager_->on_get_scheduled_server_messages(dialog_id_, generation_, std::move(info.messages), td_->messages_manager_->on_get_scheduled_server_messages(dialog_id_, generation_, std::move(info.messages),
false); false);
} }
@ -2827,7 +2833,7 @@ class SearchSentMediaQuery final : public Td::ResultHandler {
return on_error(result_ptr.move_as_error()); return on_error(result_ptr.move_as_error());
} }
auto info = td_->messages_manager_->get_messages_info(result_ptr.move_as_ok(), "SearchSentMediaQuery"); auto info = td_->messages_manager_->get_messages_info(DialogId(), result_ptr.move_as_ok(), "SearchSentMediaQuery");
td_->messages_manager_->get_channel_differences_if_needed( td_->messages_manager_->get_channel_differences_if_needed(
std::move(info), std::move(info),
PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(),
@ -2876,7 +2882,8 @@ class GetRecentLocationsQuery final : public Td::ResultHandler {
return on_error(result_ptr.move_as_error()); return on_error(result_ptr.move_as_error());
} }
auto info = td_->messages_manager_->get_messages_info(result_ptr.move_as_ok(), "GetRecentLocationsQuery"); auto info =
td_->messages_manager_->get_messages_info(dialog_id_, result_ptr.move_as_ok(), "GetRecentLocationsQuery");
td_->messages_manager_->get_channel_difference_if_needed( td_->messages_manager_->get_channel_difference_if_needed(
dialog_id_, std::move(info), dialog_id_, std::move(info),
PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), dialog_id = dialog_id_, limit = limit_, PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), dialog_id = dialog_id_, limit = limit_,
@ -2929,7 +2936,8 @@ class GetMessagePublicForwardsQuery final : public Td::ResultHandler {
return on_error(result_ptr.move_as_error()); return on_error(result_ptr.move_as_error());
} }
auto info = td_->messages_manager_->get_messages_info(result_ptr.move_as_ok(), "GetMessagePublicForwardsQuery"); auto info =
td_->messages_manager_->get_messages_info(DialogId(), result_ptr.move_as_ok(), "GetMessagePublicForwardsQuery");
td_->messages_manager_->get_channel_differences_if_needed( td_->messages_manager_->get_channel_differences_if_needed(
std::move(info), std::move(info),
PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(),
@ -9801,12 +9809,13 @@ void MessagesManager::on_get_empty_messages(DialogId dialog_id, const vector<Mes
} }
MessagesManager::MessagesInfo MessagesManager::get_messages_info( MessagesManager::MessagesInfo MessagesManager::get_messages_info(
tl_object_ptr<telegram_api::messages_Messages> &&messages_ptr, const char *source) { DialogId dialog_id, tl_object_ptr<telegram_api::messages_Messages> &&messages_ptr, const char *source) {
CHECK(messages_ptr != nullptr); CHECK(messages_ptr != nullptr);
LOG(DEBUG) << "Receive result for " << source << ": " << to_string(messages_ptr); LOG(DEBUG) << "Receive result for " << source << ": " << to_string(messages_ptr);
vector<tl_object_ptr<telegram_api::User>> users; vector<tl_object_ptr<telegram_api::User>> users;
vector<tl_object_ptr<telegram_api::Chat>> chats; vector<tl_object_ptr<telegram_api::Chat>> chats;
vector<tl_object_ptr<telegram_api::ForumTopic>> topics;
MessagesInfo result; MessagesInfo result;
switch (messages_ptr->get_id()) { switch (messages_ptr->get_id()) {
case telegram_api::messages_messages::ID: { case telegram_api::messages_messages::ID: {
@ -9832,6 +9841,7 @@ MessagesManager::MessagesInfo MessagesManager::get_messages_info(
users = std::move(messages->users_); users = std::move(messages->users_);
chats = std::move(messages->chats_); chats = std::move(messages->chats_);
topics = std::move(messages->topics_);
result.total_count = messages->count_; result.total_count = messages->count_;
result.messages = std::move(messages->messages_); result.messages = std::move(messages->messages_);
result.is_channel_messages = true; result.is_channel_messages = true;
@ -9847,6 +9857,7 @@ MessagesManager::MessagesInfo MessagesManager::get_messages_info(
td_->contacts_manager_->on_get_users(std::move(users), source); td_->contacts_manager_->on_get_users(std::move(users), source);
td_->contacts_manager_->on_get_chats(std::move(chats), source); td_->contacts_manager_->on_get_chats(std::move(chats), source);
td_->forum_topic_manager_->on_get_forum_topics(dialog_id, std::move(topics), source);
return result; return result;
} }

View File

@ -196,7 +196,8 @@ class MessagesManager final : public Actor {
int32 total_count = 0; int32 total_count = 0;
bool is_channel_messages = false; bool is_channel_messages = false;
}; };
MessagesInfo get_messages_info(tl_object_ptr<telegram_api::messages_Messages> &&messages_ptr, const char *source); MessagesInfo get_messages_info(DialogId dialog_id, tl_object_ptr<telegram_api::messages_Messages> &&messages_ptr,
const char *source);
void get_channel_difference_if_needed(DialogId dialog_id, MessagesInfo &&messages_info, void get_channel_difference_if_needed(DialogId dialog_id, MessagesInfo &&messages_info,
Promise<MessagesInfo> &&promise); Promise<MessagesInfo> &&promise);