Support generating of public links for comment messages.
GitOrigin-RevId: 68d9a0260e60719f129e05d32fcbf756e93fa5d4
This commit is contained in:
parent
ed10f1851c
commit
1cd9f5d8c9
@ -3681,8 +3681,9 @@ removeNotificationGroup notification_group_id:int32 max_notification_id:int32 =
|
||||
//@description Returns a public HTTPS link to a message. Available only for messages in supergroups and channels with a username
|
||||
//@chat_id Identifier of the chat to which the message belongs
|
||||
//@message_id Identifier of the message
|
||||
//@for_album Pass true if a link for a whole media album should be returned
|
||||
getPublicMessageLink chat_id:int53 message_id:int53 for_album:Bool = PublicMessageLink;
|
||||
//@for_album Pass true to create a link for a whole media album
|
||||
//@for_comment Pass true to create a link to a message as a channel message comment
|
||||
getPublicMessageLink chat_id:int53 message_id:int53 for_album:Bool for_comment:Bool = PublicMessageLink;
|
||||
|
||||
//@description Returns a private HTTPS link to a message in a chat. Available only for already sent messages in supergroups and channels. The link will work only for members of the chat
|
||||
//@chat_id Identifier of the chat to which the message belongs
|
||||
|
Binary file not shown.
@ -12298,6 +12298,9 @@ std::pair<DialogId, unique_ptr<MessagesManager::Message>> MessagesManager::creat
|
||||
is_active_message_reply_info(dialog_id, reply_info)) {
|
||||
top_reply_message_id = message_id;
|
||||
}
|
||||
if (top_reply_message_id.is_valid() && dialog_type != DialogType::Channel) {
|
||||
top_reply_message_id = MessageId();
|
||||
}
|
||||
|
||||
bool has_forward_info = message_info.forward_header != nullptr;
|
||||
|
||||
@ -15306,37 +15309,39 @@ void MessagesManager::get_message_force_from_server(Dialog *d, MessageId message
|
||||
LOG(INFO) << "Get " << message_id << " in " << d->dialog_id << " using " << to_string(input_message);
|
||||
auto dialog_type = d->dialog_id.get_type();
|
||||
auto m = get_message_force(d, message_id, "get_message_force_from_server");
|
||||
if (m == nullptr && message_id.is_valid() && message_id.is_server()) {
|
||||
if (d->last_new_message_id != MessageId() && message_id > d->last_new_message_id) {
|
||||
// message will not be added to the dialog anyway
|
||||
if (dialog_type == DialogType::Channel) {
|
||||
// so we try to force channel difference first
|
||||
if (m == nullptr) {
|
||||
if (message_id.is_valid() && message_id.is_server()) {
|
||||
if (d->last_new_message_id != MessageId() && message_id > d->last_new_message_id) {
|
||||
// message will not be added to the dialog anyway
|
||||
if (dialog_type == DialogType::Channel) {
|
||||
// so we try to force channel difference first
|
||||
|
||||
// replied message can't be older than already added original message, but pinned message can be
|
||||
LOG_CHECK(input_message == nullptr || input_message->get_id() == telegram_api::inputMessagePinned::ID)
|
||||
<< to_string(input_message) << " " << d->dialog_id << " " << message_id << " " << d->last_new_message_id
|
||||
<< " " << d->last_message_id << " " << d->first_database_message_id << " " << d->last_database_message_id
|
||||
<< " " << d->pinned_message_id << " " << d->last_read_all_mentions_message_id << " "
|
||||
<< d->max_unavailable_message_id << " " << d->last_clear_history_message_id << " " << d->order << " "
|
||||
<< d->deleted_last_message_id << " " << d->max_added_message_id << " " << d->pts << " "
|
||||
<< d->last_assigned_message_id << " " << d->debug_last_new_message_id << " "
|
||||
<< d->debug_first_database_message_id << " " << d->debug_last_database_message_id;
|
||||
postponed_get_message_requests_[d->dialog_id].emplace_back(message_id, std::move(promise),
|
||||
std::move(input_message));
|
||||
get_channel_difference(d->dialog_id, d->pts, true, "get_message");
|
||||
} else {
|
||||
promise.set_value(Unit());
|
||||
// replied message can't be older than already added original message, but pinned message can be
|
||||
LOG_CHECK(input_message == nullptr || input_message->get_id() == telegram_api::inputMessagePinned::ID)
|
||||
<< to_string(input_message) << " " << d->dialog_id << " " << message_id << " " << d->last_new_message_id
|
||||
<< " " << d->last_message_id << " " << d->first_database_message_id << " " << d->last_database_message_id
|
||||
<< " " << d->pinned_message_id << " " << d->last_read_all_mentions_message_id << " "
|
||||
<< d->max_unavailable_message_id << " " << d->last_clear_history_message_id << " " << d->order << " "
|
||||
<< d->deleted_last_message_id << " " << d->max_added_message_id << " " << d->pts << " "
|
||||
<< d->last_assigned_message_id << " " << d->debug_last_new_message_id << " "
|
||||
<< d->debug_first_database_message_id << " " << d->debug_last_database_message_id;
|
||||
postponed_get_message_requests_[d->dialog_id].emplace_back(message_id, std::move(promise),
|
||||
std::move(input_message));
|
||||
get_channel_difference(d->dialog_id, d->pts, true, "get_message");
|
||||
} else {
|
||||
promise.set_value(Unit());
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (d->deleted_message_ids.count(message_id) == 0 && dialog_type != DialogType::SecretChat) {
|
||||
return get_message_from_server({d->dialog_id, message_id}, std::move(promise), std::move(input_message));
|
||||
}
|
||||
} else if (m == nullptr && message_id.is_valid_scheduled() && message_id.is_scheduled_server()) {
|
||||
if (d->deleted_scheduled_server_message_ids.count(message_id.get_scheduled_server_message_id()) == 0 &&
|
||||
dialog_type != DialogType::SecretChat && input_message == nullptr) {
|
||||
return get_message_from_server({d->dialog_id, message_id}, std::move(promise));
|
||||
if (d->deleted_message_ids.count(message_id) == 0 && dialog_type != DialogType::SecretChat) {
|
||||
return get_message_from_server({d->dialog_id, message_id}, std::move(promise), std::move(input_message));
|
||||
}
|
||||
} else if (message_id.is_valid_scheduled() && message_id.is_scheduled_server()) {
|
||||
if (d->deleted_scheduled_server_message_ids.count(message_id.get_scheduled_server_message_id()) == 0 &&
|
||||
dialog_type != DialogType::SecretChat && input_message == nullptr) {
|
||||
return get_message_from_server({d->dialog_id, message_id}, std::move(promise));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15571,42 +15576,95 @@ bool MessagesManager::is_message_edited_recently(FullMessageId full_message_id,
|
||||
}
|
||||
|
||||
std::pair<string, string> MessagesManager::get_public_message_link(FullMessageId full_message_id, bool for_group,
|
||||
Promise<Unit> &&promise) {
|
||||
bool &for_comment, Promise<Unit> &&promise) {
|
||||
auto dialog_id = full_message_id.get_dialog_id();
|
||||
auto d = get_dialog_force(dialog_id);
|
||||
if (d == nullptr) {
|
||||
promise.set_error(Status::Error(6, "Chat not found"));
|
||||
promise.set_error(Status::Error(400, "Chat not found"));
|
||||
return {};
|
||||
}
|
||||
if (!have_input_peer(dialog_id, AccessRights::Read)) {
|
||||
promise.set_error(Status::Error(6, "Can't access the chat"));
|
||||
promise.set_error(Status::Error(400, "Can't access the chat"));
|
||||
return {};
|
||||
}
|
||||
if (dialog_id.get_type() != DialogType::Channel ||
|
||||
td_->contacts_manager_->get_channel_username(dialog_id.get_channel_id()).empty()) {
|
||||
promise.set_error(Status::Error(
|
||||
6, "Public message links are available only for messages in supergroups and channel chats with a username"));
|
||||
400, "Public message links are available only for messages in supergroups and channel chats with a username"));
|
||||
return {};
|
||||
}
|
||||
|
||||
auto *m = get_message_force(d, full_message_id.get_message_id(), "get_public_message_link");
|
||||
if (m == nullptr) {
|
||||
promise.set_error(Status::Error(6, "Message not found"));
|
||||
promise.set_error(Status::Error(400, "Message not found"));
|
||||
return {};
|
||||
}
|
||||
if (m->message_id.is_yet_unsent()) {
|
||||
promise.set_error(Status::Error(6, "Message is yet unsent"));
|
||||
promise.set_error(Status::Error(400, "Message is yet unsent"));
|
||||
return {};
|
||||
}
|
||||
if (m->message_id.is_scheduled()) {
|
||||
promise.set_error(Status::Error(6, "Message is scheduled"));
|
||||
promise.set_error(Status::Error(400, "Message is scheduled"));
|
||||
return {};
|
||||
}
|
||||
if (!m->message_id.is_server()) {
|
||||
promise.set_error(Status::Error(6, "Message is local"));
|
||||
promise.set_error(Status::Error(400, "Message is local"));
|
||||
return {};
|
||||
}
|
||||
|
||||
if (m->media_album_id == 0) {
|
||||
for_group = true; // default is true
|
||||
}
|
||||
|
||||
string comment_link;
|
||||
if (!m->top_reply_message_id.is_valid()) {
|
||||
for_comment = false;
|
||||
}
|
||||
if (d->deleted_message_ids.count(m->top_reply_message_id) != 0) {
|
||||
for_comment = false;
|
||||
}
|
||||
if (for_comment) {
|
||||
CHECK(dialog_id.get_type() == DialogType::Channel); // only channel messages can have top_reply_message_id
|
||||
auto *top_m = get_message_force(d, m->top_reply_message_id, "get_public_message_link");
|
||||
if (top_m == nullptr) {
|
||||
get_message_force_from_server(d, m->top_reply_message_id, std::move(promise));
|
||||
return {};
|
||||
}
|
||||
if (top_m->sender_user_id.is_valid() || top_m->forward_info == nullptr ||
|
||||
!top_m->forward_info->sender_dialog_id.is_valid() || !top_m->forward_info->message_id.is_valid() ||
|
||||
DialogId(td_->contacts_manager_->get_channel_linked_channel_id(dialog_id.get_channel_id())) !=
|
||||
top_m->forward_info->sender_dialog_id) {
|
||||
for_comment = false;
|
||||
} else {
|
||||
auto linked_dialog_id = top_m->forward_info->sender_dialog_id;
|
||||
auto linked_message_id = top_m->forward_info->message_id;
|
||||
auto linked_d = get_dialog(linked_dialog_id);
|
||||
CHECK(linked_d != nullptr);
|
||||
CHECK(linked_dialog_id.get_type() == DialogType::Channel);
|
||||
if (!have_input_peer(linked_dialog_id, AccessRights::Read) ||
|
||||
td_->contacts_manager_->get_channel_username(linked_dialog_id.get_channel_id()).empty() ||
|
||||
linked_d->deleted_message_ids.count(linked_message_id) != 0) {
|
||||
for_comment = false;
|
||||
} else {
|
||||
auto *linked_m = get_message_force(linked_d, linked_message_id, "get_public_message_link");
|
||||
if (linked_m == nullptr) {
|
||||
get_message_force_from_server(linked_d, linked_message_id, std::move(promise));
|
||||
return {};
|
||||
}
|
||||
|
||||
auto it = public_message_links_[for_group].find({linked_dialog_id, linked_message_id});
|
||||
if (it == public_message_links_[for_group].end()) {
|
||||
td_->create_handler<ExportChannelMessageLinkQuery>(std::move(promise))
|
||||
->send(linked_dialog_id.get_channel_id(), linked_message_id, for_group, false);
|
||||
return {};
|
||||
}
|
||||
|
||||
comment_link = PSTRING() << it->second.first << (it->second.first.find('?') == string::npos ? '?' : '&')
|
||||
<< "comment_id=" << m->message_id.get_server_message_id().get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto it = public_message_links_[for_group].find(full_message_id);
|
||||
if (it == public_message_links_[for_group].end()) {
|
||||
td_->create_handler<ExportChannelMessageLinkQuery>(std::move(promise))
|
||||
@ -15615,7 +15673,11 @@ std::pair<string, string> MessagesManager::get_public_message_link(FullMessageId
|
||||
}
|
||||
|
||||
promise.set_value(Unit());
|
||||
return it->second;
|
||||
if (for_comment) {
|
||||
return {std::move(comment_link), it->second.second};
|
||||
} else {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
void MessagesManager::on_get_public_message_link(FullMessageId full_message_id, bool for_group, string url,
|
||||
@ -15628,30 +15690,30 @@ string MessagesManager::get_message_link(FullMessageId full_message_id, Promise<
|
||||
auto dialog_id = full_message_id.get_dialog_id();
|
||||
auto d = get_dialog_force(dialog_id);
|
||||
if (d == nullptr) {
|
||||
promise.set_error(Status::Error(6, "Chat not found"));
|
||||
promise.set_error(Status::Error(400, "Chat not found"));
|
||||
return {};
|
||||
}
|
||||
if (!have_input_peer(dialog_id, AccessRights::Read)) {
|
||||
promise.set_error(Status::Error(6, "Can't access the chat"));
|
||||
promise.set_error(Status::Error(400, "Can't access the chat"));
|
||||
return {};
|
||||
}
|
||||
if (dialog_id.get_type() != DialogType::Channel) {
|
||||
promise.set_error(
|
||||
Status::Error(6, "Message links are available only for messages in supergroups and channel chats"));
|
||||
Status::Error(400, "Message links are available only for messages in supergroups and channel chats"));
|
||||
return {};
|
||||
}
|
||||
|
||||
auto *m = get_message_force(d, full_message_id.get_message_id(), "get_message_link");
|
||||
if (m == nullptr) {
|
||||
promise.set_error(Status::Error(6, "Message not found"));
|
||||
promise.set_error(Status::Error(400, "Message not found"));
|
||||
return {};
|
||||
}
|
||||
if (m->message_id.is_scheduled()) {
|
||||
promise.set_error(Status::Error(6, "Message is scheduled"));
|
||||
promise.set_error(Status::Error(400, "Message is scheduled"));
|
||||
return {};
|
||||
}
|
||||
if (!m->message_id.is_server()) {
|
||||
promise.set_error(Status::Error(6, "Message is local"));
|
||||
promise.set_error(Status::Error(400, "Message is local"));
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -562,7 +562,7 @@ class MessagesManager : public Actor {
|
||||
|
||||
bool is_message_edited_recently(FullMessageId full_message_id, int32 seconds);
|
||||
|
||||
std::pair<string, string> get_public_message_link(FullMessageId full_message_id, bool for_group,
|
||||
std::pair<string, string> get_public_message_link(FullMessageId full_message_id, bool for_group, bool &for_comment,
|
||||
Promise<Unit> &&promise);
|
||||
|
||||
void on_get_public_message_link(FullMessageId full_message_id, bool for_group, string url, string html);
|
||||
|
@ -1093,13 +1093,14 @@ class GetMessagesRequest : public RequestOnceActor {
|
||||
class GetPublicMessageLinkRequest : public RequestActor<> {
|
||||
FullMessageId full_message_id_;
|
||||
bool for_group_;
|
||||
bool for_comment_;
|
||||
|
||||
string link_;
|
||||
string html_;
|
||||
|
||||
void do_run(Promise<Unit> &&promise) override {
|
||||
std::tie(link_, html_) =
|
||||
td->messages_manager_->get_public_message_link(full_message_id_, for_group_, std::move(promise));
|
||||
td->messages_manager_->get_public_message_link(full_message_id_, for_group_, for_comment_, std::move(promise));
|
||||
}
|
||||
|
||||
void do_send_result() override {
|
||||
@ -1107,10 +1108,13 @@ class GetPublicMessageLinkRequest : public RequestActor<> {
|
||||
}
|
||||
|
||||
public:
|
||||
GetPublicMessageLinkRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id, int64 message_id, bool for_group)
|
||||
GetPublicMessageLinkRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id, int64 message_id, bool for_group,
|
||||
bool for_comment)
|
||||
: RequestActor(std::move(td), request_id)
|
||||
, full_message_id_(DialogId(dialog_id), MessageId(message_id))
|
||||
, for_group_(for_group) {
|
||||
, for_group_(for_group)
|
||||
, for_comment_(for_comment) {
|
||||
set_tries(5); // get top message + get linked channel message + get message HTML + get linked channel message link
|
||||
}
|
||||
};
|
||||
|
||||
@ -5100,7 +5104,8 @@ void Td::on_request(uint64 id, const td_api::getMessages &request) {
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::getPublicMessageLink &request) {
|
||||
CHECK_IS_USER();
|
||||
CREATE_REQUEST(GetPublicMessageLinkRequest, request.chat_id_, request.message_id_, request.for_album_);
|
||||
CREATE_REQUEST(GetPublicMessageLinkRequest, request.chat_id_, request.message_id_, request.for_album_,
|
||||
request.for_comment_);
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::getMessageLink &request) {
|
||||
|
@ -2615,10 +2615,12 @@ class CliClient final : public Actor {
|
||||
string chat_id;
|
||||
string message_id;
|
||||
string for_album;
|
||||
string for_comment;
|
||||
std::tie(chat_id, args) = split(args);
|
||||
std::tie(message_id, for_album) = split(args);
|
||||
std::tie(message_id, args) = split(args);
|
||||
std::tie(for_album, for_comment) = split(args);
|
||||
send_request(td_api::make_object<td_api::getPublicMessageLink>(as_chat_id(chat_id), as_message_id(message_id),
|
||||
as_bool(for_album)));
|
||||
as_bool(for_album), as_bool(for_comment)));
|
||||
} else if (op == "gmlink") {
|
||||
string chat_id;
|
||||
string message_id;
|
||||
|
Loading…
Reference in New Issue
Block a user