Add td_api::searchPublicHashtagStories.

This commit is contained in:
levlam 2024-06-04 14:48:28 +03:00
parent 54015a1842
commit 7c5ee12a0e
6 changed files with 112 additions and 1 deletions

View File

@ -4026,6 +4026,9 @@ story id:int32 sender_chat_id:int53 sender_id:MessageSender date:int32 is_being_
//@pinned_story_ids Identifiers of the pinned stories; returned only in getChatPostedToChatPageStories with from_story_id == 0
stories total_count:int32 stories:vector<story> pinned_story_ids:vector<int32> = Stories;
//@description Contains a list of stories found by a search @total_count Approximate total number of stories found @stories List of stories @next_offset The offset for the next request. If empty, then there are no more results
foundStories total_count:int32 stories:vector<story> next_offset:string = FoundStories;
//@description Contains identifier of a story along with identifier of its sender
//@sender_chat_id Identifier of the chat that posted the story
//@story_id Unique story identifier among stories of the given sender
@ -8065,12 +8068,18 @@ searchCallMessages offset:string limit:int32 only_missed:Bool = FoundMessages;
//@limit The maximum number of messages to be returned; up to 100
searchOutgoingDocumentMessages query:string limit:int32 = FoundMessages;
//@description Searches for public channel posts with the given hashtag or cashtag. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit
//@description Searches for public channel posts containing the given hashtag or cashtag. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit
//@hashtag Hashtag or cashtag to search for
//@offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results
//@limit The maximum number of messages to be returned; up to 100. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit
searchPublicHashtagMessages hashtag:string offset:string limit:int32 = FoundMessages;
//@description Searches for public stories containing the given hashtag or cashtag. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit
//@hashtag Hashtag or cashtag to search for
//@offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results
//@limit The maximum number of stories to be returned; up to 100. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit
searchPublicHashtagStories hashtag:string offset:string limit:int32 = FoundStories;
//@description Returns recently searched for hashtags or cashtags by their prefix @prefix Prefix of hashtags or cashtags to return @limit The maximum number of items to be returned
getSearchedForHashtags prefix:string limit:int32 = Hashtags;

View File

@ -15,6 +15,7 @@
#include "td/telegram/FileReferenceManager.h"
#include "td/telegram/files/FileManager.h"
#include "td/telegram/Global.h"
#include "td/telegram/HashtagHints.h"
#include "td/telegram/logevent/LogEvent.h"
#include "td/telegram/logevent/LogEventHelper.h"
#include "td/telegram/MediaArea.hpp"
@ -703,6 +704,61 @@ class DeleteStoriesQuery final : public Td::ResultHandler {
}
};
class SearchStoriesQuery final : public Td::ResultHandler {
Promise<td_api::object_ptr<td_api::foundStories>> promise_;
public:
explicit SearchStoriesQuery(Promise<td_api::object_ptr<td_api::foundStories>> &&promise)
: promise_(std::move(promise)) {
}
void send(string hashtag, string offset, int32 limit) {
int32 flags = telegram_api::stories_searchPosts::HASHTAG_MASK;
send_query(
G()->net_query_creator().create(telegram_api::stories_searchPosts(flags, hashtag, nullptr, offset, limit)));
}
void on_result(BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::stories_searchPosts>(packet);
if (result_ptr.is_error()) {
return on_error(result_ptr.move_as_error());
}
auto ptr = result_ptr.move_as_ok();
LOG(DEBUG) << "Receive result for SearchStoriesQuery: " << to_string(ptr);
td_->user_manager_->on_get_users(std::move(ptr->users_), "SearchStoriesQuery");
td_->chat_manager_->on_get_chats(std::move(ptr->chats_), "SearchStoriesQuery");
auto total_count = ptr->count_;
if (total_count < static_cast<int32>(ptr->stories_.size())) {
LOG(ERROR) << "Receive total count = " << total_count << " and " << ptr->stories_.size() << " stories";
total_count = static_cast<int32>(ptr->stories_.size());
}
vector<td_api::object_ptr<td_api::story>> stories;
for (auto &found_story : ptr->stories_) {
DialogId owner_dialog_id(found_story->peer_);
auto story_id = td_->story_manager_->on_get_story(owner_dialog_id, std::move(found_story->story_));
if (story_id.is_valid()) {
auto story_object = td_->story_manager_->get_story_object({owner_dialog_id, story_id});
if (story_object == nullptr) {
LOG(ERROR) << "Receive deleted " << story_id << " from " << owner_dialog_id;
} else {
stories.push_back(std::move(story_object));
}
}
}
promise_.set_value(td_api::make_object<td_api::foundStories>(total_count, std::move(stories), ptr->next_offset_));
}
void on_error(Status status) final {
if (status.message() == "SEARCH_QUERY_EMPTY") {
return promise_.set_value(td_api::make_object<td_api::foundStories>());
}
promise_.set_error(std::move(status));
}
};
class TogglePinnedStoriesToTopQuery final : public Td::ResultHandler {
Promise<Unit> promise_;
DialogId dialog_id_;
@ -2539,6 +2595,30 @@ void StoryManager::on_get_dialog_expiring_stories(DialogId owner_dialog_id,
}
}
void StoryManager::search_hashtag_posts(string hashtag, string offset, int32 limit,
Promise<td_api::object_ptr<td_api::foundStories>> &&promise) {
if (limit <= 0) {
return promise.set_error(Status::Error(400, "Parameter limit must be positive"));
}
if (limit > MAX_SEARCH_STORIES) {
limit = MAX_SEARCH_STORIES;
}
bool is_cashtag = false;
if (hashtag[0] == '#' || hashtag[0] == '$') {
is_cashtag = (hashtag[0] == '$');
hashtag = hashtag.substr(1);
}
if (hashtag.empty()) {
return promise.set_value(td_api::make_object<td_api::foundStories>());
}
send_closure(is_cashtag ? td_->cashtag_search_hints_ : td_->hashtag_search_hints_, &HashtagHints::hashtag_used,
hashtag);
td_->create_handler<SearchStoriesQuery>(std::move(promise))
->send(PSTRING() << (is_cashtag ? '$' : '#') << hashtag, std::move(offset), limit);
}
void StoryManager::set_pinned_stories(DialogId owner_dialog_id, vector<StoryId> story_ids, Promise<Unit> &&promise) {
TRY_STATUS_PROMISE(promise, td_->dialog_manager_->check_dialog_access(owner_dialog_id, false, AccessRights::Write,
"set_pinned_stories"));

View File

@ -253,6 +253,9 @@ class StoryManager final : public Actor {
void reload_dialog_expiring_stories(DialogId dialog_id);
void search_hashtag_posts(string hashtag, string offset, int32 limit,
Promise<td_api::object_ptr<td_api::foundStories>> &&promise);
void set_pinned_stories(DialogId owner_dialog_id, vector<StoryId> story_ids, Promise<Unit> &&promise);
void open_story(DialogId owner_dialog_id, StoryId story_id, Promise<Unit> &&promise);
@ -366,6 +369,8 @@ class StoryManager final : public Actor {
class SendStoryLogEvent;
class EditStoryLogEvent;
static constexpr int32 MAX_SEARCH_STORIES = 100; // server-side limit
static constexpr int32 OPENED_STORY_POLL_PERIOD = 60;
static constexpr int32 VIEWED_STORY_POLL_PERIOD = 300;

View File

@ -5315,6 +5315,15 @@ void Td::on_request(uint64 id, td_api::searchPublicHashtagMessages &request) {
std::move(promise));
}
void Td::on_request(uint64 id, td_api::searchPublicHashtagStories &request) {
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.hashtag_);
CLEAN_INPUT_STRING(request.offset_);
CREATE_REQUEST_PROMISE();
story_manager_->search_hashtag_posts(std::move(request.hashtag_), std::move(request.offset_), request.limit_,
std::move(promise));
}
void Td::on_request(uint64 id, td_api::getSearchedForHashtags &request) {
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.prefix_);

View File

@ -800,6 +800,8 @@ class Td final : public Actor {
void on_request(uint64 id, td_api::searchPublicHashtagMessages &request);
void on_request(uint64 id, td_api::searchPublicHashtagStories &request);
void on_request(uint64 id, td_api::getSearchedForHashtags &request);
void on_request(uint64 id, td_api::removeSearchedForHashtag &request);

View File

@ -3064,6 +3064,12 @@ class CliClient final : public Actor {
string offset;
get_args(args, hashtag, limit, offset);
send_request(td_api::make_object<td_api::searchPublicHashtagMessages>(hashtag, offset, as_limit(limit)));
} else if (op == "sphs") {
string hashtag;
string limit;
string offset;
get_args(args, hashtag, limit, offset);
send_request(td_api::make_object<td_api::searchPublicHashtagStories>(hashtag, offset, as_limit(limit)));
} else if (op == "gsfh") {
string hashtag;
string limit;