Add class EncryptedFile.

This commit is contained in:
levlam 2021-08-01 06:17:51 +03:00
parent 966e8b1311
commit 1223c72741
14 changed files with 132 additions and 122 deletions

View File

@ -482,6 +482,7 @@ set(TDLIB_SOURCE
td/telegram/Document.h
td/telegram/DocumentsManager.h
td/telegram/DraftMessage.h
td/telegram/EncryptedFile.h
td/telegram/FileReferenceManager.h
td/telegram/files/FileBitmask.h
td/telegram/files/FileData.h

View File

@ -12,6 +12,7 @@
#include "td/telegram/DialogId.h"
#include "td/telegram/Document.h"
#include "td/telegram/EncryptedFile.h"
#include "td/telegram/files/FileId.h"
#include "td/telegram/Photo.h"
#include "td/telegram/SecretInputMedia.h"
@ -35,7 +36,7 @@ class DocumentsManager {
public:
tl_object_ptr<telegram_api::document> document;
// or
tl_object_ptr<telegram_api::encryptedFile> secret_file;
unique_ptr<EncryptedFile> secret_file;
tl_object_ptr<secret_api::decryptedMessageMediaDocument> secret_document;
// or
tl_object_ptr<telegram_api::WebDocument> web_document;
@ -62,7 +63,7 @@ class DocumentsManager {
, attributes(std::move(attributes)) {
}
RemoteDocument(tl_object_ptr<telegram_api::encryptedFile> &&secret_file,
RemoteDocument(unique_ptr<EncryptedFile> &&secret_file,
tl_object_ptr<secret_api::decryptedMessageMediaDocument> &&secret_document,
vector<tl_object_ptr<telegram_api::DocumentAttribute>> &&attributes)
: document(nullptr)

View File

@ -0,0 +1,73 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#pragma once
#include "td/telegram/telegram_api.h"
#include "td/utils/common.h"
#include "td/utils/format.h"
#include "td/utils/StringBuilder.h"
#include "td/utils/tl_helpers.h"
namespace td {
struct EncryptedFile {
static constexpr int32 MAGIC = 0x473d738a;
int64 id_ = 0;
int64 access_hash_ = 0;
int32 size_ = 0;
int32 dc_id_ = 0;
int32 key_fingerprint_ = 0;
EncryptedFile() = default;
EncryptedFile(int64 id, int64 access_hash, int32 size, int32 dc_id, int32 key_fingerprint)
: id_(id), access_hash_(access_hash), size_(size), dc_id_(dc_id), key_fingerprint_(key_fingerprint) {
}
static unique_ptr<EncryptedFile> get_encrypted_file(tl_object_ptr<telegram_api::EncryptedFile> file_ptr) {
if (file_ptr == nullptr || file_ptr->get_id() != telegram_api::encryptedFile::ID) {
return nullptr;
}
auto file = move_tl_object_as<telegram_api::encryptedFile>(file_ptr);
return make_unique<EncryptedFile>(file->id_, file->access_hash_, file->size_, file->dc_id_, file->key_fingerprint_);
}
template <class StorerT>
void store(StorerT &storer) const {
using td::store;
store(MAGIC, storer);
store(id_, storer);
store(access_hash_, storer);
store(size_, storer);
store(dc_id_, storer);
store(key_fingerprint_, storer);
}
template <class ParserT>
void parse(ParserT &parser) {
using td::parse;
int32 got_magic;
parse(got_magic, parser);
parse(id_, parser);
parse(access_hash_, parser);
parse(size_, parser);
parse(dc_id_, parser);
parse(key_fingerprint_, parser);
if (got_magic != MAGIC) {
parser.set_error("EncryptedFile magic mismatch");
}
}
};
inline StringBuilder &operator<<(StringBuilder &sb, const EncryptedFile &file) {
return sb << "[" << tag("id", file.id_) << tag("access_hash", file.access_hash_) << tag("size", file.size_)
<< tag("dc_id", file.dc_id_) << tag("key_fingerprint", file.key_fingerprint_) << "]";
}
} // namespace td

View File

@ -3789,7 +3789,7 @@ static unique_ptr<MessageContent> get_document_message_content(Td *td, tl_object
}
unique_ptr<MessageContent> get_secret_message_content(
Td *td, string message_text, tl_object_ptr<telegram_api::encryptedFile> file,
Td *td, string message_text, unique_ptr<EncryptedFile> file,
tl_object_ptr<secret_api::DecryptedMessageMedia> &&media,
vector<tl_object_ptr<secret_api::MessageEntity>> &&secret_entities, DialogId owner_dialog_id,
MultiPromiseActor &load_data_multipromise) {

View File

@ -7,6 +7,7 @@
#pragma once
#include "td/telegram/DialogId.h"
#include "td/telegram/EncryptedFile.h"
#include "td/telegram/files/FileId.h"
#include "td/telegram/FullMessageId.h"
#include "td/telegram/InputGroupCallId.h"
@ -176,7 +177,7 @@ void unregister_message_content(Td *td, const MessageContent *content, FullMessa
const char *source);
unique_ptr<MessageContent> get_secret_message_content(
Td *td, string message_text, tl_object_ptr<telegram_api::encryptedFile> file,
Td *td, string message_text, unique_ptr<EncryptedFile> file,
tl_object_ptr<secret_api::DecryptedMessageMedia> &&media,
vector<tl_object_ptr<secret_api::MessageEntity>> &&secret_entities, DialogId owner_dialog_id,
MultiPromiseActor &load_data_multipromise);

View File

@ -12744,15 +12744,13 @@ void MessagesManager::on_send_secret_message_error(int64 random_id, Status error
}
void MessagesManager::on_send_secret_message_success(int64 random_id, MessageId message_id, int32 date,
tl_object_ptr<telegram_api::EncryptedFile> file_ptr,
Promise<> promise) {
unique_ptr<EncryptedFile> file, Promise<> promise) {
promise.set_value(Unit()); // TODO: set after message is saved
FileId new_file_id;
if (file_ptr != nullptr && file_ptr->get_id() == telegram_api::encryptedFile::ID) {
auto file = move_tl_object_as<telegram_api::encryptedFile>(file_ptr);
if (file != nullptr) {
if (!DcId::is_valid(file->dc_id_)) {
LOG(ERROR) << "Wrong dc_id = " << file->dc_id_ << " in file " << to_string(file);
LOG(ERROR) << "Wrong dc_id = " << file->dc_id_ << " in file " << *file;
} else {
DialogId owner_dialog_id;
auto it = being_sent_messages_.find(random_id);
@ -12936,7 +12934,7 @@ void MessagesManager::on_update_secret_chat_state(SecretChatId secret_chat_id, S
}
void MessagesManager::on_get_secret_message(SecretChatId secret_chat_id, UserId user_id, MessageId message_id,
int32 date, tl_object_ptr<telegram_api::encryptedFile> file,
int32 date, unique_ptr<EncryptedFile> file,
tl_object_ptr<secret_api::decryptedMessage> message, Promise<> promise) {
LOG(DEBUG) << "On get " << to_string(message);
CHECK(message != nullptr);

View File

@ -17,6 +17,7 @@
#include "td/telegram/DialogLocation.h"
#include "td/telegram/DialogParticipant.h"
#include "td/telegram/DialogSource.h"
#include "td/telegram/EncryptedFile.h"
#include "td/telegram/files/FileId.h"
#include "td/telegram/files/FileSourceId.h"
#include "td/telegram/FolderId.h"
@ -228,8 +229,8 @@ class MessagesManager final : public Actor {
void open_secret_message(SecretChatId secret_chat_id, int64 random_id, Promise<>);
void on_send_secret_message_success(int64 random_id, MessageId message_id, int32 date,
tl_object_ptr<telegram_api::EncryptedFile> file_ptr, Promise<> promise);
void on_send_secret_message_success(int64 random_id, MessageId message_id, int32 date, unique_ptr<EncryptedFile> file,
Promise<> promise);
void on_send_secret_message_error(int64 random_id, Status error, Promise<> promise);
void delete_secret_messages(SecretChatId secret_chat_id, std::vector<int64> random_ids, Promise<> promise);
@ -242,8 +243,8 @@ class MessagesManager final : public Actor {
void on_update_secret_chat_state(SecretChatId secret_chat_id, SecretChatState state);
void on_get_secret_message(SecretChatId secret_chat_id, UserId user_id, MessageId message_id, int32 date,
tl_object_ptr<telegram_api::encryptedFile> file,
tl_object_ptr<secret_api::decryptedMessage> message, Promise<> promise);
unique_ptr<EncryptedFile> file, tl_object_ptr<secret_api::decryptedMessage> message,
Promise<> promise);
void on_secret_chat_screenshot_taken(SecretChatId secret_chat_id, UserId user_id, MessageId message_id, int32 date,
int64 random_id, Promise<> promise);

View File

@ -660,7 +660,7 @@ StringBuilder &operator<<(StringBuilder &string_builder, const AnimationSize &an
<< animation_size.main_frame_timestamp;
}
Photo get_encrypted_file_photo(FileManager *file_manager, tl_object_ptr<telegram_api::encryptedFile> &&file,
Photo get_encrypted_file_photo(FileManager *file_manager, unique_ptr<EncryptedFile> &&file,
tl_object_ptr<secret_api::decryptedMessageMediaPhoto> &&photo,
DialogId owner_dialog_id) {
FileId file_id = file_manager->register_remote(

View File

@ -7,6 +7,7 @@
#pragma once
#include "td/telegram/DialogId.h"
#include "td/telegram/EncryptedFile.h"
#include "td/telegram/files/FileId.h"
#include "td/telegram/files/FileType.h"
#include "td/telegram/net/DcId.h"
@ -137,7 +138,7 @@ StringBuilder &operator<<(StringBuilder &string_builder, const AnimationSize &an
Photo get_photo(FileManager *file_manager, tl_object_ptr<telegram_api::Photo> &&photo, DialogId owner_dialog_id);
Photo get_photo(FileManager *file_manager, tl_object_ptr<telegram_api::photo> &&photo, DialogId owner_dialog_id);
Photo get_encrypted_file_photo(FileManager *file_manager, tl_object_ptr<telegram_api::encryptedFile> &&file,
Photo get_encrypted_file_photo(FileManager *file_manager, unique_ptr<EncryptedFile> &&file,
tl_object_ptr<secret_api::decryptedMessageMediaPhoto> &&photo, DialogId owner_dialog_id);
Photo get_web_document_photo(FileManager *file_manager, tl_object_ptr<telegram_api::WebDocument> web_document,
DialogId owner_dialog_id);

View File

@ -1238,11 +1238,6 @@ Status SecretChatActor::do_inbound_message_decrypted(unique_ptr<log_event::Inbou
auto qts_promise = std::move(message->promise);
// process message
tl_object_ptr<telegram_api::encryptedFile> file;
if (message->has_encrypted_file) {
file = message->file.as_encrypted_file();
}
if (message->decrypted_message_layer->message_->get_id() == secret_api::decryptedMessage46::ID) {
auto old = move_tl_object_as<secret_api::decryptedMessage46>(message->decrypted_message_layer->message_);
old->flags_ &= ~secret_api::decryptedMessage::GROUPED_ID_MASK; // just in case
@ -1266,7 +1261,8 @@ Status SecretChatActor::do_inbound_message_decrypted(unique_ptr<log_event::Inbou
auto decrypted_message =
move_tl_object_as<secret_api::decryptedMessage>(message->decrypted_message_layer->message_);
context_->on_inbound_message(get_user_id(), MessageId(ServerMessageId(message->message_id)), message->date,
std::move(file), std::move(decrypted_message), std::move(save_message_finish));
std::move(message->file), std::move(decrypted_message),
std::move(save_message_finish));
} else if (message->decrypted_message_layer->message_->get_id() == secret_api::decryptedMessageService::ID) {
auto decrypted_message_service =
move_tl_object_as<secret_api::decryptedMessageService>(message->decrypted_message_layer->message_);
@ -1618,31 +1614,24 @@ void SecretChatActor::on_outbound_send_message_result(NetQueryPtr query, Promise
}
case telegram_api::messages_sentEncryptedFile::ID: {
auto sent = move_tl_object_as<telegram_api::messages_sentEncryptedFile>(result);
std::function<telegram_api::object_ptr<telegram_api::EncryptedFile>()> get_file;
telegram_api::downcast_call(
*sent->file_, overloaded(
[&](telegram_api::encryptedFileEmpty &) {
state->message->file = log_event::EncryptedInputFile::from_input_encrypted_file(
telegram_api::inputEncryptedFileEmpty());
get_file = [] {
return telegram_api::make_object<telegram_api::encryptedFileEmpty>();
};
},
[&](telegram_api::encryptedFile &file) {
state->message->file = log_event::EncryptedInputFile::from_input_encrypted_file(
telegram_api::inputEncryptedFile(file.id_, file.access_hash_));
get_file = [id = file.id_, access_hash = file.access_hash_, size = file.size_,
dc_id = file.dc_id_, key_fingerprint = file.key_fingerprint_] {
return telegram_api::make_object<telegram_api::encryptedFile>(id, access_hash, size,
dc_id, key_fingerprint);
};
}));
state->send_result_ = [this, random_id = state->message->random_id,
message_id = MessageId(ServerMessageId(state->message->message_id)), date = sent->date_,
get_file = std::move(get_file)](Promise<> promise) {
this->context_->on_send_message_ok(random_id, message_id, date, get_file(), std::move(promise));
};
auto file = EncryptedFile::get_encrypted_file(std::move(sent->file_));
if (file == nullptr) {
state->message->file = log_event::EncryptedInputFile::from_input_encrypted_file(nullptr);
state->send_result_ = [this, random_id = state->message->random_id,
message_id = MessageId(ServerMessageId(state->message->message_id)),
date = sent->date_](Promise<> promise) {
this->context_->on_send_message_ok(random_id, message_id, date, nullptr, std::move(promise));
};
} else {
state->message->file = log_event::EncryptedInputFile::from_input_encrypted_file(
make_tl_object<telegram_api::inputEncryptedFile>(file->id_, file->access_hash_));
state->send_result_ = [this, random_id = state->message->random_id,
message_id = MessageId(ServerMessageId(state->message->message_id)),
date = sent->date_, file = *file](Promise<> promise) {
this->context_->on_send_message_ok(random_id, message_id, date, make_unique<EncryptedFile>(file),
std::move(promise));
};
}
state->send_result_(std::move(send_message_finish_promise));
return;
}

View File

@ -7,6 +7,7 @@
#pragma once
#include "td/telegram/DhConfig.h"
#include "td/telegram/EncryptedFile.h"
#include "td/telegram/FolderId.h"
#include "td/telegram/logevent/SecretChatEvent.h"
#include "td/telegram/MessageId.h"
@ -84,8 +85,7 @@ class SecretChatActor final : public NetQueryCallback {
// this update through binlog too. So it wouldn't be deleted before update is saved.
// inbound messages
virtual void on_inbound_message(UserId user_id, MessageId message_id, int32 date,
tl_object_ptr<telegram_api::encryptedFile> file,
virtual void on_inbound_message(UserId user_id, MessageId message_id, int32 date, unique_ptr<EncryptedFile> file,
tl_object_ptr<secret_api::decryptedMessage> message, Promise<> promise) = 0;
virtual void on_delete_messages(std::vector<int64> random_id, Promise<> promise) = 0;
virtual void on_flush_history(bool remove_from_dialog_list, MessageId message_id, Promise<> promise) = 0;
@ -97,8 +97,8 @@ class SecretChatActor final : public NetQueryCallback {
// outbound messages
virtual void on_send_message_ack(int64 random_id) = 0;
virtual void on_send_message_ok(int64 random_id, MessageId message_id, int32 date,
tl_object_ptr<telegram_api::EncryptedFile> file, Promise<> promise) = 0;
virtual void on_send_message_ok(int64 random_id, MessageId message_id, int32 date, unique_ptr<EncryptedFile> file,
Promise<> promise) = 0;
virtual void on_send_message_error(int64 random_id, Status error, Promise<> promise) = 0;
};

View File

@ -9,6 +9,7 @@
#include "td/telegram/ConfigShared.h"
#include "td/telegram/ContactsManager.h"
#include "td/telegram/DhCache.h"
#include "td/telegram/EncryptedFile.h"
#include "td/telegram/FolderId.h"
#include "td/telegram/Global.h"
#include "td/telegram/logevent/SecretChatEvent.h"
@ -198,17 +199,7 @@ void SecretChatsManager::on_new_message(tl_object_ptr<telegram_api::EncryptedMes
});
if (message_ptr->get_id() == telegram_api::encryptedMessage::ID) {
auto message = move_tl_object_as<telegram_api::encryptedMessage>(message_ptr);
if (message->file_->get_id() == telegram_api::encryptedFile::ID) {
auto file = move_tl_object_as<telegram_api::encryptedFile>(message->file_);
event->file.id = file->id_;
event->file.access_hash = file->access_hash_;
event->file.size = file->size_;
event->file.dc_id = file->dc_id_;
event->file.key_fingerprint = file->key_fingerprint_;
event->has_encrypted_file = true;
}
event->file = EncryptedFile::get_encrypted_file(std::move(message->file_));
}
add_inbound_message(std::move(event));
}
@ -350,8 +341,7 @@ unique_ptr<SecretChatActor::Context> SecretChatsManager::make_secret_chat_contex
user_id, state, is_outbound, ttl, date, key_hash, layer, initial_folder_id);
}
void on_inbound_message(UserId user_id, MessageId message_id, int32 date,
tl_object_ptr<telegram_api::encryptedFile> file,
void on_inbound_message(UserId user_id, MessageId message_id, int32 date, unique_ptr<EncryptedFile> file,
tl_object_ptr<secret_api::decryptedMessage> message, Promise<> promise) final {
send_closure_later(G()->messages_manager(), &MessagesManager::on_get_secret_message, secret_chat_id_, user_id,
message_id, date, std::move(file), std::move(message), std::move(promise));
@ -365,8 +355,8 @@ unique_ptr<SecretChatActor::Context> SecretChatsManager::make_secret_chat_contex
void on_send_message_ack(int64 random_id) final {
send_closure_later(G()->messages_manager(), &MessagesManager::on_send_message_get_quick_ack, random_id);
}
void on_send_message_ok(int64 random_id, MessageId message_id, int32 date,
tl_object_ptr<telegram_api::EncryptedFile> file, Promise<> promise) final {
void on_send_message_ok(int64 random_id, MessageId message_id, int32 date, unique_ptr<EncryptedFile> file,
Promise<> promise) final {
send_closure_later(G()->messages_manager(), &MessagesManager::on_send_secret_message_success, random_id,
message_id, date, std::move(file), std::move(promise));
}

View File

@ -6,6 +6,7 @@
//
#pragma once
#include "td/telegram/EncryptedFile.h"
#include "td/telegram/Global.h"
#include "td/telegram/logevent/LogEvent.h"
#include "td/telegram/secret_api.h"
@ -218,53 +219,6 @@ inline StringBuilder &operator<<(StringBuilder &sb, const EncryptedInputFile &fi
return sb << to_string(file.as_input_encrypted_file());
}
// encryptedFile#4a70994c id:long access_hash:long size:int dc_id:int key_fingerprint:int = EncryptedFile;
struct EncryptedFileLocation {
static constexpr int32 MAGIC = 0x473d738a;
int64 id = 0;
int64 access_hash = 0;
int32 size = 0;
int32 dc_id = 0;
int32 key_fingerprint = 0;
tl_object_ptr<telegram_api::encryptedFile> as_encrypted_file() {
return make_tl_object<telegram_api::encryptedFile>(id, access_hash, size, dc_id, key_fingerprint);
}
template <class StorerT>
void store(StorerT &storer) const {
using td::store;
store(MAGIC, storer);
store(id, storer);
store(access_hash, storer);
store(size, storer);
store(dc_id, storer);
store(key_fingerprint, storer);
}
template <class ParserT>
void parse(ParserT &parser) {
using td::parse;
int32 got_magic;
parse(got_magic, parser);
parse(id, parser);
parse(access_hash, parser);
parse(size, parser);
parse(dc_id, parser);
parse(key_fingerprint, parser);
if (got_magic != MAGIC) {
parser.set_error("EncryptedFileLocation magic mismatch");
return;
}
}
};
inline StringBuilder &operator<<(StringBuilder &sb, const EncryptedFileLocation &file) {
return sb << "[" << tag("id", file.id) << tag("access_hash", file.access_hash) << tag("size", file.size)
<< tag("dc_id", file.dc_id) << tag("key_fingerprint", file.key_fingerprint) << "]";
}
// LogEvents
// TODO: Qts and SeqNoState could be just Logevents that are updated during regenerate
class InboundSecretMessage final : public SecretChatLogEventBase<InboundSecretMessage> {
@ -291,15 +245,15 @@ class InboundSecretMessage final : public SecretChatLogEventBase<InboundSecretMe
return decrypted_message_layer->layer_;
}
EncryptedFileLocation file;
unique_ptr<EncryptedFile> file;
bool has_encrypted_file = false;
bool is_pending = false;
template <class StorerT>
void store(StorerT &storer) const {
using td::store;
bool has_encrypted_file = file != nullptr;
BEGIN_STORE_FLAGS();
STORE_FLAG(has_encrypted_file);
STORE_FLAG(is_pending);
@ -328,6 +282,7 @@ class InboundSecretMessage final : public SecretChatLogEventBase<InboundSecretMe
void parse(ParserT &parser) {
using td::parse;
bool has_encrypted_file;
bool no_qts;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(has_encrypted_file);
@ -364,7 +319,7 @@ class InboundSecretMessage final : public SecretChatLogEventBase<InboundSecretMe
<< tag("date", date) << tag("auth_key_id", format::as_hex(auth_key_id)) << tag("message_id", message_id)
<< tag("my_in_seq_no", my_in_seq_no) << tag("my_out_seq_no", my_out_seq_no)
<< tag("his_in_seq_no", his_in_seq_no) << tag("message", to_string(decrypted_message_layer))
<< tag("is_pending", is_pending) << format::cond(has_encrypted_file, tag("file", file)) << "]";
<< tag("is_pending", is_pending) << format::cond(file != nullptr, tag("file", *file)) << "]";
}
};

View File

@ -4,6 +4,7 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include "td/telegram/EncryptedFile.h"
#include "td/telegram/FolderId.h"
#include "td/telegram/Global.h"
#include "td/telegram/MessageId.h"
@ -535,14 +536,13 @@ class FakeSecretChatContext final : public SecretChatActor::Context {
int32 date, string key_hash, int32 layer, FolderId initial_folder_id) final {
}
void on_inbound_message(UserId user_id, MessageId message_id, int32 date,
tl_object_ptr<telegram_api::encryptedFile> file,
void on_inbound_message(UserId user_id, MessageId message_id, int32 date, unique_ptr<EncryptedFile> file,
tl_object_ptr<secret_api::decryptedMessage> message, Promise<>) final;
void on_send_message_error(int64 random_id, Status error, Promise<>) final;
void on_send_message_ack(int64 random_id) final;
void on_send_message_ok(int64 random_id, MessageId message_id, int32 date,
tl_object_ptr<telegram_api::EncryptedFile> file, Promise<>) final;
void on_send_message_ok(int64 random_id, MessageId message_id, int32 date, unique_ptr<EncryptedFile> file,
Promise<>) final;
void on_delete_messages(std::vector<int64> random_id, Promise<>) final;
void on_flush_history(bool, MessageId, Promise<>) final;
void on_read_message(int64, Promise<>) final;
@ -974,7 +974,7 @@ void FakeSecretChatContext::send_net_query(NetQueryPtr query, ActorShared<NetQue
send_closure(master_, &Master::send_net_query, std::move(query), std::move(callback), ordered);
}
void FakeSecretChatContext::on_inbound_message(UserId user_id, MessageId message_id, int32 date,
tl_object_ptr<telegram_api::encryptedFile> file,
unique_ptr<EncryptedFile> file,
tl_object_ptr<secret_api::decryptedMessage> message, Promise<> promise) {
send_closure(master_, &Master::on_inbound_message, message->message_, std::move(promise));
}
@ -984,7 +984,7 @@ void FakeSecretChatContext::on_send_message_error(int64 random_id, Status error,
void FakeSecretChatContext::on_send_message_ack(int64 random_id) {
}
void FakeSecretChatContext::on_send_message_ok(int64 random_id, MessageId message_id, int32 date,
tl_object_ptr<telegram_api::EncryptedFile> file, Promise<> promise) {
unique_ptr<EncryptedFile> file, Promise<> promise) {
send_closure(master_, &Master::on_send_message_ok, random_id, std::move(promise));
}
void FakeSecretChatContext::on_delete_messages(std::vector<int64> random_id, Promise<> promise) {