diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 94c78fad1..bdcb6c797 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3440,8 +3440,10 @@ setPollAnswer chat_id:int53 message_id:int53 option_ids:vector = Ok; //@description Returns users voted for the specified option in a non-anonymous polls. For the optimal performance the number of returned users is chosen by the library //@chat_id Identifier of the chat to which the poll belongs @message_id Identifier of the message containing the poll -//@option_id 0-based identifier of the answer option @offset Number of users to skip in the result; must be non-negative -getPollVoters chat_id:int53 message_id:int53 option_id:int32 offset:int32 = Users; +//@option_id 0-based identifier of the answer option +//@offset Number of users to skip in the result; must be non-negative +//@limit The maximum number of users to be returned; must be positive and can't be greater than 50. Fewer users may be returned than specified by the limit, even if the end of the voter list has not been reached +getPollVoters chat_id:int53 message_id:int53 option_id:int32 offset:int32 limit:int32 = Users; //@description Stops a poll. A poll in a message can be stopped when the message has can_be_edited flag set //@chat_id Identifier of the chat to which the poll belongs @message_id Identifier of the message containing the poll @reply_markup The new message reply markup; for bots only diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 93fb7bae9..22414c58a 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index fe63c7f22..993b58837 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -2826,11 +2826,11 @@ void set_message_content_poll_answer(Td *td, const MessageContent *content, Full } void get_message_content_poll_voters(Td *td, const MessageContent *content, FullMessageId full_message_id, - int32 option_id, int32 offset, + int32 option_id, int32 offset, int32 limit, Promise>> &&promise) { CHECK(content->get_type() == MessageContentType::Poll); td->poll_manager_->get_poll_voters(static_cast(content)->poll_id, full_message_id, option_id, - offset, std::move(promise)); + offset, limit, std::move(promise)); } void stop_message_content_poll(Td *td, const MessageContent *content, FullMessageId full_message_id, diff --git a/td/telegram/MessageContent.h b/td/telegram/MessageContent.h index 1675b8059..765ded13f 100644 --- a/td/telegram/MessageContent.h +++ b/td/telegram/MessageContent.h @@ -194,7 +194,7 @@ void set_message_content_poll_answer(Td *td, const MessageContent *content, Full vector &&option_ids, Promise &&promise); void get_message_content_poll_voters(Td *td, const MessageContent *content, FullMessageId full_message_id, - int32 option_id, int32 offset, + int32 option_id, int32 offset, int32 limit, Promise>> &&promise); void stop_message_content_poll(Td *td, const MessageContent *content, FullMessageId full_message_id, diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 659ff6d5e..5041640d6 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -30122,7 +30122,7 @@ void MessagesManager::set_poll_answer(FullMessageId full_message_id, vectorcontent.get(), full_message_id, std::move(option_ids), std::move(promise)); } -void MessagesManager::get_poll_voters(FullMessageId full_message_id, int32 option_id, int32 offset, +void MessagesManager::get_poll_voters(FullMessageId full_message_id, int32 option_id, int32 offset, int32 limit, Promise>> &&promise) { auto m = get_message_force(full_message_id, "get_poll_voters"); if (m == nullptr) { @@ -30141,7 +30141,7 @@ void MessagesManager::get_poll_voters(FullMessageId full_message_id, int32 optio return promise.set_error(Status::Error(5, "Poll results can't be received")); } - get_message_content_poll_voters(td_, m->content.get(), full_message_id, option_id, offset, std::move(promise)); + get_message_content_poll_voters(td_, m->content.get(), full_message_id, option_id, offset, limit, std::move(promise)); } void MessagesManager::stop_poll(FullMessageId full_message_id, td_api::object_ptr &&reply_markup, diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index c2e86b392..92d7cec6f 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -803,7 +803,7 @@ class MessagesManager : public Actor { void set_poll_answer(FullMessageId full_message_id, vector &&option_ids, Promise &&promise); - void get_poll_voters(FullMessageId full_message_id, int32 option_id, int32 offset, + void get_poll_voters(FullMessageId full_message_id, int32 option_id, int32 offset, int32 limit, Promise>> &&promise); void stop_poll(FullMessageId full_message_id, td_api::object_ptr &&reply_markup, diff --git a/td/telegram/PollManager.cpp b/td/telegram/PollManager.cpp index bb50e2843..26f6bf852 100644 --- a/td/telegram/PollManager.cpp +++ b/td/telegram/PollManager.cpp @@ -839,13 +839,19 @@ PollManager::PollOptionVoters &PollManager::get_poll_option_voters(const Poll *p } void PollManager::get_poll_voters(PollId poll_id, FullMessageId full_message_id, int32 option_id, int32 offset, - Promise>> &&promise) { + int32 limit, Promise>> &&promise) { if (is_local_poll_id(poll_id)) { return promise.set_error(Status::Error(400, "Poll results can't be received")); } if (offset < 0) { return promise.set_error(Status::Error(400, "Invalid offset specified")); } + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); + } + if (limit > MAX_GET_POLL_VOTERS) { + limit = MAX_GET_POLL_VOTERS; + } auto poll = get_poll(poll_id); CHECK(poll != nullptr); @@ -870,7 +876,7 @@ void PollManager::get_poll_voters(PollId poll_id, FullMessageId full_message_id, } if (offset < cur_offset) { vector result; - for (int32 i = offset; i != cur_offset && i - offset < MAX_GET_POLL_VOTERS; i++) { + for (int32 i = offset; i != cur_offset && i - offset < limit; i++) { result.push_back(voters.voter_user_ids[i]); } return promise.set_value({poll->options[option_id].voter_count, std::move(result)}); @@ -885,16 +891,15 @@ void PollManager::get_poll_voters(PollId poll_id, FullMessageId full_message_id, return; } - auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), poll_id, option_id]( + auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), poll_id, option_id, limit]( Result> &&result) { - send_closure(actor_id, &PollManager::on_get_poll_voters, poll_id, option_id, std::move(result)); + send_closure(actor_id, &PollManager::on_get_poll_voters, poll_id, option_id, limit, std::move(result)); }); td_->create_handler(std::move(query_promise)) - ->send(poll_id, full_message_id, BufferSlice(poll->options[option_id].data), voters.next_offset, - MAX_GET_POLL_VOTERS); + ->send(poll_id, full_message_id, BufferSlice(poll->options[option_id].data), voters.next_offset, max(limit, 15)); } -void PollManager::on_get_poll_voters(PollId poll_id, int32 option_id, +void PollManager::on_get_poll_voters(PollId poll_id, int32 option_id, int32 limit, Result> &&result) { auto poll = get_poll(poll_id); CHECK(poll != nullptr); @@ -961,6 +966,9 @@ void PollManager::on_get_poll_voters(PollId poll_id, int32 option_id, } } voters.voter_user_ids.insert(voters.voter_user_ids.end(), user_ids.begin(), user_ids.end()); + if (static_cast(user_ids.size()) > limit) { + user_ids.resize(limit); + } for (auto &promise : promises) { promise.set_value({vote_list->count_, vector(user_ids)}); diff --git a/td/telegram/PollManager.h b/td/telegram/PollManager.h index 41c4557f2..db2ac4f02 100644 --- a/td/telegram/PollManager.h +++ b/td/telegram/PollManager.h @@ -58,7 +58,7 @@ class PollManager : public Actor { void set_poll_answer(PollId poll_id, FullMessageId full_message_id, vector &&option_ids, Promise &&promise); - void get_poll_voters(PollId poll_id, FullMessageId full_message_id, int32 option_id, int32 offset, + void get_poll_voters(PollId poll_id, FullMessageId full_message_id, int32 option_id, int32 offset, int32 limit, Promise>> &&promise); void stop_poll(PollId poll_id, FullMessageId full_message_id, unique_ptr &&reply_markup, @@ -124,7 +124,7 @@ class PollManager : public Actor { bool was_invalidated = false; // the list needs to be invalidated when voters are changed }; - static constexpr int32 MAX_GET_POLL_VOTERS = 20; // server side limit + static constexpr int32 MAX_GET_POLL_VOTERS = 50; // server side limit class SetPollAnswerLogEvent; class StopPollLogEvent; @@ -179,7 +179,7 @@ class PollManager : public Actor { PollOptionVoters &get_poll_option_voters(const Poll *poll, PollId poll_id, int32 option_id); - void on_get_poll_voters(PollId poll_id, int32 option_id, + void on_get_poll_voters(PollId poll_id, int32 option_id, int32 limit, Result> &&result); void do_stop_poll(PollId poll_id, FullMessageId full_message_id, unique_ptr &&reply_markup, diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 63a87ee13..572172946 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -7265,7 +7265,7 @@ void Td::on_request(uint64 id, td_api::getPollVoters &request) { } }); messages_manager_->get_poll_voters({DialogId(request.chat_id_), MessageId(request.message_id_)}, request.option_id_, - request.offset_, std::move(query_promise)); + request.offset_, request.limit_, std::move(query_promise)); } void Td::on_request(uint64 id, td_api::stopPoll &request) { diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index fb30dce5b..b34dc68ee 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3494,12 +3494,15 @@ class CliClient final : public Actor { string message_id; string option_id; string offset; + string limit; std::tie(chat_id, args) = split(args); std::tie(message_id, args) = split(args); - std::tie(option_id, offset) = split(args); + std::tie(option_id, args) = split(args); + std::tie(offset, limit) = split(args); send_request(td_api::make_object(as_chat_id(chat_id), as_message_id(message_id), - to_integer(option_id), to_integer(offset))); + to_integer(option_id), to_integer(offset), + to_integer(limit))); } else if (op == "stoppoll") { string chat_id; string message_id;