Rewrite searchChatMembers and getSupergroupMembers implementation.

This commit is contained in:
levlam 2021-01-25 17:26:04 +03:00
parent 60673fea78
commit d25edad06d
7 changed files with 203 additions and 273 deletions

View File

@ -2429,30 +2429,23 @@ class GetChannelParticipantQuery : public Td::ResultHandler {
};
class GetChannelParticipantsQuery : public Td::ResultHandler {
Promise<Unit> promise_;
Promise<tl_object_ptr<telegram_api::channels_channelParticipants>> promise_;
ChannelId channel_id_;
ChannelParticipantsFilter filter_{nullptr};
int32 offset_;
int32 limit_;
int64 random_id_;
public:
explicit GetChannelParticipantsQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
explicit GetChannelParticipantsQuery(Promise<tl_object_ptr<telegram_api::channels_channelParticipants>> &&promise)
: promise_(std::move(promise)) {
}
void send(ChannelId channel_id, ChannelParticipantsFilter filter, int32 offset, int32 limit, int64 random_id) {
void send(ChannelId channel_id, ChannelParticipantsFilter filter, int32 offset, int32 limit) {
auto input_channel = td->contacts_manager_->get_input_channel(channel_id);
if (input_channel == nullptr) {
return promise_.set_error(Status::Error(3, "Supergroup not found"));
}
channel_id_ = channel_id;
filter_ = std::move(filter);
offset_ = offset;
limit_ = limit;
random_id_ = random_id;
send_query(G()->net_query_creator().create(telegram_api::channels_getParticipants(
std::move(input_channel), filter_.get_input_channel_participants_filter(), offset, limit, 0)));
std::move(input_channel), filter.get_input_channel_participants_filter(), offset, limit, 0)));
}
void on_result(uint64 id, BufferSlice packet) override {
@ -2462,31 +2455,22 @@ class GetChannelParticipantsQuery : public Td::ResultHandler {
}
auto participants_ptr = result_ptr.move_as_ok();
LOG(INFO) << "Receive result for GetChannelParticipantsQuery with filter "
<< to_string(filter_.get_input_channel_participants_filter()) << ": " << to_string(participants_ptr);
LOG(INFO) << "Receive result for GetChannelParticipantsQuery: " << to_string(participants_ptr);
switch (participants_ptr->get_id()) {
case telegram_api::channels_channelParticipants::ID: {
auto participants = telegram_api::move_object_as<telegram_api::channels_channelParticipants>(participants_ptr);
td->contacts_manager_->on_get_users(std::move(participants->users_), "GetChannelParticipantsQuery");
td->contacts_manager_->on_get_channel_participants_success(channel_id_, std::move(filter_), offset_, limit_,
random_id_, participants->count_,
std::move(participants->participants_));
promise_.set_value(telegram_api::move_object_as<telegram_api::channels_channelParticipants>(participants_ptr));
break;
}
case telegram_api::channels_channelParticipantsNotModified::ID:
LOG(ERROR) << "Receive channelParticipantsNotModified";
break;
return on_error(id, Status::Error(500, "Receive channelParticipantsNotModified"));
default:
UNREACHABLE();
}
promise_.set_value(Unit());
}
void on_error(uint64 id, Status status) override {
td->contacts_manager_->on_get_channel_error(channel_id_, status, "GetChannelParticipantsQuery");
td->contacts_manager_->on_get_channel_participants_fail(channel_id_, std::move(filter_), offset_, limit_,
random_id_);
promise_.set_error(std::move(status));
}
};
@ -10627,9 +10611,17 @@ bool ContactsManager::is_user_contact(const User *u, UserId user_id, bool is_mut
return u != nullptr && (is_mutual ? u->is_mutual_contact : u->is_contact) && user_id != get_my_id();
}
void ContactsManager::on_get_channel_participants_success(
ChannelId channel_id, ChannelParticipantsFilter filter, int32 offset, int32 limit, int64 random_id,
int32 total_count, vector<tl_object_ptr<telegram_api::ChannelParticipant>> &&participants) {
void ContactsManager::on_get_channel_participants(
ChannelId channel_id, ChannelParticipantsFilter filter, int32 offset, int32 limit, string additional_query,
int32 additional_limit, tl_object_ptr<telegram_api::channels_channelParticipants> &&channel_participants,
Promise<DialogParticipants> &&promise) {
if (G()->close_flag()) {
return promise.set_error(Status::Error(500, "Request aborted"));
}
on_get_users(std::move(channel_participants->users_), "on_get_channel_participants");
int32 total_count = channel_participants->count_;
auto participants = std::move(channel_participants->participants_);
LOG(INFO) << "Receive " << participants.size() << " members in " << channel_id;
bool is_full = offset == 0 && static_cast<int32>(participants.size()) < limit && total_count < limit;
@ -10738,17 +10730,24 @@ void ContactsManager::on_get_channel_participants_success(
}
}
if (random_id != 0) {
received_channel_participants_[random_id] = {total_count, std::move(result)};
}
}
if (!additional_query.empty()) {
auto user_ids = transform(result, [](const auto &participant) { return participant.user_id; });
std::pair<int32, vector<UserId>> result_user_ids = search_among_users(user_ids, additional_query, additional_limit);
void ContactsManager::on_get_channel_participants_fail(ChannelId channel_id, ChannelParticipantsFilter filter,
int32 offset, int32 limit, int64 random_id) {
if (random_id != 0) {
// clean up
received_channel_participants_.erase(random_id);
total_count = result_user_ids.first;
std::unordered_set<UserId, UserIdHash> result_user_ids_set(result_user_ids.second.begin(),
result_user_ids.second.end());
auto all_participants = std::move(result);
result.clear();
for (auto &participant : all_participants) {
if (result_user_ids_set.count(participant.user_id)) {
result.push_back(std::move(participant));
result_user_ids_set.erase(participant.user_id);
}
}
}
promise.set_value(DialogParticipants{total_count, std::move(result)});
}
bool ContactsManager::speculative_add_count(int32 &count, int32 delta_count, int32 min_count) {
@ -11247,13 +11246,16 @@ void ContactsManager::on_update_channel_full_linked_channel_id(ChannelFull *chan
td_->messages_manager_->on_dialog_linked_channel_updated(DialogId(channel_id), old_linked_channel_id,
linked_channel_id);
}
auto new_linked_linked_channel_id = get_linked_channel_id(linked_channel_id);
LOG(INFO) << "Uplate linked channel in " << linked_channel_id << " from " << old_linked_linked_channel_id << " to "
<< new_linked_linked_channel_id;
if (old_linked_linked_channel_id != new_linked_linked_channel_id) {
// must be called after the linked channel is changed
td_->messages_manager_->on_dialog_linked_channel_updated(DialogId(linked_channel_id), old_linked_linked_channel_id,
new_linked_linked_channel_id);
if (linked_channel_id.is_valid()) {
auto new_linked_linked_channel_id = get_linked_channel_id(linked_channel_id);
LOG(INFO) << "Uplate linked channel in " << linked_channel_id << " from " << old_linked_linked_channel_id << " to "
<< new_linked_linked_channel_id;
if (old_linked_linked_channel_id != new_linked_linked_channel_id) {
// must be called after the linked channel is changed
td_->messages_manager_->on_dialog_linked_channel_updated(
DialogId(linked_channel_id), old_linked_linked_channel_id, new_linked_linked_channel_id);
}
}
}
@ -13401,24 +13403,34 @@ DialogParticipant ContactsManager::get_chat_participant(ChatId chat_id, UserId u
return *result;
}
DialogParticipants ContactsManager::search_chat_participants(ChatId chat_id, const string &query, int32 limit,
DialogParticipantsFilter filter, bool force,
Promise<Unit> &&promise) {
void ContactsManager::search_chat_participants(ChatId chat_id, const string &query, int32 limit,
DialogParticipantsFilter filter, Promise<DialogParticipants> &&promise) {
if (limit < 0) {
promise.set_error(Status::Error(3, "Parameter limit must be non-negative"));
return {};
return promise.set_error(Status::Error(3, "Parameter limit must be non-negative"));
}
if (force) {
promise.set_value(Unit());
} else if (!load_chat_full(chat_id, force, std::move(promise), "search_chat_participants")) {
return {};
auto load_chat_full_promise = PromiseCreator::lambda([actor_id = actor_id(this), chat_id, query, limit, filter,
promise = std::move(promise)](Result<Unit> &&result) mutable {
if (result.is_error()) {
promise.set_error(result.move_as_error());
} else {
send_closure(actor_id, &ContactsManager::do_search_chat_participants, chat_id, query, limit, filter,
std::move(promise));
}
});
load_chat_full(chat_id, false, std::move(load_chat_full_promise), "search_chat_participants");
}
void ContactsManager::do_search_chat_participants(ChatId chat_id, const string &query, int32 limit,
DialogParticipantsFilter filter,
Promise<DialogParticipants> &&promise) {
if (G()->close_flag()) {
return promise.set_error(Status::Error(500, "Request aborted"));
}
// promise is already set
auto chat_full = get_chat_full(chat_id);
if (chat_full == nullptr) {
return {};
return promise.set_error(Status::Error(500, "Can't find basic group full info"));
}
auto is_dialog_participant_suitable = [this, filter](const DialogParticipant &participant) {
@ -13452,7 +13464,9 @@ DialogParticipants ContactsManager::search_chat_participants(ChatId chat_id, con
int32 total_count;
std::tie(total_count, user_ids) = search_among_users(user_ids, query, limit);
return {total_count, transform(user_ids, [&](UserId user_id) { return *get_chat_participant(chat_full, user_id); })};
promise.set_value(DialogParticipants{total_count, transform(user_ids, [this, chat_full](UserId user_id) {
return *get_chat_participant(chat_full, user_id);
})});
}
DialogParticipant ContactsManager::get_channel_participant(ChannelId channel_id, UserId user_id, int64 &random_id,
@ -13516,88 +13530,69 @@ DialogParticipant ContactsManager::get_channel_participant(ChannelId channel_id,
return DialogParticipant();
}
DialogParticipants ContactsManager::get_channel_participants(
ChannelId channel_id, const tl_object_ptr<td_api::SupergroupMembersFilter> &filter, const string &additional_query,
int32 offset, int32 limit, int32 additional_limit, int64 &random_id, bool without_bot_info, bool force,
Promise<Unit> &&promise) {
if (random_id != 0) {
// request has already been sent before
auto it = received_channel_participants_.find(random_id);
CHECK(it != received_channel_participants_.end());
auto result = std::move(it->second);
received_channel_participants_.erase(it);
promise.set_value(Unit());
if (additional_query.empty()) {
return result;
}
auto user_ids = transform(result.participants_, [](const auto &participant) { return participant.user_id; });
std::pair<int32, vector<UserId>> result_user_ids = search_among_users(user_ids, additional_query, additional_limit);
result.total_count_ = result_user_ids.first;
std::unordered_set<UserId, UserIdHash> result_user_ids_set(result_user_ids.second.begin(),
result_user_ids.second.end());
auto all_participants = std::move(result.participants_);
result.participants_.clear();
for (auto &participant : all_participants) {
if (result_user_ids_set.count(participant.user_id)) {
result.participants_.push_back(std::move(participant));
result_user_ids_set.erase(participant.user_id);
}
}
return result;
}
DialogParticipants result;
void ContactsManager::get_channel_participants(ChannelId channel_id,
tl_object_ptr<td_api::SupergroupMembersFilter> &&filter,
string additional_query, int32 offset, int32 limit,
int32 additional_limit, bool without_bot_info,
Promise<DialogParticipants> &&promise) {
if (limit <= 0) {
promise.set_error(Status::Error(3, "Parameter limit must be positive"));
return result;
return promise.set_error(Status::Error(400, "Parameter limit must be positive"));
}
if (limit > MAX_GET_CHANNEL_PARTICIPANTS) {
limit = MAX_GET_CHANNEL_PARTICIPANTS;
}
if (offset < 0) {
promise.set_error(Status::Error(3, "Parameter offset must be non-negative"));
return result;
return promise.set_error(Status::Error(400, "Parameter offset must be non-negative"));
}
auto channel_full = get_channel_full_force(channel_id, "get_channel_participants");
if (td_->auth_manager_->is_bot()) {
without_bot_info = true;
}
if (!without_bot_info && (channel_full == nullptr || (!force && channel_full->is_expired()))) {
if (force) {
LOG(ERROR) << "Can't find cached ChannelFull";
} else {
send_get_channel_full_query(channel_full, channel_id, std::move(promise), "get_channel_participants");
return result;
auto load_channel_full_promise =
PromiseCreator::lambda([actor_id = actor_id(this), channel_id, filter = ChannelParticipantsFilter(filter),
additional_query = std::move(additional_query), offset, limit, additional_limit,
promise = std::move(promise)](Result<Unit> &&result) mutable {
if (result.is_error()) {
promise.set_error(result.move_as_error());
} else {
send_closure(actor_id, &ContactsManager::do_get_channel_participants, channel_id, std::move(filter),
std::move(additional_query), offset, limit, additional_limit, std::move(promise));
}
});
if (!without_bot_info && !td_->auth_manager_->is_bot()) {
auto channel_full = get_channel_full_force(channel_id, "get_channel_participants");
if (channel_full == nullptr || channel_full->is_expired()) {
send_get_channel_full_query(channel_full, channel_id, std::move(load_channel_full_promise),
"get_channel_participants");
return;
}
}
if (channel_full != nullptr && !channel_full->is_expired() && !channel_full->can_get_participants) {
promise.set_error(Status::Error(3, "Member list is inaccessible"));
return result;
}
do {
random_id = Random::secure_int64();
} while (random_id == 0 || received_channel_participants_.find(random_id) != received_channel_participants_.end());
received_channel_participants_[random_id]; // reserve place for result
send_get_channel_participants_query(channel_id, ChannelParticipantsFilter(filter), offset, limit, random_id,
std::move(promise));
return result;
load_channel_full_promise.set_value(Unit());
}
void ContactsManager::send_get_channel_participants_query(ChannelId channel_id, ChannelParticipantsFilter filter,
int32 offset, int32 limit, int64 random_id,
Promise<Unit> &&promise) {
LOG(DEBUG) << "Get members of the " << channel_id << " with filter " << filter << ", offset = " << offset
<< " and limit = " << limit;
td_->create_handler<GetChannelParticipantsQuery>(std::move(promise))
->send(channel_id, std::move(filter), offset, limit, random_id);
void ContactsManager::do_get_channel_participants(ChannelId channel_id, ChannelParticipantsFilter &&filter,
string additional_query, int32 offset, int32 limit,
int32 additional_limit, Promise<DialogParticipants> &&promise) {
if (G()->close_flag()) {
return promise.set_error(Status::Error(500, "Request aborted"));
}
auto channel_full = get_channel_full_force(channel_id, "do_get_channel_participants");
if (channel_full != nullptr && !channel_full->is_expired() && !channel_full->can_get_participants) {
return promise.set_error(Status::Error(400, "Member list is inaccessible"));
}
auto get_channel_participants_promise = PromiseCreator::lambda(
[actor_id = actor_id(this), channel_id, filter, additional_query = std::move(additional_query), offset, limit,
additional_limit, promise = std::move(promise)](
Result<tl_object_ptr<telegram_api::channels_channelParticipants>> &&result) mutable {
if (result.is_error()) {
promise.set_error(result.move_as_error());
} else {
send_closure(actor_id, &ContactsManager::on_get_channel_participants, channel_id, std::move(filter), offset,
limit, std::move(additional_query), additional_limit, result.move_as_ok(), std::move(promise));
}
});
td_->create_handler<GetChannelParticipantsQuery>(std::move(get_channel_participants_promise))
->send(channel_id, std::move(filter), offset, limit);
}
vector<DialogAdministrator> ContactsManager::get_dialog_administrators(DialogId dialog_id, int left_tries,

View File

@ -220,13 +220,6 @@ class ContactsManager : public Actor {
bool on_get_channel_error(ChannelId channel_id, const Status &status, const string &source);
void on_get_channel_participants_success(ChannelId channel_id, ChannelParticipantsFilter filter, int32 offset,
int32 limit, int64 random_id, int32 total_count,
vector<tl_object_ptr<telegram_api::ChannelParticipant>> &&participants);
void on_get_channel_participants_fail(ChannelId channel_id, ChannelParticipantsFilter filter, int32 offset,
int32 limit, int64 random_id);
static Slice get_dialog_invite_link_hash(const string &invite_link);
void on_get_chat_invite_link(ChatId chat_id, tl_object_ptr<telegram_api::ExportedChatInvite> &&invite_link_ptr);
@ -501,20 +494,15 @@ class ContactsManager : public Actor {
DialogParticipant get_chat_participant(ChatId chat_id, UserId user_id, bool force, Promise<Unit> &&promise);
DialogParticipants search_chat_participants(ChatId chat_id, const string &query, int32 limit,
DialogParticipantsFilter filter, bool force, Promise<Unit> &&promise);
void search_chat_participants(ChatId chat_id, const string &query, int32 limit, DialogParticipantsFilter filter,
Promise<DialogParticipants> &&promise);
DialogParticipant get_channel_participant(ChannelId channel_id, UserId user_id, int64 &random_id, bool force,
Promise<Unit> &&promise);
DialogParticipants get_channel_participants(ChannelId channel_id,
const tl_object_ptr<td_api::SupergroupMembersFilter> &filter,
const string &additional_query, int32 offset, int32 limit,
int32 additional_limit, int64 &random_id, bool without_bot_info,
bool force, Promise<Unit> &&promise);
void send_get_channel_participants_query(ChannelId channel_id, ChannelParticipantsFilter filter, int32 offset,
int32 limit, int64 random_id, Promise<Unit> &&promise);
void get_channel_participants(ChannelId channel_id, tl_object_ptr<td_api::SupergroupMembersFilter> &&filter,
string additional_query, int32 offset, int32 limit, int32 additional_limit,
bool without_bot_info, Promise<DialogParticipants> &&promise);
DialogParticipant get_dialog_participant(ChannelId channel_id,
tl_object_ptr<telegram_api::ChannelParticipant> &&participant_ptr) const;
@ -1425,6 +1413,18 @@ class ContactsManager : public Actor {
void delete_chat_participant(ChatId chat_id, UserId user_id, Promise<Unit> &&promise);
void do_search_chat_participants(ChatId chat_id, const string &query, int32 limit, DialogParticipantsFilter filter,
Promise<DialogParticipants> &&promise);
void do_get_channel_participants(ChannelId channel_id, ChannelParticipantsFilter &&filter, string additional_query,
int32 offset, int32 limit, int32 additional_limit,
Promise<DialogParticipants> &&promise);
void on_get_channel_participants(ChannelId channel_id, ChannelParticipantsFilter filter, int32 offset, int32 limit,
string additional_query, int32 additional_limit,
tl_object_ptr<telegram_api::channels_channelParticipants> &&channel_participants,
Promise<DialogParticipants> &&promise);
void change_channel_participant_status_impl(ChannelId channel_id, UserId user_id, DialogParticipantStatus status,
DialogParticipantStatus old_status, Promise<Unit> &&promise);
@ -1567,7 +1567,6 @@ class ContactsManager : public Actor {
std::unordered_map<int64, std::pair<vector<UserId>, vector<int32>>> imported_contacts_;
std::unordered_map<int64, DialogParticipant> received_channel_participant_;
std::unordered_map<int64, DialogParticipants> received_channel_participants_;
std::unordered_map<ChannelId, vector<DialogParticipant>, ChannelIdHash> cached_channel_participants_;

View File

@ -9,7 +9,6 @@
#include "td/telegram/AccessRights.h"
#include "td/telegram/AuthManager.h"
#include "td/telegram/ContactsManager.h"
#include "td/telegram/DialogParticipant.h"
#include "td/telegram/Global.h"
#include "td/telegram/MessageId.h"
#include "td/telegram/MessagesManager.h"
@ -1483,23 +1482,29 @@ void GroupCallManager::try_load_group_call_administrators(InputGroupCallId input
return;
}
unique_ptr<int64> random_id_ptr = td::make_unique<int64>();
auto random_id_raw = random_id_ptr.get();
auto promise = PromiseCreator::lambda(
[actor_id = actor_id(this), input_group_call_id, random_id = std::move(random_id_ptr)](Result<Unit> &&result) {
auto promise =
PromiseCreator::lambda([actor_id = actor_id(this), input_group_call_id](Result<DialogParticipants> &&result) {
send_closure(actor_id, &GroupCallManager::finish_load_group_call_administrators, input_group_call_id,
*random_id, std::move(result));
std::move(result));
});
td_->messages_manager_->search_dialog_participants(
dialog_id, string(), 100, DialogParticipantsFilter(DialogParticipantsFilter::Type::Administrators),
*random_id_raw, true, true, std::move(promise));
dialog_id, string(), 100, DialogParticipantsFilter(DialogParticipantsFilter::Type::Administrators), true,
std::move(promise));
}
void GroupCallManager::finish_load_group_call_administrators(InputGroupCallId input_group_call_id, int64 random_id,
Result<Unit> &&result) {
void GroupCallManager::finish_load_group_call_administrators(InputGroupCallId input_group_call_id,
Result<DialogParticipants> &&result) {
if (G()->close_flag()) {
return;
}
if (result.is_error()) {
LOG(WARNING) << "Failed to get administrators of " << input_group_call_id << ": " << result.error();
return;
}
if (!need_group_call_participants(input_group_call_id)) {
return;
}
auto *group_call = get_group_call(input_group_call_id);
CHECK(group_call != nullptr);
@ -1508,34 +1513,11 @@ void GroupCallManager::finish_load_group_call_administrators(InputGroupCallId in
}
vector<UserId> administrator_user_ids;
if (result.is_ok()) {
result = Status::Error(500, "Failed to receive result");
unique_ptr<bool> ignore_result = make_unique<bool>();
auto ignore_result_ptr = ignore_result.get();
auto promise = PromiseCreator::lambda([&result, ignore_result = std::move(ignore_result)](Result<Unit> new_result) {
if (!*ignore_result) {
result = std::move(new_result);
}
});
auto participants = td_->messages_manager_->search_dialog_participants(
group_call->dialog_id, string(), 100, DialogParticipantsFilter(DialogParticipantsFilter::Type::Administrators),
random_id, true, true, std::move(promise));
for (auto &administrator : participants.participants_) {
if (administrator.status.can_manage_calls() && administrator.user_id != td_->contacts_manager_->get_my_id()) {
administrator_user_ids.push_back(administrator.user_id);
}
auto participants = result.move_as_ok();
for (auto &administrator : participants.participants_) {
if (administrator.status.can_manage_calls() && administrator.user_id != td_->contacts_manager_->get_my_id()) {
administrator_user_ids.push_back(administrator.user_id);
}
*ignore_result_ptr = true;
}
if (result.is_error()) {
LOG(WARNING) << "Failed to get administrators of " << input_group_call_id << ": " << result.error();
return;
}
if (!need_group_call_participants(input_group_call_id)) {
return;
}
auto *group_call_participants = add_group_call_participants(input_group_call_id);

View File

@ -7,6 +7,7 @@
#pragma once
#include "td/telegram/DialogId.h"
#include "td/telegram/DialogParticipant.h"
#include "td/telegram/GroupCallId.h"
#include "td/telegram/GroupCallParticipant.h"
#include "td/telegram/InputGroupCallId.h"
@ -151,8 +152,7 @@ class GroupCallManager : public Actor {
void try_load_group_call_administrators(InputGroupCallId input_group_call_id, DialogId dialog_id);
void finish_load_group_call_administrators(InputGroupCallId input_group_call_id, int64 random_id,
Result<Unit> &&result);
void finish_load_group_call_administrators(InputGroupCallId input_group_call_id, Result<DialogParticipants> &&result);
bool on_join_group_call_response(InputGroupCallId input_group_call_id, string json_response);

View File

@ -11275,9 +11275,9 @@ void MessagesManager::on_update_dialog_online_member_count_timeout(DialogId dial
if (participant_count == 0 || participant_count >= 195) {
td_->create_handler<GetOnlinesQuery>()->send(dialog_id);
} else {
td_->contacts_manager_->send_get_channel_participants_query(
dialog_id.get_channel_id(),
ChannelParticipantsFilter(td_api::make_object<td_api::supergroupMembersFilterRecent>()), 0, 200, 0, Auto());
td_->contacts_manager_->get_channel_participants(dialog_id.get_channel_id(),
td_api::make_object<td_api::supergroupMembersFilterRecent>(),
string(), 0, 200, 200, true, Auto());
}
return;
}
@ -18927,10 +18927,9 @@ void MessagesManager::open_dialog(Dialog *d) {
if (!is_broadcast_channel(dialog_id)) {
auto participant_count = td_->contacts_manager_->get_channel_participant_count(dialog_id.get_channel_id());
if (participant_count < 195) { // include unknown participant_count
td_->contacts_manager_->send_get_channel_participants_query(
dialog_id.get_channel_id(),
ChannelParticipantsFilter(td_api::make_object<td_api::supergroupMembersFilterRecent>()), 0, 200, 0,
Auto());
td_->contacts_manager_->get_channel_participants(dialog_id.get_channel_id(),
td_api::make_object<td_api::supergroupMembersFilterRecent>(),
string(), 0, 200, 200, true, Auto());
}
}
get_channel_difference(dialog_id, d->pts, true, "open_dialog");
@ -30308,28 +30307,25 @@ DialogParticipants MessagesManager::search_private_chat_participants(UserId my_u
})};
}
DialogParticipants MessagesManager::search_dialog_participants(DialogId dialog_id, const string &query, int32 limit,
DialogParticipantsFilter filter, int64 &random_id,
bool without_bot_info, bool force,
Promise<Unit> &&promise) {
void MessagesManager::search_dialog_participants(DialogId dialog_id, const string &query, int32 limit,
DialogParticipantsFilter filter, bool without_bot_info,
Promise<DialogParticipants> &&promise) {
LOG(INFO) << "Receive searchChatMembers request to search for \"" << query << "\" in " << dialog_id << " with filter "
<< filter;
if (!have_dialog_force(dialog_id)) {
promise.set_error(Status::Error(3, "Chat not found"));
return {};
return promise.set_error(Status::Error(3, "Chat not found"));
}
if (limit < 0) {
promise.set_error(Status::Error(3, "Parameter limit must be non-negative"));
return {};
return promise.set_error(Status::Error(3, "Parameter limit must be non-negative"));
}
switch (dialog_id.get_type()) {
case DialogType::User:
promise.set_value(Unit());
return search_private_chat_participants(td_->contacts_manager_->get_my_id(), dialog_id.get_user_id(), query,
limit, filter);
promise.set_value(search_private_chat_participants(td_->contacts_manager_->get_my_id(), dialog_id.get_user_id(),
query, limit, filter));
return;
case DialogType::Chat:
return td_->contacts_manager_->search_chat_participants(dialog_id.get_chat_id(), query, limit, filter, force,
return td_->contacts_manager_->search_chat_participants(dialog_id.get_chat_id(), query, limit, filter,
std::move(promise));
case DialogType::Channel: {
tl_object_ptr<td_api::SupergroupMembersFilter> request_filter;
@ -30379,21 +30375,21 @@ DialogParticipants MessagesManager::search_dialog_participants(DialogId dialog_i
UNREACHABLE();
}
return td_->contacts_manager_->get_channel_participants(dialog_id.get_channel_id(), request_filter,
additional_query, 0, limit, additional_limit, random_id,
without_bot_info, force, std::move(promise));
return td_->contacts_manager_->get_channel_participants(dialog_id.get_channel_id(), std::move(request_filter),
std::move(additional_query), 0, limit, additional_limit,
without_bot_info, std::move(promise));
}
case DialogType::SecretChat: {
promise.set_value(Unit());
auto peer_user_id = td_->contacts_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id());
return search_private_chat_participants(td_->contacts_manager_->get_my_id(), peer_user_id, query, limit, filter);
promise.set_value(
search_private_chat_participants(td_->contacts_manager_->get_my_id(), peer_user_id, query, limit, filter));
return;
}
case DialogType::None:
default:
UNREACHABLE();
promise.set_error(Status::Error(500, "Wrong chat type"));
}
return {};
}
vector<DialogAdministrator> MessagesManager::get_dialog_administrators(DialogId dialog_id, int left_tries,

View File

@ -477,9 +477,8 @@ class MessagesManager : public Actor {
DialogParticipant get_dialog_participant(DialogId dialog_id, UserId user_id, int64 &random_id, bool force,
Promise<Unit> &&promise);
DialogParticipants search_dialog_participants(DialogId dialog_id, const string &query, int32 limit,
DialogParticipantsFilter filter, int64 &random_id,
bool without_bot_info, bool force, Promise<Unit> &&promise);
void search_dialog_participants(DialogId dialog_id, const string &query, int32 limit, DialogParticipantsFilter filter,
bool without_bot_info, Promise<DialogParticipants> &&promise);
vector<DialogAdministrator> get_dialog_administrators(DialogId dialog_id, int left_tries, Promise<Unit> &&promise);

View File

@ -1961,36 +1961,6 @@ class GetChatMemberRequest : public RequestActor<> {
}
};
class SearchChatMembersRequest : public RequestActor<> {
DialogId dialog_id_;
string query_;
int32 limit_;
DialogParticipantsFilter filter_;
int64 random_id_ = 0;
DialogParticipants participants_;
void do_run(Promise<Unit> &&promise) override {
participants_ = td->messages_manager_->search_dialog_participants(dialog_id_, query_, limit_, filter_, random_id_,
false, get_tries() < 3, std::move(promise));
}
void do_send_result() override {
send_result(participants_.get_chat_members_object(td));
}
public:
SearchChatMembersRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id, string &&query, int32 limit,
DialogParticipantsFilter filter)
: RequestActor(std::move(td), request_id)
, dialog_id_(dialog_id)
, query_(std::move(query))
, limit_(limit)
, filter_(filter) {
set_tries(3);
}
};
class GetChatAdministratorsRequest : public RequestActor<> {
DialogId dialog_id_;
@ -2271,36 +2241,6 @@ class GetRecentInlineBotsRequest : public RequestActor<> {
}
};
class GetSupergroupMembersRequest : public RequestActor<> {
ChannelId channel_id_;
tl_object_ptr<td_api::SupergroupMembersFilter> filter_;
int32 offset_;
int32 limit_;
int64 random_id_ = 0;
DialogParticipants participants_;
void do_run(Promise<Unit> &&promise) override {
participants_ = td->contacts_manager_->get_channel_participants(
channel_id_, filter_, string(), offset_, limit_, -1, random_id_, false, get_tries() < 3, std::move(promise));
}
void do_send_result() override {
send_result(participants_.get_chat_members_object(td));
}
public:
GetSupergroupMembersRequest(ActorShared<Td> td, uint64 request_id, int32 channel_id,
tl_object_ptr<td_api::SupergroupMembersFilter> &&filter, int32 offset, int32 limit)
: RequestActor(std::move(td), request_id)
, channel_id_(channel_id)
, filter_(std::move(filter))
, offset_(offset)
, limit_(limit) {
set_tries(3);
}
};
class GetUserProfilePhotosRequest : public RequestActor<> {
UserId user_id_;
int32 offset_;
@ -6327,8 +6267,18 @@ void Td::on_request(uint64 id, const td_api::getChatMember &request) {
void Td::on_request(uint64 id, td_api::searchChatMembers &request) {
CLEAN_INPUT_STRING(request.query_);
CREATE_REQUEST(SearchChatMembersRequest, request.chat_id_, std::move(request.query_), request.limit_,
get_dialog_participants_filter(request.filter_));
CREATE_REQUEST_PROMISE();
auto query_promise =
PromiseCreator::lambda([promise = std::move(promise), td = this](Result<DialogParticipants> result) mutable {
if (result.is_error()) {
promise.set_error(result.move_as_error());
} else {
promise.set_value(result.ok().get_chat_members_object(td));
}
});
messages_manager_->search_dialog_participants(DialogId(request.chat_id_), request.query_, request.limit_,
get_dialog_participants_filter(request.filter_), false,
std::move(query_promise));
}
void Td::on_request(uint64 id, td_api::getChatAdministrators &request) {
@ -6691,8 +6641,17 @@ void Td::on_request(uint64 id, const td_api::reportSupergroupSpam &request) {
}
void Td::on_request(uint64 id, td_api::getSupergroupMembers &request) {
CREATE_REQUEST(GetSupergroupMembersRequest, request.supergroup_id_, std::move(request.filter_), request.offset_,
request.limit_);
CREATE_REQUEST_PROMISE();
auto query_promise =
PromiseCreator::lambda([promise = std::move(promise), td = this](Result<DialogParticipants> result) mutable {
if (result.is_error()) {
promise.set_error(result.move_as_error());
} else {
promise.set_value(result.ok().get_chat_members_object(td));
}
});
contacts_manager_->get_channel_participants(ChannelId(request.supergroup_id_), std::move(request.filter_), string(),
request.offset_, request.limit_, -1, false, std::move(query_promise));
}
void Td::on_request(uint64 id, const td_api::deleteSupergroup &request) {