From bda5a3c5bdd5194f887787d82a7fa4f2d0697d11 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 18 Sep 2020 19:42:31 +0300 Subject: [PATCH] Allow sending chat actions inside message thread. GitOrigin-RevId: 6ad0b659f957013fa493386ad808eb6767399253 --- td/generate/scheme/td_api.tl | 4 ++-- td/generate/scheme/td_api.tlo | Bin 181780 -> 181824 bytes td/telegram/MessagesManager.cpp | 40 ++++++++++++++++++++++++-------- td/telegram/MessagesManager.h | 5 ++-- td/telegram/Td.cpp | 3 ++- td/telegram/cli.cpp | 7 ++++-- 6 files changed, 42 insertions(+), 17 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 4b079c614..ac4c341f0 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3903,8 +3903,8 @@ getInlineGameHighScores inline_message_id:string user_id:int32 = GameHighScores; deleteChatReplyMarkup chat_id:int53 message_id:int53 = Ok; -//@description Sends a notification about user activity in a chat @chat_id Chat identifier @action The action description -sendChatAction chat_id:int53 action:ChatAction = Ok; +//@description Sends a notification about user activity in a chat @chat_id Chat identifier @message_thread_id If not 0, a message thread identifier of the action @action The action description +sendChatAction chat_id:int53 message_thread_id:int53 action:ChatAction = Ok; //@description Informs TDLib that the chat is opened by the user. Many useful activities depend on the chat being opened or closed (e.g., in supergroups and channels all updates are received only for opened chats) @chat_id Chat identifier diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 8a1f3a4f98be4315e0b18c2495889187c0349678..780dfa59d181c4c6834b0887d3d0eaf670f7a095 100644 GIT binary patch delta 48 zcmbQz!+oHKyP<_~3zN@OmXL>kYNiKFWs;a4p~j>!ou>;(C}=XVPQIJSzkR_}rV;}H Dz2^~C delta 34 qcmX@m!#$;kyP<_~3zN@O7KP_G&rT1R$|Ny8Vkwix_B~UXS_}a8&kf=L diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 496a07c6e..1b1053369 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -3247,14 +3247,17 @@ class SetTypingQuery : public Td::ResultHandler { explicit SetTypingQuery(Promise &&promise) : promise_(std::move(promise)) { } - NetQueryRef send(DialogId dialog_id, tl_object_ptr &&action) { + NetQueryRef send(DialogId dialog_id, MessageId message_id, tl_object_ptr &&action) { dialog_id_ = dialog_id; auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); CHECK(input_peer != nullptr); int32 flags = 0; - auto net_query = G()->net_query_creator().create( - telegram_api::messages_setTyping(flags, std::move(input_peer), 0, std::move(action))); + if (message_id.is_valid()) { + flags |= telegram_api::messages_setTyping::TOP_MSG_ID_MASK; + } + auto net_query = G()->net_query_creator().create(telegram_api::messages_setTyping( + flags, std::move(input_peer), message_id.get_server_message_id().get(), std::move(action))); auto result = net_query.get_weak(); send_query(std::move(net_query)); return result; @@ -20952,6 +20955,12 @@ MessagesManager::Message *MessagesManager::get_message_to_send( m->send_date = G()->unix_time(); m->date = is_scheduled ? options.schedule_date : m->send_date; m->reply_to_message_id = reply_to_message_id; + if (reply_to_message_id.is_valid()) { + const Message *reply_m = get_message(d, reply_to_message_id); + if (reply_m != nullptr) { + m->top_reply_message_id = reply_m->top_reply_message_id; + } + } m->is_channel_post = is_channel_post; m->is_outgoing = is_scheduled || dialog_id != DialogId(my_id); m->from_background = options.from_background; @@ -24483,6 +24492,12 @@ Result MessagesManager::add_local_message( } m->date = G()->unix_time(); m->reply_to_message_id = get_reply_to_message_id(d, reply_to_message_id); + if (m->reply_to_message_id.is_valid()) { + const Message *reply_m = get_message(d, m->reply_to_message_id); + if (reply_m != nullptr) { + m->top_reply_message_id = reply_m->top_reply_message_id; + } + } m->is_channel_post = is_channel_post; m->is_outgoing = dialog_id != DialogId(my_id) && sender_user_id == my_id; m->disable_notification = disable_notification; @@ -27806,7 +27821,7 @@ bool MessagesManager::get_dialog_has_scheduled_messages(const Dialog *d) const { return d->has_scheduled_server_messages || d->has_scheduled_database_messages || d->scheduled_messages != nullptr; } -bool MessagesManager::is_dialog_action_unneded(DialogId dialog_id) const { +bool MessagesManager::is_dialog_action_unneeded(DialogId dialog_id) const { if (is_anonymous_administrator(dialog_id)) { return true; } @@ -27827,8 +27842,8 @@ bool MessagesManager::is_dialog_action_unneded(DialogId dialog_id) const { return false; } -void MessagesManager::send_dialog_action(DialogId dialog_id, const tl_object_ptr &action, - Promise &&promise) { +void MessagesManager::send_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, + const tl_object_ptr &action, Promise &&promise) { if (action == nullptr) { return promise.set_error(Status::Error(5, "Action must be non-empty")); } @@ -27836,6 +27851,10 @@ void MessagesManager::send_dialog_action(DialogId dialog_id, const tl_object_ptr if (!have_dialog_force(dialog_id)) { return promise.set_error(Status::Error(5, "Chat not found")); } + if (top_thread_message_id != MessageId() && + (!top_thread_message_id.is_valid() || !top_thread_message_id.is_server())) { + return promise.set_error(Status::Error(5, "Invalid message thread specified")); + } auto can_send_status = can_send_message(dialog_id); if (can_send_status.is_error()) { @@ -27845,7 +27864,7 @@ void MessagesManager::send_dialog_action(DialogId dialog_id, const tl_object_ptr return promise.set_value(Unit()); } - if (is_dialog_action_unneded(dialog_id)) { + if (is_dialog_action_unneeded(dialog_id)) { return promise.set_value(Unit()); } @@ -27959,7 +27978,8 @@ void MessagesManager::send_dialog_action(DialogId dialog_id, const tl_object_ptr LOG(INFO) << "Cancel previous set typing query"; cancel_query(query_ref); } - query_ref = td_->create_handler(std::move(promise))->send(dialog_id, std::move(send_action)); + query_ref = td_->create_handler(std::move(promise)) + ->send(dialog_id, top_thread_message_id, std::move(send_action)); } void MessagesManager::on_send_dialog_action_timeout(DialogId dialog_id) { @@ -28035,7 +28055,7 @@ void MessagesManager::on_send_dialog_action_timeout(DialogId dialog_id) { } CHECK(action != nullptr); LOG(INFO) << "Send action in " << dialog_id << ": " << to_string(action); - send_dialog_action(dialog_id, std::move(action), Auto()); + send_dialog_action(dialog_id, m->top_reply_message_id, std::move(action), Auto()); } void MessagesManager::on_active_dialog_action_timeout(DialogId dialog_id) { @@ -29828,7 +29848,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq if (queue_id & 1) { LOG(INFO) << "Add " << message_id << " from " << source << " to queue " << queue_id; yet_unsent_media_queues_[queue_id][message_id.get()]; // reserve place for promise - if (!td_->auth_manager_->is_bot() && !is_dialog_action_unneded(dialog_id)) { + if (!td_->auth_manager_->is_bot() && !is_dialog_action_unneeded(dialog_id)) { pending_send_dialog_action_timeout_.add_timeout_in(dialog_id.get(), 1.0); } } diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 2839762bf..58359d55e 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -472,7 +472,8 @@ class MessagesManager : public Actor { tl_object_ptr get_game_high_scores_object(int64 random_id); - void send_dialog_action(DialogId dialog_id, const tl_object_ptr &action, Promise &&promise); + void send_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, + const tl_object_ptr &action, Promise &&promise); vector get_dialog_lists_to_add_dialog(DialogId dialog_id); @@ -2283,7 +2284,7 @@ class MessagesManager : public Actor { bool update_dialog_silent_send_message(Dialog *d, bool silent_send_message); - bool is_dialog_action_unneded(DialogId dialog_id) const; + bool is_dialog_action_unneeded(DialogId dialog_id) const; void on_send_dialog_action_timeout(DialogId dialog_id); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index f8a3aec8c..c66055824 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5798,7 +5798,8 @@ void Td::on_request(uint64 id, const td_api::deleteChatReplyMarkup &request) { void Td::on_request(uint64 id, td_api::sendChatAction &request) { CREATE_OK_REQUEST_PROMISE(); - messages_manager_->send_dialog_action(DialogId(request.chat_id_), std::move(request.action_), std::move(promise)); + messages_manager_->send_dialog_action(DialogId(request.chat_id_), MessageId(request.message_thread_id_), + std::move(request.action_), std::move(promise)); } void Td::on_request(uint64 id, td_api::sendChatScreenshotTakenNotification &request) { diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 3c3f4f6f4..6027c6b2d 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2936,9 +2936,12 @@ class CliClient final : public Actor { send_request(td_api::make_object(as_chat_list(op), std::move(chat_ids))); } else if (op == "sca") { string chat_id; + string message_thread_id; string action; - std::tie(chat_id, action) = split(args); - send_request(td_api::make_object(as_chat_id(chat_id), get_chat_action(action))); + std::tie(chat_id, args) = split(args); + std::tie(message_thread_id, action) = split(args); + send_request(td_api::make_object( + as_chat_id(chat_id), as_message_thread_id(message_thread_id), get_chat_action(action))); } else if (op == "smt" || op == "smtp" || op == "smtf" || op == "smtpf") { const string &chat_id = args; for (int i = 1; i <= 200; i++) {