diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 3f57a27f..cb8edb3d 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -268,8 +268,8 @@ game id:int64 short_name:string title:string text:formattedText description:stri //@description Describes a poll @id Unique poll identifier @question Poll question, 1-255 characters @options List of poll answer options //@total_voter_count Total number of voters, participating in the poll @is_closed True, if the poll is closed -//@is_anonymous True, if the poll is anonymous @type Type of the poll -poll id:int64 question:string options:vector total_voter_count:int32 is_closed:Bool is_anonymous:Bool type:PollType = Poll; +//@is_anonymous True, if the poll is anonymous @recent_voter_user_ids User identifiers of recent voters, if the poll is non-anonymous @type Type of the poll +poll id:int64 question:string options:vector total_voter_count:int32 is_closed:Bool is_anonymous:Bool recent_voter_user_ids:vector type:PollType = Poll; //@description Describes a user profile photo @id Photo identifier; 0 for an empty photo. Can be used to find a photo in a list of userProfilePhotos diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 3e3f0c07..5d80ca35 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index c846d450..b088dcdc 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -12721,8 +12721,8 @@ tl_object_ptr ContactsManager::get_user_object(UserId user_id, con u->is_received, std::move(type), u->language_code); } -vector ContactsManager::get_user_ids_object(const vector &user_ids) const { - return transform(user_ids, [this](UserId user_id) { return get_user_id_object(user_id, "get_user_ids_object"); }); +vector ContactsManager::get_user_ids_object(const vector &user_ids, const char *source) const { + return transform(user_ids, [this, source](UserId user_id) { return get_user_id_object(user_id, source); }); } tl_object_ptr ContactsManager::get_users_object(int32 total_count, @@ -12730,7 +12730,7 @@ tl_object_ptr ContactsManager::get_users_object(int32 total_count if (total_count == -1) { total_count = narrow_cast(user_ids.size()); } - return td_api::make_object(total_count, get_user_ids_object(user_ids)); + return td_api::make_object(total_count, get_user_ids_object(user_ids, "get_users_object")); } tl_object_ptr ContactsManager::get_user_full_info_object(UserId user_id) const { @@ -12961,7 +12961,7 @@ tl_object_ptr ContactsManager::get_chat_invite_link_ invite_link_photo = as_dialog_photo(invite_link_info->photo); photo = &invite_link_photo; participant_count = invite_link_info->participant_count; - member_user_ids = get_user_ids_object(invite_link_info->participant_user_ids); + member_user_ids = get_user_ids_object(invite_link_info->participant_user_ids, "get_chat_invite_link_info_object"); is_public = invite_link_info->is_public; if (invite_link_info->is_chat) { diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index f76ded91..8d9cbdd7 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -485,7 +485,7 @@ class ContactsManager : public Actor { tl_object_ptr get_user_object(UserId user_id) const; - vector get_user_ids_object(const vector &user_ids) const; + vector get_user_ids_object(const vector &user_ids, const char *source) const; tl_object_ptr get_users_object(int32 total_count, const vector &user_ids) const; diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index f043f68b..90b8ded2 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -4501,7 +4501,7 @@ tl_object_ptr get_message_content_object(const MessageCo case MessageContentType::ChatCreate: { const MessageChatCreate *m = static_cast(content); return make_tl_object( - m->title, td->contacts_manager_->get_user_ids_object(m->participant_user_ids)); + m->title, td->contacts_manager_->get_user_ids_object(m->participant_user_ids, "MessageChatCreate")); } case MessageContentType::ChatChangeTitle: { const MessageChatChangeTitle *m = static_cast(content); @@ -4517,7 +4517,8 @@ tl_object_ptr get_message_content_object(const MessageCo return make_tl_object(); case MessageContentType::ChatAddUsers: { const MessageChatAddUsers *m = static_cast(content); - return make_tl_object(td->contacts_manager_->get_user_ids_object(m->user_ids)); + return make_tl_object( + td->contacts_manager_->get_user_ids_object(m->user_ids, "MessageChatAddUsers")); } case MessageContentType::ChatJoinedByLink: return make_tl_object(); diff --git a/td/telegram/PollManager.cpp b/td/telegram/PollManager.cpp index ecd89f1d..d9d01b81 100644 --- a/td/telegram/PollManager.cpp +++ b/td/telegram/PollManager.cpp @@ -8,6 +8,7 @@ #include "td/telegram/AccessRights.h" #include "td/telegram/AuthManager.h" +#include "td/telegram/ContactsManager.h" #include "td/telegram/Dependencies.h" #include "td/telegram/DialogId.h" #include "td/telegram/Global.h" @@ -287,6 +288,9 @@ void PollManager::on_load_poll_from_database(PollId poll_id, string value) { if (status.is_error()) { LOG(FATAL) << status << ": " << format::as_hex_dump<4>(Slice(value)); } + for (auto &user_id : result->recent_voter_user_ids) { + td_->contacts_manager_->have_user_force(user_id); + } polls_[poll_id] = std::move(result); } } @@ -480,8 +484,10 @@ td_api::object_ptr PollManager::get_poll_object(PollId poll_id, co poll_type = td_api::make_object(poll->allow_multiple_answers); } - return td_api::make_object(poll_id.get(), poll->question, std::move(poll_options), total_voter_count, - poll->is_closed, poll->is_anonymous, std::move(poll_type)); + return td_api::make_object( + poll_id.get(), poll->question, std::move(poll_options), total_voter_count, poll->is_closed, poll->is_anonymous, + td_->contacts_manager_->get_user_ids_object(poll->recent_voter_user_ids, "get_poll_object"), + std::move(poll_type)); } telegram_api::object_ptr PollManager::get_input_poll_option(const PollOption &poll_option) { @@ -1069,6 +1075,23 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr recent_voter_user_ids; + for (auto &user_id_int : poll_results->recent_voters_) { + UserId user_id(user_id_int); + if (user_id.is_valid()) { + recent_voter_user_ids.push_back(user_id); + } else { + LOG(ERROR) << "Receive " << user_id << " as recent voter in " << poll_id; + } + } + if (poll->is_anonymous && !recent_voter_user_ids.empty()) { + LOG(ERROR) << "Receive anonymous " << poll_id << " with recent voters " << recent_voter_user_ids; + recent_voter_user_ids.clear(); + } + if (recent_voter_user_ids != poll->recent_voter_user_ids) { + poll->recent_voter_user_ids = std::move(recent_voter_user_ids); + is_changed = true; + } if (!td_->auth_manager_->is_bot() && !poll->is_closed) { auto timeout = get_polling_timeout(); diff --git a/td/telegram/PollManager.h b/td/telegram/PollManager.h index d07aac9e..749f9b9a 100644 --- a/td/telegram/PollManager.h +++ b/td/telegram/PollManager.h @@ -12,6 +12,7 @@ #include "td/telegram/ReplyMarkup.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" #include "td/actor/actor.h" #include "td/actor/PromiseFuture.h" @@ -95,6 +96,7 @@ class PollManager : public Actor { struct Poll { string question; vector options; + vector recent_voter_user_ids; int32 total_voter_count = 0; int32 correct_option_id = -1; bool is_anonymous = true; diff --git a/td/telegram/PollManager.hpp b/td/telegram/PollManager.hpp index 5d583e71..e6e78e05 100644 --- a/td/telegram/PollManager.hpp +++ b/td/telegram/PollManager.hpp @@ -43,11 +43,13 @@ template void PollManager::Poll::store(StorerT &storer) const { using ::td::store; bool is_public = !is_anonymous; + bool has_recent_voters = !recent_voter_user_ids.empty(); BEGIN_STORE_FLAGS(); STORE_FLAG(is_closed); STORE_FLAG(is_public); STORE_FLAG(allow_multiple_answers); STORE_FLAG(is_quiz); + STORE_FLAG(has_recent_voters); END_STORE_FLAGS(); store(question, storer); @@ -56,17 +58,22 @@ void PollManager::Poll::store(StorerT &storer) const { if (is_quiz) { store(correct_option_id, storer); } + if (has_recent_voters) { + store(recent_voter_user_ids, storer); + } } template void PollManager::Poll::parse(ParserT &parser) { using ::td::parse; bool is_public; + bool has_recent_voters; BEGIN_PARSE_FLAGS(); PARSE_FLAG(is_closed); PARSE_FLAG(is_public); PARSE_FLAG(allow_multiple_answers); PARSE_FLAG(is_quiz); + PARSE_FLAG(has_recent_voters); END_PARSE_FLAGS(); is_anonymous = !is_public; @@ -79,6 +86,9 @@ void PollManager::Poll::parse(ParserT &parser) { parser.set_error("Wrong correct_option_id"); } } + if (has_recent_voters) { + parse(recent_voter_user_ids, parser); + } } template