diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 81539a63..21579e7c 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1490,7 +1490,8 @@ messageSchedulingStateSendWhenOnline = MessageSchedulingState; //@description Options to be used when a message is send //@disable_notification Pass true to disable notification for the message. Must be false if the message is sent to a secret chat //@from_background Pass true if the message is sent from the background -sendMessageOptions disable_notification:Bool from_background:Bool = SendMessageOptions; +//@scheduling_state Message scheduling state. Messages sent to a secret chat, live location messages and self-destructing messages can't be scheduled +sendMessageOptions disable_notification:Bool from_background:Bool scheduling_state:MessageSchedulingState = SendMessageOptions; //@class InputMessageContent @description The content of a message to send diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index a084480f..1cec8740 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 05d2d825..5fb3d53e 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -17287,11 +17287,10 @@ MessagesManager::Message *MessagesManager::get_message_to_send(Dialog *d, Messag CHECK(d != nullptr); CHECK(!reply_to_message_id.is_scheduled()); - int32 schedule_date = 0; - bool is_scheduled = schedule_date != 0; + bool is_scheduled = options.schedule_date != 0; DialogId dialog_id = d->dialog_id; - MessageId message_id = - is_scheduled ? get_next_yet_unsent_scheduled_message_id(d, schedule_date) : get_next_yet_unsent_message_id(d); + MessageId message_id = is_scheduled ? get_next_yet_unsent_scheduled_message_id(d, options.schedule_date) + : get_next_yet_unsent_message_id(d); LOG(INFO) << "Create " << message_id << " in " << dialog_id; auto dialog_type = dialog_id.get_type(); @@ -17309,7 +17308,7 @@ MessagesManager::Message *MessagesManager::get_message_to_send(Dialog *d, Messag m->sender_user_id = my_id; } m->send_date = G()->unix_time(); - m->date = is_scheduled ? schedule_date : m->send_date; + m->date = is_scheduled ? options.schedule_date : m->send_date; m->reply_to_message_id = reply_to_message_id; m->is_channel_post = is_channel_post; m->is_outgoing = is_scheduled || dialog_id != DialogId(my_id); @@ -17960,17 +17959,35 @@ Result MessagesManager::process_input_message_content( } Result MessagesManager::process_send_message_options( - DialogId dialog_id, tl_object_ptr &&options) { + DialogId dialog_id, tl_object_ptr &&options) const { SendMessageOptions result; if (options != nullptr) { result.disable_notification = options->disable_notification_; result.from_background = options->from_background_; + TRY_RESULT_ASSIGN(result.schedule_date, get_message_schedule_date(std::move(options->scheduling_state_))); } - bool is_secret = dialog_id.get_type() == DialogType::SecretChat; + auto dialog_type = dialog_id.get_type(); + bool is_secret = dialog_type == DialogType::SecretChat; if (result.disable_notification && is_secret) { return Status::Error(400, "Can't send messages with silent notifications to secret chats"); } + if (result.schedule_date != 0) { + if (is_secret) { + return Status::Error(400, "Can't schedule messages in secret chats"); + } + if (td_->auth_manager_->is_bot()) { + return Status::Error(400, "Bots can't send scheduled messages"); + } + } + if (result.schedule_date == SCHEDULE_WHEN_ONLINE_DATE) { + if (dialog_type != DialogType::User) { + return Status::Error(400, "Messages can be scheduled till online only in private chats"); + } + if (dialog_id == get_my_dialog_id()) { + return Status::Error(400, "Can't scheduled till online messages in chat with self"); + } + } return result; } @@ -20521,7 +20538,8 @@ Result> MessagesManager::resend_messages(DialogId dialog_id, v CHECK(message != nullptr); send_update_delete_messages(dialog_id, {message->message_id.get()}, true, false); - SendMessageOptions options(message->disable_notification, message->from_background); + SendMessageOptions options(message->disable_notification, message->from_background, + get_message_schedule_date(message.get())); Message *m = get_message_to_send(d, get_reply_to_message_id(d, message->reply_to_message_id), options, std::move(new_contents[i]), &need_update_dialog_pos); m->reply_markup = std::move(message->reply_markup); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 8ed39670..e001e0eb 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -1370,10 +1370,11 @@ class MessagesManager : public Actor { struct SendMessageOptions { bool disable_notification = false; bool from_background = false; + int32 schedule_date = 0; SendMessageOptions() = default; - SendMessageOptions(bool disable_notification, bool from_background) - : disable_notification(disable_notification), from_background(from_background) { + SendMessageOptions(bool disable_notification, bool from_background, int32 schedule_date) + : disable_notification(disable_notification), from_background(from_background), schedule_date(schedule_date) { } }; @@ -1498,7 +1499,7 @@ class MessagesManager : public Actor { DialogId dialog_id, tl_object_ptr &&input_message_content); Result process_send_message_options(DialogId dialog_id, - tl_object_ptr &&options); + tl_object_ptr &&options) const; Message *get_message_to_send(Dialog *d, MessageId reply_to_message_id, const SendMessageOptions &options, unique_ptr &&content, bool *need_update_dialog_pos, diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 29bea19b..dcfddbc6 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -1277,8 +1277,9 @@ class CliClient final : public Actor { auto chat = as_chat_id(chat_id); auto id = send_request(td_api::make_object( chat, reply_to_message_id, - td_api::make_object(disable_notification, from_background), nullptr, - std::move(input_message_content))); + td_api::make_object(disable_notification, from_background, + as_message_scheduling_state(schedule_date_)), + nullptr, std::move(input_message_content))); query_id_to_send_message_info_[id].start_time = Time::now(); } @@ -2751,6 +2752,8 @@ class CliClient final : public Actor { send_request(td_api::make_object( as_chat_id(chat_id), query, to_integer(from_search_id), to_integer(limit), get_search_messages_filter(filter))); + } else if (op == "ssd") { + schedule_date_ = args; } else if (op == "sm" || op == "sms" || op == "smr" || op == "smf") { string chat_id; string reply_to_message_id; @@ -3995,6 +3998,7 @@ class CliClient final : public Actor { std::unordered_map being_downloaded_files_; int32 my_id_ = 0; + string schedule_date_; ConcurrentScheduler *scheduler_{nullptr};