diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index a0ddc7994..6270fd295 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3057,8 +3057,8 @@ internalLinkTypeBotStartInGroup bot_username:string start_parameter:string = Int //@description The link is a link to the change phone number section of the app internalLinkTypeChangePhoneNumber = InternalLinkType; -//@description The link is a chat invite link. Call checkChatInviteLink to process the link -internalLinkTypeChatInvite = InternalLinkType; +//@description The link is a chat invite link. Call checkChatInviteLink with the given URL to process the link @url Internal representation of the link +internalLinkTypeChatInvite url:string = InternalLinkType; //@description The link is a link to the filter settings section of the app internalLinkTypeFilterSettings = InternalLinkType; diff --git a/td/telegram/LinkManager.cpp b/td/telegram/LinkManager.cpp index 26dd976d5..dc379a525 100644 --- a/td/telegram/LinkManager.cpp +++ b/td/telegram/LinkManager.cpp @@ -65,6 +65,26 @@ static bool is_valid_username(Slice username) { return true; } +static string get_url_query_hash(bool is_tg, const HttpUrlQuery &url_query) { + const auto &path = url_query.path_; + if (is_tg) { + if (path.size() == 1 && path[0] == "join" && !url_query.get_arg("invite").empty()) { + // join?invite=abcdef + return url_query.get_arg("invite").str(); + } + } else { + if (path.size() >= 2 && path[0] == "joinchat" && !path[1].empty()) { + // /joinchat/ + return path[1]; + } + if (path.size() >= 1 && path[0].size() >= 2 && (path[0][0] == ' ' || path[0][0] == '+')) { + // /+ + return path[0].substr(1); + } + } + return string(); +} + class LinkManager::InternalLinkActiveSessions final : public InternalLink { td_api::object_ptr get_internal_link_type_object() const final { return td_api::make_object(); @@ -144,8 +164,14 @@ class LinkManager::InternalLinkConfirmPhone final : public InternalLink { }; class LinkManager::InternalLinkDialogInvite final : public InternalLink { + string url_; + td_api::object_ptr get_internal_link_type_object() const final { - return td_api::make_object(); + return td_api::make_object(url_); + } + + public: + explicit InternalLinkDialogInvite(string url) : url_(std::move(url)) { } }; @@ -783,7 +809,8 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que } else if (path.size() == 1 && path[0] == "join") { // join?invite= if (has_arg("invite")) { - return td::make_unique(); + return td::make_unique(PSTRING() << "tg:join?invite=" + << url_encode(get_url_query_hash(true, url_query))); } } else if (path.size() == 1 && path[0] == "addstickers") { // addstickers?set= @@ -889,12 +916,14 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q } else if (path[0] == "joinchat") { if (path.size() >= 2 && !path[1].empty()) { // /joinchat/ - return td::make_unique(); + return td::make_unique(PSTRING() << "tg:join?invite=" + << url_encode(get_url_query_hash(false, url_query))); } } else if (path[0][0] == ' ' || path[0][0] == '+') { if (path[0].size() >= 2) { // /+ - return td::make_unique(); + return td::make_unique( + PSTRING() << "tg:join?invite=" + url_encode(get_url_query_hash(false, url_query))); } } else if (path[0] == "addstickers") { if (path.size() >= 2 && !path[1].empty()) { @@ -1157,24 +1186,7 @@ string LinkManager::get_dialog_invite_link_hash(Slice invite_link) { return string(); } const auto url_query = parse_url_query(link_info.query_); - const auto &path = url_query.path_; - - if (link_info.is_tg_) { - if (path.size() == 1 && path[0] == "join" && !url_query.get_arg("invite").empty()) { - // join?invite=abcdef - return url_query.get_arg("invite").str(); - } - } else { - if (path.size() >= 2 && path[0] == "joinchat" && !path[1].empty()) { - // /joinchat/ - return path[1]; - } - if (path.size() >= 1 && path[0].size() >= 2 && (path[0][0] == ' ' || path[0][0] == '+')) { - // /+ - return path[0].substr(1); - } - } - return string(); + return get_url_query_hash(link_info.is_tg_, url_query); } Result LinkManager::get_message_link_info(Slice url) { diff --git a/test/link.cpp b/test/link.cpp index 843d117ec..2061ff72a 100644 --- a/test/link.cpp +++ b/test/link.cpp @@ -113,8 +113,8 @@ TEST(Link, parse_internal_link) { auto change_phone_number = [] { return td::td_api::make_object(); }; - auto chat_invite = [] { - return td::td_api::make_object(); + auto chat_invite = [](td::string hash) { + return td::td_api::make_object("tg:join?invite=" + hash); }; auto filter_settings = [] { return td::td_api::make_object(); @@ -181,9 +181,9 @@ TEST(Link, parse_internal_link) { parse_internal_link("www%2etelegram.me/levlam/1", message()); parse_internal_link("www%2Etelegram.dog/levlam/1", message()); parse_internal_link("www%252Etelegram.dog/levlam/1", nullptr); - parse_internal_link("www.t.me/s/s/s/s/s/joinchat/1", chat_invite()); - parse_internal_link("www.t.me/s/%73/%73/s/%73/joinchat/1", chat_invite()); - parse_internal_link("http://t.me/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/joinchat/1", chat_invite()); + parse_internal_link("www.t.me/s/s/s/s/s/joinchat/1", chat_invite("1")); + parse_internal_link("www.t.me/s/%73/%73/s/%73/joinchat/1", chat_invite("1")); + parse_internal_link("http://t.me/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/joinchat/1", chat_invite("1")); parse_internal_link("http://t.me/levlam/1", message()); parse_internal_link("https://t.me/levlam/1", message()); parse_internal_link("hTtp://www.t.me:443/levlam/1", message()); @@ -347,29 +347,33 @@ TEST(Link, parse_internal_link) { parse_internal_link("t.me/joinchat?/abcdef", nullptr); parse_internal_link("t.me/joinchat/?abcdef", nullptr); parse_internal_link("t.me/joinchat/#abcdef", nullptr); - parse_internal_link("t.me/joinchat/abacaba", chat_invite()); - parse_internal_link("t.me/joinchat/aba%20aba", chat_invite()); - parse_internal_link("t.me/joinchat/123456a", chat_invite()); - parse_internal_link("t.me/joinchat/12345678901", chat_invite()); - parse_internal_link("t.me/joinchat/123456", chat_invite()); - parse_internal_link("t.me/joinchat/123456/123123/12/31/a/s//21w/?asdas#test", chat_invite()); + parse_internal_link("t.me/joinchat/abacaba", chat_invite("abacaba")); + parse_internal_link("t.me/joinchat/aba%20aba", chat_invite("aba%20aba")); + parse_internal_link("t.me/joinchat/aba%30aba", chat_invite("aba0aba")); + parse_internal_link("t.me/joinchat/123456a", chat_invite("123456a")); + parse_internal_link("t.me/joinchat/12345678901", chat_invite("12345678901")); + parse_internal_link("t.me/joinchat/123456", chat_invite("123456")); + parse_internal_link("t.me/joinchat/123456/123123/12/31/a/s//21w/?asdas#test", chat_invite("123456")); parse_internal_link("t.me/+?invite=abcdef", nullptr); - parse_internal_link("t.me/+a", chat_invite()); + parse_internal_link("t.me/+a", chat_invite("a")); parse_internal_link("t.me/+", nullptr); parse_internal_link("t.me/+/abcdef", nullptr); parse_internal_link("t.me/ ?/abcdef", nullptr); parse_internal_link("t.me/+?abcdef", nullptr); parse_internal_link("t.me/+#abcdef", nullptr); - parse_internal_link("t.me/ abacaba", chat_invite()); - parse_internal_link("t.me/+aba%20aba", chat_invite()); - parse_internal_link("t.me/+123456a", chat_invite()); - parse_internal_link("t.me/%2012345678901", chat_invite()); - parse_internal_link("t.me/+123456", chat_invite()); - parse_internal_link("t.me/ 123456/123123/12/31/a/s//21w/?asdas#test", chat_invite()); + parse_internal_link("t.me/ abacaba", chat_invite("abacaba")); + parse_internal_link("t.me/+aba%20aba", chat_invite("aba%20aba")); + parse_internal_link("t.me/+aba%30aba", chat_invite("aba0aba")); + parse_internal_link("t.me/+123456a", chat_invite("123456a")); + parse_internal_link("t.me/%2012345678901", chat_invite("12345678901")); + parse_internal_link("t.me/+123456", chat_invite("123456")); + parse_internal_link("t.me/ 123456/123123/12/31/a/s//21w/?asdas#test", chat_invite("123456")); parse_internal_link("t.me/ /123456/123123/12/31/a/s//21w/?asdas#test", nullptr); - parse_internal_link("tg:join?invite=abcdef", chat_invite()); + parse_internal_link("tg:join?invite=abcdef", chat_invite("abcdef")); + parse_internal_link("tg:join?invite=abc%20def", chat_invite("abc%20def")); + parse_internal_link("tg://join?invite=abc%30def", chat_invite("abc0def")); parse_internal_link("tg:join?invite=", unknown_deep_link()); parse_internal_link("t.me/addstickers?set=abcdef", nullptr);