Add td_api::internalLinkTypeStory.

This commit is contained in:
levlam 2023-06-05 17:56:16 +03:00
parent 2fcdb02c39
commit f57ab79f67
4 changed files with 77 additions and 0 deletions

View File

@ -4789,6 +4789,11 @@ internalLinkTypeSettings = InternalLinkType;
//@expect_custom_emoji True, if the sticker set is expected to contain custom emoji
internalLinkTypeStickerSet sticker_set_name:string expect_custom_emoji:Bool = InternalLinkType;
//@description The link is a link to a story. Call searchPublicChat with the given sender username, check that a user is returned, then call getStory with the received user identifier and the given story identifier
//@sender_username Username of the sender of the story
//@story_id Story identifier
internalLinkTypeStory sender_username:string story_id:int32 = InternalLinkType;
//@description The link is a link to a theme. TDLib has no theme support yet @theme_name Name of the theme
internalLinkTypeTheme theme_name:string = InternalLinkType;

View File

@ -21,6 +21,7 @@
#include "td/telegram/misc.h"
#include "td/telegram/net/Proxy.h"
#include "td/telegram/ServerMessageId.h"
#include "td/telegram/StoryId.h"
#include "td/telegram/Td.h"
#include "td/telegram/TdDb.h"
#include "td/telegram/telegram_api.h"
@ -67,6 +68,11 @@ static bool is_valid_web_app_name(Slice name) {
return name.size() >= 3 && is_valid_username(name);
}
static bool is_valid_story_id(Slice story_id) {
auto r_story_id = to_integer_safe<int32>(story_id);
return r_story_id.is_ok() && StoryId(r_story_id.ok()).is_server();
}
static string get_url_query_hash(bool is_tg, const HttpUrlQuery &url_query) {
const auto &path = url_query.path_;
if (is_tg) {
@ -605,6 +611,20 @@ class LinkManager::InternalLinkStickerSet final : public InternalLink {
}
};
class LinkManager::InternalLinkStory final : public InternalLink {
string sender_username_;
StoryId story_id_;
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
return td_api::make_object<td_api::internalLinkTypeStory>(sender_username_, story_id_.get());
}
public:
InternalLinkStory(string sender_username, StoryId story_id)
: sender_username_(std::move(sender_username)), story_id_(story_id) {
}
};
class LinkManager::InternalLinkTheme final : public InternalLink {
string theme_name_;
@ -1199,6 +1219,10 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_tg_link_query(Slice que
return td::make_unique<InternalLinkWebApp>(std::move(username), arg.second,
url_query.get_arg("startapp").str());
}
if (arg.first == "story" && is_valid_story_id(arg.second)) {
// resolve?domain=<username>&story=<story_id>
return td::make_unique<InternalLinkStory>(std::move(username), StoryId(to_integer<int32>(arg.second)));
}
}
if (!url_query.get_arg("attach").empty()) {
// resolve?domain=<username>&attach=<bot_username>
@ -1592,6 +1616,10 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_t_me_link_query(Slice q
// /<bot_username>?game=<short_name>
return td::make_unique<InternalLinkGame>(std::move(username), arg.second);
}
if (arg.first == "story" && is_valid_story_id(arg.second)) {
// /<username>?story=<story_id>
return td::make_unique<InternalLinkStory>(std::move(username), StoryId(to_integer<int32>(arg.second)));
}
}
if (!url_query.get_arg("attach").empty()) {
// /<username>?attach=<bot_username>
@ -2067,6 +2095,20 @@ Result<string> LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp
<< url_encode(link->sticker_set_name_);
}
}
case td_api::internalLinkTypeStory::ID: {
auto link = static_cast<const td_api::internalLinkTypeStory *>(type_ptr);
if (!is_valid_username(link->sender_username_)) {
return Status::Error(400, "Invalid sender username specified");
}
if (!StoryId(link->story_id_).is_server()) {
return Status::Error(400, "Invalid story identifier specified");
}
if (is_internal) {
return PSTRING() << "tg://resolve?domain=" << link->sender_username_ << "&story=" << link->story_id_;
} else {
return PSTRING() << get_t_me_url() << link->sender_username_ << "?story=" << link->story_id_;
}
}
case td_api::internalLinkTypeTheme::ID: {
auto link = static_cast<const td_api::internalLinkTypeTheme *>(type_ptr);
if (link->theme_name_.empty()) {

View File

@ -144,6 +144,7 @@ class LinkManager final : public Actor {
class InternalLinkRestorePurchases;
class InternalLinkSettings;
class InternalLinkStickerSet;
class InternalLinkStory;
class InternalLinkTheme;
class InternalLinkThemeSettings;
class InternalLinkUnknownDeepLink;

View File

@ -317,6 +317,10 @@ static auto sticker_set(const td::string &sticker_set_name, bool expect_custom_e
return td::td_api::make_object<td::td_api::internalLinkTypeStickerSet>(sticker_set_name, expect_custom_emoji);
}
static auto story(const td::string &sender_username, td::int32 story_id) {
return td::td_api::make_object<td::td_api::internalLinkTypeStory>(sender_username, story_id);
}
static auto theme(const td::string &theme_name) {
return td::td_api::make_object<td::td_api::internalLinkTypeTheme>(theme_name);
}
@ -1046,6 +1050,31 @@ TEST(Link, parse_internal_link_part4) {
parse_internal_link("t.me//username?game=asd", nullptr);
parse_internal_link("https://telegram.dog/tele%63ram?game=t%63st", game("telecram", "tcst"));
parse_internal_link("tg:resolve?domain=username&story=123", story("username", 123));
parse_internal_link("TG://resolve?domain=username&story=", public_chat("username"));
parse_internal_link("TG://resolve?domain=username&story=0", public_chat("username"));
parse_internal_link("TG://resolve?domain=username&story=-1", public_chat("username"));
parse_internal_link("TG://test@resolve?domain=username&story=1", nullptr);
parse_internal_link("tg:resolve:80?domain=username&story=1", nullptr);
parse_internal_link("tg:http://resolve?domain=username&story=1", nullptr);
parse_internal_link("tg:https://resolve?domain=username&story=1", nullptr);
parse_internal_link("tg:resolve?domain=&story=1", unknown_deep_link("tg://resolve?domain=&story=1"));
parse_internal_link("tg:resolve?domain=telegram&&&&&&&story=%30", public_chat("telegram"));
parse_internal_link("tg:resolve?domain=telegram&&&&&&&story=%31", story("telegram", 1));
parse_internal_link("tg:resolve?domain=telegram&&&&&&&story=%31ab", public_chat("telegram"));
parse_internal_link("tg:resolve?domain=telegram&&&&&&&story=%31%39", story("telegram", 19));
parse_internal_link("tg:resolve?domain=telegram&&&&&&&story=2222222222", public_chat("telegram"));
parse_internal_link("t.me/username/0/a//s/as?story=1234", story("username", 1234));
parse_internal_link("t.me/username/aasdas/2?test=1&story=3#12312", story("username", 3));
parse_internal_link("t.me/username/0?story=1", story("username", 1));
parse_internal_link("t.me/username/-1?story=2", story("username", 2));
parse_internal_link("t.me/username?story=5", story("username", 5));
parse_internal_link("t.me/username?story=", public_chat("username"));
parse_internal_link("t.me/username#story=123", public_chat("username"));
parse_internal_link("t.me//username?story=123", nullptr);
parse_internal_link("https://telegram.dog/tele%63ram?story=%31%39", story("telecram", 19));
parse_internal_link("tg:resolve?domain=username&appname=aasdasd&startapp=123asd",
web_app("username", "aasdasd", "123asd"));
parse_internal_link("TG://resolve?domain=username&appname=&startapp=123asd", public_chat("username"));