Allow to use deleteChatHistory to revoke messages for all members in some channels.

This commit is contained in:
levlam 2022-03-29 12:14:21 +03:00
parent 977ebca580
commit 759d02770d
4 changed files with 49 additions and 17 deletions

View File

@ -4465,7 +4465,7 @@ getMessageThreadHistory chat_id:int53 message_id:int53 from_message_id:int53 off
//@chat_id Chat identifier @remove_from_chat_list Pass true to remove the chat from all chat lists @revoke Pass true to delete chat history for all users
deleteChatHistory chat_id:int53 remove_from_chat_list:Bool revoke:Bool = Ok;
//@description Deletes a chat along with all messages in the corresponding chat for all chat members; requires owner privileges. For group chats this will release the username and remove all members. Chats with more than 1000 members can't be deleted using this method @chat_id Chat identifier
//@description Deletes a chat along with all messages in the corresponding chat for all chat members. For group chats this will release the username and remove all members. Use the field chat.can_be_deleted_for_all_users to find whether the method can be applied to the chat @chat_id Chat identifier
deleteChat chat_id:int53 = 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

View File

@ -4172,27 +4172,28 @@ void ContactsManager::ChannelFull::store(StorerT &storer) const {
STORE_FLAG(has_restricted_count);
STORE_FLAG(has_banned_count);
STORE_FLAG(legacy_has_invite_link);
STORE_FLAG(has_sticker_set);
STORE_FLAG(has_sticker_set); // 5
STORE_FLAG(has_linked_channel_id);
STORE_FLAG(has_migrated_from_max_message_id);
STORE_FLAG(has_migrated_from_chat_id);
STORE_FLAG(can_get_participants);
STORE_FLAG(can_set_username);
STORE_FLAG(can_set_username); // 10
STORE_FLAG(can_set_sticker_set);
STORE_FLAG(false); // legacy_can_view_statistics
STORE_FLAG(is_all_history_available);
STORE_FLAG(can_set_location);
STORE_FLAG(has_location);
STORE_FLAG(has_location); // 15
STORE_FLAG(has_bot_user_ids);
STORE_FLAG(is_slow_mode_enabled);
STORE_FLAG(is_slow_mode_delay_active);
STORE_FLAG(has_stats_dc_id);
STORE_FLAG(has_photo);
STORE_FLAG(has_photo); // 20
STORE_FLAG(is_can_view_statistics_inited);
STORE_FLAG(can_view_statistics);
STORE_FLAG(legacy_has_active_group_call_id);
STORE_FLAG(has_invite_link);
STORE_FLAG(has_bot_commands);
STORE_FLAG(has_bot_commands); // 25
STORE_FLAG(can_be_deleted);
END_STORE_FLAGS();
if (has_description) {
store(description, storer);
@ -6829,8 +6830,8 @@ void ContactsManager::delete_channel(ChannelId channel_id, Promise<Unit> &&promi
if (c == nullptr) {
return promise.set_error(Status::Error(400, "Chat info not found"));
}
if (!get_channel_status(c).is_creator()) {
return promise.set_error(Status::Error(400, "Not enough rights to delete the chat"));
if (!get_channel_can_be_deleted(channel_id)) {
return promise.set_error(Status::Error(400, "The chat can't be deleted"));
}
td_->create_handler<DeleteChannelQuery>(std::move(promise))->send(channel_id);
@ -11044,6 +11045,10 @@ void ContactsManager::on_get_chat_full(tl_object_ptr<telegram_api::ChatFull> &&c
}
on_update_channel_full_slow_mode_delay(channel_full, channel_id, slow_mode_delay, slow_mode_next_send_date);
}
if (channel_full->can_be_deleted != channel->can_delete_channel_) {
channel_full->can_be_deleted = channel->can_delete_channel_;
channel_full->need_save_to_database = true;
}
ChatId migrated_from_chat_id;
MessageId migrated_from_max_message_id;
@ -14731,6 +14736,17 @@ int32 ContactsManager::get_channel_slow_mode_delay(ChannelId channel_id) {
return channel_full->slow_mode_delay;
}
bool ContactsManager::get_channel_can_be_deleted(ChannelId channel_id) {
auto channel_full = get_channel_full_const(channel_id);
if (channel_full == nullptr) {
channel_full = get_channel_full_force(channel_id, false, "get_channel_can_be_deleted");
if (channel_full == nullptr) {
return get_channel_status(channel_id).is_creator();
}
}
return channel_full->can_be_deleted;
}
bool ContactsManager::have_channel(ChannelId channel_id) const {
return channels_.count(channel_id) > 0;
}

View File

@ -531,6 +531,7 @@ class ContactsManager final : public Actor {
bool get_channel_has_linked_channel(ChannelId channel_id) const;
ChannelId get_channel_linked_channel_id(ChannelId channel_id);
int32 get_channel_slow_mode_delay(ChannelId channel_id);
bool get_channel_can_be_deleted(ChannelId channel_id);
void add_dialog_participant(DialogId dialog_id, UserId user_id, int32 forward_limit, Promise<Unit> &&promise);
@ -902,6 +903,7 @@ class ContactsManager final : public Actor {
bool can_view_statistics = false;
bool is_can_view_statistics_inited = false;
bool is_all_history_available = true;
bool can_be_deleted = false;
bool is_slow_mode_next_send_date_changed = true;
bool is_changed = true; // have new changes that need to be sent to the client and database

View File

@ -2860,15 +2860,20 @@ class DeleteChannelHistoryQuery final : public Td::ResultHandler {
explicit DeleteChannelHistoryQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
}
void send(ChannelId channel_id, MessageId max_message_id, bool allow_error) {
void send(ChannelId channel_id, MessageId max_message_id, bool allow_error, bool revoke) {
channel_id_ = channel_id;
max_message_id_ = max_message_id;
allow_error_ = allow_error;
auto input_channel = td_->contacts_manager_->get_input_channel(channel_id);
CHECK(input_channel != nullptr);
int32 flags = 0;
if (revoke) {
flags |= telegram_api::channels_deleteHistory::FOR_EVERYONE_MASK;
}
send_query(G()->net_query_creator().create(telegram_api::channels_deleteHistory(
0, false /*ignored*/, std::move(input_channel), max_message_id.get_server_message_id().get())));
flags, false /*ignored*/, std::move(input_channel), max_message_id.get_server_message_id().get())));
}
void on_result(BufferSlice packet) final {
@ -11396,11 +11401,17 @@ void MessagesManager::delete_dialog_history(DialogId dialog_id, bool remove_from
// ok
break;
case DialogType::Channel:
if (is_broadcast_channel(dialog_id)) {
return promise.set_error(Status::Error(400, "Can't delete chat history in a channel"));
}
if (td_->contacts_manager_->is_channel_public(dialog_id.get_channel_id())) {
return promise.set_error(Status::Error(400, "Can't delete chat history in a public supergroup"));
if (revoke) {
if (!td_->contacts_manager_->get_channel_can_be_deleted(d->dialog_id.get_channel_id())) {
return promise.set_error(Status::Error(400, "Can't delete chat history for all chat members"));
}
} else {
if (is_broadcast_channel(dialog_id)) {
return promise.set_error(Status::Error(400, "Can't delete chat history in a channel"));
}
if (td_->contacts_manager_->is_channel_public(dialog_id.get_channel_id())) {
return promise.set_error(Status::Error(400, "Can't delete chat history in a public supergroup"));
}
}
break;
case DialogType::SecretChat:
@ -11498,7 +11509,7 @@ void MessagesManager::delete_dialog_history_on_server(DialogId dialog_id, Messag
}
case DialogType::Channel:
td_->create_handler<DeleteChannelHistoryQuery>(std::move(promise))
->send(dialog_id.get_channel_id(), max_message_id, allow_error);
->send(dialog_id.get_channel_id(), max_message_id, allow_error, revoke);
break;
case DialogType::SecretChat:
send_closure(G()->secret_chats_manager(), &SecretChatsManager::delete_all_messages,
@ -21448,11 +21459,14 @@ td_api::object_ptr<td_api::chat> MessagesManager::get_chat_object(const Dialog *
case DialogType::Channel:
if (is_broadcast_channel(d->dialog_id) ||
td_->contacts_manager_->is_channel_public(d->dialog_id.get_channel_id())) {
// deleteChatHistory can't be used in channels and public supergroups
// deleteChatHistory can't be used in channels and public supergroups to delete messages for self
} else {
// private supergroups can be deleted for self
can_delete_for_self = true;
}
if (td_->contacts_manager_->get_channel_can_be_deleted(d->dialog_id.get_channel_id())) {
can_delete_for_all_users = true;
}
break;
case DialogType::SecretChat:
if (td_->contacts_manager_->get_secret_chat_state(d->dialog_id.get_secret_chat_id()) ==