diff options
| author | levlam <levlam@telegram.org> | 2025-09-02 15:10:26 +0300 |
|---|---|---|
| committer | levlam <levlam@telegram.org> | 2025-09-02 15:10:26 +0300 |
| commit | a11e78b035390d4bdeb1b078fb15fe44e532564d (patch) | |
| tree | cfbc6e81d75059bad5620ca9c14ad54535ad139e | |
| parent | a87a360557edd83e78e19b6abb448e7a1498f22c (diff) | |
Add td_api::internalLinkTypeStoryAlbum.
| -rw-r--r-- | td/generate/scheme/td_api.tl | 6 | ||||
| -rw-r--r-- | td/telegram/LinkManager.cpp | 46 | ||||
| -rw-r--r-- | td/telegram/LinkManager.h | 1 | ||||
| -rw-r--r-- | test/link.cpp | 30 |
4 files changed, 82 insertions, 1 deletions
diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index c9b2bf37c..f374d78dd 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -7987,6 +7987,12 @@ internalLinkTypeStickerSet sticker_set_name:string expect_custom_emoji:Bool = In //@story_id Story identifier internalLinkTypeStory story_poster_username:string story_id:int32 = InternalLinkType; +//@description The link is a link to an album of stories. Call searchPublicChat with the given username, then call getStoryAlbumStories with the received chat identifier +//-and the given story album identifier, then show the story album if received +//@story_album_owner_username Username of the owner of the story album +//@story_album_id Story album identifier +internalLinkTypeStoryAlbum story_album_owner_username:string story_album_id:int32 = InternalLinkType; + //@description The link is a link to a cloud theme. TDLib has no theme support yet @theme_name Name of the theme internalLinkTypeTheme theme_name:string = InternalLinkType; diff --git a/td/telegram/LinkManager.cpp b/td/telegram/LinkManager.cpp index 7644bf220..5aeb19471 100644 --- a/td/telegram/LinkManager.cpp +++ b/td/telegram/LinkManager.cpp @@ -27,6 +27,7 @@ #include "td/telegram/ServerMessageId.h" #include "td/telegram/StarGiftCollectionId.h" #include "td/telegram/StickersManager.h" +#include "td/telegram/StoryAlbumId.h" #include "td/telegram/StoryId.h" #include "td/telegram/Td.h" #include "td/telegram/TdDb.h" @@ -164,6 +165,11 @@ static bool is_valid_star_gift_collection_id(Slice collection_id) { return r_collection_id.is_ok() && StarGiftCollectionId(r_collection_id.ok()).is_valid(); } +static bool is_valid_story_album_id(Slice story_album_id) { + auto r_story_album_id = to_integer_safe<int32>(story_album_id); + return r_story_album_id.is_ok() && StoryAlbumId(r_story_album_id.ok()).is_valid(); +} + static string get_url_query_hash(bool is_tg, const HttpUrlQuery &url_query) { const auto &path = url_query.path_; if (is_tg) { @@ -919,6 +925,20 @@ class LinkManager::InternalLinkStory final : public InternalLink { } }; +class LinkManager::InternalLinkStoryAlbum final : public InternalLink { + string story_album_owner_username_; + StoryAlbumId story_album_id_; + + td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final { + return td_api::make_object<td_api::internalLinkTypeStoryAlbum>(story_album_owner_username_, story_album_id_.get()); + } + + public: + InternalLinkStoryAlbum(string story_album_owner_username, StoryAlbumId story_album_id) + : story_album_owner_username_(std::move(story_album_owner_username)), story_album_id_(story_album_id) { + } +}; + class LinkManager::InternalLinkTheme final : public InternalLink { string theme_name_; @@ -1665,10 +1685,15 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_tg_link_query(Slice que return td::make_unique<InternalLinkMonoforum>(std::move(username)); } if (arg.first == "collection" && is_valid_star_gift_collection_id(arg.second)) { - // resolve?domain=<username>&collection=<story_id> + // resolve?domain=<username>&collection=<collection_id> return td::make_unique<InternalLinkStarGiftCollection>(std::move(username), StarGiftCollectionId(to_integer<int32>(arg.second))); } + if (arg.first == "album" && is_valid_story_album_id(arg.second)) { + // resolve?domain=<username>&album=<story_album_id> + return td::make_unique<InternalLinkStoryAlbum>(std::move(username), + StoryAlbumId(to_integer<int32>(arg.second))); + } } if (username == "telegrampassport") { // resolve?domain=telegrampassport&bot_id=...&scope=...&public_key=...&nonce=...&callback_url=... @@ -2148,6 +2173,10 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_t_me_link_query(Slice q return td::make_unique<InternalLinkStarGiftCollection>(std::move(username), StarGiftCollectionId(to_integer<int32>(path[2]))); } + if (path.size() == 3 && path[1] == "a" && is_valid_story_album_id(path[2])) { + // /<username>/a/<story_album_id> + return td::make_unique<InternalLinkStoryAlbum>(std::move(username), StoryAlbumId(to_integer<int32>(path[2]))); + } if (path.size() == 2 && is_valid_web_app_name(path[1])) { // /<username>/<web_app_name> // /<username>/<web_app_name>?startapp=<start_parameter>&mode=compact @@ -2904,6 +2933,21 @@ Result<string> LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp return PSTRING() << get_t_me_url() << link->story_poster_username_ << "/s/" << link->story_id_; } } + case td_api::internalLinkTypeStoryAlbum::ID: { + auto link = static_cast<const td_api::internalLinkTypeStoryAlbum *>(type_ptr); + if (!is_valid_username(link->story_album_owner_username_)) { + return Status::Error(400, "Invalid story album owner username specified"); + } + if (!StoryAlbumId(link->story_album_id_).is_valid()) { + return Status::Error(400, "Invalid story album identifier specified"); + } + if (is_internal) { + return PSTRING() << "tg://resolve?domain=" << link->story_album_owner_username_ + << "&album=" << link->story_album_id_; + } else { + return PSTRING() << get_t_me_url() << link->story_album_owner_username_ << "/a/" << link->story_album_id_; + } + } case td_api::internalLinkTypeTheme::ID: { auto link = static_cast<const td_api::internalLinkTypeTheme *>(type_ptr); if (!is_valid_theme_name(link->theme_name_)) { diff --git a/td/telegram/LinkManager.h b/td/telegram/LinkManager.h index 156403651..f579f5027 100644 --- a/td/telegram/LinkManager.h +++ b/td/telegram/LinkManager.h @@ -170,6 +170,7 @@ class LinkManager final : public Actor { class InternalLinkStickerSet; class InternalLinkStarGiftCollection; class InternalLinkStory; + class InternalLinkStoryAlbum; class InternalLinkTheme; class InternalLinkThemeSettings; class InternalLinkUnknownDeepLink; diff --git a/test/link.cpp b/test/link.cpp index 4d96cd0c6..3447e2be7 100644 --- a/test/link.cpp +++ b/test/link.cpp @@ -391,6 +391,10 @@ static auto story(const td::string &poster_username, td::int32 story_id) { return td::td_api::make_object<td::td_api::internalLinkTypeStory>(poster_username, story_id); } +static auto story_album(const td::string &owner_username, td::int32 story_album_id) { + return td::td_api::make_object<td::td_api::internalLinkTypeStoryAlbum>(owner_username, story_album_id); +} + static auto theme(const td::string &theme_name) { return td::td_api::make_object<td::td_api::internalLinkTypeTheme>(theme_name); } @@ -463,6 +467,7 @@ TEST(Link, parse_internal_link_part1) { 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("t.me/boost/a/12345", story_album("boost", 12345)); parse_internal_link("t.me/boost/c/12345", gift_collection("boost", 12345)); parse_internal_link("t.me/boost/s/12345", story("boost", 12345)); parse_internal_link("t.me/boost/s", chat_boost("tg://boost?domain=s")); @@ -1444,6 +1449,31 @@ TEST(Link, parse_internal_link_part4) { parse_internal_link("t.me/username?story=123", public_chat("username")); parse_internal_link("https://telegram.dog/tele%63ram/s/%31%39", story("telecram", 19)); + parse_internal_link("tg:resolve?domain=username&album=123", story_album("username", 123)); + parse_internal_link("TG://resolve?domain=username&album=", public_chat("username")); + parse_internal_link("TG://resolve?domain=username&album=0", public_chat("username")); + parse_internal_link("TG://resolve?domain=username&album=-1", public_chat("username")); + parse_internal_link("TG://test@resolve?domain=username&album=1", nullptr); + parse_internal_link("tg:resolve:80?domain=username&album=1", nullptr); + parse_internal_link("tg:http://resolve?domain=username&album=1", nullptr); + parse_internal_link("tg:https://resolve?domain=username&album=1", nullptr); + parse_internal_link("tg:resolve?domain=&album=1", unknown_deep_link("tg://resolve?domain=&album=1")); + parse_internal_link("tg:resolve?domain=telegram&&&&&&&album=%30", public_chat("telegram")); + parse_internal_link("tg:resolve?domain=telegram&&&&&&&album=%31", story_album("telegram", 1)); + parse_internal_link("tg:resolve?domain=telegram&&&&&&&album=%31ab", public_chat("telegram")); + parse_internal_link("tg:resolve?domain=telegram&&&&&&&album=%31%39", story_album("telegram", 19)); + parse_internal_link("tg:resolve?domain=telegram&&&&&&&album=2222222222", public_chat("telegram")); + + parse_internal_link("t.me/username/a/1234", story_album("username", 1234)); + parse_internal_link("t.me/username/a/3?qwe=12312#12312", story_album("username", 3)); + parse_internal_link("t.me/username/a/1", story_album("username", 1)); + parse_internal_link("t.me/username/a/2", story_album("username", 2)); + parse_internal_link("t.me/username/a/5", story_album("username", 5)); + parse_internal_link("t.me/username/a/", public_chat("username")); + parse_internal_link("t.me/username#/a/123", public_chat("username")); + parse_internal_link("t.me/username?story_album=123&album=123", public_chat("username")); + parse_internal_link("https://telegram.dog/tele%63ram/a/%31%39", story_album("telecram", 19)); + parse_internal_link("t.me/h", public_chat("h")); parse_internal_link("t.me/h/hh", public_chat("h")); parse_internal_link("t.me/i", nullptr); |
