Add members filter to searchChatMembers.
GitOrigin-RevId: 8d553d6c73e32446eaa7e6ebb5bdf562458d258d
This commit is contained in:
parent
28672b750c
commit
15828a2329
@ -340,6 +340,24 @@ chatMember user_id:int32 inviter_user_id:int32 joined_chat_date:int32 status:Cha
|
||||
chatMembers total_count:int32 members:vector<chatMember> = ChatMembers;
|
||||
|
||||
|
||||
//@class ChatMembersFilter @description Specifies the kind of chat members to return in searchChatMembers
|
||||
|
||||
//@description Returns the creator and administrators
|
||||
chatMembersFilterAdministrators = ChatMembersFilter;
|
||||
|
||||
//@description Returns all chat members, including restricted chat members
|
||||
chatMembersFilterMembers = ChatMembersFilter;
|
||||
|
||||
//@description Returns users under certain restrictions in the chat; can be used only by administrators in a supergroup
|
||||
chatMembersFilterRestricted = ChatMembersFilter;
|
||||
|
||||
//@description Returns users banned from the chat; can be used only by administrators in a supergroup or in a channel
|
||||
chatMembersFilterBanned = ChatMembersFilter;
|
||||
|
||||
//@description Returns bot members of the chat
|
||||
chatMembersFilterBots = ChatMembersFilter;
|
||||
|
||||
|
||||
//@class SupergroupMembersFilter @description Specifies the kind of chat members to return in getSupergroupMembers
|
||||
|
||||
//@description Returns recently active users in reverse chronological order
|
||||
@ -2724,8 +2742,8 @@ setChatMemberStatus chat_id:int53 user_id:int32 status:ChatMemberStatus = Ok;
|
||||
//@description Returns information about a single member of a chat @chat_id Chat identifier @user_id User identifier
|
||||
getChatMember chat_id:int53 user_id:int32 = ChatMember;
|
||||
|
||||
//@description Searches for a specified query in the first name, last name and username of the members of a specified chat. Requires administrator rights in channels @chat_id Chat identifier @query Query to search for @limit The maximum number of users to be returned
|
||||
searchChatMembers chat_id:int53 query:string limit:int32 = ChatMembers;
|
||||
//@description Searches for a specified query in the first name, last name and username of the members of a specified chat. Requires administrator rights in channels @chat_id Chat identifier @query Query to search for @limit The maximum number of users to be returned The type of users to return. By default, chatMembersFilterMembers
|
||||
searchChatMembers chat_id:int53 query:string limit:int32 filter:ChatMembersFilter = ChatMembers;
|
||||
|
||||
//@description Returns a list of users who are administrators of the chat @chat_id Chat identifier
|
||||
getChatAdministrators chat_id:int53 = Users;
|
||||
|
Binary file not shown.
@ -8816,6 +8816,7 @@ DialogParticipant ContactsManager::get_chat_participant(ChatId chat_id, UserId u
|
||||
|
||||
std::pair<int32, vector<DialogParticipant>> ContactsManager::search_chat_participants(ChatId chat_id,
|
||||
const string &query, int32 limit,
|
||||
DialogParticipantsFilter filter,
|
||||
bool force,
|
||||
Promise<Unit> &&promise) {
|
||||
if (limit < 0) {
|
||||
@ -8835,7 +8836,31 @@ std::pair<int32, vector<DialogParticipant>> ContactsManager::search_chat_partici
|
||||
return {};
|
||||
}
|
||||
|
||||
auto user_ids = transform(chat_full->participants, [](const auto &participant) { return participant.user_id; });
|
||||
auto is_dialog_participant_suitable = [this](const DialogParticipant &participant, DialogParticipantsFilter filter) {
|
||||
switch (filter) {
|
||||
case DialogParticipantsFilter::Administrators:
|
||||
return participant.status.is_administrator();
|
||||
case DialogParticipantsFilter::Members:
|
||||
return participant.status.is_member(); // should be always true
|
||||
case DialogParticipantsFilter::Restricted:
|
||||
return participant.status.is_restricted(); // should be always false
|
||||
case DialogParticipantsFilter::Banned:
|
||||
return participant.status.is_banned(); // should be always false
|
||||
case DialogParticipantsFilter::Bots:
|
||||
return is_user_bot(participant.user_id);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
vector<UserId> user_ids;
|
||||
for (auto &participant : chat_full->participants) {
|
||||
if (is_dialog_participant_suitable(participant, filter)) {
|
||||
user_ids.push_back(participant.user_id);
|
||||
}
|
||||
}
|
||||
|
||||
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); })};
|
||||
@ -8902,8 +8927,8 @@ DialogParticipant ContactsManager::get_channel_participant(ChannelId channel_id,
|
||||
}
|
||||
|
||||
std::pair<int32, vector<DialogParticipant>> ContactsManager::get_channel_participants(
|
||||
ChannelId channel_id, const tl_object_ptr<td_api::SupergroupMembersFilter> &filter, int32 offset, int32 limit,
|
||||
int64 &random_id, bool force, Promise<Unit> &&promise) {
|
||||
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 force, Promise<Unit> &&promise) {
|
||||
if (random_id != 0) {
|
||||
// request has already been sent before
|
||||
auto it = received_channel_participants_.find(random_id);
|
||||
@ -8911,6 +8936,25 @@ std::pair<int32, vector<DialogParticipant>> ContactsManager::get_channel_partici
|
||||
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.second, [](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.first = 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.second);
|
||||
result.second.clear();
|
||||
for (auto &participant : all_participants) {
|
||||
if (result_user_ids_set.count(participant.user_id)) {
|
||||
result.second.push_back(std::move(participant));
|
||||
result_user_ids_set.erase(participant.user_id);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -377,14 +377,16 @@ class ContactsManager : public Actor {
|
||||
DialogParticipant get_chat_participant(ChatId chat_id, UserId user_id, bool force, Promise<Unit> &&promise);
|
||||
|
||||
std::pair<int32, vector<DialogParticipant>> search_chat_participants(ChatId chat_id, const string &query, int32 limit,
|
||||
bool force, Promise<Unit> &&promise);
|
||||
DialogParticipantsFilter filter, bool force,
|
||||
Promise<Unit> &&promise);
|
||||
|
||||
DialogParticipant get_channel_participant(ChannelId channel_id, UserId user_id, int64 &random_id, bool force,
|
||||
Promise<Unit> &&promise);
|
||||
|
||||
std::pair<int32, vector<DialogParticipant>> get_channel_participants(
|
||||
ChannelId channel_id, const tl_object_ptr<td_api::SupergroupMembersFilter> &filter, int32 offset, int32 limit,
|
||||
int64 &random_id, bool force, Promise<Unit> &&promise);
|
||||
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 force,
|
||||
Promise<Unit> &&promise);
|
||||
|
||||
DialogParticipant get_dialog_participant(ChannelId channel_id,
|
||||
tl_object_ptr<telegram_api::ChannelParticipant> &&participant_ptr) const;
|
||||
|
@ -425,4 +425,25 @@ ChannelParticipantsFilter::ChannelParticipantsFilter(const tl_object_ptr<td_api:
|
||||
}
|
||||
}
|
||||
|
||||
DialogParticipantsFilter get_dialog_participants_filter(const tl_object_ptr<td_api::ChatMembersFilter> &filter) {
|
||||
if (filter == nullptr) {
|
||||
return DialogParticipantsFilter::Members;
|
||||
}
|
||||
switch (filter->get_id()) {
|
||||
case td_api::chatMembersFilterAdministrators::ID:
|
||||
return DialogParticipantsFilter::Administrators;
|
||||
case td_api::chatMembersFilterMembers::ID:
|
||||
return DialogParticipantsFilter::Members;
|
||||
case td_api::chatMembersFilterRestricted::ID:
|
||||
return DialogParticipantsFilter::Restricted;
|
||||
case td_api::chatMembersFilterBanned::ID:
|
||||
return DialogParticipantsFilter::Banned;
|
||||
case td_api::chatMembersFilterBots::ID:
|
||||
return DialogParticipantsFilter::Bots;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return DialogParticipantsFilter::Members;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -252,6 +252,10 @@ class ChannelParticipantsFilter {
|
||||
}
|
||||
};
|
||||
|
||||
enum class DialogParticipantsFilter : int32 { Administrators, Members, Restricted, Banned, Bots };
|
||||
|
||||
DialogParticipantsFilter get_dialog_participants_filter(const tl_object_ptr<td_api::ChatMembersFilter> &filter);
|
||||
|
||||
DialogParticipantStatus get_dialog_participant_status(const tl_object_ptr<td_api::ChatMemberStatus> &status);
|
||||
|
||||
DialogParticipantStatus get_dialog_participant_status(
|
||||
|
@ -21562,11 +21562,33 @@ DialogParticipant MessagesManager::get_dialog_participant(DialogId dialog_id, Us
|
||||
return DialogParticipant();
|
||||
}
|
||||
|
||||
std::pair<int32, vector<DialogParticipant>> MessagesManager::search_private_chat_participants(UserId my_user_id,
|
||||
UserId peer_user_id,
|
||||
const string &query,
|
||||
int32 limit) const {
|
||||
auto result = td_->contacts_manager_->search_among_users({my_user_id, peer_user_id}, query, limit);
|
||||
std::pair<int32, vector<DialogParticipant>> MessagesManager::search_private_chat_participants(
|
||||
UserId my_user_id, UserId peer_user_id, const string &query, int32 limit, DialogParticipantsFilter filter) const {
|
||||
vector<UserId> user_ids;
|
||||
switch (filter) {
|
||||
case DialogParticipantsFilter::Administrators:
|
||||
break;
|
||||
case DialogParticipantsFilter::Members:
|
||||
user_ids.push_back(my_user_id);
|
||||
user_ids.push_back(peer_user_id);
|
||||
break;
|
||||
case DialogParticipantsFilter::Restricted:
|
||||
break;
|
||||
case DialogParticipantsFilter::Banned:
|
||||
break;
|
||||
case DialogParticipantsFilter::Bots:
|
||||
if (td_->auth_manager_->is_bot()) {
|
||||
user_ids.push_back(my_user_id);
|
||||
}
|
||||
if (td_->contacts_manager_->is_user_bot(peer_user_id)) {
|
||||
user_ids.push_back(peer_user_id);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
auto result = td_->contacts_manager_->search_among_users(user_ids, query, limit);
|
||||
return {result.first, transform(result.second, [&](UserId user_id) {
|
||||
return DialogParticipant(user_id, user_id == my_user_id ? peer_user_id : my_user_id, 0,
|
||||
DialogParticipantStatus::Member());
|
||||
@ -21574,7 +21596,8 @@ std::pair<int32, vector<DialogParticipant>> MessagesManager::search_private_chat
|
||||
}
|
||||
|
||||
std::pair<int32, vector<DialogParticipant>> MessagesManager::search_dialog_participants(
|
||||
DialogId dialog_id, const string &query, int32 limit, int64 &random_id, bool force, Promise<Unit> &&promise) {
|
||||
DialogId dialog_id, const string &query, int32 limit, DialogParticipantsFilter filter, int64 &random_id, bool force,
|
||||
Promise<Unit> &&promise) {
|
||||
LOG(INFO) << "Receive SearchChatMembers request to search for " << query << " in " << dialog_id;
|
||||
if (!have_dialog_force(dialog_id)) {
|
||||
promise.set_error(Status::Error(3, "Chat not found"));
|
||||
@ -21589,19 +21612,49 @@ std::pair<int32, vector<DialogParticipant>> MessagesManager::search_dialog_parti
|
||||
case DialogType::User:
|
||||
promise.set_value(Unit());
|
||||
return search_private_chat_participants(td_->contacts_manager_->get_my_id("search_dialog_participants"),
|
||||
dialog_id.get_user_id(), query, limit);
|
||||
dialog_id.get_user_id(), query, limit, filter);
|
||||
case DialogType::Chat:
|
||||
return td_->contacts_manager_->search_chat_participants(dialog_id.get_chat_id(), query, limit, force,
|
||||
return td_->contacts_manager_->search_chat_participants(dialog_id.get_chat_id(), query, limit, filter, force,
|
||||
std::move(promise));
|
||||
case DialogType::Channel:
|
||||
return td_->contacts_manager_->get_channel_participants(
|
||||
dialog_id.get_channel_id(), td_api::make_object<td_api::supergroupMembersFilterSearch>(query), 0, limit,
|
||||
random_id, force, std::move(promise));
|
||||
case DialogType::Channel: {
|
||||
tl_object_ptr<td_api::SupergroupMembersFilter> request_filter;
|
||||
string additional_query;
|
||||
int32 additional_limit = 0;
|
||||
switch (filter) {
|
||||
case DialogParticipantsFilter::Administrators:
|
||||
request_filter = td_api::make_object<td_api::supergroupMembersFilterAdministrators>();
|
||||
additional_query = query;
|
||||
additional_limit = limit;
|
||||
limit = 100;
|
||||
break;
|
||||
case DialogParticipantsFilter::Members:
|
||||
request_filter = td_api::make_object<td_api::supergroupMembersFilterSearch>(query);
|
||||
break;
|
||||
case DialogParticipantsFilter::Restricted:
|
||||
request_filter = td_api::make_object<td_api::supergroupMembersFilterRestricted>(query);
|
||||
break;
|
||||
case DialogParticipantsFilter::Banned:
|
||||
request_filter = td_api::make_object<td_api::supergroupMembersFilterBanned>(query);
|
||||
break;
|
||||
case DialogParticipantsFilter::Bots:
|
||||
request_filter = td_api::make_object<td_api::supergroupMembersFilterBots>();
|
||||
additional_query = query;
|
||||
additional_limit = limit;
|
||||
limit = 100;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
return td_->contacts_manager_->get_channel_participants(dialog_id.get_channel_id(), request_filter,
|
||||
additional_query, 0, limit, additional_limit, random_id,
|
||||
force, 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("search_dialog_participants"),
|
||||
peer_user_id, query, limit);
|
||||
peer_user_id, query, limit, filter);
|
||||
}
|
||||
case DialogType::None:
|
||||
default:
|
||||
|
@ -1171,7 +1171,8 @@ class MessagesManager : public Actor {
|
||||
Promise<Unit> &&promise);
|
||||
|
||||
std::pair<int32, vector<DialogParticipant>> search_dialog_participants(DialogId dialog_id, const string &query,
|
||||
int32 limit, int64 &random_id, bool force,
|
||||
int32 limit, DialogParticipantsFilter filter,
|
||||
int64 &random_id, bool force,
|
||||
Promise<Unit> &&promise);
|
||||
|
||||
vector<UserId> get_dialog_administrators(DialogId dialog_id, int left_tries, Promise<Unit> &&promise);
|
||||
@ -2397,7 +2398,8 @@ class MessagesManager : public Actor {
|
||||
void update_dialogs_hints_rating(const Dialog *d);
|
||||
|
||||
std::pair<int32, vector<DialogParticipant>> search_private_chat_participants(UserId my_user_id, UserId peer_user_id,
|
||||
const string &query, int32 limit) const;
|
||||
const string &query, int32 limit,
|
||||
DialogParticipantsFilter filter) const;
|
||||
|
||||
static unique_ptr<Message> *find_message(unique_ptr<Message> *v, MessageId message_id);
|
||||
static const unique_ptr<Message> *find_message(const unique_ptr<Message> *v, MessageId message_id);
|
||||
|
@ -6,8 +6,6 @@
|
||||
//
|
||||
#include "td/telegram/Td.h"
|
||||
|
||||
#include "td/db/binlog/BinlogEvent.h"
|
||||
|
||||
#include "td/telegram/net/ConnectionCreator.h"
|
||||
#include "td/telegram/net/DcId.h"
|
||||
#include "td/telegram/net/MtprotoHeader.h"
|
||||
@ -71,6 +69,8 @@
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
|
||||
#include "td/db/binlog/BinlogEvent.h"
|
||||
|
||||
#include "td/mtproto/utils.h" // for create_storer, fetch_result, etc, TODO
|
||||
|
||||
#include "td/utils/buffer.h"
|
||||
@ -1850,12 +1850,13 @@ class SearchChatMembersRequest : public RequestActor<> {
|
||||
DialogId dialog_id_;
|
||||
string query_;
|
||||
int32 limit_;
|
||||
DialogParticipantsFilter filter_;
|
||||
int64 random_id_ = 0;
|
||||
|
||||
std::pair<int32, vector<DialogParticipant>> participants_;
|
||||
|
||||
void do_run(Promise<Unit> &&promise) override {
|
||||
participants_ = td->messages_manager_->search_dialog_participants(dialog_id_, query_, limit_, random_id_,
|
||||
participants_ = td->messages_manager_->search_dialog_participants(dialog_id_, query_, limit_, filter_, random_id_,
|
||||
get_tries() < 3, std::move(promise));
|
||||
}
|
||||
|
||||
@ -1871,8 +1872,13 @@ class SearchChatMembersRequest : public RequestActor<> {
|
||||
}
|
||||
|
||||
public:
|
||||
SearchChatMembersRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id, string &&query, int32 limit)
|
||||
: RequestActor(std::move(td), request_id), dialog_id_(dialog_id), query_(std::move(query)), limit_(limit) {
|
||||
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);
|
||||
}
|
||||
};
|
||||
@ -2158,8 +2164,8 @@ class GetSupergroupMembersRequest : public RequestActor<> {
|
||||
std::pair<int32, vector<DialogParticipant>> participants_;
|
||||
|
||||
void do_run(Promise<Unit> &&promise) override {
|
||||
participants_ = td->contacts_manager_->get_channel_participants(channel_id_, filter_, offset_, limit_, random_id_,
|
||||
get_tries() < 3, std::move(promise));
|
||||
participants_ = td->contacts_manager_->get_channel_participants(channel_id_, filter_, string(), offset_, limit_, -1,
|
||||
random_id_, get_tries() < 3, std::move(promise));
|
||||
}
|
||||
|
||||
void do_send_result() override {
|
||||
@ -5476,7 +5482,8 @@ 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_);
|
||||
CREATE_REQUEST(SearchChatMembersRequest, request.chat_id_, std::move(request.query_), request.limit_,
|
||||
get_dialog_participants_filter(request.filter_));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::getChatAdministrators &request) {
|
||||
|
@ -923,6 +923,30 @@ class CliClient final : public Actor {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static tl_object_ptr<td_api::ChatMembersFilter> get_chat_members_filter(MutableSlice filter) {
|
||||
filter = trim(filter);
|
||||
to_lower_inplace(filter);
|
||||
if (filter == "a" || filter == "admin" || filter == "administrators") {
|
||||
return make_tl_object<td_api::chatMembersFilterAdministrators>();
|
||||
}
|
||||
if (filter == "b" || filter == "banned") {
|
||||
return make_tl_object<td_api::chatMembersFilterBanned>();
|
||||
}
|
||||
if (filter == "bot" || filter == "bots") {
|
||||
return make_tl_object<td_api::chatMembersFilterBots>();
|
||||
}
|
||||
if (filter == "m" || filter == "members") {
|
||||
return make_tl_object<td_api::chatMembersFilterMembers>();
|
||||
}
|
||||
if (filter == "r" || filter == "rest" || filter == "restricted") {
|
||||
return make_tl_object<td_api::chatMembersFilterRestricted>();
|
||||
}
|
||||
if (!filter.empty()) {
|
||||
LOG(ERROR) << "Unsupported chat member filter " << filter;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
tl_object_ptr<td_api::TopChatCategory> get_top_chat_category(MutableSlice category) {
|
||||
category = trim(category);
|
||||
to_lower_inplace(category);
|
||||
@ -1969,10 +1993,13 @@ class CliClient final : public Actor {
|
||||
string chat_id;
|
||||
string limit;
|
||||
string query;
|
||||
string filter;
|
||||
|
||||
std::tie(chat_id, args) = split(args);
|
||||
std::tie(limit, query) = split(args);
|
||||
send_request(make_tl_object<td_api::searchChatMembers>(as_chat_id(chat_id), query, to_integer<int32>(limit)));
|
||||
std::tie(limit, args) = split(args);
|
||||
std::tie(query, filter) = split(args);
|
||||
send_request(make_tl_object<td_api::searchChatMembers>(as_chat_id(chat_id), query, to_integer<int32>(limit),
|
||||
get_chat_members_filter(filter)));
|
||||
} else if (op == "gcm") {
|
||||
string chat_id;
|
||||
string user_id;
|
||||
|
Reference in New Issue
Block a user