Add td_api::resendMessages.
GitOrigin-RevId: 41c14a76aaf05745592328909e47efd5feca2437
This commit is contained in:
parent
ee3921f959
commit
378b1df843
@ -3110,6 +3110,11 @@ sendInlineQueryResultMessage chat_id:int53 reply_to_message_id:int53 disable_not
|
||||
//@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 Resends failed to send messages. Can be called only for failed to send 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
|
||||
//@chat_id Identifier of the chat to send messages @message_ids Identifiers of the messages to resend. Message identifiers must be in a strictly increasing order
|
||||
resendMessages chat_id:int53 message_ids:vector<int53> = 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.
@ -15552,7 +15552,7 @@ tl_object_ptr<td_api::message> MessagesManager::get_message_object(DialogId dial
|
||||
tl_object_ptr<td_api::MessageSendingState> sending_state;
|
||||
if (m->is_failed_to_send) {
|
||||
sending_state = make_tl_object<td_api::messageSendingStateFailed>(
|
||||
m->send_error_code, m->send_error_message, m->send_error_code == 429, max(m->try_resend_at - Time::now(), 0.0));
|
||||
m->send_error_code, m->send_error_message, can_resend_message(m), max(m->try_resend_at - Time::now(), 0.0));
|
||||
} else if (m->message_id.is_yet_unsent()) {
|
||||
sending_state = make_tl_object<td_api::messageSendingStatePending>();
|
||||
}
|
||||
@ -16253,15 +16253,15 @@ Result<MessageId> MessagesManager::send_message(DialogId dialog_id, MessageId re
|
||||
update_dialog_draft_message(d, nullptr, false, !need_update_dialog_pos);
|
||||
}
|
||||
|
||||
save_send_message_logevent(dialog_id, m);
|
||||
do_send_message(dialog_id, m);
|
||||
|
||||
send_update_new_message(d, m);
|
||||
if (need_update_dialog_pos) {
|
||||
send_update_chat_last_message(d, "send_message");
|
||||
}
|
||||
|
||||
auto message_id = m->message_id;
|
||||
save_send_message_logevent(dialog_id, m);
|
||||
do_send_message(dialog_id, m);
|
||||
return message_id;
|
||||
return m->message_id;
|
||||
}
|
||||
|
||||
Result<InputMessageContent> MessagesManager::process_input_message_content(
|
||||
@ -16338,7 +16338,7 @@ Result<vector<MessageId>> MessagesManager::send_message_group(
|
||||
return Status::Error(4, "Too much messages to send as an album");
|
||||
}
|
||||
if (input_message_contents.empty()) {
|
||||
return Status::Error(4, "There is no messages to send");
|
||||
return Status::Error(4, "There are no messages to send");
|
||||
}
|
||||
|
||||
Dialog *d = get_dialog_force(dialog_id);
|
||||
@ -16394,7 +16394,7 @@ Result<vector<MessageId>> MessagesManager::send_message_group(
|
||||
return result;
|
||||
}
|
||||
|
||||
void MessagesManager::save_send_message_logevent(DialogId dialog_id, Message *m) {
|
||||
void MessagesManager::save_send_message_logevent(DialogId dialog_id, const Message *m) {
|
||||
if (!G()->parameters().use_message_db) {
|
||||
return;
|
||||
}
|
||||
@ -16407,7 +16407,7 @@ void MessagesManager::save_send_message_logevent(DialogId dialog_id, Message *m)
|
||||
m->send_message_logevent_id = binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::SendMessage, storer);
|
||||
}
|
||||
|
||||
void MessagesManager::do_send_message(DialogId dialog_id, Message *m, vector<int> bad_parts) {
|
||||
void MessagesManager::do_send_message(DialogId dialog_id, const Message *m, vector<int> bad_parts) {
|
||||
bool is_edit = m->message_id.is_server();
|
||||
LOG(INFO) << "Do " << (is_edit ? "edit" : "send") << ' ' << FullMessageId(dialog_id, m->message_id);
|
||||
bool is_secret = dialog_id.get_type() == DialogType::SecretChat;
|
||||
@ -16484,7 +16484,7 @@ void MessagesManager::do_send_message(DialogId dialog_id, Message *m, vector<int
|
||||
}
|
||||
}
|
||||
|
||||
void MessagesManager::on_message_media_uploaded(DialogId dialog_id, Message *m,
|
||||
void MessagesManager::on_message_media_uploaded(DialogId dialog_id, const Message *m,
|
||||
tl_object_ptr<telegram_api::InputMedia> &&input_media, FileId file_id,
|
||||
FileId thumbnail_file_id) {
|
||||
CHECK(m != nullptr);
|
||||
@ -16563,7 +16563,7 @@ void MessagesManager::on_message_media_uploaded(DialogId dialog_id, Message *m,
|
||||
}
|
||||
}
|
||||
|
||||
void MessagesManager::on_secret_message_media_uploaded(DialogId dialog_id, Message *m,
|
||||
void MessagesManager::on_secret_message_media_uploaded(DialogId dialog_id, const Message *m,
|
||||
SecretInputMedia &&secret_input_media, FileId file_id,
|
||||
FileId thumbnail_file_id) {
|
||||
CHECK(m != nullptr);
|
||||
@ -17016,7 +17016,7 @@ class MessagesManager::SendBotStartMessageLogEvent {
|
||||
};
|
||||
|
||||
void MessagesManager::save_send_bot_start_message_logevent(UserId bot_user_id, DialogId dialog_id,
|
||||
const string ¶meter, Message *m) {
|
||||
const string ¶meter, const Message *m) {
|
||||
if (!G()->parameters().use_message_db) {
|
||||
return;
|
||||
}
|
||||
@ -17035,7 +17035,7 @@ void MessagesManager::save_send_bot_start_message_logevent(UserId bot_user_id, D
|
||||
}
|
||||
|
||||
void MessagesManager::do_send_bot_start_message(UserId bot_user_id, DialogId dialog_id, const string ¶meter,
|
||||
Message *m) {
|
||||
const Message *m) {
|
||||
LOG(INFO) << "Do send bot start " << FullMessageId(dialog_id, m->message_id) << " to bot " << bot_user_id;
|
||||
|
||||
int64 random_id = begin_send_message(dialog_id, m);
|
||||
@ -17118,9 +17118,8 @@ Result<MessageId> MessagesManager::send_inline_query_result_message(DialogId dia
|
||||
|
||||
if (to_secret) {
|
||||
save_send_message_logevent(dialog_id, m);
|
||||
auto message_id = m->message_id;
|
||||
do_send_message(dialog_id, m);
|
||||
return message_id;
|
||||
return m->message_id;
|
||||
}
|
||||
|
||||
save_send_inline_query_result_message_logevent(dialog_id, m, query_id, result_id);
|
||||
@ -17155,8 +17154,8 @@ class MessagesManager::SendInlineQueryResultMessageLogEvent {
|
||||
}
|
||||
};
|
||||
|
||||
void MessagesManager::save_send_inline_query_result_message_logevent(DialogId dialog_id, Message *m, int64 query_id,
|
||||
const string &result_id) {
|
||||
void MessagesManager::save_send_inline_query_result_message_logevent(DialogId dialog_id, const Message *m,
|
||||
int64 query_id, const string &result_id) {
|
||||
if (!G()->parameters().use_message_db) {
|
||||
return;
|
||||
}
|
||||
@ -17174,7 +17173,7 @@ void MessagesManager::save_send_inline_query_result_message_logevent(DialogId di
|
||||
binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::SendInlineQueryResultMessage, storer);
|
||||
}
|
||||
|
||||
void MessagesManager::do_send_inline_query_result_message(DialogId dialog_id, Message *m, int64 query_id,
|
||||
void MessagesManager::do_send_inline_query_result_message(DialogId dialog_id, const Message *m, int64 query_id,
|
||||
const string &result_id) {
|
||||
LOG(INFO) << "Do send inline query result " << FullMessageId(dialog_id, m->message_id);
|
||||
|
||||
@ -17337,6 +17336,33 @@ bool MessagesManager::can_edit_message(DialogId dialog_id, const Message *m, boo
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MessagesManager::can_resend_message(const Message *m) {
|
||||
if (m->send_error_code != 429) {
|
||||
return false;
|
||||
}
|
||||
if (m->is_bot_start_message) {
|
||||
return false;
|
||||
}
|
||||
if (m->forward_info != nullptr || m->real_forward_from_dialog_id.is_valid()) {
|
||||
// TODO implement resending of forwarded messages
|
||||
return false;
|
||||
}
|
||||
if (m->via_bot_user_id.is_valid() || m->hide_via_bot) {
|
||||
// via bot message
|
||||
if (!get_message_content_game_bot_user_id(m->content.get()).is_valid()) {
|
||||
// TODO implement resending via_bot messages other than games
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto content_type = m->content->get_type();
|
||||
if (content_type == MessageContentType::ChatSetTtl || content_type == MessageContentType::ScreenshotTaken) {
|
||||
// TODO implement resending of ChatSetTtl and ScreenshotTaken messages
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MessagesManager::is_broadcast_channel(DialogId dialog_id) const {
|
||||
if (dialog_id.get_type() != DialogType::Channel) {
|
||||
return false;
|
||||
@ -18407,7 +18433,7 @@ Result<vector<MessageId>> MessagesManager::forward_messages(DialogId to_dialog_i
|
||||
return Status::Error(4, "Too much messages to forward");
|
||||
}
|
||||
if (message_ids.empty()) {
|
||||
return Status::Error(4, "There is no messages to forward");
|
||||
return Status::Error(4, "There are no messages to forward");
|
||||
}
|
||||
|
||||
Dialog *from_dialog = get_dialog_force(from_dialog_id);
|
||||
@ -18480,7 +18506,7 @@ Result<vector<MessageId>> MessagesManager::forward_messages(DialogId to_dialog_i
|
||||
auto content_type = content->get_type();
|
||||
bool is_game = content_type == MessageContentType::Game;
|
||||
if (need_copy) {
|
||||
if (is_game) {
|
||||
if (is_game && !get_message_content_game_bot_user_id(content.get()).is_valid()) {
|
||||
LOG(INFO) << "Can't copy game from " << message_id;
|
||||
continue;
|
||||
}
|
||||
@ -18642,6 +18668,118 @@ Result<vector<MessageId>> MessagesManager::forward_messages(DialogId to_dialog_i
|
||||
return result;
|
||||
}
|
||||
|
||||
Result<vector<MessageId>> MessagesManager::resend_messages(DialogId dialog_id, vector<MessageId> message_ids) {
|
||||
if (message_ids.empty()) {
|
||||
return Status::Error(4, "There are no messages to resend");
|
||||
}
|
||||
|
||||
Dialog *d = get_dialog_force(dialog_id);
|
||||
if (d == nullptr) {
|
||||
return Status::Error(400, "Chat not found");
|
||||
}
|
||||
|
||||
TRY_STATUS(can_send_message(dialog_id));
|
||||
|
||||
MessageId last_message_id;
|
||||
for (auto &message_id : message_ids) {
|
||||
message_id = get_persistent_message_id(d, message_id);
|
||||
const Message *m = get_message_force(d, message_id, "resend_messages");
|
||||
if (m == nullptr) {
|
||||
return Status::Error(400, "Message not found");
|
||||
}
|
||||
if (!m->is_failed_to_send) {
|
||||
return Status::Error(400, "Message is not failed to send");
|
||||
}
|
||||
if (!can_resend_message(m)) {
|
||||
return Status::Error(400, "Message can't be re-sent");
|
||||
}
|
||||
if (m->try_resend_at < Time::now()) {
|
||||
return Status::Error(400, "Message can't be re-sent yet");
|
||||
}
|
||||
if (m->message_id.get() <= last_message_id.get()) {
|
||||
return Status::Error(400, "Message identifiers must be in a strictly increasing order");
|
||||
}
|
||||
last_message_id = message_id;
|
||||
}
|
||||
|
||||
vector<unique_ptr<MessageContent>> new_contents(message_ids.size());
|
||||
std::unordered_map<int64, std::pair<int64, int32>> new_media_album_ids;
|
||||
for (size_t i = 0; i < message_ids.size(); i++) {
|
||||
MessageId message_id = message_ids[i];
|
||||
const Message *m = get_message(d, message_id);
|
||||
CHECK(m != nullptr);
|
||||
|
||||
unique_ptr<MessageContent> content = dup_message_content(td_, dialog_id, m->content.get(), false);
|
||||
if (content == nullptr) {
|
||||
LOG(INFO) << "Can't resend " << message_id;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto can_send_status = can_send_message_content(dialog_id, content.get(), false);
|
||||
if (can_send_status.is_error()) {
|
||||
LOG(INFO) << "Can't resend " << message_id << ": " << can_send_status.message();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!get_message_content_game_bot_user_id(content.get()).is_valid()) {
|
||||
// must not happen
|
||||
LOG(ERROR) << "Can't resend game from " << message_id;
|
||||
continue;
|
||||
}
|
||||
|
||||
new_contents[i] = std::move(content);
|
||||
|
||||
if (m->media_album_id != 0) {
|
||||
auto &new_media_album_id = new_media_album_ids[m->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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vector<MessageId> result(message_ids.size());
|
||||
bool need_update_dialog_pos = false;
|
||||
for (size_t i = 0; i < message_ids.size(); i++) {
|
||||
if (new_contents[i] == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
unique_ptr<Message> message = delete_message(d, message_ids[i], true, &need_update_dialog_pos, "resend_messages");
|
||||
CHECK(message != nullptr);
|
||||
send_update_delete_messages(dialog_id, {message->message_id.get()}, true, false);
|
||||
|
||||
Message *m =
|
||||
get_message_to_send(d, get_reply_to_message_id(d, message->reply_to_message_id), message->disable_notification,
|
||||
message->from_background, std::move(new_contents[i]), &need_update_dialog_pos);
|
||||
m->reply_markup = std::move(message->reply_markup);
|
||||
m->via_bot_user_id = message->via_bot_user_id;
|
||||
m->disable_web_page_preview = message->disable_web_page_preview;
|
||||
m->clear_draft = false; // never clear draft in resend
|
||||
m->ttl = message->ttl;
|
||||
m->is_content_secret = message->is_content_secret;
|
||||
m->media_album_id = new_media_album_ids[message->media_album_id].first;
|
||||
|
||||
save_send_message_logevent(dialog_id, m);
|
||||
do_send_message(dialog_id, m);
|
||||
|
||||
send_update_new_message(d, m);
|
||||
|
||||
result[i] = m->message_id;
|
||||
}
|
||||
|
||||
if (need_update_dialog_pos) {
|
||||
send_update_chat_last_message(d, "resend_messages");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Result<MessageId> MessagesManager::send_dialog_set_ttl_message(DialogId dialog_id, int32 ttl) {
|
||||
if (dialog_id.get_type() != DialogType::SecretChat) {
|
||||
return Status::Error(5, "Can't set chat ttl in non-secret chat");
|
||||
|
@ -351,6 +351,8 @@ class MessagesManager : public Actor {
|
||||
bool from_background, bool in_game_share, bool as_album, bool send_copy,
|
||||
bool remove_caption) TD_WARN_UNUSED_RESULT;
|
||||
|
||||
Result<vector<MessageId>> resend_messages(DialogId dialog_id, vector<MessageId> message_ids) TD_WARN_UNUSED_RESULT;
|
||||
|
||||
Result<MessageId> send_dialog_set_ttl_message(DialogId dialog_id, int32 ttl);
|
||||
|
||||
Status send_screenshot_taken_notification_message(DialogId dialog_id);
|
||||
@ -918,9 +920,9 @@ class MessagesManager : public Actor {
|
||||
|
||||
mutable int32 last_access_date = 0;
|
||||
|
||||
uint64 send_message_logevent_id = 0;
|
||||
mutable uint64 send_message_logevent_id = 0;
|
||||
|
||||
NetQueryRef send_query_ref;
|
||||
mutable NetQueryRef send_query_ref;
|
||||
|
||||
template <class StorerT>
|
||||
void store(StorerT &storer) const;
|
||||
@ -1355,6 +1357,8 @@ class MessagesManager : public Actor {
|
||||
Status can_send_message_content(DialogId dialog_id, const MessageContent *content,
|
||||
bool is_forward) const TD_WARN_UNUSED_RESULT;
|
||||
|
||||
static bool can_resend_message(const Message *m);
|
||||
|
||||
bool can_edit_message(DialogId dialog_id, const Message *m, bool is_editing, bool only_reply_markup = false) const;
|
||||
|
||||
bool can_report_dialog(DialogId dialog_id) const;
|
||||
@ -1400,12 +1404,13 @@ class MessagesManager : public Actor {
|
||||
tl_object_ptr<telegram_api::InputEncryptedFile> input_encrypted_file,
|
||||
BufferSlice thumbnail);
|
||||
|
||||
void do_send_message(DialogId dialog_id, Message *m, vector<int> bad_parts = {});
|
||||
void do_send_message(DialogId dialog_id, const Message *m, vector<int> bad_parts = {});
|
||||
|
||||
void on_message_media_uploaded(DialogId dialog_id, Message *m, tl_object_ptr<telegram_api::InputMedia> &&input_media,
|
||||
FileId file_id, FileId thumbnail_file_id);
|
||||
void on_message_media_uploaded(DialogId dialog_id, const Message *m,
|
||||
tl_object_ptr<telegram_api::InputMedia> &&input_media, FileId file_id,
|
||||
FileId thumbnail_file_id);
|
||||
|
||||
void on_secret_message_media_uploaded(DialogId dialog_id, Message *m, SecretInputMedia &&secret_input_media,
|
||||
void on_secret_message_media_uploaded(DialogId dialog_id, const Message *m, SecretInputMedia &&secret_input_media,
|
||||
FileId file_id, FileId thumbnail_file_id);
|
||||
|
||||
void on_upload_message_media_finished(int64 media_album_id, DialogId dialog_id, MessageId message_id, Status result);
|
||||
@ -1417,14 +1422,15 @@ class MessagesManager : public Actor {
|
||||
void on_yet_unsent_media_queue_updated(DialogId dialog_id);
|
||||
|
||||
void save_send_bot_start_message_logevent(UserId bot_user_id, DialogId dialog_id, const string ¶meter,
|
||||
Message *m);
|
||||
const Message *m);
|
||||
|
||||
void do_send_bot_start_message(UserId bot_user_id, DialogId dialog_id, const string ¶meter, Message *m);
|
||||
void do_send_bot_start_message(UserId bot_user_id, DialogId dialog_id, const string ¶meter, const Message *m);
|
||||
|
||||
void save_send_inline_query_result_message_logevent(DialogId dialog_id, Message *m, int64 query_id,
|
||||
void save_send_inline_query_result_message_logevent(DialogId dialog_id, const Message *m, int64 query_id,
|
||||
const string &result_id);
|
||||
|
||||
void do_send_inline_query_result_message(DialogId dialog_id, Message *m, int64 query_id, const string &result_id);
|
||||
void do_send_inline_query_result_message(DialogId dialog_id, const Message *m, int64 query_id,
|
||||
const string &result_id);
|
||||
|
||||
uint64 save_send_screenshot_taken_notification_message_logevent(DialogId dialog_id, const Message *m);
|
||||
|
||||
@ -2128,7 +2134,7 @@ class MessagesManager : public Actor {
|
||||
|
||||
static void add_message_dependencies(Dependencies &dependencies, DialogId dialog_id, const Message *m);
|
||||
|
||||
void save_send_message_logevent(DialogId dialog_id, Message *m);
|
||||
void save_send_message_logevent(DialogId dialog_id, const Message *m);
|
||||
|
||||
uint64 save_change_dialog_report_spam_state_on_server_logevent(DialogId dialog_id, bool is_spam_dialog);
|
||||
|
||||
|
@ -5831,6 +5831,18 @@ void Td::on_request(uint64 id, const td_api::forwardMessages &request) {
|
||||
messages_manager_->get_messages_object(-1, dialog_id, r_message_ids.ok()));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::resendMessages &request) {
|
||||
DialogId dialog_id(request.chat_id_);
|
||||
auto r_message_ids =
|
||||
messages_manager_->resend_messages(dialog_id, MessagesManager::get_message_ids(request.message_ids_));
|
||||
if (r_message_ids.is_error()) {
|
||||
return send_closure(actor_id(this), &Td::send_error, id, r_message_ids.move_as_error());
|
||||
}
|
||||
|
||||
send_closure(actor_id(this), &Td::send_result, id,
|
||||
messages_manager_->get_messages_object(-1, dialog_id, r_message_ids.ok()));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::getWebPagePreview &request) {
|
||||
CHECK_IS_USER();
|
||||
CREATE_REQUEST(GetWebPagePreviewRequest, std::move(request.text_));
|
||||
|
@ -612,6 +612,8 @@ class Td final : public NetQueryCallback {
|
||||
|
||||
void on_request(uint64 id, const td_api::forwardMessages &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::resendMessages &request);
|
||||
|
||||
void on_request(uint64 id, td_api::getWebPagePreview &request);
|
||||
|
||||
void on_request(uint64 id, td_api::getWebPageInstantView &request);
|
||||
|
Reference in New Issue
Block a user