From d47bd927fe54711d48ddb500769644278621f504 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 31 Mar 2023 15:50:49 +0300 Subject: [PATCH] Add td_api::checkChatFilterInviteLink. --- td/generate/scheme/td_api.tl | 11 +++- td/telegram/DialogFilterManager.cpp | 98 +++++++++++++++++++++++++++++ td/telegram/DialogFilterManager.h | 7 +++ td/telegram/MessagesManager.h | 4 +- td/telegram/Td.cpp | 7 +++ td/telegram/Td.h | 2 + td/telegram/cli.cpp | 4 +- 7 files changed, 129 insertions(+), 4 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 8af73bdda..4b4410c15 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -923,7 +923,7 @@ basicGroupFullInfo photo:chatPhoto description:string creator_user_id:int53 memb //@date Point in time (Unix timestamp) when the current user joined, or the point in time when the supergroup or channel was created, in case the user is not a member //@status Status of the current user in the supergroup or channel; custom title will always be empty //@member_count Number of members in the supergroup or channel; 0 if unknown. Currently, it is guaranteed to be known only if the supergroup or channel was received -//-through searchPublicChats, searchChatsNearby, getInactiveSupergroupChats, getSuitableDiscussionChats, getGroupsInCommon, or getUserPrivacySettingRules +//-through searchPublicChats, searchChatsNearby, getInactiveSupergroupChats, getSuitableDiscussionChats, getGroupsInCommon, getUserPrivacySettingRules, or in chatFilterInviteLinkInfo.missing_chat_ids //@has_linked_chat True, if the channel has a discussion group, or the supergroup is the designated discussion group for a channel //@has_location True, if the supergroup is connected to a location, i.e. the supergroup is a location-based supergroup //@sign_messages True, if messages sent to the channel need to contain information about the sender. This field is only applicable to channels @@ -1326,6 +1326,12 @@ chatFilterInviteLink invite_link:string name:string chat_ids:vector = Cha //@description Represents a list of chat filter invite links @invite_links List of the invite links chatFilterInviteLinks invite_links:vector = ChatFilterInviteLinks; +//@description Contains information about an invite link to a chat filter +//@chat_filter_info Basic information about the chat filter; chat filter identifier will be 0 if the user didn't have the chat filter yet +//@missing_chat_ids Identifiers of the chats from the link, which aren't added to the filter yet +//@added_chat_ids Identifiers of the chats from the link, which are added to the filter already +chatFilterInviteLinkInfo chat_filter_info:chatFilterInfo missing_chat_ids:vector added_chat_ids:vector = ChatFilterInviteLinkInfo; + //@description Describes a recommended chat filter @filter The chat filter @param_description Chat filter description recommendedChatFilter filter:chatFilter description:string = RecommendedChatFilter; @@ -6821,6 +6827,9 @@ editChatFilterInviteLink chat_filter_id:int32 invite_link:string name:string cha //@invite_link Invite link to be deleted deleteChatFilterInviteLink chat_filter_id:int32 invite_link:string = Ok; +//@description Checks the validity of an invite link for a chat filter and returns information about the corresponding chat filter @invite_link Invite link to be checked +checkChatFilterInviteLink invite_link:string = ChatFilterInviteLinkInfo; + //@description Changes the chat title. Supported only for basic groups, supergroups and channels. Requires can_change_info administrator right //@chat_id Chat identifier diff --git a/td/telegram/DialogFilterManager.cpp b/td/telegram/DialogFilterManager.cpp index e87aeb3cd..4dcb06be4 100644 --- a/td/telegram/DialogFilterManager.cpp +++ b/td/telegram/DialogFilterManager.cpp @@ -13,6 +13,7 @@ #include "td/telegram/DialogFilter.hpp" #include "td/telegram/DialogFilterInviteLink.h" #include "td/telegram/Global.h" +#include "td/telegram/LinkManager.h" #include "td/telegram/logevent/LogEvent.h" #include "td/telegram/MessagesManager.h" #include "td/telegram/OptionManager.h" @@ -248,6 +249,35 @@ class DeleteExportedChatlistInviteQuery final : public Td::ResultHandler { } }; +class CheckChatlistInviteQuery final : public Td::ResultHandler { + Promise> promise_; + string invite_link_; + + public: + explicit CheckChatlistInviteQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(const string &invite_link) { + invite_link_ = invite_link; + send_query(G()->net_query_creator().create( + telegram_api::chatlists_checkChatlistInvite(LinkManager::get_dialog_filter_invite_link_slug(invite_link_)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + td_->dialog_filter_manager_->on_get_chatlist_invite(invite_link_, result_ptr.move_as_ok(), std::move(promise_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + class GetDialogsQuery final : public Td::ResultHandler { Promise promise_; bool is_single_ = false; @@ -1618,6 +1648,74 @@ void DialogFilterManager::delete_dialog_filter_invite_link(DialogFilterId dialog td_->create_handler(std::move(promise))->send(dialog_filter_id, invite_link); } +void DialogFilterManager::check_dialog_filter_invite_link( + const string &invite_link, Promise> &&promise) { + if (!DialogFilterInviteLink::is_valid_invite_link(invite_link)) { + return promise.set_error(Status::Error(400, "Wrong invite link")); + } + + CHECK(!invite_link.empty()); + td_->create_handler(std::move(promise))->send(invite_link); +} + +void DialogFilterManager::on_get_chatlist_invite( + const string &invite_link, telegram_api::object_ptr &&invite_ptr, + Promise> &&promise) { + CHECK(invite_ptr != nullptr); + LOG(INFO) << "Receive information about chat folder invite link " << invite_link << ": " << to_string(invite_ptr); + + td_api::object_ptr info; + vector> missing_peers; + vector> already_peers; + vector> chats; + vector> users; + switch (invite_ptr->get_id()) { + case telegram_api::chatlists_chatlistInviteAlready::ID: { + auto invite = move_tl_object_as(invite_ptr); + DialogFilterId dialog_filter_id = DialogFilterId(invite->filter_id_); + if (!dialog_filter_id.is_valid()) { + return promise.set_error(Status::Error(500, "Receive invalid chat folder identifier")); + } + auto dialog_filter = get_dialog_filter(dialog_filter_id); + if (dialog_filter == nullptr) { + reload_dialog_filters(); + return promise.set_error(Status::Error(500, "Receive unknown chat folder")); + } + info = dialog_filter->get_chat_filter_info_object(); + missing_peers = std::move(invite->missing_peers_); + already_peers = std::move(invite->already_peers_); + chats = std::move(invite->chats_); + users = std::move(invite->users_); + break; + } + case telegram_api::chatlists_chatlistInvite::ID: { + auto invite = move_tl_object_as(invite_ptr); + auto icon_name = DialogFilter::get_icon_name_by_emoji(invite->emoticon_); + if (icon_name.empty()) { + icon_name = "Custom"; + } + info = td_api::make_object(0, invite->title_, + td_api::make_object(icon_name)); + missing_peers = std::move(invite->peers_); + chats = std::move(invite->chats_); + users = std::move(invite->users_); + break; + } + default: + UNREACHABLE(); + break; + } + + td_->contacts_manager_->on_get_users(std::move(users), "on_get_chatlist_invite"); + td_->contacts_manager_->on_get_chats(std::move(chats), "on_get_chatlist_invite"); + + auto missing_dialog_ids = td_->messages_manager_->get_peers_dialog_ids(std::move(missing_peers)); + auto already_dialog_ids = td_->messages_manager_->get_peers_dialog_ids(std::move(already_peers)); + promise.set_value(td_api::make_object( + std::move(info), transform(missing_dialog_ids, [](DialogId dialog_id) { return dialog_id.get(); }), + transform(already_dialog_ids, [](DialogId dialog_id) { return dialog_id.get(); }))); +} + void DialogFilterManager::get_current_state(vector> &updates) const { if (have_dialog_filters()) { updates.push_back(get_update_chat_filters_object()); diff --git a/td/telegram/DialogFilterManager.h b/td/telegram/DialogFilterManager.h index 3ea278332..44b752ca3 100644 --- a/td/telegram/DialogFilterManager.h +++ b/td/telegram/DialogFilterManager.h @@ -85,6 +85,13 @@ class DialogFilterManager final : public Actor { void delete_dialog_filter_invite_link(DialogFilterId dialog_filter_id, string invite_link, Promise promise); + void check_dialog_filter_invite_link(const string &invite_link, + Promise> &&promise); + + void on_get_chatlist_invite(const string &invite_link, + telegram_api::object_ptr &&invite_ptr, + Promise> &&promise); + void on_get_dialog_filter(telegram_api::object_ptr filter); void get_recommended_dialog_filters(Promise> &&promise); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index cb766e9fd..4807bcd6f 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -180,6 +180,8 @@ class MessagesManager final : public Actor { bool have_input_peer(DialogId dialog_id, AccessRights access_rights) const; + vector get_peers_dialog_ids(vector> &&peers); + void on_get_empty_messages(DialogId dialog_id, const vector &empty_message_ids); void get_channel_difference_if_needed(DialogId dialog_id, MessagesInfo &&messages_info, @@ -2593,8 +2595,6 @@ class MessagesManager final : public Actor { vector sort_dialogs_by_order(const vector &dialog_ids, int32 limit) const; - vector get_peers_dialog_ids(vector> &&peers); - static bool need_unread_counter(int64 dialog_order); int32 get_dialog_total_count(const DialogList &list) const; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index c426cb4c0..6eedf663f 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6185,6 +6185,13 @@ void Td::on_request(uint64 id, td_api::deleteChatFilterInviteLink &request) { std::move(request.invite_link_), std::move(promise)); } +void Td::on_request(uint64 id, td_api::checkChatFilterInviteLink &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.invite_link_); + CREATE_REQUEST_PROMISE(); + dialog_filter_manager_->check_dialog_filter_invite_link(std::move(request.invite_link_), std::move(promise)); +} + void Td::on_request(uint64 id, td_api::setChatTitle &request) { CLEAN_INPUT_STRING(request.title_); CREATE_OK_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index b60cfec6b..0823dc76b 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -933,6 +933,8 @@ class Td final : public Actor { void on_request(uint64 id, td_api::deleteChatFilterInviteLink &request); + void on_request(uint64 id, td_api::checkChatFilterInviteLink &request); + void on_request(uint64 id, td_api::setChatTitle &request); void on_request(uint64 id, const td_api::setChatPhoto &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 761e3b5b6..49760b08c 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -4586,7 +4586,7 @@ class CliClient final : public Actor { get_args(args, main_chat_list_position, chat_filter_ids); send_request(td_api::make_object(as_chat_filter_ids(chat_filter_ids), main_chat_list_position)); - } else if (op == "ccfil") { + } else if (op == "crcfil") { ChatFilterId chat_filter_id; string name; string chat_ids; @@ -4610,6 +4610,8 @@ class CliClient final : public Actor { string invite_link; get_args(args, chat_filter_id, invite_link); send_request(td_api::make_object(chat_filter_id, invite_link)); + } else if (op == "ccfil") { + send_request(td_api::make_object(args)); } else if (op == "grcf") { send_request(td_api::make_object()); } else if (op == "gcfdin") {