Move get_message_link_info to LinkManager.

This commit is contained in:
levlam 2021-05-27 20:47:04 +03:00
parent 2d534e48d6
commit 5832a59ee5
7 changed files with 181 additions and 159 deletions

View File

@ -524,6 +524,7 @@ set(TDLIB_SOURCE
td/telegram/MessageCopyOptions.h
td/telegram/MessageEntity.h
td/telegram/MessageId.h
td/telegram/MessageLinkInfo.h
td/telegram/MessageReplyInfo.h
td/telegram/MessagesDb.h
td/telegram/MessageSearchFilter.h

View File

@ -592,7 +592,7 @@ void LinkManager::get_link_login_url(const string &url, bool allow_write_access,
}
string LinkManager::get_dialog_invite_link_hash(Slice invite_link) {
auto link_info = LinkManager::get_link_info(invite_link);
auto link_info = get_link_info(invite_link);
if (!link_info.is_internal_) {
return string();
}
@ -617,4 +617,143 @@ string LinkManager::get_dialog_invite_link_hash(Slice invite_link) {
return string();
}
Result<MessageLinkInfo> LinkManager::get_message_link_info(Slice url) {
if (url.empty()) {
return Status::Error("URL must be non-empty");
}
auto link_info = get_link_info(url);
if (!link_info.is_internal_) {
return Status::Error("Invalid message link URL");
}
url = link_info.query_;
Slice username;
Slice channel_id_slice;
Slice message_id_slice;
Slice comment_message_id_slice = "0";
bool is_single = false;
bool for_comment = false;
if (link_info.is_tg_) {
// resolve?domain=username&post=12345&single
// privatepost?channel=123456789&msg_id=12345
bool is_resolve = false;
if (begins_with(url, "resolve")) {
url = url.substr(7);
is_resolve = true;
} else if (begins_with(url, "privatepost")) {
url = url.substr(11);
} else {
return Status::Error("Wrong message link URL");
}
if (begins_with(url, "/")) {
url = url.substr(1);
}
if (!begins_with(url, "?")) {
return Status::Error("Wrong message link URL");
}
url = url.substr(1);
auto args = full_split(url, '&');
for (auto arg : args) {
auto key_value = split(arg, '=');
if (is_resolve) {
if (key_value.first == "domain") {
username = key_value.second;
}
if (key_value.first == "post") {
message_id_slice = key_value.second;
}
} else {
if (key_value.first == "channel") {
channel_id_slice = key_value.second;
}
if (key_value.first == "msg_id") {
message_id_slice = key_value.second;
}
}
if (key_value.first == "single") {
is_single = true;
}
if (key_value.first == "comment") {
comment_message_id_slice = key_value.second;
}
if (key_value.first == "thread") {
for_comment = true;
}
}
} else {
// /c/123456789/12345
// /username/12345?single
CHECK(!url.empty() && url[0] == '/');
url.remove_prefix(1);
auto username_end_pos = url.find('/');
if (username_end_pos == Slice::npos) {
return Status::Error("Wrong message link URL");
}
username = url.substr(0, username_end_pos);
url = url.substr(username_end_pos + 1);
if (username == "c") {
username = Slice();
auto channel_id_end_pos = url.find('/');
if (channel_id_end_pos == Slice::npos) {
return Status::Error("Wrong message link URL");
}
channel_id_slice = url.substr(0, channel_id_end_pos);
url = url.substr(channel_id_end_pos + 1);
}
auto query_pos = url.find('?');
message_id_slice = url.substr(0, query_pos);
if (query_pos != Slice::npos) {
auto args = full_split(url.substr(query_pos + 1), '&');
for (auto arg : args) {
auto key_value = split(arg, '=');
if (key_value.first == "single") {
is_single = true;
}
if (key_value.first == "comment") {
comment_message_id_slice = key_value.second;
}
if (key_value.first == "thread") {
for_comment = true;
}
}
}
}
ChannelId channel_id;
if (username.empty()) {
auto r_channel_id = to_integer_safe<int32>(channel_id_slice);
if (r_channel_id.is_error() || !ChannelId(r_channel_id.ok()).is_valid()) {
return Status::Error("Wrong channel ID");
}
channel_id = ChannelId(r_channel_id.ok());
}
auto r_message_id = to_integer_safe<int32>(message_id_slice);
if (r_message_id.is_error() || !ServerMessageId(r_message_id.ok()).is_valid()) {
return Status::Error("Wrong message ID");
}
auto r_comment_message_id = to_integer_safe<int32>(comment_message_id_slice);
if (r_comment_message_id.is_error() ||
!(r_comment_message_id.ok() == 0 || ServerMessageId(r_comment_message_id.ok()).is_valid())) {
return Status::Error("Wrong comment message ID");
}
MessageLinkInfo info;
info.username = username.str();
info.channel_id = channel_id;
info.message_id = MessageId(ServerMessageId(r_message_id.ok()));
info.comment_message_id = MessageId(ServerMessageId(r_comment_message_id.ok()));
info.is_single = is_single;
info.for_comment = for_comment;
LOG(INFO) << "Have link to " << info.message_id << " in chat @" << info.username << "/" << channel_id.get();
return std::move(info);
}
} // namespace td

View File

@ -8,6 +8,7 @@
#include "td/telegram/DialogId.h"
#include "td/telegram/MessageId.h"
#include "td/telegram/MessageLinkInfo.h"
#include "td/telegram/td_api.h"
#include "td/actor/actor.h"
@ -84,6 +85,8 @@ class LinkManager : public Actor {
static string get_dialog_invite_link_hash(Slice invite_link);
static Result<MessageLinkInfo> get_message_link_info(Slice url);
private:
void tear_down() override;

View File

@ -0,0 +1,30 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#pragma once
#include "td/telegram/ChannelId.h"
#include "td/telegram/DialogId.h"
#include "td/telegram/MessageId.h"
#include "td/utils/common.h"
namespace td {
struct MessageLinkInfo {
string username;
// or
ChannelId channel_id;
MessageId message_id;
bool is_single = false;
DialogId comment_dialog_id;
MessageId comment_message_id;
bool for_comment = false;
};
} // namespace td

View File

@ -17375,147 +17375,8 @@ void MessagesManager::on_get_public_message_link(FullMessageId full_message_id,
std::move(url), std::move(html)};
}
Result<MessagesManager::MessageLinkInfo> MessagesManager::get_message_link_info(Slice url) {
if (url.empty()) {
return Status::Error("URL must be non-empty");
}
auto link_info = LinkManager::get_link_info(url);
if (!link_info.is_internal_) {
return Status::Error("Invalid message link URL");
}
url = link_info.query_;
Slice username;
Slice channel_id_slice;
Slice message_id_slice;
Slice comment_message_id_slice = "0";
bool is_single = false;
bool for_comment = false;
if (link_info.is_tg_) {
// resolve?domain=username&post=12345&single
// privatepost?channel=123456789&msg_id=12345
bool is_resolve = false;
if (begins_with(url, "resolve")) {
url = url.substr(7);
is_resolve = true;
} else if (begins_with(url, "privatepost")) {
url = url.substr(11);
} else {
return Status::Error("Wrong message link URL");
}
if (begins_with(url, "/")) {
url = url.substr(1);
}
if (!begins_with(url, "?")) {
return Status::Error("Wrong message link URL");
}
url = url.substr(1);
auto args = full_split(url, '&');
for (auto arg : args) {
auto key_value = split(arg, '=');
if (is_resolve) {
if (key_value.first == "domain") {
username = key_value.second;
}
if (key_value.first == "post") {
message_id_slice = key_value.second;
}
} else {
if (key_value.first == "channel") {
channel_id_slice = key_value.second;
}
if (key_value.first == "msg_id") {
message_id_slice = key_value.second;
}
}
if (key_value.first == "single") {
is_single = true;
}
if (key_value.first == "comment") {
comment_message_id_slice = key_value.second;
}
if (key_value.first == "thread") {
for_comment = true;
}
}
} else {
// /c/123456789/12345
// /username/12345?single
CHECK(!url.empty() && url[0] == '/');
url.remove_prefix(1);
auto username_end_pos = url.find('/');
if (username_end_pos == Slice::npos) {
return Status::Error("Wrong message link URL");
}
username = url.substr(0, username_end_pos);
url = url.substr(username_end_pos + 1);
if (username == "c") {
username = Slice();
auto channel_id_end_pos = url.find('/');
if (channel_id_end_pos == Slice::npos) {
return Status::Error("Wrong message link URL");
}
channel_id_slice = url.substr(0, channel_id_end_pos);
url = url.substr(channel_id_end_pos + 1);
}
auto query_pos = url.find('?');
message_id_slice = url.substr(0, query_pos);
if (query_pos != Slice::npos) {
auto args = full_split(url.substr(query_pos + 1), '&');
for (auto arg : args) {
auto key_value = split(arg, '=');
if (key_value.first == "single") {
is_single = true;
}
if (key_value.first == "comment") {
comment_message_id_slice = key_value.second;
}
if (key_value.first == "thread") {
for_comment = true;
}
}
}
}
ChannelId channel_id;
if (username.empty()) {
auto r_channel_id = to_integer_safe<int32>(channel_id_slice);
if (r_channel_id.is_error() || !ChannelId(r_channel_id.ok()).is_valid()) {
return Status::Error("Wrong channel ID");
}
channel_id = ChannelId(r_channel_id.ok());
}
auto r_message_id = to_integer_safe<int32>(message_id_slice);
if (r_message_id.is_error() || !ServerMessageId(r_message_id.ok()).is_valid()) {
return Status::Error("Wrong message ID");
}
auto r_comment_message_id = to_integer_safe<int32>(comment_message_id_slice);
if (r_comment_message_id.is_error() ||
!(r_comment_message_id.ok() == 0 || ServerMessageId(r_comment_message_id.ok()).is_valid())) {
return Status::Error("Wrong comment message ID");
}
MessageLinkInfo info;
info.username = username.str();
info.channel_id = channel_id;
info.message_id = MessageId(ServerMessageId(r_message_id.ok()));
info.comment_message_id = MessageId(ServerMessageId(r_comment_message_id.ok()));
info.is_single = is_single;
info.for_comment = for_comment;
LOG(INFO) << "Have link to " << info.message_id << " in chat @" << info.username << "/" << channel_id.get();
return std::move(info);
}
void MessagesManager::get_message_link_info(Slice url, Promise<MessageLinkInfo> &&promise) {
auto r_message_link_info = get_message_link_info(url);
auto r_message_link_info = LinkManager::get_message_link_info(url);
if (r_message_link_info.is_error()) {
return promise.set_error(Status::Error(400, r_message_link_info.error().message()));
}

View File

@ -28,6 +28,7 @@
#include "td/telegram/MessageContentType.h"
#include "td/telegram/MessageCopyOptions.h"
#include "td/telegram/MessageId.h"
#include "td/telegram/MessageLinkInfo.h"
#include "td/telegram/MessageReplyInfo.h"
#include "td/telegram/MessagesDb.h"
#include "td/telegram/MessageSearchFilter.h"
@ -579,18 +580,6 @@ class MessagesManager : public Actor {
void on_get_public_message_link(FullMessageId full_message_id, bool for_group, string url, string html);
struct MessageLinkInfo {
string username;
// or
ChannelId channel_id;
MessageId message_id;
bool is_single = false;
DialogId comment_dialog_id;
MessageId comment_message_id;
bool for_comment = false;
};
void get_message_link_info(Slice url, Promise<MessageLinkInfo> &&promise);
td_api::object_ptr<td_api::messageLinkInfo> get_message_link_info_object(const MessageLinkInfo &info) const;
@ -2621,8 +2610,6 @@ class MessagesManager : public Actor {
void ttl_db_loop(double server_now);
void ttl_db_on_result(Result<std::pair<std::vector<std::pair<DialogId, BufferSlice>>, int32>> r_result, bool dummy);
static Result<MessageLinkInfo> get_message_link_info(Slice url);
void on_get_message_link_dialog(MessageLinkInfo &&info, Promise<MessageLinkInfo> &&promise);
void on_get_message_link_message(MessageLinkInfo &&info, DialogId dialog_id, Promise<MessageLinkInfo> &&promise);

View File

@ -55,6 +55,7 @@
#include "td/telegram/MessageCopyOptions.h"
#include "td/telegram/MessageEntity.h"
#include "td/telegram/MessageId.h"
#include "td/telegram/MessageLinkInfo.h"
#include "td/telegram/MessageSearchFilter.h"
#include "td/telegram/MessagesManager.h"
#include "td/telegram/misc.h"
@ -1174,12 +1175,12 @@ class GetMessageEmbeddingCodeRequest : public RequestActor<> {
}
};
class GetMessageLinkInfoRequest : public RequestActor<MessagesManager::MessageLinkInfo> {
class GetMessageLinkInfoRequest : public RequestActor<MessageLinkInfo> {
string url_;
MessagesManager::MessageLinkInfo message_link_info_;
MessageLinkInfo message_link_info_;
void do_run(Promise<MessagesManager::MessageLinkInfo> &&promise) override {
void do_run(Promise<MessageLinkInfo> &&promise) override {
if (get_tries() < 2) {
promise.set_value(std::move(message_link_info_));
return;
@ -1187,7 +1188,7 @@ class GetMessageLinkInfoRequest : public RequestActor<MessagesManager::MessageLi
td->messages_manager_->get_message_link_info(url_, std::move(promise));
}
void do_set_result(MessagesManager::MessageLinkInfo &&result) override {
void do_set_result(MessageLinkInfo &&result) override {
message_link_info_ = std::move(result);
}