From 714397da803fa9e749a056053a778a71b99b2332 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 15 Sep 2023 16:24:26 +0300 Subject: [PATCH] Add td_api::internalLinkTypeChatBoost. --- td/generate/scheme/td_api.tl | 3 +++ td/telegram/LinkManager.cpp | 45 +++++++++++++++++++++++++++++++++++- td/telegram/LinkManager.h | 1 + test/link.cpp | 23 ++++++++++++++++++ 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 1ca9e2bdc..908276d47 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -5077,6 +5077,9 @@ internalLinkTypeBotStartInGroup bot_username:string start_parameter:string admin //@description The link is a link to the change phone number section of the app internalLinkTypeChangePhoneNumber = InternalLinkType; +//@description The link is a link to boost a Telegram chat. Call getChatBoostLinkInfo with the given URL to process the link @url URL to be passed to getChatBoostLinkInfo +internalLinkTypeChatBoost url:string = InternalLinkType; + //@description The link is an invite link to a chat folder. Call checkChatFolderInviteLink with the given invite link to process the link @invite_link Internal representation of the invite link internalLinkTypeChatFolderInvite invite_link:string = InternalLinkType; diff --git a/td/telegram/LinkManager.cpp b/td/telegram/LinkManager.cpp index adced7044..1bc0ec0f6 100644 --- a/td/telegram/LinkManager.cpp +++ b/td/telegram/LinkManager.cpp @@ -392,6 +392,18 @@ class LinkManager::InternalLinkDefaultMessageAutoDeleteTimerSettings final : pub } }; +class LinkManager::InternalLinkDialogBoost final : public InternalLink { + string url_; + + td_api::object_ptr get_internal_link_type_object() const final { + return td_api::make_object(url_); + } + + public: + explicit InternalLinkDialogBoost(string url) : url_(std::move(url)) { + } +}; + class LinkManager::InternalLinkDialogFolderInvite final : public InternalLink { string url_; @@ -1417,6 +1429,15 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que PSTRING() << "tg://privatepost" << copy_arg("channel") << copy_arg("post") << copy_arg("single") << copy_arg("thread") << copy_arg("comment") << copy_arg("t")); } + } else if (path.size() == 1 && path[0] == "boost") { + // boost?domain=channel_username + // boost?channel=123456 + if (has_arg("domain")) { + return td::make_unique(PSTRING() << "tg://boost" << copy_arg("domain")); + } + if (has_arg("channel")) { + return td::make_unique(PSTRING() << "tg://boost" << copy_arg("channel")); + } } else if (path.size() == 1 && path[0] == "bg") { // bg?color= // bg?gradient=-&rotation=... @@ -1484,6 +1505,9 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q return td::make_unique(PSTRING() << "tg://privatepost?channel=" << to_integer(path[1]) << "&post=" << post << copy_arg("single") << thread << copy_arg("comment") << copy_arg("t")); + } else if (path.size() >= 2 && to_integer(path[1]) > 0 && url_query.has_arg("boost")) { + // /c/123456789?boost + return td::make_unique(PSTRING() << "tg://boost?channel=" << to_integer(path[1])); } } else if (path[0] == "login") { if (path.size() >= 2 && !path[1].empty()) { @@ -1637,6 +1661,10 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q } return td::make_unique(std::move(username), arg.second, arg.first == "livestream"); } + if (arg.first == "boost") { + // /?boost + return td::make_unique(PSTRING() << "tg://boost?domain=" << url_encode(username)); + } if (arg.first == "start" && is_valid_start_parameter(arg.second)) { // /?start= return td::make_unique(std::move(username), arg.second, is_trusted); @@ -1945,6 +1973,21 @@ Result LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp return Status::Error("HTTP link is unavailable for the link type"); } return "tg://settings/change_number"; + case td_api::internalLinkTypeChatBoost::ID: { + auto link = static_cast(type_ptr); + auto parsed_link = parse_internal_link(link->url_); + if (parsed_link == nullptr) { + return Status::Error(400, "Invalid chat boost URL specified"); + } + auto parsed_object = parsed_link->get_internal_link_type_object(); + if (parsed_object->get_id() != td_api::internalLinkTypeChatBoost::ID) { + return Status::Error(400, "Invalid chat boost URL specified"); + } + if (!is_internal) { + return Status::Error(400, "Use getChatBoostLink to get an HTTPS link to boost a chat"); + } + return std::move(static_cast(*parsed_object).url_); + } case td_api::internalLinkTypeChatFolderInvite::ID: { auto link = static_cast(type_ptr); auto slug = get_dialog_filter_invite_link_slug(link->invite_link_); @@ -2069,7 +2112,7 @@ Result LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp return Status::Error(400, "Invalid message URL specified"); } if (!is_internal) { - return Status::Error(400, "Use getMessageLink to get HTTPS link to a message"); + return Status::Error(400, "Use getMessageLink to get an HTTPS link to a message"); } return std::move(static_cast(*parsed_object).url_); } diff --git a/td/telegram/LinkManager.h b/td/telegram/LinkManager.h index 8c4d19999..4dcb92e6f 100644 --- a/td/telegram/LinkManager.h +++ b/td/telegram/LinkManager.h @@ -124,6 +124,7 @@ class LinkManager final : public Actor { class InternalLinkChangePhoneNumber; class InternalLinkConfirmPhone; class InternalLinkDefaultMessageAutoDeleteTimerSettings; + class InternalLinkDialogBoost; class InternalLinkDialogFolderInvite; class InternalLinkDialogFolderSettings; class InternalLinkDialogInvite; diff --git a/test/link.cpp b/test/link.cpp index 3d4c48a4e..b1203af6e 100644 --- a/test/link.cpp +++ b/test/link.cpp @@ -97,6 +97,10 @@ static void parse_internal_link(const td::string &url, td::td_api::object_ptrget_id() == td::td_api::internalLinkTypeChatBoost::ID) { + // external chat boost links must be generated with getChatBoostLink + continue; + } if (!is_internal && expected->get_id() == td::td_api::internalLinkTypeMessage::ID) { // external message links must be generated with getMessageLink continue; @@ -219,6 +223,10 @@ static auto change_phone_number() { return td::td_api::make_object(); } +static auto chat_boost(const td::string &url) { + return td::td_api::make_object(url); +} + static auto chat_folder_invite(const td::string &slug) { return td::td_api::make_object("tg:addlist?slug=" + slug); } @@ -382,6 +390,21 @@ TEST(Link, parse_internal_link_part1) { parse_internal_link("t.m/levlam/1", nullptr); parse_internal_link("t.men/levlam/1", nullptr); + parse_internal_link("t.me/levlam?boos", public_chat("levlam")); + parse_internal_link("telegram.me/levlam?booster", public_chat("levlam")); + parse_internal_link("telegram.dog/levlam?boost", chat_boost("tg://boost?domain=levlam")); + parse_internal_link("www.t.me/levlam?boost", chat_boost("tg://boost?domain=levlam")); + parse_internal_link("t.me/c/l12345?boost", nullptr); + parse_internal_link("t.me/c/12345l5431?boost", chat_boost("tg://boost?channel=12345")); + parse_internal_link("t.me/c/12345?boost", chat_boost("tg://boost?channel=12345")); + parse_internal_link("t.me/c/123456789012?boost", chat_boost("tg://boost?channel=123456789012")); + parse_internal_link("t.me/c/123456789012?boost=12312&domain=123", chat_boost("tg://boost?channel=123456789012")); + + parse_internal_link("tg:boost?domain=username/12345&single", chat_boost("tg://boost?domain=username%2F12345")); + parse_internal_link("tg:boost?domain=username&channel=12345", chat_boost("tg://boost?domain=username")); + parse_internal_link("tg:boost?channel=12345&domain=username", chat_boost("tg://boost?domain=username")); + parse_internal_link("tg:boost?channel=12345", chat_boost("tg://boost?channel=12345")); + parse_internal_link("tg:resolve?domain=username&post=12345&single", message("tg://resolve?domain=username&post=12345&single")); parse_internal_link("tg:resolve?domain=username&post=12345&single&startattach=1&attach=test",