diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index a7a6147be..9092f2f39 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3717,12 +3717,11 @@ sendBotStartMessage bot_user_id:int32 chat_id:int53 parameter:string = Message; sendInlineQueryResultMessage chat_id:int53 reply_to_message_id:int53 options:messageSendOptions query_id:int64 result_id:string hide_via_bot:Bool = Message; //@description Forwards previously sent messages. Returns the forwarded messages in the same order as the message identifiers passed in message_ids. If a message can't be forwarded, null will be returned instead of the message -//@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 +//@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. Message identifiers must be in a strictly increasing order //@options Options to be used to send the messages -//@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 //@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 caption of message copies needs to be removed. Ignored if send_copy is false -forwardMessages chat_id:int53 from_chat_id:int53 message_ids:vector options:messageSendOptions as_album:Bool send_copy:Bool remove_caption:Bool = Messages; +forwardMessages chat_id:int53 from_chat_id:int53 message_ids:vector options:messageSendOptions send_copy:Bool remove_caption:Bool = Messages; //@description Resends messages which failed to send. Can be called only for messages for which messageSendingStateFailed.can_retry is true and after specified in messageSendingStateFailed.retry_after time passed. //-If a message is re-sent, the corresponding failed to send message is deleted. Returns the sent messages in the same order as the message identifiers passed in message_ids. If a message can't be re-sent, null will be returned instead of the message diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 72a96bc83..200fafae9 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 b877c1450..b23955e94 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -3022,7 +3022,7 @@ class ForwardMessagesActor : public NetActorOnce { } auto query = G()->net_query_creator().create(telegram_api::messages_forwardMessages( - flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, std::move(from_input_peer), + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, std::move(from_input_peer), MessagesManager::get_server_message_ids(message_ids), std::move(random_ids), std::move(to_input_peer), schedule_date)); if (G()->shared_config().get_option_boolean("use_quick_ack")) { @@ -23434,9 +23434,6 @@ void MessagesManager::do_forward_messages(DialogId to_dialog_id, DialogId from_d if (messages[0]->from_background) { flags |= SEND_MESSAGE_FLAG_FROM_BACKGROUND; } - if (messages[0]->media_album_id != 0) { - flags |= SEND_MESSAGE_FLAG_GROUP_MEDIA; - } if (messages[0]->in_game_share) { flags |= SEND_MESSAGE_FLAG_WITH_MY_SCORE; } @@ -23457,7 +23454,7 @@ Result MessagesManager::forward_message(DialogId to_dialog_id, Dialog vector all_copy_options; all_copy_options.push_back(std::move(copy_options)); TRY_RESULT(result, forward_messages(to_dialog_id, from_dialog_id, {message_id}, std::move(options), in_game_share, - false, std::move(all_copy_options))); + std::move(all_copy_options))); CHECK(result.size() == 1); auto sent_message_id = result[0]; if (sent_message_id == MessageId()) { @@ -23469,7 +23466,7 @@ Result MessagesManager::forward_message(DialogId to_dialog_id, Dialog Result> MessagesManager::forward_messages(DialogId to_dialog_id, DialogId from_dialog_id, vector message_ids, tl_object_ptr &&options, - bool in_game_share, bool as_album, + bool in_game_share, vector &©_options) { CHECK(copy_options.size() == message_ids.size()); if (message_ids.size() > 100) { // TODO replace with const from config or implement mass-forward @@ -23498,14 +23495,21 @@ Result> MessagesManager::forward_messages(DialogId to_dialog_i TRY_STATUS(can_send_message(to_dialog_id)); TRY_RESULT(message_send_options, process_message_send_options(to_dialog_id, std::move(options))); - for (auto message_id : message_ids) { - if (message_id.is_valid_scheduled()) { - return Status::Error(5, "Can't forward scheduled messages"); + { + MessageId last_message_id; + for (auto message_id : message_ids) { + if (message_id.is_valid_scheduled()) { + return Status::Error(5, "Can't forward scheduled messages"); + } + if (message_id.is_scheduled() || !message_id.is_valid()) { + return Status::Error(5, "Invalid message identifier"); + } + + if (message_id <= last_message_id) { + return Status::Error(400, "Message identifiers must be in a strictly increasing order"); + } + last_message_id = message_id; } - if (!message_id.is_valid()) { - return Status::Error(5, "Invalid message identifier"); - } - CHECK(!message_id.is_scheduled()); } bool to_secret = to_dialog_id.get_type() == DialogType::SecretChat; @@ -23517,11 +23521,14 @@ Result> MessagesManager::forward_messages(DialogId to_dialog_i struct CopiedMessage { unique_ptr content; unique_ptr reply_markup; + int64 media_album_id; bool disable_web_page_preview; size_t index; }; vector copied_messages; + std::unordered_map> new_media_album_ids; + 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++) { @@ -23562,9 +23569,22 @@ Result> MessagesManager::forward_messages(DialogId to_dialog_i continue; } + if (forwarded_message->media_album_id != 0) { + auto &new_media_album_id = new_media_album_ids[forwarded_message->media_album_id]; + new_media_album_id.second++; + if (new_media_album_id.second == 2) { // have at least 2 messages in the new album + CHECK(new_media_album_id.first == 0); + new_media_album_id.first = generate_new_media_album_id(); + } + if (new_media_album_id.second == MAX_GROUPED_MESSAGES + 1) { + CHECK(new_media_album_id.first != 0); + new_media_album_id.first = 0; // just in case + } + } + if (need_copy) { - copied_messages.push_back( - {std::move(content), std::move(reply_markup), get_message_disable_web_page_preview(forwarded_message), i}); + copied_messages.push_back({std::move(content), std::move(reply_markup), forwarded_message->media_album_id, + get_message_disable_web_page_preview(forwarded_message), i}); continue; } @@ -23613,6 +23633,7 @@ Result> MessagesManager::forward_messages(DialogId to_dialog_i m->real_forward_from_message_id = message_id; m->via_bot_user_id = forwarded_message->via_bot_user_id; m->in_game_share = in_game_share; + m->media_album_id = forwarded_message->media_album_id; if (forwarded_message->view_count > 0 && is_broadcast_channel(from_dialog_id)) { forwarded_message->forward_count++; send_update_message_interaction_info(from_dialog_id, forwarded_message); @@ -23671,24 +23692,11 @@ Result> MessagesManager::forward_messages(DialogId to_dialog_i } 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 = generate_new_media_album_id(); - for (auto m : forwarded_messages) { - m->media_album_id = media_album_id; - } - } - } - for (auto m : forwarded_messages) { + if (m->media_album_id != 0) { + m->media_album_id = new_media_album_ids[m->media_album_id].first; + } + send_update_new_message(to_dialog, m); } @@ -23696,26 +23704,13 @@ Result> MessagesManager::forward_messages(DialogId to_dialog_i } 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) { - media_album_id = generate_new_media_album_id(); - } - } - for (auto &copied_message : copied_messages) { Message *m = get_message_to_send(to_dialog, MessageId(), message_send_options, std::move(copied_message.content), &need_update_dialog_pos, nullptr, true); m->disable_web_page_preview = copied_message.disable_web_page_preview; - m->media_album_id = media_album_id; + if (copied_message.media_album_id != 0) { + m->media_album_id = new_media_album_ids[copied_message.media_album_id].first; + } m->reply_markup = std::move(copied_message.reply_markup); save_send_message_logevent(to_dialog_id, m); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 2a2ebf9d2..59a8a2452 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -402,7 +402,6 @@ class MessagesManager : public Actor { Result> forward_messages(DialogId to_dialog_id, DialogId from_dialog_id, vector message_ids, tl_object_ptr &&options, bool in_game_share, - bool as_album, vector &©_options) TD_WARN_UNUSED_RESULT; Result> resend_messages(DialogId dialog_id, vector message_ids) TD_WARN_UNUSED_RESULT; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 22aa960a0..1b2c6501e 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5773,9 +5773,9 @@ void Td::on_request(uint64 id, td_api::forwardMessages &request) { auto message_copy_options = transform(input_message_ids, [send_copy = request.send_copy_, remove_caption = request.remove_caption_]( MessageId) { return MessageCopyOptions(send_copy, remove_caption); }); - auto r_message_ids = messages_manager_->forward_messages(dialog_id, DialogId(request.from_chat_id_), - std::move(input_message_ids), std::move(request.options_), - false, request.as_album_, std::move(message_copy_options)); + auto r_message_ids = + messages_manager_->forward_messages(dialog_id, DialogId(request.from_chat_id_), std::move(input_message_ids), + std::move(request.options_), false, std::move(message_copy_options)); if (r_message_ids.is_error()) { return send_closure(actor_id(this), &Td::send_error, id, r_message_ids.move_as_error()); } diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index d299187c8..22b10679f 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2726,7 +2726,7 @@ class CliClient final : public Actor { send_request(td_api::make_object(as_chat_id(chat_id), as_message_ids(message_ids), as_bool(revoke))); - } else if (op == "fm" || op == "fmg" || op == "cm" || op == "cmg") { + } else if (op == "fm" || op == "cm") { string chat_id; string from_chat_id; string message_ids; @@ -2735,8 +2735,8 @@ class CliClient final : public Actor { auto chat = as_chat_id(chat_id); send_request(td_api::make_object( - chat, as_chat_id(from_chat_id), as_message_ids(message_ids), default_message_send_options(), op[2] == 'g', - op[0] == 'c', Random::fast(0, 1) == 1)); + chat, as_chat_id(from_chat_id), as_message_ids(message_ids), default_message_send_options(), op[0] == 'c', + Random::fast(0, 1) == 1)); } else if (op == "resend") { string chat_id; string message_ids;