Support search within message thread.

GitOrigin-RevId: 8ea2ac97000527d743b5a983eed57c3dd206b76c
This commit is contained in:
levlam 2020-09-08 14:17:56 +03:00
parent 3aee352751
commit 1a6ca88777
6 changed files with 54 additions and 28 deletions

View File

@ -1842,7 +1842,7 @@ searchMessagesFilterVoiceAndVideoNote = SearchMessagesFilter;
//@description Returns only messages with mentions of the current user, or messages that are replies to their messages
searchMessagesFilterMention = SearchMessagesFilter;
//@description Returns only messages with unread mentions of the current user, or messages that are replies to their messages. When using this filter the results can't be additionally filtered by a query or by the sending user
//@description Returns only messages with unread mentions of the current user, or messages that are replies to their messages. When using this filter the results can't be additionally filtered by a query, a message thread or by the sending user
searchMessagesFilterUnreadMention = SearchMessagesFilter;
//@description Returns only failed to send messages. This filter can be used only if the message database is used
@ -3610,7 +3610,8 @@ deleteChatHistory chat_id:int53 remove_from_chat_list:Bool revoke:Bool = Ok;
//@offset Specify 0 to get results from exactly the from_message_id or a negative offset to get the specified message and some newer messages
//@limit The maximum number of messages to be returned; must be positive and can't be greater than 100. If the offset is negative, the limit must be greater than -offset. Fewer messages may be returned than specified by the limit, even if the end of the message history has not been reached
//@filter Filter for message content in the search results
searchChatMessages chat_id:int53 query:string sender_user_id:int32 from_message_id:int53 offset:int32 limit:int32 filter:SearchMessagesFilter = Messages;
//@message_thread_id If not 0, only messages in the specified thread will be returned; supergroups only
searchChatMessages chat_id:int53 query:string sender_user_id:int32 from_message_id:int53 offset:int32 limit:int32 filter:SearchMessagesFilter message_thread_id:int53 = Messages;
//@description Searches for messages in all chats except secret chats. Returns the results in reverse chronological order (i.e., in order of decreasing (date, chat_id, message_id)).
//-For optimal performance the number of returned messages is chosen by the library

Binary file not shown.

View File

@ -1591,7 +1591,7 @@ class SearchMessagesQuery : public Td::ResultHandler {
void send(DialogId dialog_id, const string &query, UserId sender_user_id,
telegram_api::object_ptr<telegram_api::InputUser> &&sender_input_user, MessageId from_message_id,
int32 offset, int32 limit, MessageSearchFilter filter, int64 random_id) {
int32 offset, int32 limit, MessageSearchFilter filter, MessageId top_thread_message_id, int64 random_id) {
auto input_peer = dialog_id.is_valid() ? td->messages_manager_->get_input_peer(dialog_id, AccessRights::Read)
: make_tl_object<telegram_api::inputPeerEmpty>();
if (input_peer == nullptr) {
@ -1617,9 +1617,13 @@ class SearchMessagesQuery : public Td::ResultHandler {
if (sender_input_user != nullptr) {
flags |= telegram_api::messages_search::FROM_ID_MASK;
}
if (top_thread_message_id.is_valid()) {
flags |= telegram_api::messages_search::TOP_MSG_ID_MASK;
}
send_query(G()->net_query_creator().create(telegram_api::messages_search(
flags, std::move(input_peer), query, std::move(sender_input_user), 0, get_input_messages_filter(filter), 0,
flags, std::move(input_peer), query, std::move(sender_input_user),
top_thread_message_id.get_server_message_id().get(), get_input_messages_filter(filter), 0,
std::numeric_limits<int32>::max(), from_message_id.get_server_message_id().get(), offset, limit,
std::numeric_limits<int32>::max(), 0, 0)));
}
@ -18460,7 +18464,8 @@ void MessagesManager::on_read_history_finished(DialogId dialog_id, uint64 genera
std::pair<int32, vector<MessageId>> MessagesManager::search_dialog_messages(
DialogId dialog_id, const string &query, UserId sender_user_id, MessageId from_message_id, int32 offset,
int32 limit, MessageSearchFilter filter, int64 &random_id, bool use_db, Promise<Unit> &&promise) {
int32 limit, MessageSearchFilter filter, MessageId top_thread_message_id, int64 &random_id, bool use_db,
Promise<Unit> &&promise) {
if (random_id != 0) {
// request has already been sent before
auto it = found_dialog_messages_.find(random_id);
@ -18473,8 +18478,8 @@ std::pair<int32, vector<MessageId>> MessagesManager::search_dialog_messages(
random_id = 0;
}
LOG(INFO) << "Search messages with query \"" << query << "\" in " << dialog_id << " sent by " << sender_user_id
<< " filtered by " << filter << " from " << from_message_id << " with offset " << offset << " and limit "
<< limit;
<< " in thread of " << top_thread_message_id << " filtered by " << filter << " from " << from_message_id
<< " with offset " << offset << " and limit " << limit;
std::pair<int32, vector<MessageId>> result;
if (limit <= 0) {
@ -18523,6 +18528,17 @@ std::pair<int32, vector<MessageId>> MessagesManager::search_dialog_messages(
return result;
}
if (top_thread_message_id != MessageId()) {
if (!top_thread_message_id.is_valid() || !top_thread_message_id.is_server()) {
promise.set_error(Status::Error(400, "Invalid message thread ID specified"));
return result;
}
if (dialog_id.get_type() != DialogType::Channel || is_broadcast_channel(dialog_id)) {
promise.set_error(Status::Error(400, "Can't filter by message thread ID in the chat"));
return result;
}
}
do {
random_id = Random::secure_int64();
} while (random_id == 0 || found_dialog_messages_.find(random_id) != found_dialog_messages_.end());
@ -18534,14 +18550,18 @@ std::pair<int32, vector<MessageId>> MessagesManager::search_dialog_messages(
return result;
}
if (input_user != nullptr) {
promise.set_error(Status::Error(6, "Non-empty sender user is unsupported with the specified filter"));
promise.set_error(Status::Error(6, "Filtering by sender user is unsupported with the specified filter"));
return result;
}
if (top_thread_message_id != MessageId()) {
promise.set_error(Status::Error(6, "Filtering by message thread is unsupported with the specified filter"));
return result;
}
}
// Trying to use database
if (use_db && query.empty() && G()->parameters().use_message_db && filter != MessageSearchFilter::Empty &&
input_user == nullptr) { // TODO support filter by users in the database
input_user == nullptr && top_thread_message_id == MessageId()) { // TODO support filter by users in the database
MessageId first_db_message_id = get_first_database_message_id_by_index(d, filter);
int32 message_count = d->message_count_by_index[message_search_filter_index(filter)];
auto fixed_from_message_id = from_message_id;
@ -18577,7 +18597,8 @@ std::pair<int32, vector<MessageId>> MessagesManager::search_dialog_messages(
}
LOG(DEBUG) << "Search messages on server in " << dialog_id << " with query \"" << query << "\" from user "
<< sender_user_id << " from " << from_message_id << " and with limit " << limit;
<< sender_user_id << " in thread of " << top_thread_message_id << " from " << from_message_id
<< " and with limit " << limit;
switch (dialog_id.get_type()) {
case DialogType::None:
@ -18586,7 +18607,7 @@ std::pair<int32, vector<MessageId>> MessagesManager::search_dialog_messages(
case DialogType::Channel:
td_->create_handler<SearchMessagesQuery>(std::move(promise))
->send(dialog_id, query, sender_user_id, std::move(input_user), from_message_id, offset, limit, filter,
random_id);
top_thread_message_id, random_id);
break;
case DialogType::SecretChat:
if (filter == MessageSearchFilter::UnreadMention) {
@ -18675,7 +18696,7 @@ std::pair<int32, vector<FullMessageId>> MessagesManager::search_call_messages(Me
LOG(DEBUG) << "Search call messages on server from " << from_message_id << " and with limit " << limit;
td_->create_handler<SearchMessagesQuery>(std::move(promise))
->send(DialogId(), "", UserId(), nullptr, from_message_id, 0, limit, filter, random_id);
->send(DialogId(), "", UserId(), nullptr, from_message_id, 0, limit, filter, MessageId(), random_id);
return result;
}
@ -19549,7 +19570,7 @@ int32 MessagesManager::get_dialog_message_count(DialogId dialog_id, MessageSearc
case DialogType::Chat:
case DialogType::Channel:
td_->create_handler<SearchMessagesQuery>(std::move(promise))
->send(dialog_id, "", UserId(), nullptr, MessageId(), 0, 1, filter, random_id);
->send(dialog_id, "", UserId(), nullptr, MessageId(), 0, 1, filter, MessageId(), random_id);
break;
case DialogType::None:
case DialogType::SecretChat:

View File

@ -661,7 +661,8 @@ class MessagesManager : public Actor {
std::pair<int32, vector<MessageId>> search_dialog_messages(DialogId dialog_id, const string &query,
UserId sender_user_id, MessageId from_message_id,
int32 offset, int32 limit, MessageSearchFilter filter,
int64 &random_id, bool use_db, Promise<Unit> &&promise);
MessageId top_thread_message_id, int64 &random_id,
bool use_db, Promise<Unit> &&promise);
struct FoundMessages {
vector<FullMessageId> full_message_ids;

View File

@ -1398,14 +1398,15 @@ class SearchChatMessagesRequest : public RequestActor<> {
int32 offset_;
int32 limit_;
MessageSearchFilter filter_;
MessageId top_thread_message_id_;
int64 random_id_;
std::pair<int32, vector<MessageId>> messages_;
void do_run(Promise<Unit> &&promise) override {
messages_ = td->messages_manager_->search_dialog_messages(dialog_id_, query_, sender_user_id_, from_message_id_,
offset_, limit_, filter_, random_id_, get_tries() == 3,
std::move(promise));
offset_, limit_, filter_, top_thread_message_id_,
random_id_, get_tries() == 3, std::move(promise));
}
void do_send_result() override {
@ -1424,7 +1425,7 @@ class SearchChatMessagesRequest : public RequestActor<> {
public:
SearchChatMessagesRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id, string query, int32 user_id,
int64 from_message_id, int32 offset, int32 limit,
tl_object_ptr<td_api::SearchMessagesFilter> filter)
tl_object_ptr<td_api::SearchMessagesFilter> filter, int64 message_thread_id)
: RequestActor(std::move(td), request_id)
, dialog_id_(dialog_id)
, query_(std::move(query))
@ -1433,6 +1434,7 @@ class SearchChatMessagesRequest : public RequestActor<> {
, offset_(offset)
, limit_(limit)
, filter_(get_message_search_filter(filter))
, top_thread_message_id_(message_thread_id)
, random_id_(0) {
set_tries(3);
}
@ -5459,7 +5461,8 @@ void Td::on_request(uint64 id, td_api::searchChatMessages &request) {
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.query_);
CREATE_REQUEST(SearchChatMessagesRequest, request.chat_id_, std::move(request.query_), request.sender_user_id_,
request.from_message_id_, request.offset_, request.limit_, std::move(request.filter_));
request.from_message_id_, request.offset_, request.limit_, std::move(request.filter_),
request.message_thread_id_);
}
void Td::on_request(uint64 id, td_api::searchSecretMessages &request) {

View File

@ -319,7 +319,7 @@ class CliClient final : public Actor {
LOG(ERROR) << (last_message_id >> 20);
send_request(td_api::make_object<td_api::searchChatMessages>(
search_chat_id_, "", 0, last_message_id, 0, 100,
td_api::make_object<td_api::searchMessagesFilterPhotoAndVideo>()));
td_api::make_object<td_api::searchMessagesFilterPhotoAndVideo>(), 0));
} else {
search_chat_id_ = 0;
}
@ -1864,7 +1864,7 @@ class CliClient final : public Actor {
search_chat_id_ = as_chat_id(args);
send_request(td_api::make_object<td_api::searchChatMessages>(
search_chat_id_, "", 0, 0, 0, 100, td_api::make_object<td_api::searchMessagesFilterPhotoAndVideo>()));
search_chat_id_, "", 0, 0, 0, 100, td_api::make_object<td_api::searchMessagesFilterPhotoAndVideo>(), 0));
} else if (op == "Search" || op == "SearchA" || op == "SearchM") {
string from_date;
string limit;
@ -1899,7 +1899,7 @@ class CliClient final : public Actor {
}
send_request(td_api::make_object<td_api::searchChatMessages>(as_chat_id(chat_id), query, 0, 0, 0,
to_integer<int32>(limit), nullptr));
to_integer<int32>(limit), nullptr, 0));
} else if (op == "SMME") {
string chat_id;
string limit;
@ -1910,7 +1910,7 @@ class CliClient final : public Actor {
}
send_request(td_api::make_object<td_api::searchChatMessages>(as_chat_id(chat_id), "", my_id_, 0, 0,
to_integer<int32>(limit), nullptr));
to_integer<int32>(limit), nullptr, 0));
} else if (op == "SMU") {
string chat_id;
string user_id;
@ -1923,7 +1923,7 @@ class CliClient final : public Actor {
}
send_request(td_api::make_object<td_api::searchChatMessages>(as_chat_id(chat_id), "", as_user_id(user_id), 0, 0,
to_integer<int32>(limit), nullptr));
to_integer<int32>(limit), nullptr, 0));
} else if (op == "SM") {
string chat_id;
string filter;
@ -1947,7 +1947,7 @@ class CliClient final : public Actor {
send_request(td_api::make_object<td_api::searchChatMessages>(
as_chat_id(chat_id), "", 0, as_message_id(offset_message_id), to_integer<int32>(offset),
to_integer<int32>(limit), as_search_messages_filter(filter)));
to_integer<int32>(limit), as_search_messages_filter(filter), 0));
} else if (op == "SC") {
string limit;
string offset_message_id;
@ -1992,7 +1992,7 @@ class CliClient final : public Actor {
}
send_request(td_api::make_object<td_api::searchChatMessages>(
as_chat_id(chat_id), query, 0, as_message_id(offset_message_id), 0, to_integer<int32>(limit),
td_api::make_object<td_api::searchMessagesFilterAudio>()));
td_api::make_object<td_api::searchMessagesFilterAudio>(), 0));
} else if (op == "SearchDocument") {
string chat_id;
string offset_message_id;
@ -2010,7 +2010,7 @@ class CliClient final : public Actor {
}
send_request(td_api::make_object<td_api::searchChatMessages>(
as_chat_id(chat_id), query, 0, to_integer<int64>(offset_message_id), 0, to_integer<int32>(limit),
td_api::make_object<td_api::searchMessagesFilterDocument>()));
td_api::make_object<td_api::searchMessagesFilterDocument>(), 0));
} else if (op == "SearchPhoto") {
string chat_id;
string offset_message_id;
@ -2028,7 +2028,7 @@ class CliClient final : public Actor {
}
send_request(td_api::make_object<td_api::searchChatMessages>(
as_chat_id(chat_id), query, 0, as_message_id(offset_message_id), 0, to_integer<int32>(limit),
td_api::make_object<td_api::searchMessagesFilterPhoto>()));
td_api::make_object<td_api::searchMessagesFilterPhoto>(), 0));
} else if (op == "SearchChatPhoto") {
string chat_id;
string offset_message_id;
@ -2046,7 +2046,7 @@ class CliClient final : public Actor {
}
send_request(td_api::make_object<td_api::searchChatMessages>(
as_chat_id(chat_id), query, 0, as_message_id(offset_message_id), 0, to_integer<int32>(limit),
td_api::make_object<td_api::searchMessagesFilterChatPhoto>()));
td_api::make_object<td_api::searchMessagesFilterChatPhoto>(), 0));
} else if (op == "gcmc") {
string chat_id;
string filter;