Add getExternalLink method.

This commit is contained in:
levlam 2021-02-04 14:36:11 +03:00
parent 1403815148
commit 2193928cf6
7 changed files with 113 additions and 0 deletions

View File

@ -4179,6 +4179,9 @@ viewMessages chat_id:int53 message_thread_id:int53 message_ids:vector<int53> for
//@description Informs TDLib that the message content has been opened (e.g., the user has opened a photo, video, document, location or venue, or has listened to an audio file or voice note message). An updateMessageContentOpened update will be generated if something has changed @chat_id Chat identifier of the message @message_id Identifier of the message with the opened content
openMessageContent chat_id:int53 message_id:int53 = Ok;
//@description Returns an HTTP URL to open when user clicks on a given HTTP link. This method can be used to automatically login user on a Telegram site @link The HTTP link
getExternalLink link:string = HttpUrl;
//@description Marks all mentions in a chat as read @chat_id Chat identifier
readAllChatMentions chat_id:int53 = Ok;

Binary file not shown.

View File

@ -45,6 +45,7 @@
#include "td/utils/common.h"
#include "td/utils/crypto.h"
#include "td/utils/format.h"
#include "td/utils/HttpUrl.h"
#include "td/utils/JsonBuilder.h"
#include "td/utils/logging.h"
#include "td/utils/misc.h"
@ -888,6 +889,8 @@ void ConfigManager::start_up() {
expire_time_ = expire_time;
set_timeout_in(expire_time_.in());
}
autologin_update_time_ = Time::now() - 365 * 86400;
}
ActorShared<> ConfigManager::create_reference() {
@ -964,6 +967,59 @@ void ConfigManager::get_app_config(Promise<td_api::object_ptr<td_api::JsonValue>
}
}
void ConfigManager::get_external_link(string &&link, Promise<string> &&promise) {
if (G()->close_flag()) {
return promise.set_value(std::move(link));
}
auto r_url = parse_url(link);
if (r_url.is_error()) {
return promise.set_value(std::move(link));
}
if (!td::contains(autologin_domains_, r_url.ok().host_)) {
return promise.set_value(std::move(link));
}
if (autologin_update_time_ < Time::now() - 10000) {
auto query_promise = PromiseCreator::lambda([link = std::move(link), promise = std::move(promise)](
Result<td_api::object_ptr<td_api::JsonValue>> &&result) mutable {
if (result.is_error()) {
return promise.set_value(std::move(link));
}
send_closure(G()->config_manager(), &ConfigManager::get_external_link, std::move(link), std::move(promise));
});
return get_app_config(std::move(query_promise));
}
if (autologin_token_.empty()) {
return promise.set_value(std::move(link));
}
auto url = r_url.move_as_ok();
url.protocol_ = HttpUrl::Protocol::Https;
Slice path = Slice(url.query_).truncate(url.query_.find_first_of("?#"));
Slice parameters_hash = Slice(url.query_).substr(path.size());
Slice parameters = parameters_hash;
parameters.truncate(parameters.find('#'));
Slice hash = parameters_hash.substr(parameters.size());
string added_parameter;
if (parameters.empty()) {
added_parameter = '?';
} else if (parameters.size() == 1) {
CHECK(parameters == "?");
} else {
added_parameter = '&';
}
added_parameter += "autologin_token=";
added_parameter += autologin_token_;
url.query_ = PSTRING() << path << parameters << added_parameter << hash;
promise.set_value(url.get_url());
}
void ConfigManager::get_content_settings(Promise<Unit> &&promise) {
if (G()->close_flag()) {
return promise.set_error(Status::Error(500, "Request aborted"));
@ -1475,6 +1531,10 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
const bool archive_and_mute =
G()->shared_config().get_option_boolean("archive_and_mute_new_chats_from_unknown_users");
autologin_token_.clear();
autologin_domains_.clear();
autologin_update_time_ = Time::now();
vector<tl_object_ptr<telegram_api::jsonObjectValue>> new_values;
string ignored_restriction_reasons;
vector<string> dice_emojis;
@ -1640,6 +1700,30 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
}
continue;
}
if (key == "autologin_token") {
if (value->get_id() == telegram_api::jsonString::ID) {
autologin_token_ = url_encode(static_cast<telegram_api::jsonString *>(value)->value_);
} else {
LOG(ERROR) << "Receive unexpected autologin_token " << to_string(*value);
}
continue;
}
if (key == "autologin_domains") {
if (value->get_id() == telegram_api::jsonArray::ID) {
auto domains = std::move(static_cast<telegram_api::jsonArray *>(value)->value_);
for (auto &domain : domains) {
CHECK(domain != nullptr);
if (domain->get_id() == telegram_api::jsonString::ID) {
autologin_domains_.push_back(std::move(static_cast<telegram_api::jsonString *>(domain.get())->value_));
} else {
LOG(ERROR) << "Receive unexpected autologin domain " << to_string(domain);
}
}
} else {
LOG(ERROR) << "Receive unexpected autologin_domains " << to_string(*value);
}
continue;
}
new_values.push_back(std::move(key_value));
}

View File

@ -93,6 +93,8 @@ class ConfigManager : public NetQueryCallback {
void get_app_config(Promise<td_api::object_ptr<td_api::JsonValue>> &&promise);
void get_external_link(string &&link, Promise<string> &&promise);
void get_content_settings(Promise<Unit> &&promise);
void set_content_settings(bool ignore_sensitive_content_restrictions, Promise<Unit> &&promise);
@ -114,6 +116,10 @@ class ConfigManager : public NetQueryCallback {
int ref_cnt_{1};
Timestamp expire_time_;
string autologin_token_;
vector<string> autologin_domains_;
double autologin_update_time_ = 0.0;
FloodControlStrict lazy_request_flood_control_;
vector<Promise<td_api::object_ptr<td_api::JsonValue>>> get_app_config_queries_;

View File

@ -5460,6 +5460,21 @@ void Td::on_request(uint64 id, const td_api::openMessageContent &request) {
id, messages_manager_->open_message_content({DialogId(request.chat_id_), MessageId(request.message_id_)}));
}
void Td::on_request(uint64 id, td_api::getExternalLink &request) {
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.link_);
CREATE_REQUEST_PROMISE();
auto query_promise = [promise = std::move(promise)](Result<string> &&result) mutable {
if (result.is_error()) {
promise.set_error(result.move_as_error());
} else {
promise.set_value(td_api::make_object<td_api::httpUrl>(result.ok()));
}
};
send_closure_later(G()->config_manager(), &ConfigManager::get_external_link, std::move(request.link_),
std::move(query_promise));
}
void Td::on_request(uint64 id, const td_api::getChatHistory &request) {
CHECK_IS_USER();
CREATE_REQUEST(GetChatHistoryRequest, request.chat_id_, request.from_message_id_, request.offset_, request.limit_,

View File

@ -574,6 +574,8 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, const td_api::openMessageContent &request);
void on_request(uint64 id, td_api::getExternalLink &request);
void on_request(uint64 id, const td_api::getChatHistory &request);
void on_request(uint64 id, const td_api::deleteChatHistory &request);

View File

@ -3841,6 +3841,9 @@ class CliClient final : public Actor {
string message_id;
get_args(args, chat_id, message_id);
send_request(td_api::make_object<td_api::openMessageContent>(as_chat_id(chat_id), as_message_id(message_id)));
} else if (op == "gel") {
string link = args;
send_request(td_api::make_object<td_api::getExternalLink>(link));
} else if (op == "racm") {
string chat_id = args;
send_request(td_api::make_object<td_api::readAllChatMentions>(as_chat_id(chat_id)));