Add send_copy parameter to forwardMessages.

GitOrigin-RevId: 059f992cc8b9c6ae1c6ab3910ffc52b906d12e88
This commit is contained in:
levlam 2019-08-09 17:41:26 +03:00
parent 1685d77455
commit c71dbc28a0
8 changed files with 124 additions and 58 deletions

View File

@ -3102,7 +3102,9 @@ sendInlineQueryResultMessage chat_id:int53 reply_to_message_id:int53 disable_not
//@chat_id Identifier of the chat to which to forward messages @from_chat_id Identifier of the chat from which to forward messages @message_ids Identifiers of the messages to forward
//@disable_notification Pass true to disable notification for the message, doesn't work if messages are forwarded to a secret chat @from_background Pass true if the messages are sent from the background
//@as_album True, if the messages should be grouped into an album after forwarding. For this to work, no more than 10 messages may be forwarded, and all of them must be photo or video messages
forwardMessages chat_id:int53 from_chat_id:int53 message_ids:vector<int53> disable_notification:Bool from_background:Bool as_album:Bool = Messages;
//@send_copy True, if content of the messages needs to be copied without links to the original messages. Always true if the messages are forwarded to a secret chat
//@remove_caption True, if media captions of message copies needs to be removed. Ignored if send_copy is false
forwardMessages chat_id:int53 from_chat_id:int53 message_ids:vector<int53> disable_notification:Bool from_background:Bool as_album:Bool send_copy:Bool remove_caption:Bool = Messages;
//@description Changes the current TTL setting (sets a new self-destruct timer) in a secret chat and sends the corresponding message @chat_id Chat identifier @ttl New TTL value, in seconds
sendChatSetTtlMessage chat_id:int53 ttl:int32 = Message;

Binary file not shown.

View File

@ -2898,7 +2898,7 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo
}
new_photo->photos.push_back(old_photo->photos.back());
FileId old_file_id = get_message_content_file_id(old_content);
FileId old_file_id = get_message_content_upload_file_id(old_content);
FileView old_file_view = td->file_manager_->get_file_view(old_file_id);
FileId new_file_id = new_photo->photos[0].file_id;
FileView new_file_view = td->file_manager_->get_file_view(new_file_id);
@ -3903,7 +3903,7 @@ unique_ptr<MessageContent> get_message_content(Td *td, FormattedText message,
}
unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const MessageContent *content,
bool for_forward) {
bool for_forward, bool remove_caption) {
CHECK(content != nullptr);
bool to_secret = dialog_id.get_type() == DialogType::SecretChat;
@ -3926,6 +3926,9 @@ unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const
switch (content->get_type()) {
case MessageContentType::Animation: {
auto result = make_unique<MessageAnimation>(*static_cast<const MessageAnimation *>(content));
if (remove_caption) {
result->caption = FormattedText();
}
if (td->documents_manager_->has_input_media(result->file_id, thumbnail_file_id, to_secret)) {
return std::move(result);
}
@ -3935,6 +3938,9 @@ unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const
}
case MessageContentType::Audio: {
auto result = make_unique<MessageAudio>(*static_cast<const MessageAudio *>(content));
if (remove_caption) {
result->caption = FormattedText();
}
if (td->documents_manager_->has_input_media(result->file_id, thumbnail_file_id, to_secret)) {
return std::move(result);
}
@ -3946,6 +3952,9 @@ unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const
return make_unique<MessageContact>(*static_cast<const MessageContact *>(content));
case MessageContentType::Document: {
auto result = make_unique<MessageDocument>(*static_cast<const MessageDocument *>(content));
if (remove_caption) {
result->caption = FormattedText();
}
if (td->documents_manager_->has_input_media(result->file_id, thumbnail_file_id, to_secret)) {
return std::move(result);
}
@ -3967,6 +3976,9 @@ unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const
return make_unique<MessageLocation>(*static_cast<const MessageLocation *>(content));
case MessageContentType::Photo: {
auto result = make_unique<MessagePhoto>(*static_cast<const MessagePhoto *>(content));
if (remove_caption) {
result->caption = FormattedText();
}
if (result->photo.photos.size() > 2 && !to_secret) {
// already sent photo
@ -4037,6 +4049,9 @@ unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const
return make_unique<MessageVenue>(*static_cast<const MessageVenue *>(content));
case MessageContentType::Video: {
auto result = make_unique<MessageVideo>(*static_cast<const MessageVideo *>(content));
if (remove_caption) {
result->caption = FormattedText();
}
if (td->documents_manager_->has_input_media(result->file_id, thumbnail_file_id, to_secret)) {
return std::move(result);
}
@ -4056,6 +4071,9 @@ unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const
}
case MessageContentType::VoiceNote: {
auto result = make_unique<MessageVoiceNote>(*static_cast<const MessageVoiceNote *>(content));
if (remove_caption) {
result->caption = FormattedText();
}
result->is_listened = false;
if (td->documents_manager_->has_input_media(result->file_id, thumbnail_file_id, to_secret)) {
return std::move(result);
@ -4526,7 +4544,7 @@ int32 get_message_content_duration(const MessageContent *content, const Td *td)
}
}
FileId get_message_content_file_id(const MessageContent *content) {
FileId get_message_content_upload_file_id(const MessageContent *content) {
switch (content->get_type()) {
case MessageContentType::Animation:
return static_cast<const MessageAnimation *>(content)->file_id;
@ -4555,6 +4573,17 @@ FileId get_message_content_file_id(const MessageContent *content) {
return FileId();
}
FileId get_message_content_any_file_id(const MessageContent *content) {
FileId result = get_message_content_upload_file_id(content);
if (!result.is_valid() && content->get_type() == MessageContentType::Photo) {
const auto &sizes = static_cast<const MessagePhoto *>(content)->photo.photos;
if (!sizes.empty()) {
result = sizes.back().file_id;
}
}
return result;
}
void update_message_content_file_id_remote(MessageContent *content, FileId file_id) {
if (file_id.get_remote() == 0) {
return;
@ -4629,7 +4658,7 @@ vector<FileId> get_message_content_file_ids(const MessageContent *content, const
case MessageContentType::VoiceNote: {
vector<FileId> result;
result.reserve(2);
FileId file_id = get_message_content_file_id(content);
FileId file_id = get_message_content_upload_file_id(content);
if (file_id.is_valid()) {
result.push_back(file_id);
}
@ -4945,9 +4974,9 @@ void add_message_content_dependencies(Dependencies &dependencies, const MessageC
void on_sent_message_content(Td *td, const MessageContent *content) {
switch (content->get_type()) {
case MessageContentType::Animation:
return td->animations_manager_->add_saved_animation_by_id(get_message_content_file_id(content));
return td->animations_manager_->add_saved_animation_by_id(get_message_content_any_file_id(content));
case MessageContentType::Sticker:
return td->stickers_manager_->add_recent_sticker_by_id(false, get_message_content_file_id(content));
return td->stickers_manager_->add_recent_sticker_by_id(false, get_message_content_any_file_id(content));
default:
// nothing to do
return;

View File

@ -211,7 +211,7 @@ unique_ptr<MessageContent> get_message_content(Td *td, FormattedText message_tex
int32 *ttl);
unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const MessageContent *content,
bool for_forward);
bool for_forward, bool remove_caption = false);
unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<telegram_api::MessageAction> &&action,
DialogId owner_dialog_id, MessageId reply_to_message_id);
@ -225,7 +225,9 @@ const FormattedText *get_message_content_caption(const MessageContent *content);
int32 get_message_content_duration(const MessageContent *content, const Td *td);
FileId get_message_content_file_id(const MessageContent *content);
FileId get_message_content_upload_file_id(const MessageContent *content);
FileId get_message_content_any_file_id(const MessageContent *content);
void update_message_content_file_id_remote(MessageContent *content, FileId file_id);

View File

@ -9387,7 +9387,7 @@ void MessagesManager::on_send_secret_message_error(int64 random_id, Status error
auto full_message_id = it->second;
auto *m = get_message(full_message_id);
if (m != nullptr) {
auto file_id = get_message_content_file_id(m->content.get());
auto file_id = get_message_content_upload_file_id(m->content.get());
if (file_id.is_valid()) {
if (G()->close_flag() && G()->parameters().use_message_db) {
// do not send error, message will be re-sent
@ -15986,7 +15986,7 @@ vector<FileId> MessagesManager::get_message_file_ids(const Message *m) const {
}
void MessagesManager::cancel_upload_message_content_files(const MessageContent *content) {
auto file_id = get_message_content_file_id(content);
auto file_id = get_message_content_upload_file_id(content);
// always cancel file upload, it should be a no-op in the worst case
if (being_uploaded_files_.erase(file_id) || file_id.is_valid()) {
cancel_upload_file(file_id);
@ -16377,7 +16377,7 @@ void MessagesManager::do_send_message(DialogId dialog_id, Message *m, vector<int
return;
}
FileId file_id = get_message_content_file_id(content);
FileId file_id = get_message_content_any_file_id(content); // any_file_id, because it could be a photo sent by ID
FileView file_view = td_->file_manager_->get_file_view(file_id);
FileId thumbnail_file_id = get_message_content_thumbnail_file_id(content, td_);
LOG(DEBUG) << "Need to send file " << file_id << " with thumbnail " << thumbnail_file_id;
@ -16701,7 +16701,7 @@ void MessagesManager::do_send_message_group(int64 media_album_id) {
reply_to_message_id = m->reply_to_message_id;
flags = get_message_flags(m);
file_ids.push_back(get_message_content_file_id(m->content.get()));
file_ids.push_back(get_message_content_any_file_id(m->content.get()));
random_ids.push_back(begin_send_message(dialog_id, m));
LOG(INFO) << "Have file " << file_ids.back() << " in " << m->message_id << " with result " << request.results[i]
@ -16716,7 +16716,7 @@ void MessagesManager::do_send_message_group(int64 media_album_id) {
auto input_media = get_input_media(m->content.get(), td_, m->ttl, true);
if (input_media == nullptr) {
// TODO return CHECK
auto file_id = get_message_content_file_id(m->content.get());
auto file_id = get_message_content_any_file_id(m->content.get());
auto file_view = td_->file_manager_->get_file_view(file_id);
bool has_remote = file_view.has_remote_location();
bool is_web = has_remote ? file_view.remote_location().is_web() : false;
@ -18316,7 +18316,7 @@ Result<MessageId> MessagesManager::forward_message(DialogId to_dialog_id, Dialog
bool disable_notification, bool from_background,
bool in_game_share) {
TRY_RESULT(result, forward_messages(to_dialog_id, from_dialog_id, {message_id}, disable_notification, from_background,
in_game_share, false));
in_game_share, false, false, false));
CHECK(result.size() == 1);
auto sent_message_id = result[0];
if (sent_message_id == MessageId()) {
@ -18327,7 +18327,8 @@ Result<MessageId> MessagesManager::forward_message(DialogId to_dialog_id, Dialog
Result<vector<MessageId>> MessagesManager::forward_messages(DialogId to_dialog_id, DialogId from_dialog_id,
vector<MessageId> message_ids, bool disable_notification,
bool from_background, bool in_game_share, bool as_album) {
bool from_background, bool in_game_share, bool as_album,
bool send_copy, bool remove_caption) {
if (message_ids.size() > 100) { // TODO replace with const from config or implement mass-forward
return Status::Error(4, "Too much messages to forward");
}
@ -18359,20 +18360,19 @@ Result<vector<MessageId>> MessagesManager::forward_messages(DialogId to_dialog_i
}
}
int64 media_album_id = 0;
if (as_album && message_ids.size() > 1 && message_ids.size() <= MAX_GROUPED_MESSAGES) {
do {
media_album_id = Random::secure_int64();
} while (media_album_id >= 0 || pending_message_group_sends_.count(media_album_id) != 0);
}
bool to_secret = to_dialog_id.get_type() == DialogType::SecretChat;
vector<MessageId> result(message_ids.size());
vector<Message *> forwarded_messages;
vector<MessageId> forwarded_message_ids;
vector<unique_ptr<MessageContent>> unforwarded_message_contents(message_ids.size());
vector<bool> unforwarded_message_disable_web_page_previews(message_ids.size());
struct CopiedMessage {
unique_ptr<MessageContent> content;
bool disable_web_page_preview;
size_t index;
};
vector<CopiedMessage> copied_messages;
auto my_id = td_->contacts_manager_->get_my_id();
bool need_update_dialog_pos = false;
for (size_t i = 0; i < message_ids.size(); i++) {
@ -18389,32 +18389,26 @@ Result<vector<MessageId>> MessagesManager::forward_messages(DialogId to_dialog_i
continue;
}
unique_ptr<MessageContent> content = dup_message_content(td_, to_dialog_id, forwarded_message->content.get(), true);
bool need_copy = !message_id.is_server() || to_secret || send_copy;
unique_ptr<MessageContent> content =
dup_message_content(td_, to_dialog_id, forwarded_message->content.get(), true, need_copy && remove_caption);
if (content == nullptr) {
LOG(INFO) << "Can't forward " << message_id;
continue;
}
auto can_send_status = can_send_message_content(to_dialog_id, content.get(), true);
auto can_send_status = can_send_message_content(to_dialog_id, content.get(), !need_copy);
if (can_send_status.is_error()) {
LOG(INFO) << "Can't forward " << message_id << ": " << can_send_status.message();
continue;
}
if (!message_id.is_server() || to_secret) {
unforwarded_message_contents[i] = std::move(content);
unforwarded_message_disable_web_page_previews[i] = forwarded_message->disable_web_page_preview;
if (need_copy) {
copied_messages.push_back({std::move(content), forwarded_message->disable_web_page_preview, i});
continue;
}
auto content_type = content->get_type();
if (media_album_id != 0 && !is_allowed_media_group_content(content_type)) {
media_album_id = 0;
for (auto m : forwarded_messages) {
m->media_album_id = 0;
}
}
bool is_game = content_type == MessageContentType::Game;
unique_ptr<MessageForwardInfo> forward_info;
if (!is_game && content_type != MessageContentType::Audio) {
@ -18457,7 +18451,6 @@ Result<vector<MessageId>> MessagesManager::forward_messages(DialogId to_dialog_i
&need_update_dialog_pos, std::move(forward_info));
m->debug_forward_from = from_dialog_id;
m->via_bot_user_id = forwarded_message->via_bot_user_id;
m->media_album_id = media_album_id;
m->in_game_share = in_game_share;
if (forwarded_message->views > 0 && m->forward_info != nullptr) {
m->views = forwarded_message->views;
@ -18507,26 +18500,64 @@ Result<vector<MessageId>> MessagesManager::forward_messages(DialogId to_dialog_i
result[i] = m->message_id;
forwarded_messages.push_back(m);
forwarded_message_ids.push_back(message_id);
send_update_new_message(to_dialog, m);
}
if (!forwarded_messages.empty()) {
if (as_album && forwarded_messages.size() > 1 && forwarded_messages.size() <= MAX_GROUPED_MESSAGES) {
bool allow_album = true;
for (auto m : forwarded_messages) {
if (!is_allowed_media_group_content(m->content->get_type())) {
allow_album = false;
break;
}
}
if (allow_album) {
int64 media_album_id = 0;
do {
media_album_id = Random::secure_int64();
} while (media_album_id >= 0 || pending_message_group_sends_.count(media_album_id) != 0);
for (auto m : forwarded_messages) {
m->media_album_id = media_album_id;
}
}
}
for (auto m : forwarded_messages) {
send_update_new_message(to_dialog, m);
}
do_forward_messages(to_dialog_id, from_dialog_id, forwarded_messages, forwarded_message_ids, 0);
}
for (size_t i = 0; i < unforwarded_message_contents.size(); i++) {
if (unforwarded_message_contents[i] != nullptr) {
Message *m = get_message_to_send(to_dialog, MessageId(), disable_notification, from_background,
std::move(unforwarded_message_contents[i]), &need_update_dialog_pos);
m->disable_web_page_preview = unforwarded_message_disable_web_page_previews[i];
if (to_secret) {
m->media_album_id = media_album_id;
if (!copied_messages.empty()) {
int64 media_album_id = 0;
if (as_album && copied_messages.size() > 1 && copied_messages.size() <= MAX_GROUPED_MESSAGES) {
bool allow_album = true;
for (auto &copied_message : copied_messages) {
if (!is_allowed_media_group_content(copied_message.content->get_type())) {
allow_album = false;
break;
}
}
if (allow_album) {
do {
media_album_id = Random::secure_int64();
} while (media_album_id >= 0 || pending_message_group_sends_.count(media_album_id) != 0);
}
}
for (auto &copied_message : copied_messages) {
Message *m = get_message_to_send(to_dialog, MessageId(), disable_notification, from_background,
std::move(copied_message.content), &need_update_dialog_pos);
m->disable_web_page_preview = copied_message.disable_web_page_preview;
m->media_album_id = media_album_id;
save_send_message_logevent(to_dialog_id, m);
do_send_message(to_dialog_id, m);
result[i] = m->message_id;
result[copied_message.index] = m->message_id;
send_update_new_message(to_dialog, m);
}
@ -21592,7 +21623,7 @@ void MessagesManager::on_send_dialog_action_timeout(DialogId dialog_id) {
return;
}
auto file_id = get_message_content_file_id(m->content.get());
auto file_id = get_message_content_upload_file_id(m->content.get());
if (!file_id.is_valid()) {
LOG(ERROR) << "Have no file in "
<< to_string(get_message_content_object(m->content.get(), td_, m->date, m->is_content_secret));
@ -24176,7 +24207,7 @@ bool MessagesManager::update_message_content(DialogId dialog_id, Message *old_me
MessageContentType old_content_type = old_content->get_type();
MessageContentType new_content_type = new_content->get_type();
auto old_file_id = get_message_content_file_id(old_content.get());
auto old_file_id = get_message_content_any_file_id(old_content.get());
bool need_finish_upload = old_file_id.is_valid() && need_merge_files;
if (old_content_type != new_content_type) {
need_update = true;
@ -24185,7 +24216,7 @@ bool MessagesManager::update_message_content(DialogId dialog_id, Message *old_me
old_message->is_content_secret = is_secret_message_content(old_message->ttl, new_content->get_type());
if (need_merge_files && old_file_id.is_valid()) {
auto new_file_id = get_message_content_file_id(new_content.get());
auto new_file_id = get_message_content_any_file_id(new_content.get());
if (new_file_id.is_valid()) {
FileView old_file_view = td_->file_manager_->get_file_view(old_file_id);
FileView new_file_view = td_->file_manager_->get_file_view(new_file_id);
@ -24242,7 +24273,7 @@ bool MessagesManager::update_message_content(DialogId dialog_id, Message *old_me
}
update_message_content_file_id_remote(old_content.get(), old_file_id);
} else {
update_message_content_file_id_remote(old_content.get(), get_message_content_file_id(new_content.get()));
update_message_content_file_id_remote(old_content.get(), get_message_content_any_file_id(new_content.get()));
}
if (is_content_changed && !need_update) {
LOG(INFO) << "Content of " << old_message->message_id << " in " << dialog_id << " has changed";

View File

@ -348,8 +348,8 @@ class MessagesManager : public Actor {
Result<vector<MessageId>> forward_messages(DialogId to_dialog_id, DialogId from_dialog_id,
vector<MessageId> message_ids, bool disable_notification,
bool from_background, bool in_game_share,
bool as_album) TD_WARN_UNUSED_RESULT;
bool from_background, bool in_game_share, bool as_album, bool send_copy,
bool remove_caption) TD_WARN_UNUSED_RESULT;
Result<MessageId> send_dialog_set_ttl_message(DialogId dialog_id, int32 ttl);

View File

@ -5821,7 +5821,8 @@ void Td::on_request(uint64 id, const td_api::forwardMessages &request) {
DialogId dialog_id(request.chat_id_);
auto r_message_ids = messages_manager_->forward_messages(
dialog_id, DialogId(request.from_chat_id_), MessagesManager::get_message_ids(request.message_ids_),
request.disable_notification_, request.from_background_, false, request.as_album_);
request.disable_notification_, request.from_background_, false, request.as_album_, request.send_copy_,
request.remove_caption_);
if (r_message_ids.is_error()) {
return send_closure(actor_id(this), &Td::send_error, id, r_message_ids.move_as_error());
}

View File

@ -2454,7 +2454,7 @@ class CliClient final : public Actor {
send_request(td_api::make_object<td_api::deleteMessages>(as_chat_id(chat_id), as_message_ids(message_ids, ','),
as_bool(revoke)));
} else if (op == "fm" || op == "fmg") {
} else if (op == "fm" || op == "fmg" || op == "cm" || op == "cmg") {
string chat_id;
string from_chat_id;
string message_ids;
@ -2462,8 +2462,9 @@ class CliClient final : public Actor {
std::tie(from_chat_id, message_ids) = split(args);
auto chat = as_chat_id(chat_id);
send_request(td_api::make_object<td_api::forwardMessages>(
chat, as_chat_id(from_chat_id), as_message_ids(message_ids), false, false, op == "fmg"));
send_request(td_api::make_object<td_api::forwardMessages>(chat, as_chat_id(from_chat_id),
as_message_ids(message_ids), false, false, op[2] == 'g',
op[0] == 'c', static_cast<bool>(Random::fast(0, 1))));
} else if (op == "csc" || op == "CreateSecretChat") {
send_request(td_api::make_object<td_api::createSecretChat>(as_secret_chat_id(args)));
} else if (op == "cnsc" || op == "CreateNewSecretChat") {