diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index eba0dc009..a63d93503 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -7180,6 +7180,9 @@ setPinnedChats chat_list:ChatList chat_ids:vector = Ok; readChatList chat_list:ChatList = Ok; +//@description Returns a story @user_id Identifier of the user, which sent the story @story_id Story identifier +getStory user_id:int53 story_id:int32 = Story; + //@description Sends a new story. Returns a temporary story with identifier 0 //@content Content of the story //@caption Story caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters diff --git a/td/telegram/StoryManager.cpp b/td/telegram/StoryManager.cpp index 69253d6b3..85f23730a 100644 --- a/td/telegram/StoryManager.cpp +++ b/td/telegram/StoryManager.cpp @@ -829,6 +829,44 @@ void StoryManager::reload_story(StoryFullId story_full_id, Promise &&promi td_->create_handler(std::move(promise))->send(user_id, {story_full_id.get_story_id().get()}); } +void StoryManager::get_story(DialogId owner_dialog_id, StoryId story_id, + Promise> &&promise) { + if (!td_->messages_manager_->have_dialog_info_force(owner_dialog_id)) { + return promise.set_error(Status::Error(400, "Story sender not found")); + } + if (!td_->messages_manager_->have_input_peer(owner_dialog_id, AccessRights::Read)) { + return promise.set_error(Status::Error(400, "Can't access the story sender")); + } + if (!story_id.is_server()) { + return promise.set_error(Status::Error(400, "Invalid story identifier specified")); + } + if (owner_dialog_id.get_type() != DialogType::User) { + return promise.set_value(nullptr); + } + + StoryFullId story_full_id{owner_dialog_id, story_id}; + const Story *story = get_story(story_full_id); + if (story != nullptr) { + return promise.set_value(get_story_object(story_full_id, story)); + } + + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), story_full_id, promise = std::move(promise)](Result &&result) mutable { + send_closure(actor_id, &StoryManager::do_get_story, story_full_id, std::move(result), std::move(promise)); + }); + td_->create_handler(std::move(query_promise)) + ->send(owner_dialog_id.get_user_id(), {story_id.get()}); +} + +void StoryManager::do_get_story(StoryFullId story_full_id, Result &&result, + Promise> &&promise) { + G()->ignore_result_if_closing(result); + if (result.is_error()) { + return promise.set_error(result.move_as_error()); + } + promise.set_value(get_story_object(story_full_id)); +} + void StoryManager::send_story(td_api::object_ptr &&input_story_content, td_api::object_ptr &&input_caption, td_api::object_ptr &&rules, bool is_pinned, diff --git a/td/telegram/StoryManager.h b/td/telegram/StoryManager.h index a15a61f8e..c1d20e30a 100644 --- a/td/telegram/StoryManager.h +++ b/td/telegram/StoryManager.h @@ -75,6 +75,8 @@ class StoryManager final : public Actor { StoryManager &operator=(StoryManager &&) = delete; ~StoryManager() final; + void get_story(DialogId owner_dialog_id, StoryId story_id, Promise> &&promise); + void send_story(td_api::object_ptr &&input_story_content, td_api::object_ptr &&input_caption, td_api::object_ptr &&rules, bool is_pinned, @@ -160,6 +162,9 @@ class StoryManager final : public Actor { void change_story_files(StoryFullId story_full_id, const Story *story, const vector &old_file_ids); + void do_get_story(StoryFullId story_full_id, Result &&result, + Promise> &&promise); + void do_send_story(unique_ptr &&pending_story, vector bad_parts); void on_upload_story(FileId file_id, telegram_api::object_ptr input_file); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 2c40a64d0..eb69a340d 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -121,6 +121,7 @@ #include "td/telegram/StickersManager.h" #include "td/telegram/StickerType.h" #include "td/telegram/StorageManager.h" +#include "td/telegram/StoryId.h" #include "td/telegram/StoryManager.h" #include "td/telegram/SuggestedAction.h" #include "td/telegram/Support.h" @@ -5619,6 +5620,12 @@ void Td::on_request(uint64 id, td_api::editMessageSchedulingState &request) { std::move(request.scheduling_state_), std::move(promise)); } +void Td::on_request(uint64 id, const td_api::getStory &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + story_manager_->get_story(DialogId(UserId(request.user_id_)), StoryId(request.story_id_), std::move(promise)); +} + void Td::on_request(uint64 id, td_api::sendStory &request) { CHECK_IS_USER(); CREATE_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index e78baf14a..13182ca59 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -786,6 +786,8 @@ class Td final : public Actor { void on_request(uint64 id, td_api::editMessageSchedulingState &request); + void on_request(uint64 id, const td_api::getStory &request); + void on_request(uint64 id, td_api::sendStory &request); void on_request(uint64 id, td_api::editStory &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 5fff35203..2e70600af 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3935,6 +3935,11 @@ class CliClient final : public Actor { send_request(td_api::make_object(as_chat_list(op), as_chat_ids(args))); } else if (op == "rcl" || op == "rcla" || begins_with(op, "rcl-")) { send_request(td_api::make_object(as_chat_list(op))); + } else if (op == "gst") { + UserId user_id; + StoryId story_id; + get_args(args, user_id, story_id); + send_request(td_api::make_object(user_id, story_id)); } else if (op == "ssp" || op == "sspp") { string photo; string caption;