From 2992d1e5e4988930c4dd194764477182d2095bc7 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 1 Apr 2022 00:00:50 +0300 Subject: [PATCH] Prolong opened web view every minute. --- td/telegram/AttachMenuManager.cpp | 107 ++++++++++++++++++++++++++++++ td/telegram/AttachMenuManager.h | 16 ++++- 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/td/telegram/AttachMenuManager.cpp b/td/telegram/AttachMenuManager.cpp index 476314851..52c15d73a 100644 --- a/td/telegram/AttachMenuManager.cpp +++ b/td/telegram/AttachMenuManager.cpp @@ -16,6 +16,7 @@ #include "td/telegram/files/FileManager.h" #include "td/telegram/logevent/LogEvent.h" #include "td/telegram/MessagesManager.h" +#include "td/telegram/StateManager.h" #include "td/telegram/Td.h" #include "td/telegram/TdDb.h" #include "td/telegram/ThemeManager.h" @@ -108,6 +109,49 @@ class RequestWebViewQuery final : public Td::ResultHandler { } }; +class ProlongWebViewQuery final : public Td::ResultHandler { + DialogId dialog_id_; + + public: + void send(DialogId dialog_id, UserId bot_user_id, int64 query_id, MessageId reply_to_message_id, bool silent) { + dialog_id_ = dialog_id; + + auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + auto r_input_user = td_->contacts_manager_->get_input_user(bot_user_id); + if (input_peer == nullptr || r_input_user.is_error()) { + return; + } + + int32 flags = 0; + if (reply_to_message_id.is_valid()) { + flags |= telegram_api::messages_prolongWebView::REPLY_TO_MSG_ID_MASK; + } + if (silent) { + flags |= telegram_api::messages_prolongWebView::SILENT_MASK; + } + + send_query(G()->net_query_creator().create(telegram_api::messages_prolongWebView( + flags, false /*ignored*/, std::move(input_peer), r_input_user.move_as_ok(), query_id, + reply_to_message_id.get_server_message_id().get()))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + bool ptr = result_ptr.ok(); + if (!ptr) { + LOG(ERROR) << "Failed to prolong a web view"; + } + } + + void on_error(Status status) final { + td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "ProlongWebViewQuery"); + } +}; + class GetAttachMenuBotsQuery final : public Td::ResultHandler { Promise> promise_; @@ -382,6 +426,22 @@ void AttachMenuManager::init() { } } + class StateCallback final : public StateManager::Callback { + public: + explicit StateCallback(ActorId parent) : parent_(std::move(parent)) { + } + bool on_online(bool is_online) final { + if (is_online) { + send_closure(parent_, &AttachMenuManager::on_online, is_online); + } + return parent_.is_alive(); + } + + private: + ActorId parent_; + }; + send_closure(G()->state_manager(), &StateManager::add_callback, make_unique(actor_id(this))); + send_update_attach_menu_bots(); reload_attach_menu_bots(Promise()); } @@ -398,6 +458,46 @@ bool AttachMenuManager::is_active() const { return !G()->close_flag() && td_->auth_manager_->is_authorized() && !td_->auth_manager_->is_bot(); } +void AttachMenuManager::on_online(bool is_online) { + if (is_online) { + ping_web_view(); + } else { + ping_web_view_timeout_.cancel_timeout(); + } +} + +void AttachMenuManager::ping_web_view_static(void *td_void) { + if (G()->close_flag()) { + return; + } + + CHECK(td_void != nullptr); + auto td = static_cast(td_void); + + td->attach_menu_manager_->ping_web_view(); +} + +void AttachMenuManager::ping_web_view() { + if (G()->close_flag() || opened_web_views_.empty()) { + return; + } + + for (const auto &it : opened_web_views_) { + const auto &opened_web_view = it.second; + bool silent = td_->messages_manager_->get_dialog_silent_send_message(opened_web_view.dialog_id_); + td_->create_handler()->send(opened_web_view.dialog_id_, opened_web_view.bot_user_id_, it.first, + opened_web_view.reply_to_message_id_, silent); + } + + schedule_ping_web_view(); +} + +void AttachMenuManager::schedule_ping_web_view() { + ping_web_view_timeout_.set_callback(ping_web_view_static); + ping_web_view_timeout_.set_callback_data(static_cast(td_)); + ping_web_view_timeout_.set_timeout_in(PING_WEB_VIEW_TIMEOUT); +} + void AttachMenuManager::request_web_view(DialogId dialog_id, UserId bot_user_id, MessageId reply_to_message_id, string &&url, bool from_bot_menu, td_api::object_ptr &&theme, @@ -448,6 +548,10 @@ void AttachMenuManager::open_web_view(int64 query_id, DialogId dialog_id, UserId LOG(ERROR) << "Receive web app query identifier == 0"; return; } + + if (opened_web_views_.empty()) { + schedule_ping_web_view(); + } OpenedWebView opened_web_view; opened_web_view.dialog_id_ = dialog_id; opened_web_view.bot_user_id_ = bot_user_id; @@ -457,6 +561,9 @@ void AttachMenuManager::open_web_view(int64 query_id, DialogId dialog_id, UserId void AttachMenuManager::close_web_view(int64 query_id, Promise &&promise) { opened_web_views_.erase(query_id); + if (opened_web_views_.empty()) { + ping_web_view_timeout_.cancel_timeout(); + } promise.set_value(Unit()); } diff --git a/td/telegram/AttachMenuManager.h b/td/telegram/AttachMenuManager.h index 57fb7c504..981e2402e 100644 --- a/td/telegram/AttachMenuManager.h +++ b/td/telegram/AttachMenuManager.h @@ -15,6 +15,7 @@ #include "td/actor/actor.h" #include "td/actor/PromiseFuture.h" +#include "td/actor/Timeout.h" #include "td/utils/common.h" #include "td/utils/FlatHashSet.h" @@ -47,14 +48,14 @@ class AttachMenuManager final : public Actor { void get_current_state(vector> &updates) const; private: + static const int32 PING_WEB_VIEW_TIMEOUT = 60; + void start_up() final; void timeout_expired() final; void tear_down() final; - bool is_active() const; - struct AttachMenuBotColor { int32 light_color_ = -1; int32 dark_color_ = -1; @@ -95,6 +96,16 @@ class AttachMenuManager final : public Actor { friend bool operator!=(const AttachMenuBot &lhs, const AttachMenuBot &rhs); + bool is_active() const; + + void on_online(bool is_online); + + static void ping_web_view_static(void *td_void); + + void ping_web_view(); + + void schedule_ping_web_view(); + Result get_attach_menu_bot(tl_object_ptr &&bot) const; td_api::object_ptr get_attach_menu_bot_object(const AttachMenuBot &bot) const; @@ -129,6 +140,7 @@ class AttachMenuManager final : public Actor { MessageId reply_to_message_id_; }; FlatHashMap opened_web_views_; + Timeout ping_web_view_timeout_; }; } // namespace td