diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 8d475e048..2c4c02c97 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -599,6 +599,12 @@ chatInviteLinkMembers total_count:int32 members:vector = C //@is_public True, if the chat is a public supergroup or channel, i.e. it has a username or it is a location-based supergroup chatInviteLinkInfo chat_id:int53 accessible_for:int32 type:ChatType title:string photo:chatPhotoInfo description:string member_count:int32 member_user_ids:vector requires_approval:Bool is_public:Bool = ChatInviteLinkInfo; +//@description Describes a user waiting administrator approval to join a chat @user_id User identifier @request_date Point in time (Unix timestamp) when the user sent the chat join request @bio A short bio of the user +chatJoinRequest user_id:int53 request_date:int32 bio:string = ChatJoinRequest; + +//@description Contains a list of chat join requests @total_count Approximate total count of requests found @requests List of the requests +chatJoinRequests total_count:int32 requests:vector = ChatJoinRequests; + //@description Represents a basic group of 0-200 users (must be upgraded to a supergroup to accommodate more than 200 users) //@id Group identifier @@ -4928,6 +4934,14 @@ checkChatInviteLink invite_link:string = ChatInviteLinkInfo; //@description Uses an invite link to add the current user to the chat if possible @invite_link Invite link to use joinChatByInviteLink invite_link:string = Chat; +//@description Returns pending join requests in a chat +//@chat_id Chat identifier +//@invite_link Invite link for which to return join requests. If empty, all join requests will be returned. Requires administrator privileges and can_invite_users right in the chat for own links and owner privileges for other links +//@query A query to search for in the first names, last names and usernames of the users to return +//@offset_request A chat join request from which to return next requests; pass null to get results from the beginning +//@limit The maximum number of chat join requests to return +getChatJoinRequests chat_id:int53 invite_link:string query:string offset_request:chatJoinRequest limit:int32 = ChatJoinRequests; + //@description Creates a new call @user_id Identifier of the user to be called @protocol Description of the call protocols supported by the application @is_video True, if a video call needs to be created createCall user_id:int53 protocol:callProtocol is_video:Bool = CallId; diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index fc73d9099..942bde066 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -1952,6 +1952,77 @@ class GetChatInviteImportersQuery final : public Td::ResultHandler { } }; +class GetChatJoinRequestsQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + + public: + explicit GetChatJoinRequestsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, const string &invite_link, const string &query, int32 offset_date, + UserId offset_user_id, int32 limit) { + dialog_id_ = dialog_id; + auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(0, Status::Error(400, "Can't access the chat")); + } + + auto input_user = td->contacts_manager_->get_input_user(offset_user_id); + if (input_user == nullptr) { + input_user = make_tl_object(); + } + + int32 flags = telegram_api::messages_getChatInviteImporters::REQUESTED_MASK; + if (!invite_link.empty()) { + flags |= telegram_api::messages_getChatInviteImporters::LINK_MASK; + } + if (!query.empty()) { + flags |= telegram_api::messages_getChatInviteImporters::Q_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::messages_getChatInviteImporters(flags, false /*ignored*/, std::move(input_peer), invite_link, + query, offset_date, std::move(input_user), limit))); + } + + void on_result(uint64 id, BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(id, result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetChatJoinRequestsQuery: " << to_string(result); + + td->contacts_manager_->on_get_users(std::move(result->users_), "GetChatJoinRequestsQuery"); + + int32 total_count = result->count_; + if (total_count < static_cast(result->importers_.size())) { + LOG(ERROR) << "Receive wrong total count of join requests " << total_count << " in " << dialog_id_; + total_count = static_cast(result->importers_.size()); + } + vector> join_requests; + for (auto &request : result->importers_) { + UserId user_id(request->user_id_); + UserId approver_user_id(request->approved_by_); + if (!user_id.is_valid() || approver_user_id.is_valid() || !request->requested_) { + LOG(ERROR) << "Receive invalid join request: " << to_string(request); + total_count--; + continue; + } + join_requests.push_back(td_api::make_object( + td->contacts_manager_->get_user_id_object(user_id, "chatJoinRequest"), request->date_, request->about_)); + } + promise_.set_value(td_api::make_object(total_count, std::move(join_requests))); + } + + void on_error(uint64 id, Status status) final { + td->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetChatJoinRequestsQuery"); + promise_.set_error(std::move(status)); + } +}; + class RevokeChatInviteLinkQuery final : public Td::ResultHandler { Promise> promise_; DialogId dialog_id_; @@ -7412,6 +7483,26 @@ void ContactsManager::get_dialog_invite_link_users( ->send(dialog_id, invite_link, offset_date, offset_user_id, limit); } +void ContactsManager::get_dialog_join_requests(DialogId dialog_id, const string &invite_link, const string &query, + td_api::object_ptr offset_request, int32 limit, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, can_manage_dialog_invite_links(dialog_id)); + + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); + } + + UserId offset_user_id; + int32 offset_date = 0; + if (offset_request != nullptr) { + offset_user_id = UserId(offset_request->user_id_); + offset_date = offset_request->request_date_; + } + + td_->create_handler(std::move(promise)) + ->send(dialog_id, invite_link, query, offset_date, offset_user_id, limit); +} + void ContactsManager::revoke_dialog_invite_link(DialogId dialog_id, const string &invite_link, Promise> &&promise) { TRY_STATUS_PROMISE(promise, can_manage_dialog_invite_links(dialog_id)); diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index df4156be9..111a1e638 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -404,6 +404,10 @@ class ContactsManager final : public Actor { td_api::object_ptr offset_member, int32 limit, Promise> &&promise); + void get_dialog_join_requests(DialogId dialog_id, const string &invite_link, const string &query, + td_api::object_ptr offset_request, int32 limit, + Promise> &&promise); + void revoke_dialog_invite_link(DialogId dialog_id, const string &link, Promise> &&promise); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 9e41dde06..42f267c0e 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6332,6 +6332,15 @@ void Td::on_request(uint64 id, td_api::getChatInviteLinkMembers &request) { std::move(promise)); } +void Td::on_request(uint64 id, td_api::getChatJoinRequests &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.invite_link_); + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST_PROMISE(); + contacts_manager_->get_dialog_join_requests(DialogId(request.chat_id_), request.invite_link_, request.query_, + std::move(request.offset_request_), request.limit_, std::move(promise)); +} + void Td::on_request(uint64 id, td_api::revokeChatInviteLink &request) { CLEAN_INPUT_STRING(request.invite_link_); CREATE_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index b98ba1c41..de63f13bc 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -870,6 +870,8 @@ class Td final : public Actor { void on_request(uint64 id, td_api::getChatInviteLinkMembers &request); + void on_request(uint64 id, td_api::getChatJoinRequests &request); + void on_request(uint64 id, td_api::revokeChatInviteLink &request); void on_request(uint64 id, td_api::deleteRevokedChatInviteLink &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 854e460be..b930c080f 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2986,6 +2986,18 @@ class CliClient final : public Actor { as_chat_id(chat_id), invite_link, td_api::make_object(as_user_id(offset_user_id), offset_date, 0), as_limit(limit))); + } else if (op == "gcjr") { + string chat_id; + string invite_link; + string query; + string offset_user_id; + int32 offset_date; + string limit; + get_args(args, chat_id, invite_link, query, offset_user_id, offset_date, limit); + send_request(td_api::make_object( + as_chat_id(chat_id), invite_link, query, + td_api::make_object(as_user_id(offset_user_id), offset_date, string()), + as_limit(limit))); } else if (op == "drcil") { string chat_id; string invite_link;