diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index a7d9dfafa..61a977498 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -4455,6 +4455,10 @@ deleteFile file_id:int32 = Ok; //@description Returns information about a file with messages exported from another app @message_file_head Beginning of the message file; up to 100 first lines getMessageFileType message_file_head:string = MessageFileType; +//@description Returns a confirmation text to be shown to the user before starting message import +//@chat_id Identifier of a chat to which the messages will be imported. It must be an identifier of a private chat with a mutual contact or an identifier of a supergroup chat with can_change_info administrator right +getMessageImportConfirmationText chat_id:int53 = Text; + //@description Imports messages exported from another app //@chat_id Identifier of a chat to which the messages will be imported. It must be an identifier of a private chat with a mutual contact or an identifier of a supergroup chat with can_change_info administrator right //@message_file File with messages to import. Only inputFileLocal and inputFileGenerated are supported. The file must not be previously uploaded diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 89689edc6..6399a12dd 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 8c0366879..e35613e95 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -1049,6 +1049,38 @@ class CheckHistoryImportQuery : public Td::ResultHandler { } }; +class CheckHistoryImportPeerQuery : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + + public: + explicit CheckHistoryImportPeerQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id) { + dialog_id_ = dialog_id; + auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + CHECK(input_peer != nullptr); + send_query(G()->net_query_creator().create(telegram_api::messages_checkHistoryImportPeer(std::move(input_peer)))); + } + + void on_result(uint64 id, BufferSlice packet) override { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(id, result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for CheckHistoryImportPeerQuery: " << to_string(ptr); + promise_.set_value(std::move(ptr->confirm_text_)); + } + + void on_error(uint64 id, Status status) override { + td->messages_manager_->on_get_dialog_error(dialog_id_, status, "CheckHistoryImportPeerQuery"); + promise_.set_error(std::move(status)); + } +}; + class InitHistoryImportQuery : public Td::ResultHandler { Promise promise_; FileId file_id_; @@ -26664,38 +26696,50 @@ void MessagesManager::get_message_file_type(const string &message_file_head, td_->create_handler(std::move(promise))->send(message_file_head); } -void MessagesManager::import_messages(DialogId dialog_id, const td_api::object_ptr &message_file, - const vector> &attached_files, - Promise &&promise) { +Status MessagesManager::can_import_messages(DialogId dialog_id) { if (!have_dialog_force(dialog_id)) { - return promise.set_error(Status::Error(400, "Chat not found")); + return Status::Error(400, "Chat not found"); } - TRY_STATUS_PROMISE(promise, can_send_message(dialog_id)); + TRY_STATUS(can_send_message(dialog_id)); switch (dialog_id.get_type()) { case DialogType::User: if (!td_->contacts_manager_->is_user_contact(dialog_id.get_user_id(), true)) { - return promise.set_error(Status::Error(400, "User must be a mutual contact")); + return Status::Error(400, "User must be a mutual contact"); } break; case DialogType::Chat: - return promise.set_error(Status::Error(400, "Basic groups must be updagraded to supergroups first")); + return Status::Error(400, "Basic groups must be updagraded to supergroups first"); case DialogType::Channel: if (is_broadcast_channel(dialog_id)) { - return promise.set_error(Status::Error(400, "Can't import messages to channels")); + return Status::Error(400, "Can't import messages to channels"); } if (!td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id()).can_change_info_and_settings()) { - return promise.set_error(Status::Error(400, "Not enough rights to import messages")); + return Status::Error(400, "Not enough rights to import messages"); } break; case DialogType::SecretChat: - return promise.set_error(Status::Error(400, "Can't import messages to secret chats")); + return Status::Error(400, "Can't import messages to secret chats"); case DialogType::None: default: UNREACHABLE(); } + return Status::OK(); +} + +void MessagesManager::get_message_import_confirmation_text(DialogId dialog_id, Promise &&promise) { + TRY_STATUS_PROMISE(promise, can_import_messages(dialog_id)); + + td_->create_handler(std::move(promise))->send(dialog_id); +} + +void MessagesManager::import_messages(DialogId dialog_id, const td_api::object_ptr &message_file, + const vector> &attached_files, + Promise &&promise) { + TRY_STATUS_PROMISE(promise, can_import_messages(dialog_id)); + auto r_file_id = td_->file_manager_->get_input_file_id(FileType::Document, message_file, dialog_id, false, false); if (r_file_id.is_error()) { // TODO TRY_RESULT_PROMISE(promise, ...); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 50f6f077e..676a691a9 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -401,6 +401,8 @@ class MessagesManager : public Actor { void get_message_file_type(const string &message_file_head, Promise> &&promise); + void get_message_import_confirmation_text(DialogId dialog_id, Promise &&promise); + void import_messages(DialogId dialog_id, const td_api::object_ptr &message_file, const vector> &attached_files, Promise &&promise); @@ -2842,6 +2844,8 @@ class MessagesManager : public Actor { void on_imported_message_attachments_uploaded(int64 random_id, Result &&result); + Status can_import_messages(DialogId dialog_id); + void add_sponsored_dialog(const Dialog *d, DialogSource source); void save_sponsored_dialog(); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index d012f7a14..6d7cab580 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6561,6 +6561,19 @@ void Td::on_request(uint64 id, td_api::getMessageFileType &request) { messages_manager_->get_message_file_type(request.message_file_head_, std::move(promise)); } +void Td::on_request(uint64 id, const td_api::getMessageImportConfirmationText &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(make_tl_object(result.move_as_ok())); + } + }); + messages_manager_->get_message_import_confirmation_text(DialogId(request.chat_id_), std::move(query_promise)); +} + void Td::on_request(uint64 id, const td_api::importMessages &request) { CHECK_IS_USER(); CREATE_OK_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 95c543cac..b97476b32 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -842,6 +842,8 @@ class Td final : public NetQueryCallback { void on_request(uint64 id, td_api::getMessageFileType &request); + void on_request(uint64 id, const td_api::getMessageImportConfirmationText &request); + void on_request(uint64 id, const td_api::importMessages &request); void on_request(uint64 id, const td_api::blockMessageSenderFromReplies &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 18cf32ba9..efa63ce81 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3002,6 +3002,10 @@ class CliClient final : public Actor { } send_request(td_api::make_object(message_file_head)); } + } else if (op == "gmict") { + string chat_id; + get_args(args, chat_id); + send_request(td_api::make_object(as_chat_id(chat_id))); } else if (op == "im") { string chat_id; string message_file;