From 7d5b4e307d8c3e86ac297c1b7436edcfd8713034 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 2 Nov 2023 01:09:30 +0300 Subject: [PATCH] Add getWebPagePreview.link_preview_options. --- td/generate/scheme/td_api.tl | 6 ++- td/telegram/Td.cpp | 3 +- td/telegram/WebPagesManager.cpp | 65 ++++++++++++++++++++++----------- td/telegram/WebPagesManager.h | 16 ++++++-- td/telegram/cli.cpp | 2 +- 5 files changed, 64 insertions(+), 28 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 85b5f4246..baa38def6 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -8568,8 +8568,10 @@ searchHashtags prefix:string limit:int32 = Hashtags; removeRecentHashtag hashtag:string = Ok; -//@description Returns a web page preview by the text of the message. Do not call this function too often. Returns a 404 error if the web page has no preview @text Message text with formatting -getWebPagePreview text:formattedText = WebPage; +//@description Returns a link preview by the text of a message. Do not call this function too often. Returns a 404 error if the text has no link preview +//@text Message text with formatting +//@link_preview_options Options to be used for generation of the link preview; pass null to use default link preview options +getWebPagePreview text:formattedText link_preview_options:linkPreviewOptions = WebPage; //@description Returns an instant view version of a web page if available. Returns a 404 error if the web page has no instant view page @url The web page URL @force_full Pass true to get full instant view for the web page getWebPageInstantView url:string force_full:Bool = WebPageInstantView; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 468f6a8d1..86a8a9e30 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5924,7 +5924,8 @@ void Td::on_request(uint64 id, const td_api::resendMessages &request) { void Td::on_request(uint64 id, td_api::getWebPagePreview &request) { CHECK_IS_USER(); CREATE_REQUEST_PROMISE(); - web_pages_manager_->get_web_page_preview(std::move(request.text_), std::move(promise)); + web_pages_manager_->get_web_page_preview(std::move(request.text_), std::move(request.link_preview_options_), + std::move(promise)); } void Td::on_request(uint64 id, td_api::getWebPageInstantView &request) { diff --git a/td/telegram/WebPagesManager.cpp b/td/telegram/WebPagesManager.cpp index 604b772cf..e8ec6c040 100644 --- a/td/telegram/WebPagesManager.cpp +++ b/td/telegram/WebPagesManager.cpp @@ -61,15 +61,16 @@ namespace td { class GetWebPagePreviewQuery final : public Td::ResultHandler { Promise> promise_; - string first_url_; + unique_ptr options_; public: explicit GetWebPagePreviewQuery(Promise> &&promise) : promise_(std::move(promise)) { } - void send(const string &text, vector> &&entities, string first_url) { - first_url_ = std::move(first_url); + void send(const string &text, vector> &&entities, + unique_ptr &&options) { + options_ = std::move(options); int32 flags = 0; if (!entities.empty()) { @@ -88,7 +89,7 @@ class GetWebPagePreviewQuery final : public Td::ResultHandler { auto ptr = result_ptr.move_as_ok(); LOG(INFO) << "Receive result for GetWebPagePreviewQuery: " << to_string(ptr); - td_->web_pages_manager_->on_get_web_page_preview(first_url_, std::move(ptr), std::move(promise_)); + td_->web_pages_manager_->on_get_web_page_preview(std::move(options_), std::move(ptr), std::move(promise_)); } void on_error(Status status) final { @@ -836,14 +837,14 @@ void WebPagesManager::unregister_web_page(WebPageId web_page_id, MessageFullId m } } -void WebPagesManager::on_get_web_page_preview(const string &first_url, +void WebPagesManager::on_get_web_page_preview(unique_ptr &&options, tl_object_ptr &&message_media_ptr, Promise> &&promise) { CHECK(message_media_ptr != nullptr); int32 constructor_id = message_media_ptr->get_id(); if (constructor_id != telegram_api::messageMediaWebPage::ID) { if (constructor_id == telegram_api::messageMediaEmpty::ID) { - on_get_web_page_preview_success(first_url, WebPageId(), std::move(promise)); + on_get_web_page_preview_success(std::move(options), WebPageId(), std::move(promise)); return; } @@ -856,45 +857,67 @@ void WebPagesManager::on_get_web_page_preview(const string &first_url, auto web_page_id = on_get_web_page(std::move(message_media_web_page->webpage_), DialogId()); if (web_page_id.is_valid() && !have_web_page(web_page_id)) { - pending_get_web_pages_[web_page_id].emplace_back(first_url, std::move(promise)); + pending_get_web_pages_[web_page_id].emplace_back(std::move(options), std::move(promise)); return; } - on_get_web_page_preview_success(first_url, web_page_id, std::move(promise)); + on_get_web_page_preview_success(std::move(options), web_page_id, std::move(promise)); } -void WebPagesManager::on_get_web_page_preview_success(const string &first_url, WebPageId web_page_id, +void WebPagesManager::on_get_web_page_preview_success(unique_ptr &&options, + WebPageId web_page_id, Promise> &&promise) { CHECK(web_page_id == WebPageId() || have_web_page(web_page_id)); + CHECK(options != nullptr); + CHECK(options->link_preview_options_ != nullptr); - if (web_page_id.is_valid() && !first_url.empty()) { - on_get_web_page_by_url(first_url, web_page_id, true); + if (web_page_id.is_valid() && !options->first_url_.empty()) { + on_get_web_page_by_url(options->first_url_, web_page_id, true); } - promise.set_value(get_web_page_object(web_page_id, false, false, false, false)); + promise.set_value(get_web_page_object(web_page_id, options->link_preview_options_->force_small_media_, + options->link_preview_options_->force_large_media_, options->skip_confirmation_, + options->link_preview_options_->show_above_text_)); } void WebPagesManager::get_web_page_preview(td_api::object_ptr &&text, + td_api::object_ptr &&link_preview_options, Promise> &&promise) { TRY_RESULT_PROMISE( promise, formatted_text, get_formatted_text(td_, DialogId(), std::move(text), td_->auth_manager_->is_bot(), true, true, true)); - auto first_url = get_first_url(formatted_text).str(); - if (first_url.empty()) { + if (link_preview_options == nullptr) { + link_preview_options = td_api::make_object(); + } + if (link_preview_options->is_disabled_) { + return promise.set_value(nullptr); + } + auto url = link_preview_options->url_.empty() ? get_first_url(formatted_text).str() : link_preview_options->url_; + if (url.empty()) { return promise.set_value(nullptr); } - LOG(INFO) << "Trying to get web page preview for message \"" << formatted_text.text << '"'; + LOG(INFO) << "Trying to get web page preview for \"" << url << '"'; - auto web_page_id = get_web_page_by_url(first_url); + auto web_page_id = get_web_page_by_url(url); + bool skip_confirmation = is_visible_url(formatted_text, url); if (web_page_id.is_valid()) { - return promise.set_value(get_web_page_object(web_page_id, false, false, false, false)); + return promise.set_value(get_web_page_object(web_page_id, link_preview_options->force_small_media_, + link_preview_options->force_large_media_, skip_confirmation, + link_preview_options->show_above_text_)); } + if (!link_preview_options->url_.empty()) { + formatted_text.text = link_preview_options->url_, formatted_text.entities.clear(); + } + auto options = make_unique(); + options->first_url_ = std::move(url); + options->skip_confirmation_ = skip_confirmation; + options->link_preview_options_ = std::move(link_preview_options); td_->create_handler(std::move(promise)) ->send(formatted_text.text, get_input_message_entities(td_->contacts_manager_.get(), formatted_text.entities, "get_web_page_preview"), - std::move(first_url)); + std::move(options)); } void WebPagesManager::get_web_page_instant_view(const string &url, bool force_full, Promise &&promise) { @@ -1336,8 +1359,8 @@ tl_object_ptr WebPagesManager::get_web_page_object(WebPageId we get_formatted_text_object(description, true, duration == 0 ? std::numeric_limits::max() : duration), get_photo_object(td_->file_manager_.get(), web_page->photo_), web_page->embed_url_, web_page->embed_type_, web_page->embed_dimensions_.width, web_page->embed_dimensions_.height, web_page->duration_, web_page->author_, - web_page->has_large_media_, force_small_media, web_page->has_large_media_ && force_large_media, skip_confirmation, - invert_media, + web_page->has_large_media_, force_small_media && !force_large_media, + web_page->has_large_media_ && force_large_media, skip_confirmation, invert_media, web_page->document_.type == Document::Type::Animation ? td_->animations_manager_->get_animation_object(web_page->document_.file_id) : nullptr, @@ -1421,7 +1444,7 @@ void WebPagesManager::on_web_page_changed(WebPageId web_page_id, bool have_web_p auto requests = std::move(get_it->second); pending_get_web_pages_.erase(get_it); for (auto &request : requests) { - on_get_web_page_preview_success(request.first, have_web_page ? web_page_id : WebPageId(), + on_get_web_page_preview_success(std::move(request.first), have_web_page ? web_page_id : WebPageId(), std::move(request.second)); } } diff --git a/td/telegram/WebPagesManager.h b/td/telegram/WebPagesManager.h index 92d343f3c..9800308f1 100644 --- a/td/telegram/WebPagesManager.h +++ b/td/telegram/WebPagesManager.h @@ -46,6 +46,12 @@ class WebPagesManager final : public Actor { WebPagesManager &operator=(WebPagesManager &&) = delete; ~WebPagesManager() final; + struct GetWebPagePreviewOptions { + string first_url_; + bool skip_confirmation_ = false; + td_api::object_ptr link_preview_options_; + }; + static string get_web_page_url(const tl_object_ptr &web_page_ptr); WebPageId on_get_web_page(tl_object_ptr &&web_page_ptr, DialogId owner_dialog_id); @@ -69,6 +75,7 @@ class WebPagesManager final : public Actor { tl_object_ptr get_web_page_instant_view_object(WebPageId web_page_id) const; void get_web_page_preview(td_api::object_ptr &&text, + td_api::object_ptr &&link_preview_options, Promise> &&promise); void get_web_page_instant_view(const string &url, bool force_full, Promise &&promise); @@ -81,7 +88,8 @@ class WebPagesManager final : public Actor { void reload_web_page_by_url(const string &url, Promise &&promise); - void on_get_web_page_preview(const string &first_url, tl_object_ptr &&message_media_ptr, + void on_get_web_page_preview(unique_ptr &&options, + tl_object_ptr &&message_media_ptr, Promise> &&promise); void on_binlog_web_page_event(BinlogEvent &&event); @@ -130,7 +138,7 @@ class WebPagesManager final : public Actor { void on_pending_web_page_timeout(WebPageId web_page_id); - void on_get_web_page_preview_success(const string &first_url, WebPageId web_page_id, + void on_get_web_page_preview_success(unique_ptr &&options, WebPageId web_page_id, Promise> &&promise); void on_get_web_page_instant_view(WebPage *web_page, tl_object_ptr &&page, int32 hash, @@ -191,7 +199,9 @@ class WebPagesManager final : public Actor { FlatHashMap, WebPageIdHash> web_page_messages_; - FlatHashMap>>>, WebPageIdHash> + FlatHashMap, Promise>>>, + WebPageIdHash> pending_get_web_pages_; FlatHashMap, StoryFullIdHash> story_web_pages_; diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 0f0519edd..26873f6b7 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -5661,7 +5661,7 @@ class CliClient final : public Actor { } else if (op == "groc") { send_request(td_api::make_object(as_limit(args))); } else if (op == "gwpp") { - send_request(td_api::make_object(as_formatted_text(args))); + send_request(td_api::make_object(as_formatted_text(args), get_link_preview_options())); } else if (op == "gwpiv") { string url; bool force_full;