Add td_api::deleteChatMessagesByDate.
This commit is contained in:
parent
cf77428fab
commit
d019d89d39
@ -4392,6 +4392,10 @@ deleteMessages chat_id:int53 message_ids:vector<int53> revoke:Bool = Ok;
|
||||
//@description Deletes all messages sent by the specified user to a chat. Supported only for supergroups; requires can_delete_messages administrator privileges @chat_id Chat identifier @user_id User identifier
|
||||
deleteChatMessagesFromUser chat_id:int53 user_id:int53 = Ok;
|
||||
|
||||
//@description Deletes all messages between the specified dates in a chat. Supported only for private chats and basic groups. Messages sent in the last 30 seconds will not be deleted
|
||||
//@chat_id Chat identifier @min_date The minimum date of the messages to delete @max_date The maximum date of the messages to delete @revoke Pass true to try to delete chat messages for all users; private chats only
|
||||
deleteChatMessagesByDate chat_id:int53 min_date:int32 max_date:int32 revoke:Bool = Ok;
|
||||
|
||||
|
||||
//@description Edits the text of a message (or a text of a game message). Returns the edited message after the edit is completed on the server side
|
||||
//@chat_id The chat the message belongs to
|
||||
|
@ -2715,6 +2715,74 @@ class DeleteChannelHistoryQuery final : public Td::ResultHandler {
|
||||
}
|
||||
};
|
||||
|
||||
class DeleteMessagesByDateQuery final : public Td::ResultHandler {
|
||||
Promise<Unit> promise_;
|
||||
DialogId dialog_id_;
|
||||
int32 min_date_;
|
||||
int32 max_date_;
|
||||
bool revoke_;
|
||||
|
||||
void send_request() {
|
||||
auto input_peer = td->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read);
|
||||
if (input_peer == nullptr) {
|
||||
return promise_.set_error(Status::Error(400, "Chat is not accessible"));
|
||||
}
|
||||
|
||||
int32 flags = telegram_api::messages_deleteHistory::JUST_CLEAR_MASK |
|
||||
telegram_api::messages_deleteHistory::MIN_DATE_MASK |
|
||||
telegram_api::messages_deleteHistory::MAX_DATE_MASK;
|
||||
if (revoke_) {
|
||||
flags |= telegram_api::messages_deleteHistory::REVOKE_MASK;
|
||||
}
|
||||
|
||||
send_query(G()->net_query_creator().create(telegram_api::messages_deleteHistory(
|
||||
flags, false /*ignored*/, false /*ignored*/, std::move(input_peer), 0, min_date_, max_date_)));
|
||||
}
|
||||
|
||||
public:
|
||||
explicit DeleteMessagesByDateQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void send(DialogId dialog_id, int32 min_date, int32 max_date, bool revoke) {
|
||||
dialog_id_ = dialog_id;
|
||||
min_date_ = min_date;
|
||||
max_date_ = max_date;
|
||||
revoke_ = revoke;
|
||||
|
||||
send_request();
|
||||
}
|
||||
|
||||
void on_result(uint64 id, BufferSlice packet) final {
|
||||
auto result_ptr = fetch_result<telegram_api::messages_deleteHistory>(packet);
|
||||
if (result_ptr.is_error()) {
|
||||
return on_error(id, result_ptr.move_as_error());
|
||||
}
|
||||
|
||||
auto affected_history = result_ptr.move_as_ok();
|
||||
CHECK(affected_history->get_id() == telegram_api::messages_affectedHistory::ID);
|
||||
|
||||
if (affected_history->pts_count_ > 0) {
|
||||
affected_history->pts_count_ = 0; // force receiving real updates from the server
|
||||
auto promise = affected_history->offset_ > 0 ? Promise<Unit>() : std::move(promise_);
|
||||
td->updates_manager_->add_pending_pts_update(make_tl_object<dummyUpdate>(), affected_history->pts_,
|
||||
affected_history->pts_count_, Time::now(), std::move(promise),
|
||||
"DeleteMessagesByDateQuery");
|
||||
} else if (affected_history->offset_ <= 0) {
|
||||
promise_.set_value(Unit());
|
||||
}
|
||||
|
||||
if (affected_history->offset_ > 0) {
|
||||
send_request();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void on_error(uint64 id, Status status) final {
|
||||
td->messages_manager_->on_get_dialog_error(dialog_id_, status, "DeleteMessagesByDateQuery");
|
||||
promise_.set_error(std::move(status));
|
||||
}
|
||||
};
|
||||
|
||||
class DeletePhoneCallHistoryQuery final : public Td::ResultHandler {
|
||||
Promise<Unit> promise_;
|
||||
bool revoke_;
|
||||
@ -10806,8 +10874,6 @@ void MessagesManager::delete_dialog_messages_from_user(DialogId dialog_id, UserI
|
||||
bool is_bot = td_->auth_manager_->is_bot();
|
||||
CHECK(!is_bot);
|
||||
|
||||
LOG(INFO) << "Receive deleteChatMessagesFromUser request to delete all messages in " << dialog_id << " from the user "
|
||||
<< user_id;
|
||||
Dialog *d = get_dialog_force(dialog_id, "delete_dialog_messages_from_user");
|
||||
if (d == nullptr) {
|
||||
return promise.set_error(Status::Error(400, "Chat not found"));
|
||||
@ -10915,6 +10981,126 @@ void MessagesManager::delete_all_channel_messages_from_user_on_server(ChannelId
|
||||
->send(channel_id, user_id);
|
||||
}
|
||||
|
||||
void MessagesManager::delete_dialog_messages_by_date(DialogId dialog_id, int32 min_date, int32 max_date, bool revoke,
|
||||
Promise<Unit> &&promise) {
|
||||
bool is_bot = td_->auth_manager_->is_bot();
|
||||
CHECK(!is_bot);
|
||||
|
||||
Dialog *d = get_dialog_force(dialog_id, "delete_dialog_messages_by_date");
|
||||
if (d == nullptr) {
|
||||
return promise.set_error(Status::Error(400, "Chat not found"));
|
||||
}
|
||||
|
||||
if (!have_input_peer(dialog_id, AccessRights::Read)) {
|
||||
return promise.set_error(Status::Error(400, "Can't access the chat"));
|
||||
}
|
||||
|
||||
if (min_date > max_date) {
|
||||
return promise.set_error(Status::Error(400, "Wrong date interval specified"));
|
||||
}
|
||||
|
||||
const int32 telegram_launch_date = 1376438400;
|
||||
if (max_date < telegram_launch_date) {
|
||||
return promise.set_value(Unit());
|
||||
}
|
||||
if (min_date < telegram_launch_date) {
|
||||
min_date = telegram_launch_date;
|
||||
}
|
||||
|
||||
auto current_date = max(G()->unix_time(), 1635000000);
|
||||
if (min_date >= current_date - 30) {
|
||||
return promise.set_value(Unit());
|
||||
}
|
||||
if (max_date >= current_date - 30) {
|
||||
max_date = current_date - 31;
|
||||
}
|
||||
CHECK(min_date <= max_date);
|
||||
|
||||
switch (dialog_id.get_type()) {
|
||||
case DialogType::User:
|
||||
break;
|
||||
case DialogType::Chat:
|
||||
if (revoke) {
|
||||
return promise.set_error(Status::Error(400, "Bulk message revocation is unsupported in basic group chats"));
|
||||
}
|
||||
break;
|
||||
case DialogType::Channel:
|
||||
return promise.set_error(Status::Error(400, "Bulk message deletion is unsupported in supergroup chats"));
|
||||
case DialogType::SecretChat:
|
||||
return promise.set_error(Status::Error(400, "Bulk message deletion is unsupported in secret chats"));
|
||||
case DialogType::None:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO delete in database by dates
|
||||
|
||||
vector<MessageId> message_ids;
|
||||
find_messages_by_date(d->messages.get(), min_date, max_date, message_ids);
|
||||
|
||||
bool need_update_dialog_pos = false;
|
||||
vector<int64> deleted_message_ids;
|
||||
for (auto message_id : message_ids) {
|
||||
auto m = delete_message(d, message_id, true, &need_update_dialog_pos, DELETE_MESSAGE_USER_REQUEST_SOURCE);
|
||||
CHECK(m != nullptr);
|
||||
deleted_message_ids.push_back(m->message_id.get());
|
||||
}
|
||||
|
||||
if (need_update_dialog_pos) {
|
||||
send_update_chat_last_message(d, "delete_dialog_messages_by_date");
|
||||
}
|
||||
send_update_delete_messages(dialog_id, std::move(deleted_message_ids), true, false);
|
||||
|
||||
delete_dialog_messages_by_date_on_server(dialog_id, min_date, max_date, revoke, 0, std::move(promise));
|
||||
}
|
||||
|
||||
class MessagesManager::DeleteDialogMessagesByDateOnServerLogEvent {
|
||||
public:
|
||||
DialogId dialog_id_;
|
||||
int32 min_date_;
|
||||
int32 max_date_;
|
||||
bool revoke_;
|
||||
|
||||
template <class StorerT>
|
||||
void store(StorerT &storer) const {
|
||||
BEGIN_STORE_FLAGS();
|
||||
STORE_FLAG(revoke_);
|
||||
END_STORE_FLAGS();
|
||||
td::store(dialog_id_, storer);
|
||||
td::store(min_date_, storer);
|
||||
td::store(max_date_, storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void parse(ParserT &parser) {
|
||||
BEGIN_PARSE_FLAGS();
|
||||
PARSE_FLAG(revoke_);
|
||||
END_PARSE_FLAGS();
|
||||
td::parse(dialog_id_, parser);
|
||||
td::parse(min_date_, parser);
|
||||
td::parse(max_date_, parser);
|
||||
}
|
||||
};
|
||||
|
||||
uint64 MessagesManager::save_delete_dialog_messages_by_date_on_server_log_event(DialogId dialog_id, int32 min_date,
|
||||
int32 max_date, bool revoke) {
|
||||
DeleteDialogMessagesByDateOnServerLogEvent log_event{dialog_id, min_date, max_date, revoke};
|
||||
return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::DeleteDialogMessagesByDateOnServer,
|
||||
get_log_event_storer(log_event));
|
||||
}
|
||||
|
||||
void MessagesManager::delete_dialog_messages_by_date_on_server(DialogId dialog_id, int32 min_date, int32 max_date,
|
||||
bool revoke, uint64 log_event_id,
|
||||
Promise<Unit> &&promise) {
|
||||
if (log_event_id == 0 && G()->parameters().use_chat_info_db) {
|
||||
log_event_id = save_delete_dialog_messages_by_date_on_server_log_event(dialog_id, min_date, max_date, revoke);
|
||||
}
|
||||
|
||||
td_->create_handler<DeleteMessagesByDateQuery>(get_erase_log_event_promise(log_event_id, std::move(promise)))
|
||||
->send(dialog_id, min_date, max_date, revoke);
|
||||
}
|
||||
|
||||
int32 MessagesManager::get_unload_dialog_delay() const {
|
||||
constexpr int32 DIALOG_UNLOAD_DELAY = 60; // seconds
|
||||
constexpr int32 DIALOG_UNLOAD_BOT_DELAY = 1800; // seconds
|
||||
@ -20153,7 +20339,7 @@ td_api::object_ptr<td_api::chat> MessagesManager::get_chat_object(const Dialog *
|
||||
}
|
||||
break;
|
||||
case DialogType::Chat:
|
||||
// chats can't be deleted only for self with deleteChatHistory
|
||||
// chats can be deleted only for self with deleteChatHistory
|
||||
can_delete_for_self = true;
|
||||
break;
|
||||
case DialogType::Channel:
|
||||
@ -22154,6 +22340,23 @@ MessageId MessagesManager::find_message_by_date(const Message *m, int32 date) {
|
||||
return m->message_id;
|
||||
}
|
||||
|
||||
void MessagesManager::find_messages_by_date(const Message *m, int32 min_date, int32 max_date,
|
||||
vector<MessageId> &message_ids) {
|
||||
if (m == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m->date >= min_date) {
|
||||
find_messages_by_date(m->left.get(), min_date, max_date, message_ids);
|
||||
if (m->date <= max_date) {
|
||||
message_ids.push_back(m->message_id);
|
||||
}
|
||||
}
|
||||
if (m->date <= max_date) {
|
||||
find_messages_by_date(m->right.get(), min_date, max_date, message_ids);
|
||||
}
|
||||
}
|
||||
|
||||
void MessagesManager::on_get_dialog_message_by_date_from_database(DialogId dialog_id, int32 date, int64 random_id,
|
||||
Result<MessagesDbDialogMessage> result,
|
||||
Promise<Unit> promise) {
|
||||
@ -37415,6 +37618,26 @@ void MessagesManager::on_binlog_events(vector<BinlogEvent> &&events) {
|
||||
delete_all_channel_messages_from_user_on_server(channel_id, user_id, event.id_, Auto());
|
||||
break;
|
||||
}
|
||||
case LogEvent::HandlerType::DeleteDialogMessagesByDateOnServer: {
|
||||
if (!G()->parameters().use_message_db) {
|
||||
binlog_erase(G()->td_db()->get_binlog(), event.id_);
|
||||
break;
|
||||
}
|
||||
|
||||
DeleteDialogMessagesByDateOnServerLogEvent log_event;
|
||||
log_event_parse(log_event, event.data_).ensure();
|
||||
|
||||
auto dialog_id = log_event.dialog_id_;
|
||||
Dialog *d = get_dialog_force(dialog_id, "DeleteDialogMessagesByDateOnServerLogEvent");
|
||||
if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) {
|
||||
binlog_erase(G()->td_db()->get_binlog(), event.id_);
|
||||
break;
|
||||
}
|
||||
|
||||
delete_dialog_messages_by_date_on_server(dialog_id, log_event.min_date_, log_event.max_date_, log_event.revoke_,
|
||||
event.id_, Auto());
|
||||
break;
|
||||
}
|
||||
case LogEvent::HandlerType::ReadHistoryOnServer: {
|
||||
if (!G()->parameters().use_message_db) {
|
||||
binlog_erase(G()->td_db()->get_binlog(), event.id_);
|
||||
|
@ -365,6 +365,9 @@ class MessagesManager final : public Actor {
|
||||
|
||||
void delete_dialog_messages_from_user(DialogId dialog_id, UserId user_id, Promise<Unit> &&promise);
|
||||
|
||||
void delete_dialog_messages_by_date(DialogId dialog_id, int32 min_date, int32 max_date, bool revoke,
|
||||
Promise<Unit> &&promise);
|
||||
|
||||
void on_dialog_deleted(DialogId dialog_id, Promise<Unit> &&promise);
|
||||
|
||||
void on_update_dialog_group_call_rights(DialogId dialog_id);
|
||||
@ -1640,10 +1643,10 @@ class MessagesManager final : public Actor {
|
||||
};
|
||||
|
||||
class BlockMessageSenderFromRepliesOnServerLogEvent;
|
||||
class ToggleDialogReportSpamStateOnServerLogEvent;
|
||||
class DeleteAllCallMessagesFromServerLogEvent;
|
||||
class DeleteAllChannelMessagesFromUserOnServerLogEvent;
|
||||
class DeleteDialogHistoryFromServerLogEvent;
|
||||
class DeleteAllCallMessagesFromServerLogEvent;
|
||||
class DeleteDialogMessagesByDateOnServerLogEvent;
|
||||
class DeleteMessageLogEvent;
|
||||
class DeleteMessagesFromServerLogEvent;
|
||||
class DeleteScheduledMessagesFromServerLogEvent;
|
||||
@ -1666,6 +1669,7 @@ class MessagesManager final : public Actor {
|
||||
class ToggleDialogIsBlockedOnServerLogEvent;
|
||||
class ToggleDialogIsMarkedAsUnreadOnServerLogEvent;
|
||||
class ToggleDialogIsPinnedOnServerLogEvent;
|
||||
class ToggleDialogReportSpamStateOnServerLogEvent;
|
||||
class UnpinAllDialogMessagesOnServerLogEvent;
|
||||
class UpdateDialogNotificationSettingsOnServerLogEvent;
|
||||
class UpdateScopeNotificationSettingsOnServerLogEvent;
|
||||
@ -2007,12 +2011,17 @@ class MessagesManager final : public Actor {
|
||||
void delete_all_channel_messages_from_user_on_server(ChannelId channel_id, UserId user_id, uint64 log_event_id,
|
||||
Promise<Unit> &&promise);
|
||||
|
||||
void delete_dialog_messages_by_date_on_server(DialogId dialog_id, int32 min_date, int32 max_date, bool revoke,
|
||||
uint64 log_event_id, Promise<Unit> &&promise);
|
||||
|
||||
void read_all_dialog_mentions_on_server(DialogId dialog_id, uint64 log_event_id, Promise<Unit> &&promise);
|
||||
|
||||
void unpin_all_dialog_messages_on_server(DialogId dialog_id, uint64 log_event_id, Promise<Unit> &&promise);
|
||||
|
||||
static MessageId find_message_by_date(const Message *m, int32 date);
|
||||
|
||||
static void find_messages_by_date(const Message *m, int32 min_date, int32 max_date, vector<MessageId> &message_ids);
|
||||
|
||||
static void find_messages(const Message *m, vector<MessageId> &message_ids,
|
||||
const std::function<bool(const Message *)> &condition);
|
||||
|
||||
@ -3080,6 +3089,9 @@ class MessagesManager final : public Actor {
|
||||
|
||||
static uint64 save_delete_all_channel_messages_from_user_on_server_log_event(ChannelId channel_id, UserId user_id);
|
||||
|
||||
static uint64 save_delete_dialog_messages_by_date_on_server_log_event(DialogId dialog_id, int32 min_date,
|
||||
int32 max_date, bool revoke);
|
||||
|
||||
static uint64 save_read_all_dialog_mentions_on_server_log_event(DialogId dialog_id);
|
||||
|
||||
static uint64 save_toggle_dialog_is_pinned_on_server_log_event(DialogId dialog_id, bool is_pinned);
|
||||
|
@ -5440,6 +5440,13 @@ void Td::on_request(uint64 id, const td_api::deleteChatMessagesFromUser &request
|
||||
std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::deleteChatMessagesByDate &request) {
|
||||
CHECK_IS_USER();
|
||||
CREATE_OK_REQUEST_PROMISE();
|
||||
messages_manager_->delete_dialog_messages_by_date(DialogId(request.chat_id_), request.min_date_, request.max_date_,
|
||||
request.revoke_, std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::readAllChatMentions &request) {
|
||||
CHECK_IS_USER();
|
||||
CREATE_OK_REQUEST_PROMISE();
|
||||
|
@ -644,6 +644,8 @@ class Td final : public Actor {
|
||||
|
||||
void on_request(uint64 id, const td_api::deleteChatMessagesFromUser &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::deleteChatMessagesByDate &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::readAllChatMentions &request);
|
||||
|
||||
void on_request(uint64 id, td_api::sendMessage &request);
|
||||
|
@ -119,6 +119,7 @@ Status init_binlog(Binlog &binlog, string path, BinlogKeyValue<Binlog> &binlog_p
|
||||
case LogEvent::HandlerType::BlockMessageSenderFromRepliesOnServer:
|
||||
case LogEvent::HandlerType::UnpinAllDialogMessagesOnServer:
|
||||
case LogEvent::HandlerType::DeleteAllCallMessagesFromServer:
|
||||
case LogEvent::HandlerType::DeleteDialogMessagesByDateOnServer:
|
||||
events.to_messages_manager.push_back(event.clone());
|
||||
break;
|
||||
case LogEvent::HandlerType::AddMessagePushNotification:
|
||||
|
@ -3711,6 +3711,14 @@ class CliClient final : public Actor {
|
||||
get_args(args, chat_id, remove_from_the_chat_list, revoke);
|
||||
send_request(
|
||||
td_api::make_object<td_api::deleteChatHistory>(as_chat_id(chat_id), remove_from_the_chat_list, revoke));
|
||||
} else if (op == "dcmbd") {
|
||||
string chat_id;
|
||||
int32 min_date;
|
||||
int32 max_date;
|
||||
bool revoke;
|
||||
get_args(args, chat_id, min_date, max_date, revoke);
|
||||
send_request(
|
||||
td_api::make_object<td_api::deleteChatMessagesByDate>(as_chat_id(chat_id), min_date, max_date, revoke));
|
||||
} else if (op == "dmfu") {
|
||||
string chat_id;
|
||||
string user_id;
|
||||
|
@ -99,6 +99,7 @@ class LogEvent {
|
||||
BlockMessageSenderFromRepliesOnServer = 0x120,
|
||||
UnpinAllDialogMessagesOnServer = 0x121,
|
||||
DeleteAllCallMessagesFromServer = 0x122,
|
||||
DeleteDialogMessagesByDateOnServer = 0x123,
|
||||
GetChannelDifference = 0x140,
|
||||
AddMessagePushNotification = 0x200,
|
||||
EditMessagePushNotification = 0x201,
|
||||
|
Loading…
Reference in New Issue
Block a user