diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 2f465473..123b6dfe 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -2750,8 +2750,8 @@ getGroupsInCommon user_id:int32 offset_chat_id:int53 limit:int32 = Chats; //@only_local If true, returns only messages that are available locally without sending network requests getChatHistory chat_id:int53 from_message_id:int53 offset:int32 limit:int32 only_local:Bool = Messages; -//@description Deletes all messages in the chat only for the user. Cannot be used in channels and public supergroups @chat_id Chat identifier @remove_from_chat_list Pass true if the chat should be removed from the chat list -deleteChatHistory chat_id:int53 remove_from_chat_list:Bool = Ok; +//@description Deletes all messages in the chat. Cannot be used in channels and public supergroups @chat_id Chat identifier @remove_from_chat_list Pass true if the chat should be removed from the chat list @revoke Pass true to try to delete chat history for all chat members. Always true for secret chats, ignored for basic groups and supergroups +deleteChatHistory chat_id:int53 remove_from_chat_list:Bool revoke:Bool = Ok; //@description Searches for messages with given words in the chat. Returns the results in reverse chronological order, i.e. in order of decreasing message_id. Cannot be used in secret chats with a non-empty query //-(searchSecretMessages should be used instead), or without an enabled message database. For optimal performance the number of returned messages is chosen by the library @@ -2848,7 +2848,7 @@ sendChatScreenshotTakenNotification chat_id:int53 = Ok; //@reply_to_message_id Identifier of the message to reply to or 0 @disable_notification Pass true to disable notification for the message @input_message_content The content of the message to be added addLocalMessage chat_id:int53 sender_user_id:int32 reply_to_message_id:int53 disable_notification:Bool input_message_content:InputMessageContent = Message; -//@description Deletes messages @chat_id Chat identifier @message_ids Identifiers of the messages to be deleted @revoke Pass true to try to delete outgoing messages for all chat members (may fail if messages are too old). Always true for supergroups, channels and secret chats +//@description Deletes messages @chat_id Chat identifier @message_ids Identifiers of the messages to be deleted @revoke Pass true to try to delete messages for all chat members. Always true for supergroups, channels and secret chats deleteMessages chat_id:int53 message_ids:vector revoke:Bool = Ok; //@description Deletes all messages sent by the specified user to a chat. Supported only in supergroups; requires can_delete_messages administrator privileges @chat_id Chat identifier @user_id User identifier diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index a95a7392..34d26c80 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/generate/scheme/telegram_api.tl b/td/generate/scheme/telegram_api.tl index 61159571..078a86c8 100644 --- a/td/generate/scheme/telegram_api.tl +++ b/td/generate/scheme/telegram_api.tl @@ -1083,7 +1083,7 @@ messages.getDialogs#b098aee6 flags:# exclude_pinned:flags.0?true offset_date:int messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages; messages.search#8614ef68 flags:# peer:InputPeer q:string from_id:flags.0?InputUser filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages; messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages; -messages.deleteHistory#1c015b09 flags:# just_clear:flags.0?true peer:InputPeer max_id:int = messages.AffectedHistory; +messages.deleteHistory#1c015b09 flags:# just_clear:flags.0?true revoke:flags.1?true peer:InputPeer max_id:int = messages.AffectedHistory; messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector = messages.AffectedMessages; messages.receivedMessages#5a954c0 max_id:int = Vector; messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool; diff --git a/td/generate/scheme/telegram_api.tlo b/td/generate/scheme/telegram_api.tlo index c5668b63..df7ab647 100644 Binary files a/td/generate/scheme/telegram_api.tlo and b/td/generate/scheme/telegram_api.tlo differ diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 1948463a..83cec210 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -1471,6 +1471,7 @@ class DeleteHistoryQuery : public Td::ResultHandler { DialogId dialog_id_; MessageId max_message_id_; bool remove_from_dialog_list_; + bool revoke_; void send_request() { auto input_peer = td->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); @@ -1482,20 +1483,25 @@ class DeleteHistoryQuery : public Td::ResultHandler { if (!remove_from_dialog_list_) { flags |= telegram_api::messages_deleteHistory::JUST_CLEAR_MASK; } + if (revoke_) { + flags |= telegram_api::messages_deleteHistory::REVOKE_MASK; + } LOG(INFO) << "Delete " << dialog_id_ << " history up to " << max_message_id_ << " with flags " << flags; - send_query(G()->net_query_creator().create(create_storer(telegram_api::messages_deleteHistory( - flags, false /*ignored*/, std::move(input_peer), max_message_id_.get_server_message_id().get())))); + send_query(G()->net_query_creator().create(create_storer( + telegram_api::messages_deleteHistory(flags, false /*ignored*/, false /*ignored*/, std::move(input_peer), + max_message_id_.get_server_message_id().get())))); } public: explicit DeleteHistoryQuery(Promise &&promise) : promise_(std::move(promise)) { } - void send(DialogId dialog_id, MessageId max_message_id, bool remove_from_dialog_list) { + void send(DialogId dialog_id, MessageId max_message_id, bool remove_from_dialog_list, bool revoke) { dialog_id_ = dialog_id; max_message_id_ = max_message_id; remove_from_dialog_list_ = remove_from_dialog_list; + revoke_ = revoke; send_request(); } @@ -7557,9 +7563,10 @@ void MessagesManager::delete_messages_from_server(DialogId dialog_id, vector &&promise) { +void MessagesManager::delete_dialog_history(DialogId dialog_id, bool remove_from_dialog_list, bool revoke, + Promise &&promise) { LOG(INFO) << "Receive deleteChatHistory request to delete all messages in " << dialog_id - << ", remove_from_chat_list is " << remove_from_dialog_list; + << ", remove_from_chat_list is " << remove_from_dialog_list << ", revoke is " << revoke; Dialog *d = get_dialog_force(dialog_id); if (d == nullptr) { @@ -7604,7 +7611,7 @@ void MessagesManager::delete_dialog_history(DialogId dialog_id, bool remove_from delete_all_dialog_messages(d, remove_from_dialog_list, true); - if (last_new_message_id.is_valid() && last_new_message_id == d->max_unavailable_message_id) { + if (last_new_message_id.is_valid() && last_new_message_id == d->max_unavailable_message_id && !revoke) { // history has already been cleared, nothing to do promise.set_value(Unit()); return; @@ -7612,7 +7619,7 @@ void MessagesManager::delete_dialog_history(DialogId dialog_id, bool remove_from set_dialog_max_unavailable_message_id(dialog_id, last_new_message_id, false, "delete_dialog_history"); - delete_dialog_history_from_server(dialog_id, last_new_message_id, remove_from_dialog_list, allow_error, 0, + delete_dialog_history_from_server(dialog_id, last_new_message_id, remove_from_dialog_list, revoke, allow_error, 0, std::move(promise)); } @@ -7621,11 +7628,13 @@ class MessagesManager::DeleteDialogHistoryFromServerLogEvent { DialogId dialog_id_; MessageId max_message_id_; bool remove_from_dialog_list_; + bool revoke_; template void store(StorerT &storer) const { BEGIN_STORE_FLAGS(); STORE_FLAG(remove_from_dialog_list_); + STORE_FLAG(revoke_); END_STORE_FLAGS(); td::store(dialog_id_, storer); @@ -7636,6 +7645,7 @@ class MessagesManager::DeleteDialogHistoryFromServerLogEvent { void parse(ParserT &parser) { BEGIN_PARSE_FLAGS(); PARSE_FLAG(remove_from_dialog_list_); + PARSE_FLAG(revoke_); END_PARSE_FLAGS(); td::parse(dialog_id_, parser); @@ -7644,19 +7654,20 @@ class MessagesManager::DeleteDialogHistoryFromServerLogEvent { }; uint64 MessagesManager::save_delete_dialog_history_from_server_logevent(DialogId dialog_id, MessageId max_message_id, - bool remove_from_dialog_list) { - DeleteDialogHistoryFromServerLogEvent logevent{dialog_id, max_message_id, remove_from_dialog_list}; + bool remove_from_dialog_list, bool revoke) { + DeleteDialogHistoryFromServerLogEvent logevent{dialog_id, max_message_id, remove_from_dialog_list, revoke}; auto storer = LogEventStorerImpl(logevent); return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::DeleteDialogHistoryFromServer, storer); } void MessagesManager::delete_dialog_history_from_server(DialogId dialog_id, MessageId max_message_id, - bool remove_from_dialog_list, bool allow_error, + bool remove_from_dialog_list, bool revoke, bool allow_error, uint64 logevent_id, Promise &&promise) { LOG(INFO) << "Delete history in " << dialog_id << " up to " << max_message_id << " from server"; if (logevent_id == 0 && G()->parameters().use_message_db) { - logevent_id = save_delete_dialog_history_from_server_logevent(dialog_id, max_message_id, remove_from_dialog_list); + logevent_id = + save_delete_dialog_history_from_server_logevent(dialog_id, max_message_id, remove_from_dialog_list, revoke); } auto new_promise = get_erase_logevent_promise(logevent_id, std::move(promise)); @@ -7666,7 +7677,7 @@ void MessagesManager::delete_dialog_history_from_server(DialogId dialog_id, Mess case DialogType::User: case DialogType::Chat: td_->create_handler(std::move(promise)) - ->send(dialog_id, max_message_id, remove_from_dialog_list); + ->send(dialog_id, max_message_id, remove_from_dialog_list, revoke); break; case DialogType::Channel: td_->create_handler(std::move(promise)) @@ -24862,7 +24873,7 @@ void MessagesManager::on_binlog_events(vector &&events) { } delete_dialog_history_from_server(dialog_id, log_event.max_message_id_, log_event.remove_from_dialog_list_, - true, event.id_, Auto()); + log_event.revoke_, true, event.id_, Auto()); break; } case LogEvent::HandlerType::DeleteAllChannelMessagesFromUserOnServer: { diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 0acbae2b..1579be13 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -317,7 +317,7 @@ class MessagesManager : public Actor { void delete_messages(DialogId dialog_id, const vector &message_ids, bool revoke, Promise &&promise); - void delete_dialog_history(DialogId dialog_id, bool remove_from_dialog_list, Promise &&promise); + void delete_dialog_history(DialogId dialog_id, bool remove_from_dialog_list, bool revoke, Promise &&promise); void delete_dialog_messages_from_user(DialogId dialog_id, UserId user_id, Promise &&promise); @@ -1415,7 +1415,7 @@ class MessagesManager : public Actor { Promise &&promise); void delete_dialog_history_from_server(DialogId dialog_id, MessageId max_message_id, bool remove_from_dialog_list, - bool allow_error, uint64 logevent_id, Promise &&promise); + bool revoke, bool allow_error, uint64 logevent_id, Promise &&promise); void delete_all_channel_messages_from_user_on_server(ChannelId channel_id, UserId user_id, uint64 logevent_id, Promise &&promise); @@ -2070,7 +2070,7 @@ class MessagesManager : public Actor { bool revoke); uint64 save_delete_dialog_history_from_server_logevent(DialogId dialog_id, MessageId max_message_id, - bool remove_from_dialog_list); + bool remove_from_dialog_list, bool revoke); uint64 save_delete_all_channel_messages_from_user_on_server_logevent(ChannelId channel_id, UserId user_id); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 416871cc..1eaf7caf 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5201,7 +5201,7 @@ void Td::on_request(uint64 id, const td_api::getChatHistory &request) { void Td::on_request(uint64 id, const td_api::deleteChatHistory &request) { CHECK_IS_USER(); CREATE_OK_REQUEST_PROMISE(); - messages_manager_->delete_dialog_history(DialogId(request.chat_id_), request.remove_from_chat_list_, + messages_manager_->delete_dialog_history(DialogId(request.chat_id_), request.remove_from_chat_list_, request.revoke_, std::move(promise)); } diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 855db778..fe3688f3 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3150,9 +3150,11 @@ class CliClient final : public Actor { } else if (op == "delete") { string chat_id; string remove_from_the_chat_list; - std::tie(chat_id, remove_from_the_chat_list) = split(args); - send_request( - td_api::make_object(as_chat_id(chat_id), as_bool(remove_from_the_chat_list))); + string revoke; + std::tie(chat_id, args) = split(args); + std::tie(remove_from_the_chat_list, revoke) = split(args); + send_request(td_api::make_object(as_chat_id(chat_id), + as_bool(remove_from_the_chat_list), as_bool(revoke))); } else if (op == "dmfu") { string chat_id; string user_id;