diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 879ad9b09..636194144 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3591,14 +3591,15 @@ searchChatMessages chat_id:int53 query:string sender_user_id:int32 from_message_ //@offset_chat_id The chat identifier of the last found message, or 0 for the first request //@offset_message_id The message identifier of the last found message, or 0 for the first request //@limit The maximum number of messages to be returned; up to 100. Fewer messages may be returned than specified by the limit, even if the end of the message history has not been reached -searchMessages chat_list:ChatList query:string offset_date:int32 offset_chat_id:int53 offset_message_id:int53 limit:int32 = Messages; +//@filter Filter for message content in the search results; searchMessagesFilterCall, searchMessagesFilterMissedCall, searchMessagesFilterMention, searchMessagesFilterUnreadMention and searchMessagesFilterFailedToSend are unsupported in this function +searchMessages chat_list:ChatList query:string offset_date:int32 offset_chat_id:int53 offset_message_id:int53 limit:int32 filter:SearchMessagesFilter = Messages; //@description Searches for messages in secret chats. Returns the results in reverse chronological order. For optimal performance the number of returned messages is chosen by the library //@chat_id Identifier of the chat in which to search. Specify 0 to search in all secret chats //@query Query to search for. If empty, searchChatMessages should be used instead //@offset Offset of the first entry to return as received from the previous request; use empty string to get first chunk of results //@limit The maximum number of messages to be returned; up to 100. Fewer messages may be returned than specified by the limit, even if the end of the message history has not been reached -//@filter A filter for the content of messages in the search results +//@filter A filter for message content in the search results searchSecretMessages chat_id:int53 query:string offset:string limit:int32 filter:SearchMessagesFilter = FoundMessages; //@description Searches for call messages. Returns the results in reverse chronological order (i. e., in order of decreasing message_id). For optimal performance the number of returned messages is chosen by the library diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index d9239b422..0af42c6b0 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 057c9715b..3f14ec7d7 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -1648,6 +1648,7 @@ class SearchMessagesGlobalQuery : public Td::ResultHandler { DialogId offset_dialog_id_; MessageId offset_message_id_; int32 limit_; + SearchMessagesFilter filter_; int64 random_id_; public: @@ -1655,13 +1656,15 @@ class SearchMessagesGlobalQuery : public Td::ResultHandler { } void send(FolderId folder_id, bool ignore_folder_id, const string &query, int32 offset_date, - DialogId offset_dialog_id, MessageId offset_message_id, int32 limit, int64 random_id) { + DialogId offset_dialog_id, MessageId offset_message_id, int32 limit, SearchMessagesFilter filter, + int64 random_id) { query_ = query; offset_date_ = offset_date; offset_dialog_id_ = offset_dialog_id; offset_message_id_ = offset_message_id; limit_ = limit; random_id_ = random_id; + filter_ = filter; auto input_peer = MessagesManager::get_input_peer_force(offset_dialog_id); CHECK(input_peer != nullptr); @@ -1671,7 +1674,7 @@ class SearchMessagesGlobalQuery : public Td::ResultHandler { flags |= telegram_api::messages_searchGlobal::FOLDER_ID_MASK; } send_query(G()->net_query_creator().create(telegram_api::messages_searchGlobal( - flags, folder_id.get(), query, make_tl_object(), offset_date_, + flags, folder_id.get(), query, MessagesManager::get_input_messages_filter(filter), offset_date_, std::move(input_peer), offset_message_id.get_server_message_id().get(), limit))); } @@ -1683,7 +1686,7 @@ class SearchMessagesGlobalQuery : public Td::ResultHandler { auto info = td->messages_manager_->on_get_messages(result_ptr.move_as_ok(), "SearchMessagesGlobalQuery"); td->messages_manager_->on_get_messages_search_result(query_, offset_date_, offset_dialog_id_, offset_message_id_, - limit_, random_id_, info.total_count, + limit_, filter_, random_id_, info.total_count, std::move(info.messages)); promise_.set_value(Unit()); @@ -8745,8 +8748,8 @@ void MessagesManager::on_failed_dialog_messages_search(DialogId dialog_id, int64 } void MessagesManager::on_get_messages_search_result(const string &query, int32 offset_date, DialogId offset_dialog_id, - MessageId offset_message_id, int32 limit, int64 random_id, - int32 total_count, + MessageId offset_message_id, int32 limit, + SearchMessagesFilter filter, int64 random_id, int32 total_count, vector> &&messages) { LOG(INFO) << "Receive " << messages.size() << " found messages"; auto it = found_messages_.find(random_id); @@ -19229,11 +19232,10 @@ void MessagesManager::on_messages_db_calls_result(Result promise.set_value(Unit()); } -std::pair> MessagesManager::search_messages(FolderId folder_id, bool ignore_folder_id, - const string &query, int32 offset_date, - DialogId offset_dialog_id, - MessageId offset_message_id, int32 limit, - int64 &random_id, Promise &&promise) { +std::pair> MessagesManager::search_messages( + FolderId folder_id, bool ignore_folder_id, const string &query, int32 offset_date, DialogId offset_dialog_id, + MessageId offset_message_id, int32 limit, const tl_object_ptr &filter, + int64 &random_id, Promise &&promise) { if (random_id != 0) { // request has already been sent before auto it = found_messages_.find(random_id); @@ -19244,10 +19246,9 @@ std::pair> MessagesManager::search_messages(FolderI return result; } - std::pair> result; if (limit <= 0) { promise.set_error(Status::Error(3, "Parameter limit must be positive")); - return result; + return {}; } if (limit > MAX_SEARCH_MESSAGES) { limit = MAX_SEARCH_MESSAGES; @@ -19259,19 +19260,27 @@ std::pair> MessagesManager::search_messages(FolderI if (!offset_message_id.is_valid()) { if (offset_message_id.is_valid_scheduled()) { promise.set_error(Status::Error(3, "Parameter offset_message_id can't be a scheduled message identifier")); - return result; + return {}; } offset_message_id = MessageId(); } if (offset_message_id != MessageId() && !offset_message_id.is_server()) { promise.set_error( Status::Error(3, "Parameter offset_message_id must be identifier of the last found message or 0")); - return result; + return {}; } if (query.empty()) { promise.set_value(Unit()); - return result; + return {}; + } + + auto filter_type = get_search_messages_filter(filter); + if (filter_type == SearchMessagesFilter::Call || filter_type == SearchMessagesFilter::MissedCall || + filter_type == SearchMessagesFilter::Mention || filter_type == SearchMessagesFilter::UnreadMention || + filter_type == SearchMessagesFilter::FailedToSend) { + promise.set_error(Status::Error(400, "The filter is not supported")); + return {}; } do { @@ -19280,11 +19289,12 @@ std::pair> MessagesManager::search_messages(FolderI found_messages_[random_id]; // reserve place for result LOG(DEBUG) << "Search messages globally with query = \"" << query << "\" from date " << offset_date << ", " - << offset_dialog_id << ", " << offset_message_id << " and with limit " << limit; + << offset_dialog_id << ", " << offset_message_id << " and limit " << limit; td_->create_handler(std::move(promise)) - ->send(folder_id, ignore_folder_id, query, offset_date, offset_dialog_id, offset_message_id, limit, random_id); - return result; + ->send(folder_id, ignore_folder_id, query, offset_date, offset_dialog_id, offset_message_id, limit, filter_type, + random_id); + return {}; } int64 MessagesManager::get_dialog_message_by_date(DialogId dialog_id, int32 date, Promise &&promise) { diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index e2ab36503..c7500bc98 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -235,7 +235,8 @@ class MessagesManager : public Actor { void on_failed_dialog_messages_search(DialogId dialog_id, int64 random_id); void on_get_messages_search_result(const string &query, int32 offset_date, DialogId offset_dialog_id, - MessageId offset_message_id, int32 limit, int64 random_id, int32 total_count, + MessageId offset_message_id, int32 limit, SearchMessagesFilter filter, + int64 random_id, int32 total_count, vector> &&messages); void on_failed_messages_search(int64 random_id); @@ -672,7 +673,9 @@ class MessagesManager : public Actor { std::pair> search_messages(FolderId folder_id, bool ignore_folder_id, const string &query, int32 offset_date, DialogId offset_dialog_id, MessageId offset_message_id, - int32 limit, int64 &random_id, Promise &&promise); + int32 limit, + const tl_object_ptr &filter, + int64 &random_id, Promise &&promise); std::pair> search_call_messages(MessageId from_message_id, int32 limit, bool only_missed, int64 &random_id, bool use_db, Promise &&promise); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index f0887f540..fd01ed4bf 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -1505,6 +1505,7 @@ class SearchMessagesRequest : public RequestActor<> { DialogId offset_dialog_id_; MessageId offset_message_id_; int32 limit_; + tl_object_ptr filter_; int64 random_id_; std::pair> messages_; @@ -1512,7 +1513,7 @@ class SearchMessagesRequest : public RequestActor<> { void do_run(Promise &&promise) override { messages_ = td->messages_manager_->search_messages(folder_id_, ignore_folder_id_, query_, offset_date_, offset_dialog_id_, - offset_message_id_, limit_, random_id_, std::move(promise)); + offset_message_id_, limit_, filter_, random_id_, std::move(promise)); } void do_send_result() override { @@ -1530,7 +1531,8 @@ class SearchMessagesRequest : public RequestActor<> { public: SearchMessagesRequest(ActorShared td, uint64 request_id, FolderId folder_id, bool ignore_folder_id, string query, - int32 offset_date, int64 offset_dialog_id, int64 offset_message_id, int32 limit) + int32 offset_date, int64 offset_dialog_id, int64 offset_message_id, int32 limit, + tl_object_ptr &&filter) : RequestActor(std::move(td), request_id) , folder_id_(folder_id) , ignore_folder_id_(ignore_folder_id) @@ -1539,6 +1541,7 @@ class SearchMessagesRequest : public RequestActor<> { , offset_dialog_id_(offset_dialog_id) , offset_message_id_(offset_message_id) , limit_(limit) + , filter_(std::move(filter)) , random_id_(0) { } }; @@ -5495,7 +5498,7 @@ void Td::on_request(uint64 id, td_api::searchMessages &request) { } CREATE_REQUEST(SearchMessagesRequest, dialog_list_id.get_folder_id(), request.chat_list_ == nullptr, std::move(request.query_), request.offset_date_, request.offset_chat_id_, request.offset_message_id_, - request.limit_); + request.limit_, std::move(request.filter_)); } void Td::on_request(uint64 id, td_api::searchCallMessages &request) { diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index fc32b541f..03fea0214 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -1008,7 +1008,7 @@ class CliClient final : public Actor { return nullptr; } - static td_api::object_ptr get_search_messages_filter(MutableSlice filter) { + static td_api::object_ptr as_search_messages_filter(MutableSlice filter) { filter = trim(filter); to_lower_inplace(filter); if (filter == "an" || filter == "animation") { @@ -1869,9 +1869,11 @@ class CliClient final : public Actor { string from_date; string limit; string query; + string filter; std::tie(query, args) = split(args); - std::tie(limit, from_date) = split(args); + std::tie(limit, args) = split(args); + std::tie(filter, from_date) = split(args); if (from_date.empty()) { from_date = "0"; } @@ -1883,7 +1885,8 @@ class CliClient final : public Actor { chat_list = td_api::make_object(); } send_request(td_api::make_object( - std::move(chat_list), query, to_integer(from_date), 2147482647, 0, to_integer(limit))); + std::move(chat_list), query, to_integer(from_date), 2147482647, 0, to_integer(limit), + as_search_messages_filter(filter))); } else if (op == "SCM") { string chat_id; string limit; @@ -1944,7 +1947,7 @@ class CliClient final : public Actor { send_request(td_api::make_object( as_chat_id(chat_id), "", 0, as_message_id(offset_message_id), to_integer(offset), - to_integer(limit), get_search_messages_filter(filter))); + to_integer(limit), as_search_messages_filter(filter))); } else if (op == "SC") { string limit; string offset_message_id; @@ -2053,7 +2056,7 @@ class CliClient final : public Actor { std::tie(filter, return_local) = split(args); send_request(td_api::make_object( - as_chat_id(chat_id), get_search_messages_filter(filter), as_bool(return_local))); + as_chat_id(chat_id), as_search_messages_filter(filter), as_bool(return_local))); } else if (op == "gup" || op == "gupp") { string user_id; string offset; @@ -2936,7 +2939,7 @@ class CliClient final : public Actor { std::tie(filter, query) = split(args); send_request(td_api::make_object( - as_chat_id(chat_id), query, offset, to_integer(limit), get_search_messages_filter(filter))); + as_chat_id(chat_id), query, offset, to_integer(limit), as_search_messages_filter(filter))); } else if (op == "ssd") { schedule_date_ = args; } else if (op == "sm" || op == "sms" || op == "smr" || op == "smf") {