Support chat links that open chat's profile.
This commit is contained in:
parent
1c3672cdc6
commit
3a528d46c8
@ -6526,7 +6526,8 @@ internalLinkTypeProxy server:string port:int32 type:ProxyType = InternalLinkType
|
||||
//-If draft text isn't empty and the chat is a private chat with a regular user, then put the draft text in the input field
|
||||
//@chat_username Username of the chat
|
||||
//@draft_text Draft text for message to send in the chat
|
||||
internalLinkTypePublicChat chat_username:string draft_text:string = InternalLinkType;
|
||||
//@open_profile True, if chat profile information screen must be opened; otherwise the chat itself must be opened
|
||||
internalLinkTypePublicChat chat_username:string draft_text:string open_profile:Bool = InternalLinkType;
|
||||
|
||||
//@description The link can be used to login the current user on another device, but it must be scanned from QR-code using in-app camera. An alert similar to
|
||||
//-"This code can be used to allow someone to log in to your Telegram account. To confirm Telegram login, please go to Settings > Devices > Scan QR and scan the code" needs to be shown
|
||||
@ -6571,10 +6572,11 @@ internalLinkTypeUnknownDeepLink link:string = InternalLinkType;
|
||||
internalLinkTypeUnsupportedProxy = InternalLinkType;
|
||||
|
||||
//@description The link is a link to a user by its phone number. Call searchUserByPhoneNumber with the given phone number to process the link.
|
||||
//-If the user is found, then call createPrivateChat and open the chat. If draft text isn't empty, then put the draft text in the input field
|
||||
//-If the user is found, then call createPrivateChat and open user's profile information screen or the chat itself. If draft text isn't empty, then put the draft text in the input field
|
||||
//@phone_number Phone number of the user
|
||||
//@draft_text Draft text for message to send in the chat
|
||||
internalLinkTypeUserPhoneNumber phone_number:string draft_text:string = InternalLinkType;
|
||||
//@open_profile True, if user's profile information screen must be opened; otherwise the chat itself must be opened
|
||||
internalLinkTypeUserPhoneNumber phone_number:string draft_text:string open_profile:Bool = InternalLinkType;
|
||||
|
||||
//@description The link is a link to a user by a temporary token. Call searchUserByToken with the given token to process the link.
|
||||
//-If the user is found, then call createPrivateChat and open the chat
|
||||
|
@ -1132,7 +1132,7 @@ void AccountManager::get_user_link_impl(Promise<td_api::object_ptr<td_api::userL
|
||||
auto username = td_->user_manager_->get_user_first_username(td_->user_manager_->get_my_id());
|
||||
if (!username.empty()) {
|
||||
return promise.set_value(
|
||||
td_api::make_object<td_api::userLink>(LinkManager::get_public_dialog_link(username, Slice(), true), 0));
|
||||
td_api::make_object<td_api::userLink>(LinkManager::get_public_dialog_link(username, Slice(), false, true), 0));
|
||||
}
|
||||
td_->create_handler<ExportContactTokenQuery>(std::move(promise))->send();
|
||||
}
|
||||
|
@ -655,14 +655,15 @@ class LinkManager::InternalLinkProxy final : public InternalLink {
|
||||
class LinkManager::InternalLinkPublicDialog final : public InternalLink {
|
||||
string dialog_username_;
|
||||
string draft_text_;
|
||||
bool open_profile_;
|
||||
|
||||
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
|
||||
return td_api::make_object<td_api::internalLinkTypePublicChat>(dialog_username_, draft_text_);
|
||||
return td_api::make_object<td_api::internalLinkTypePublicChat>(dialog_username_, draft_text_, open_profile_);
|
||||
}
|
||||
|
||||
public:
|
||||
InternalLinkPublicDialog(string dialog_username, string draft_text)
|
||||
: dialog_username_(std::move(dialog_username)), draft_text_(std::move(draft_text)) {
|
||||
InternalLinkPublicDialog(string dialog_username, string draft_text, bool open_profile)
|
||||
: dialog_username_(std::move(dialog_username)), draft_text_(std::move(draft_text)), open_profile_(open_profile) {
|
||||
}
|
||||
};
|
||||
|
||||
@ -769,14 +770,17 @@ class LinkManager::InternalLinkUnsupportedProxy final : public InternalLink {
|
||||
class LinkManager::InternalLinkUserPhoneNumber final : public InternalLink {
|
||||
string phone_number_;
|
||||
string draft_text_;
|
||||
bool open_profile_;
|
||||
|
||||
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
|
||||
return td_api::make_object<td_api::internalLinkTypeUserPhoneNumber>(phone_number_, draft_text_);
|
||||
return td_api::make_object<td_api::internalLinkTypeUserPhoneNumber>(phone_number_, draft_text_, open_profile_);
|
||||
}
|
||||
|
||||
public:
|
||||
InternalLinkUserPhoneNumber(Slice phone_number, string draft_text)
|
||||
: phone_number_(PSTRING() << '+' << phone_number), draft_text_(std::move(draft_text)) {
|
||||
InternalLinkUserPhoneNumber(Slice phone_number, string draft_text, bool open_profile)
|
||||
: phone_number_(PSTRING() << '+' << phone_number)
|
||||
, draft_text_(std::move(draft_text))
|
||||
, open_profile_(open_profile) {
|
||||
}
|
||||
};
|
||||
|
||||
@ -1336,7 +1340,7 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_tg_link_query(Slice que
|
||||
// resolve?domain=<username>&attach=<bot_username>
|
||||
// resolve?domain=<username>&attach=<bot_username>&startattach=<start_parameter>
|
||||
return td::make_unique<InternalLinkAttachMenuBot>(
|
||||
nullptr, td::make_unique<InternalLinkPublicDialog>(std::move(username), string()),
|
||||
nullptr, td::make_unique<InternalLinkPublicDialog>(std::move(username), string(), false),
|
||||
url_query.get_arg("attach").str(), url_query.get_arg("startattach"));
|
||||
} else if (url_query.has_arg("startattach")) {
|
||||
// resolve?domain=<bot_username>&startattach&choose=users+bots+groups+channels
|
||||
@ -1352,7 +1356,8 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_tg_link_query(Slice que
|
||||
}
|
||||
}
|
||||
// resolve?domain=<username>
|
||||
return td::make_unique<InternalLinkPublicDialog>(std::move(username), get_url_query_draft_text(url_query));
|
||||
return td::make_unique<InternalLinkPublicDialog>(std::move(username), get_url_query_draft_text(url_query),
|
||||
url_query.has_arg("profile"));
|
||||
} else {
|
||||
string phone_number_str = get_arg("phone");
|
||||
auto phone_number = phone_number_str[0] == ' ' ? Slice(phone_number_str).substr(1) : Slice(phone_number_str);
|
||||
@ -1361,11 +1366,12 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_tg_link_query(Slice que
|
||||
// resolve?phone=<phone_number>&attach=<bot_username>
|
||||
// resolve?phone=<phone_number>&attach=<bot_username>&startattach=<start_parameter>
|
||||
return td::make_unique<InternalLinkAttachMenuBot>(
|
||||
nullptr, td::make_unique<InternalLinkUserPhoneNumber>(phone_number, string()),
|
||||
nullptr, td::make_unique<InternalLinkUserPhoneNumber>(phone_number, string(), false),
|
||||
url_query.get_arg("attach").str(), url_query.get_arg("startattach"));
|
||||
}
|
||||
// resolve?phone=12345
|
||||
return td::make_unique<InternalLinkUserPhoneNumber>(phone_number, get_url_query_draft_text(url_query));
|
||||
return td::make_unique<InternalLinkUserPhoneNumber>(phone_number, get_url_query_draft_text(url_query),
|
||||
url_query.has_arg("profile"));
|
||||
}
|
||||
}
|
||||
} else if (path.size() == 1 && path[0] == "contact") {
|
||||
@ -1606,11 +1612,12 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_t_me_link_query(Slice q
|
||||
// /+<phone_number>?attach=<bot_username>
|
||||
// /+<phone_number>?attach=<bot_username>&startattach=<start_parameter>
|
||||
return td::make_unique<InternalLinkAttachMenuBot>(
|
||||
nullptr, td::make_unique<InternalLinkUserPhoneNumber>(invite_hash, string()),
|
||||
nullptr, td::make_unique<InternalLinkUserPhoneNumber>(invite_hash, string(), false),
|
||||
url_query.get_arg("attach").str(), url_query.get_arg("startattach"));
|
||||
}
|
||||
// /+<phone_number>
|
||||
return td::make_unique<InternalLinkUserPhoneNumber>(invite_hash, get_url_query_draft_text(url_query));
|
||||
return td::make_unique<InternalLinkUserPhoneNumber>(invite_hash, get_url_query_draft_text(url_query),
|
||||
url_query.has_arg("profile"));
|
||||
} else if (!invite_hash.empty() && is_base64url_characters(invite_hash)) {
|
||||
// /+<link>
|
||||
return td::make_unique<InternalLinkDialogInvite>(get_dialog_invite_link(invite_hash, true));
|
||||
@ -1795,7 +1802,7 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_t_me_link_query(Slice q
|
||||
// /<username>?attach=<bot_username>
|
||||
// /<username>?attach=<bot_username>&startattach=<start_parameter>
|
||||
return td::make_unique<InternalLinkAttachMenuBot>(
|
||||
nullptr, td::make_unique<InternalLinkPublicDialog>(std::move(username), string()),
|
||||
nullptr, td::make_unique<InternalLinkPublicDialog>(std::move(username), string(), false),
|
||||
url_query.get_arg("attach").str(), url_query.get_arg("startattach"));
|
||||
} else if (url_query.has_arg("startattach")) {
|
||||
// /<bot_username>?startattach&choose=users+bots+groups+channels
|
||||
@ -1805,7 +1812,8 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_t_me_link_query(Slice q
|
||||
}
|
||||
|
||||
// /<username>
|
||||
return td::make_unique<InternalLinkPublicDialog>(std::move(username), get_url_query_draft_text(url_query));
|
||||
return td::make_unique<InternalLinkPublicDialog>(std::move(username), get_url_query_draft_text(url_query),
|
||||
url_query.has_arg("profile"));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -1950,6 +1958,9 @@ Result<string> LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp
|
||||
if (target->link_->get_id() == td_api::internalLinkTypeUserPhoneNumber::ID) {
|
||||
auto user_phone_number_link =
|
||||
static_cast<const td_api::internalLinkTypeUserPhoneNumber *>(target->link_.get());
|
||||
if (user_phone_number_link->open_profile_) {
|
||||
return Status::Error(400, "Link must not open chat profile information screen");
|
||||
}
|
||||
string phone_number;
|
||||
if (user_phone_number_link->phone_number_[0] == '+') {
|
||||
phone_number = user_phone_number_link->phone_number_.substr(1);
|
||||
@ -1970,6 +1981,9 @@ Result<string> LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp
|
||||
return Status::Error(400, "Unsupported target link specified");
|
||||
}
|
||||
auto public_chat_link = static_cast<const td_api::internalLinkTypePublicChat *>(target->link_.get());
|
||||
if (public_chat_link->open_profile_) {
|
||||
return Status::Error(400, "Link must not open chat profile information screen");
|
||||
}
|
||||
if (!is_valid_username(public_chat_link->chat_username_)) {
|
||||
return Status::Error(400, "Invalid target public chat username specified");
|
||||
}
|
||||
@ -2289,7 +2303,7 @@ Result<string> LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp
|
||||
if (!check_utf8(link->draft_text_)) {
|
||||
return Status::Error(400, "Draft text must be encoded in UTF-8");
|
||||
}
|
||||
return get_public_dialog_link(link->chat_username_, link->draft_text_, is_internal);
|
||||
return get_public_dialog_link(link->chat_username_, link->draft_text_, link->open_profile_, is_internal);
|
||||
}
|
||||
case td_api::internalLinkTypeQrCodeAuthentication::ID:
|
||||
return Status::Error("The link must never be generated client-side");
|
||||
@ -2406,10 +2420,12 @@ Result<string> LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp
|
||||
}
|
||||
if (is_internal) {
|
||||
return PSTRING() << "tg://resolve?phone=+" << phone_number << (link->draft_text_.empty() ? "" : "&text=")
|
||||
<< url_encode(link->draft_text_);
|
||||
<< url_encode(link->draft_text_) << (link->open_profile_ ? "&profile" : "");
|
||||
} else {
|
||||
return PSTRING() << get_t_me_url() << '+' << phone_number << (link->draft_text_.empty() ? "" : "?text=")
|
||||
<< url_encode(link->draft_text_);
|
||||
bool has_draft = !link->draft_text_.empty();
|
||||
return PSTRING() << get_t_me_url() << '+' << phone_number << (has_draft ? "?text=" : "")
|
||||
<< url_encode(link->draft_text_)
|
||||
<< (link->open_profile_ ? (has_draft ? "&profile" : "?profile") : "");
|
||||
}
|
||||
}
|
||||
case td_api::internalLinkTypeUserToken::ID: {
|
||||
@ -2697,13 +2713,13 @@ string LinkManager::get_instant_view_link(Slice url, Slice rhash) {
|
||||
return PSTRING() << get_t_me_url() << "iv?url=" << url_encode(url) << "&rhash=" << url_encode(rhash);
|
||||
}
|
||||
|
||||
string LinkManager::get_public_dialog_link(Slice username, Slice draft_text, bool is_internal) {
|
||||
string LinkManager::get_public_dialog_link(Slice username, Slice draft_text, bool open_profile, bool is_internal) {
|
||||
if (is_internal) {
|
||||
return PSTRING() << "tg://resolve?domain=" << url_encode(username) << (draft_text.empty() ? "" : "&text=")
|
||||
<< url_encode(draft_text);
|
||||
<< url_encode(draft_text) << (open_profile ? "&profile" : "");
|
||||
} else {
|
||||
return PSTRING() << get_t_me_url() << url_encode(username) << (draft_text.empty() ? "" : "?text=")
|
||||
<< url_encode(draft_text);
|
||||
<< url_encode(draft_text) << (open_profile ? (draft_text.empty() ? "?profile" : "&profile") : "");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ class LinkManager final : public Actor {
|
||||
|
||||
static string get_instant_view_link(Slice url, Slice rhash);
|
||||
|
||||
static string get_public_dialog_link(Slice username, Slice draft_text, bool is_internal);
|
||||
static string get_public_dialog_link(Slice username, Slice draft_text, bool open_profile, bool is_internal);
|
||||
|
||||
static Result<string> get_proxy_link(const Proxy &proxy, bool is_internal);
|
||||
|
||||
|
@ -318,8 +318,9 @@ static auto proxy_socks(const td::string &server, td::int32 port, const td::stri
|
||||
server, port, td::td_api::make_object<td::td_api::proxyTypeSocks5>(username, password));
|
||||
}
|
||||
|
||||
static auto public_chat(const td::string &chat_username, const td::string &draft_text = td::string()) {
|
||||
return td::td_api::make_object<td::td_api::internalLinkTypePublicChat>(chat_username, draft_text);
|
||||
static auto public_chat(const td::string &chat_username, const td::string &draft_text = td::string(),
|
||||
bool open_profile = false) {
|
||||
return td::td_api::make_object<td::td_api::internalLinkTypePublicChat>(chat_username, draft_text, open_profile);
|
||||
}
|
||||
|
||||
static auto qr_code_authentication() {
|
||||
@ -363,8 +364,10 @@ static auto unsupported_proxy() {
|
||||
return td::td_api::make_object<td::td_api::internalLinkTypeUnsupportedProxy>();
|
||||
}
|
||||
|
||||
static auto user_phone_number(const td::string &phone_number, const td::string &draft_text = td::string()) {
|
||||
return td::td_api::make_object<td::td_api::internalLinkTypeUserPhoneNumber>('+' + phone_number, draft_text);
|
||||
static auto user_phone_number(const td::string &phone_number, const td::string &draft_text = td::string(),
|
||||
bool open_profile = false) {
|
||||
return td::td_api::make_object<td::td_api::internalLinkTypeUserPhoneNumber>('+' + phone_number, draft_text,
|
||||
open_profile);
|
||||
}
|
||||
|
||||
static auto user_token(const td::string &token) {
|
||||
@ -466,6 +469,8 @@ TEST(Link, parse_internal_link_part1) {
|
||||
attachment_menu_bot(nullptr, public_chat("telegram"), "test", ""));
|
||||
parse_internal_link("tg:resolve?domain=telegram&attach=test&startattach=1",
|
||||
attachment_menu_bot(nullptr, public_chat("telegram"), "test", "1"));
|
||||
parse_internal_link("tg:resolve?domain=username&profile=12&asd", public_chat("username", "", true));
|
||||
parse_internal_link("tg:resolve?domain=username&profile&text=@asd", public_chat("username", " @asd", true));
|
||||
|
||||
parse_internal_link("tg:resolve?phone=1", user_phone_number("1"));
|
||||
parse_internal_link("tg:resolve?phone=+1", user_phone_number("1"));
|
||||
@ -498,6 +503,8 @@ TEST(Link, parse_internal_link_part1) {
|
||||
parse_internal_link("tg:resolve?phone=12345678901&text=@asd", user_phone_number("12345678901", " @asd"));
|
||||
parse_internal_link("tg:resolve?domain=telegram&text=1%A02", public_chat("telegram"));
|
||||
parse_internal_link("tg:resolve?phone=12345678901&text=1%A02", user_phone_number("12345678901"));
|
||||
parse_internal_link("tg:resolve?phone=123456&profile", user_phone_number("123456", "", true));
|
||||
parse_internal_link("tg:resolve?phone=123456&profile&text=@asd", user_phone_number("123456", " @asd", true));
|
||||
|
||||
parse_internal_link("tg:contact?token=1", user_token("1"));
|
||||
parse_internal_link("tg:contact?token=123456", user_token("123456"));
|
||||
@ -552,6 +559,8 @@ TEST(Link, parse_internal_link_part1) {
|
||||
attachment_menu_bot(nullptr, public_chat("username"), "bot", ""));
|
||||
parse_internal_link("t.me/username?attach=bot&startattach=1&choose=users",
|
||||
attachment_menu_bot(nullptr, public_chat("username"), "bot", "1"));
|
||||
parse_internal_link("t.me/username?asd&profile=12", public_chat("username", "", true));
|
||||
parse_internal_link("t.me/username?profile&text=@asd", public_chat("username", " @asd", true));
|
||||
|
||||
parse_internal_link("tg:privatepost?domain=username/12345&single",
|
||||
unknown_deep_link("tg://privatepost?domain=username/12345&single"));
|
||||
@ -803,10 +812,12 @@ TEST(Link, parse_internal_link_part2) {
|
||||
parse_internal_link("t.me/+123456?attach=&startattach", user_phone_number("123456"));
|
||||
parse_internal_link("t.me/+123456?attach=&startattach=1", user_phone_number("123456"));
|
||||
parse_internal_link("t.me/+123456?attach=bot", attachment_menu_bot(nullptr, user_phone_number("123456"), "bot", ""));
|
||||
parse_internal_link("t.me/+123456?attach=bot&startattach",
|
||||
parse_internal_link("t.me/+123456?attach=bot&startattach&profile",
|
||||
attachment_menu_bot(nullptr, user_phone_number("123456"), "bot", ""));
|
||||
parse_internal_link("t.me/+123456?attach=bot&startattach=1",
|
||||
attachment_menu_bot(nullptr, user_phone_number("123456"), "bot", "1"));
|
||||
parse_internal_link("t.me/+123456?profile", user_phone_number("123456", "", true));
|
||||
parse_internal_link("t.me/+123456?profile&text=@asd", user_phone_number("123456", " @asd", true));
|
||||
|
||||
parse_internal_link("telegram.t.me?text=asd", public_chat("telegram", "asd"));
|
||||
parse_internal_link("t.me/%2012345678901?text=asd", user_phone_number("12345678901", "asd"));
|
||||
|
Loading…
Reference in New Issue
Block a user