Add td_api::canSendStory.

This commit is contained in:
levlam 2023-08-11 19:43:26 +03:00
parent 6d68de2c0c
commit fd2df72321
7 changed files with 110 additions and 11 deletions

View File

@ -4226,6 +4226,24 @@ chatTheme name:string light_settings:themeSettings dark_settings:themeSettings =
hashtags hashtags:vector<string> = Hashtags; hashtags hashtags:vector<string> = Hashtags;
//@class CanSendStoryResult @description Represents result of checking whether the current user can send a story
//@description A story can be sent
canSendStoryResultOk = CanSendStoryResult;
//@description The user must subscribe to Telegram Premium to be able to post stories
canSendStoryResultPremiumNeeded = CanSendStoryResult;
//@description The limit for the number of active stories exceeded. The user can buy Telegram Premium, delete an active story, or wait for the oldest story to expire
canSendStoryResultActiveStoryLimitExceeded = CanSendStoryResult;
//@description The weekly limit for the number of posted stories exceeded. The user needs to buy Telegram Premium or wait specified time @retry_after Time left before the user can send the next story
canSendStoryResultWeeklyLimitExceeded retry_after:int32 = CanSendStoryResult;
//@description The monthly limit for the number of posted stories exceeded. The user needs to buy Telegram Premium or wait specified time @retry_after Time left before the user can send the next story
canSendStoryResultMonthlyLimitExceeded retry_after:int32 = CanSendStoryResult;
//@class CanTransferOwnershipResult @description Represents result of checking whether the current session can be used to transfer a chat ownership to another user //@class CanTransferOwnershipResult @description Represents result of checking whether the current session can be used to transfer a chat ownership to another user
//@description The session can be used //@description The session can be used
@ -7425,6 +7443,9 @@ readChatList chat_list:ChatList = Ok;
//@only_local Pass true to get only locally available information without sending network requests //@only_local Pass true to get only locally available information without sending network requests
getStory story_sender_chat_id:int53 story_id:int32 only_local:Bool = Story; getStory story_sender_chat_id:int53 story_id:int32 only_local:Bool = Story;
//@description Checks whether the current user can send a story
canSendStory = CanSendStoryResult;
//@description Sends a new story. Returns a temporary story //@description Sends a new story. Returns a temporary story
//@content Content of the story //@content Content of the story
//@areas Clickable rectangle areas to be shown on the story media; pass null if none //@areas Clickable rectangle areas to be shown on the story media; pass null if none

View File

@ -56,6 +56,39 @@
namespace td { namespace td {
static td_api::object_ptr<td_api::CanSendStoryResult> get_can_send_story_result_object(const Status &error) {
CHECK(error.is_error());
if (error.message() == "PREMIUM_ACCOUNT_REQUIRED") {
return td_api::make_object<td_api::canSendStoryResultPremiumNeeded>();
}
if (error.message() == "STORIES_TOO_MUCH") {
return td_api::make_object<td_api::canSendStoryResultActiveStoryLimitExceeded>();
}
if (begins_with(error.message(), "STORY_SEND_FLOOD_WEEKLY_")) {
auto r_next_date = to_integer_safe<int32>(error.message().substr(Slice("STORY_SEND_FLOOD_WEEKLY_").size()));
if (r_next_date.is_ok() && r_next_date.ok() > 0) {
auto retry_after = r_next_date.ok() - G()->unix_time();
if (retry_after > 0) {
return td_api::make_object<td_api::canSendStoryResultWeeklyLimitExceeded>(retry_after);
} else {
return td_api::make_object<td_api::canSendStoryResultOk>();
}
}
}
if (begins_with(error.message(), "STORY_SEND_FLOOD_MONTHLY_")) {
auto r_next_date = to_integer_safe<int32>(error.message().substr(Slice("STORY_SEND_FLOOD_MONTHLY_").size()));
if (r_next_date.is_ok() && r_next_date.ok() > 0) {
auto retry_after = r_next_date.ok() - G()->unix_time();
if (retry_after > 0) {
return td_api::make_object<td_api::canSendStoryResultMonthlyLimitExceeded>(retry_after);
} else {
return td_api::make_object<td_api::canSendStoryResultOk>();
}
}
}
return nullptr;
}
class GetAllStoriesQuery final : public Td::ResultHandler { class GetAllStoriesQuery final : public Td::ResultHandler {
Promise<telegram_api::object_ptr<telegram_api::stories_AllStories>> promise_; Promise<telegram_api::object_ptr<telegram_api::stories_AllStories>> promise_;
@ -652,6 +685,36 @@ class ActivateStealthModeQuery final : public Td::ResultHandler {
} }
}; };
class CanSendStoryQuery final : public Td::ResultHandler {
Promise<td_api::object_ptr<td_api::CanSendStoryResult>> promise_;
public:
explicit CanSendStoryQuery(Promise<td_api::object_ptr<td_api::CanSendStoryResult>> &&promise)
: promise_(std::move(promise)) {
}
void send() {
send_query(G()->net_query_creator().create(telegram_api::stories_canSendStory()));
}
void on_result(BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::stories_canSendStory>(packet);
if (result_ptr.is_error()) {
return on_error(result_ptr.move_as_error());
}
promise_.set_value(td_api::make_object<td_api::canSendStoryResultOk>());
}
void on_error(Status status) final {
auto result = get_can_send_story_result_object(status);
if (result != nullptr) {
return promise_.set_value(std::move(result));
}
return promise_.set_error(std::move(status));
}
};
class StoryManager::SendStoryQuery final : public Td::ResultHandler { class StoryManager::SendStoryQuery final : public Td::ResultHandler {
FileId file_id_; FileId file_id_;
unique_ptr<PendingStory> pending_story_; unique_ptr<PendingStory> pending_story_;
@ -3778,6 +3841,10 @@ Result<StoryId> StoryManager::get_next_yet_unsent_story_id(DialogId dialog_id) {
return StoryId(++story_id); return StoryId(++story_id);
} }
void StoryManager::can_send_story(Promise<td_api::object_ptr<td_api::CanSendStoryResult>> &&promise) {
td_->create_handler<CanSendStoryQuery>(std::move(promise))->send();
}
void StoryManager::send_story(td_api::object_ptr<td_api::InputStoryContent> &&input_story_content, void StoryManager::send_story(td_api::object_ptr<td_api::InputStoryContent> &&input_story_content,
td_api::object_ptr<td_api::inputStoryAreas> &&input_areas, td_api::object_ptr<td_api::inputStoryAreas> &&input_areas,
td_api::object_ptr<td_api::formattedText> &&input_caption, td_api::object_ptr<td_api::formattedText> &&input_caption,

View File

@ -198,6 +198,8 @@ class StoryManager final : public Actor {
void get_story(DialogId owner_dialog_id, StoryId story_id, bool only_local, void get_story(DialogId owner_dialog_id, StoryId story_id, bool only_local,
Promise<td_api::object_ptr<td_api::story>> &&promise); Promise<td_api::object_ptr<td_api::story>> &&promise);
void can_send_story(Promise<td_api::object_ptr<td_api::CanSendStoryResult>> &&promise);
void send_story(td_api::object_ptr<td_api::InputStoryContent> &&input_story_content, void send_story(td_api::object_ptr<td_api::InputStoryContent> &&input_story_content,
td_api::object_ptr<td_api::inputStoryAreas> &&input_areas, td_api::object_ptr<td_api::inputStoryAreas> &&input_areas,
td_api::object_ptr<td_api::formattedText> &&input_caption, td_api::object_ptr<td_api::formattedText> &&input_caption,

View File

@ -5630,6 +5630,12 @@ void Td::on_request(uint64 id, const td_api::getStory &request) {
std::move(promise)); std::move(promise));
} }
void Td::on_request(uint64 id, const td_api::canSendStory &request) {
CHECK_IS_USER();
CREATE_REQUEST_PROMISE();
story_manager_->can_send_story(std::move(promise));
}
void Td::on_request(uint64 id, td_api::sendStory &request) { void Td::on_request(uint64 id, td_api::sendStory &request) {
CHECK_IS_USER(); CHECK_IS_USER();
CREATE_REQUEST_PROMISE(); CREATE_REQUEST_PROMISE();

View File

@ -791,6 +791,8 @@ class Td final : public Actor {
void on_request(uint64 id, const td_api::getStory &request); void on_request(uint64 id, const td_api::getStory &request);
void on_request(uint64 id, const td_api::canSendStory &request);
void on_request(uint64 id, td_api::sendStory &request); void on_request(uint64 id, td_api::sendStory &request);
void on_request(uint64 id, td_api::editStory &request); void on_request(uint64 id, td_api::editStory &request);

View File

@ -4040,6 +4040,8 @@ class CliClient final : public Actor {
StoryId story_id; StoryId story_id;
get_args(args, story_sender_chat_id, story_id); get_args(args, story_sender_chat_id, story_id);
send_request(td_api::make_object<td_api::getStory>(story_sender_chat_id, story_id, op == "gstl")); send_request(td_api::make_object<td_api::getStory>(story_sender_chat_id, story_id, op == "gstl"));
} else if (op == "csst") {
send_request(td_api::make_object<td_api::canSendStory>());
} else if (op == "ssp" || op == "sspp") { } else if (op == "ssp" || op == "sspp") {
string photo; string photo;
string caption; string caption;

View File

@ -64,17 +64,16 @@ void NetQueryDispatcher::dispatch(NetQueryPtr net_query) {
return; return;
} }
if (net_query->is_ready()) { if (net_query->is_ready() && net_query->is_error()) {
if (net_query->is_error()) { auto code = net_query->error().code();
auto code = net_query->error().code(); if (code == 303) {
if (code == 303) { try_fix_migrate(net_query);
try_fix_migrate(net_query); } else if (code == NetQuery::Resend) {
} else if (code == NetQuery::Resend) { net_query->resend();
net_query->resend(); } else if (code < 0 || code == 500 ||
} else if (code < 0 || code == 500 || code == 420) { (code == 420 && !begins_with(net_query->error().message(), "STORY_SEND_FLOOD_"))) {
net_query->debug("sent to NetQueryDelayer"); net_query->debug("sent to NetQueryDelayer");
return send_closure_later(delayer_, &NetQueryDelayer::delay, std::move(net_query)); return send_closure_later(delayer_, &NetQueryDelayer::delay, std::move(net_query));
}
} }
} }