diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index b6985a8fc..9138bba72 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -9555,6 +9555,9 @@ reorderActiveUsernames usernames:vector = Ok; //@description Changes the birthdate of the current user @birthdate The new value of the current user's birthdate; pass null to remove the birthdate setBirthdate birthdate:birthdate = Ok; +//@description Changes the personal chat of the current user @chat_id Identifier of the new personal chat; pass 0 to remove the chat. Use getSuitablePersonalChats to get suitable chats +setPersonalChat chat_id:int53 = Ok; + //@description Changes the emoji status of the current user; for Telegram Premium users only @emoji_status New emoji status; pass null to switch to the default badge setEmojiStatus emoji_status:emojiStatus = Ok; diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 9007b7379..2ec01f438 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -1035,6 +1035,44 @@ class UpdateBirthdayQuery final : public Td::ResultHandler { } }; +class UpdatePersonalChannelQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit UpdatePersonalChannelQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(ChannelId channel_id) { + telegram_api::object_ptr input_channel; + if (channel_id == ChannelId()) { + input_channel = telegram_api::make_object(); + } else { + input_channel = td_->contacts_manager_->get_input_channel(channel_id); + CHECK(input_channel != nullptr); + } + send_query(G()->net_query_creator().create(telegram_api::account_updatePersonalChannel(std::move(input_channel)), + {{"me"}})); + } + + 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()); + } + + LOG(DEBUG) << "Receive result for UpdatePersonalChannelQuery: " << result_ptr.ok(); + if (result_ptr.ok()) { + promise_.set_value(Unit()); + } else { + promise_.set_error(Status::Error(400, "Failed to change personal chat")); + } + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + class UpdateEmojiStatusQuery final : public Td::ResultHandler { Promise promise_; @@ -6393,7 +6431,7 @@ void ContactsManager::set_birthdate(Birthdate &&birthdate, Promise &&promi void ContactsManager::on_set_birthdate(Birthdate birthdate, Promise &&promise) { auto my_user_id = get_my_id(); UserFull *user_full = get_user_full_force(my_user_id, "on_set_birthdate"); - if (user_full != nullptr) { + if (user_full != nullptr && user_full->birthdate != birthdate) { user_full->birthdate = std::move(birthdate); user_full->is_changed = true; update_user_full(user_full, my_user_id, "on_set_birthdate"); @@ -6401,6 +6439,42 @@ void ContactsManager::on_set_birthdate(Birthdate birthdate, Promise &&prom promise.set_value(Unit()); } +void ContactsManager::set_personal_channel(DialogId dialog_id, Promise &&promise) { + ChannelId channel_id; + if (dialog_id != DialogId() && !td_->dialog_manager_->have_dialog_force(dialog_id, "set_personal_channel")) { + return promise.set_error(Status::Error(400, "Chat not found")); + } + if (dialog_id != DialogId()) { + if (dialog_id.get_type() != DialogType::Channel) { + return promise.set_error(Status::Error(400, "Chat can't be set as a personal chat")); + } + channel_id = dialog_id.get_channel_id(); + if (!is_suitable_created_public_channel(PublicDialogType::ForPersonalDialog, get_channel(channel_id))) { + return promise.set_error(Status::Error(400, "Chat can't be set as a personal chat")); + } + } + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), channel_id, promise = std::move(promise)](Result result) mutable { + if (result.is_ok()) { + send_closure(actor_id, &ContactsManager::on_set_personal_channel, channel_id, std::move(promise)); + } else { + promise.set_error(result.move_as_error()); + } + }); + td_->create_handler(std::move(query_promise))->send(channel_id); +} + +void ContactsManager::on_set_personal_channel(ChannelId channel_id, Promise &&promise) { + auto my_user_id = get_my_id(); + UserFull *user_full = get_user_full_force(my_user_id, "on_set_personal_channel"); + if (user_full != nullptr && user_full->personal_channel_id != channel_id) { + user_full->personal_channel_id = channel_id; + user_full->is_changed = true; + update_user_full(user_full, my_user_id, "on_set_personal_channel"); + } + promise.set_value(Unit()); +} + void ContactsManager::set_emoji_status(const EmojiStatus &emoji_status, Promise &&promise) { if (!td_->option_manager_->get_option_boolean("is_premium")) { return promise.set_error(Status::Error(400, "The method is available only to Telegram Premium users")); diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 54d621628..9117c4f92 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -462,6 +462,8 @@ class ContactsManager final : public Actor { void set_birthdate(Birthdate &&birthdate, Promise &&promise); + void set_personal_channel(DialogId dialog_id, Promise &&promise); + void set_emoji_status(const EmojiStatus &emoji_status, Promise &&promise); void set_chat_description(ChatId chat_id, const string &description, Promise &&promise); @@ -1300,6 +1302,8 @@ class ContactsManager final : public Actor { void on_set_birthdate(Birthdate birthdate, Promise &&promise); + void on_set_personal_channel(ChannelId channel_id, Promise &&promise); + void on_set_emoji_status(EmojiStatus emoji_status, Promise &&promise); void on_update_user_name(User *u, UserId user_id, string &&first_name, string &&last_name); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index af450eafd..703224b70 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -7681,6 +7681,12 @@ void Td::on_request(uint64 id, td_api::setBirthdate &request) { contacts_manager_->set_birthdate(Birthdate(std::move(request.birthdate_)), std::move(promise)); } +void Td::on_request(uint64 id, const td_api::setPersonalChat &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + contacts_manager_->set_personal_channel(DialogId(request.chat_id_), std::move(promise)); +} + void Td::on_request(uint64 id, const td_api::setEmojiStatus &request) { CHECK_IS_USER(); CREATE_OK_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 789fc578f..7d1917c46 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -1354,6 +1354,8 @@ class Td final : public Actor { void on_request(uint64 id, td_api::setBirthdate &request); + void on_request(uint64 id, const td_api::setPersonalChat &request); + void on_request(uint64 id, const td_api::setEmojiStatus &request); void on_request(uint64 id, const td_api::getThemedEmojiStatuses &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 95621f4bc..13943149f 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -5841,6 +5841,10 @@ class CliClient final : public Actor { send_request( td_api::make_object(td_api::make_object(day, month, year))); } + } else if (op == "spec") { + ChatId chat_id; + get_args(args, chat_id); + send_request(td_api::make_object(chat_id)); } else if (op == "sese") { send_request(td_api::make_object(nullptr)); } else if (op == "ses") {