diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index ff4d2af82..b3ef8b19e 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3040,6 +3040,10 @@ internalLinkTypeTheme theme_name:string = InternalLinkType; //@description The link is an unknown tg: link. Call getDeepLinkInfo to process the link internalLinkTypeUnknownDeepLink = InternalLinkType; +//@description The link is a link to a voice chat. Call searchPublicChat and joinGoupCall with the given chat username and the given invite hash to process the link +//@chat_username Username of the chat with the voice chat @invite_hash If non-empty, invite hash to be used to join the voice chat without being muted by administrators +internalLinkTypeVoiceChat chat_username:string invite_hash:string = InternalLinkType; + //@description Contains an HTTPS link to a message in a supergroup or channel @link Message link @is_public True, if the link will work for non-members of the chat messageLink link:string is_public:Bool = MessageLink; diff --git a/td/telegram/LinkManager.cpp b/td/telegram/LinkManager.cpp index cd98a9fbe..28444480b 100644 --- a/td/telegram/LinkManager.cpp +++ b/td/telegram/LinkManager.cpp @@ -216,6 +216,24 @@ class LinkManager::InternalLinkUnknownDeepLink : public InternalLink { } }; +class LinkManager::InternalLinkVoiceChat : public InternalLink { + string chat_username_; + string invite_hash_; + + td_api::object_ptr get_internal_link_type_object() const final { + return td_api::make_object(chat_username_, invite_hash_); + } + + InternalLinkType get_type() const final { + return InternalLinkType::VoiceChat; + } + + public: + InternalLinkVoiceChat(string chat_username, string invite_hash) + : chat_username_(std::move(chat_username)), invite_hash_(std::move(invite_hash)) { + } +}; + class RequestUrlAuthQuery : public Td::ResultHandler { Promise> promise_; string url_; @@ -537,9 +555,18 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que }; if (path.size() == 1 && path[0] == "resolve") { - // resolve?domain=username&post=12345&single - if (has_arg("domain") && has_arg("post")) { - return td::make_unique(); + if (has_arg("domain")) { + if (has_arg("post")) { + // resolve?domain=username&post=12345&single + return td::make_unique(); + } + for (auto &arg : url_query.args_) { + if (arg.first == "voicechat") { + // resolve?domain=username&voicechat + // resolve?domain=username&voicechat= + return td::make_unique(get_arg("domain"), arg.second); + } + } } } else if (path.size() == 1 && path[0] == "login") { // login?code=123456 @@ -721,10 +748,18 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q // /share/url?url=&text= return get_internal_link_message_draft(get_arg("url"), get_arg("text")); } - } else { + } else if (path[0].size() <= 64) { if (path.size() >= 2 && to_integer(path[1]) > 0) { - // //12345?single + // //12345?single&thread=&comment= return td::make_unique(); + } else { + for (auto &arg : url_query.args_) { + if (arg.first == "voicechat") { + // /?voicechat + // /?voicechat= + return td::make_unique(path[0], arg.second); + } + } } } return nullptr; diff --git a/td/telegram/LinkManager.h b/td/telegram/LinkManager.h index f1d2f9a6f..530e0a7f0 100644 --- a/td/telegram/LinkManager.h +++ b/td/telegram/LinkManager.h @@ -46,7 +46,8 @@ class LinkManager : public Actor { QrCodeAuthentication, StickerSet, Theme, - UnknownDeepLink + UnknownDeepLink, + VoiceChat }; class InternalLink { @@ -99,6 +100,7 @@ class LinkManager : public Actor { class InternalLinkStickerSet; class InternalLinkTheme; class InternalLinkUnknownDeepLink; + class InternalLinkVoiceChat; struct LinkInfo { bool is_internal_ = false; diff --git a/test/link.cpp b/test/link.cpp index 375c758ca..4b4b63c1e 100644 --- a/test/link.cpp +++ b/test/link.cpp @@ -106,6 +106,9 @@ TEST(Link, parse_internal_link) { auto unknown_deep_link = [] { return td::td_api::make_object(); }; + auto voice_chat = [](td::string chat_username, td::string invite_hash) { + return td::td_api::make_object(chat_username, invite_hash); + }; parse_internal_link("t.me/levlam/1", message()); parse_internal_link("telegram.me/levlam/1", message()); @@ -128,7 +131,7 @@ TEST(Link, parse_internal_link) { parse_internal_link("t.men/levlam/1", nullptr); parse_internal_link("tg:resolve?domain=username&post=12345&single", message()); - parse_internal_link("TG://resolve?domain=username&post=12345&single", message()); + parse_internal_link("TG://resolve?domain=username&post=12345&single&voicechat=aasd", message()); parse_internal_link("TG://test@resolve?domain=username&post=12345&single", nullptr); parse_internal_link("tg:resolve:80?domain=username&post=12345&single", nullptr); parse_internal_link("tg:http://resolve?domain=username&post=12345&single", nullptr); @@ -141,7 +144,7 @@ TEST(Link, parse_internal_link) { parse_internal_link("t.me/username/12345", message()); parse_internal_link("t.me/username/12345/", message()); parse_internal_link("t.me/username/12345#asdasd", message()); - parse_internal_link("t.me/username/12345//?single", message()); + parse_internal_link("t.me/username/12345//?voicechat=&single", message()); parse_internal_link("t.me/username/12345/asdasd//asd/asd/asd/?single", message()); parse_internal_link("t.me/username/1asdasdas/asdasd//asd/asd/asd/?single", message()); parse_internal_link("t.me/username/asd", nullptr); @@ -428,4 +431,22 @@ TEST(Link, parse_internal_link) { parse_internal_link("tg:socks?server=google.com&port=8%30&user=1&pass=", proxy_socks("google.com", 80, "1", "")); parse_internal_link("tg:socks?server=google.com&port=8%30&user=&pass=2", proxy_socks("google.com", 80, "", "2")); parse_internal_link("tg:socks?server=google.com&port=80&user=1&pass=2", proxy_socks("google.com", 80, "1", "2")); + + parse_internal_link("tg:resolve?domain=username&voice%63hat=aasdasd", voice_chat("username", "aasdasd")); + parse_internal_link("TG://resolve?domain=username&voicechat=", voice_chat("username", "")); + parse_internal_link("TG://test@resolve?domain=username&voicechat=", nullptr); + parse_internal_link("tg:resolve:80?domain=username&voicechat=", nullptr); + parse_internal_link("tg:http://resolve?domain=username&voicechat=", nullptr); + parse_internal_link("tg:https://resolve?domain=username&voicechat=", nullptr); + parse_internal_link("tg:resolve?domain=&voicechat=", unknown_deep_link()); + parse_internal_link("tg:resolve?domain=telegram&&&&&&&voicechat=%30", voice_chat("telegram", "0")); + + parse_internal_link("t.me/username/0/a//s/as?voicechat=", voice_chat("username", "")); + parse_internal_link("t.me/username/aasdas?test=1&voicechat=#12312", voice_chat("username", "")); + parse_internal_link("t.me/username/0?voicechat=", voice_chat("username", "")); + parse_internal_link("t.me/username/-1?voicechat=asdasd", voice_chat("username", "asdasd")); + parse_internal_link("t.me/username?voicechat=", voice_chat("username", "")); + parse_internal_link("t.me/username#voicechat=asdas", nullptr); + parse_internal_link("t.me//username?voicechat=", nullptr); + parse_internal_link("https://telegram.dog/telegram?voi%63e%63hat=t%63st", voice_chat("telegram", "tcst")); }