Repalce getDiscussionMessage with getMessageThread.

GitOrigin-RevId: 8f5a828b3d1decf9c9c9061eaa706362b2b0272b
This commit is contained in:
levlam 2020-09-22 17:27:35 +03:00
parent cb3f390a92
commit 3522d8dae0
7 changed files with 105 additions and 85 deletions

View File

@ -975,6 +975,10 @@ loginUrlInfoOpen url:string skip_confirm:Bool = LoginUrlInfo;
loginUrlInfoRequestConfirmation url:string domain:string bot_user_id:int32 request_write_access:Bool = LoginUrlInfo; loginUrlInfoRequestConfirmation url:string domain:string bot_user_id:int32 request_write_access:Bool = LoginUrlInfo;
//@description Contains information about a message thread @messages The messages from which the thread starts. The messages are returned in a reverse chronological order (i.e., in order of decreasing message_id)
messageThreadInfo messages:vector<message> = MessageThreadInfo;
//@class RichText @description Describes a text object inside an instant-view web page //@class RichText @description Describes a text object inside an instant-view web page
//@description A plain text @text Text //@description A plain text @text Text
@ -3533,15 +3537,15 @@ getMessageLocally chat_id:int53 message_id:int53 = Message;
//@description Returns information about a message that is replied by given message @chat_id Identifier of the chat the message belongs to @message_id Identifier of the message reply to which to get //@description Returns information about a message that is replied by given message @chat_id Identifier of the chat the message belongs to @message_id Identifier of the message reply to which to get
getRepliedMessage chat_id:int53 message_id:int53 = Message; getRepliedMessage chat_id:int53 message_id:int53 = Message;
//@description Returns information about a message that was automatically forwarded to a discussion supergroup from the given channel message @chat_id Chat identifier @message_id Identifier of the channel message
getDiscussionMessage chat_id:int53 message_id:int53 = Message;
//@description Returns information about a pinned chat message @chat_id Identifier of the chat the message belongs to //@description Returns information about a pinned chat message @chat_id Identifier of the chat the message belongs to
getChatPinnedMessage chat_id:int53 = Message; getChatPinnedMessage chat_id:int53 = Message;
//@description Returns information about messages. If a message is not found, returns null on the corresponding position of the result @chat_id Identifier of the chat the messages belong to @message_ids Identifiers of the messages to get //@description Returns information about messages. If a message is not found, returns null on the corresponding position of the result @chat_id Identifier of the chat the messages belong to @message_ids Identifiers of the messages to get
getMessages chat_id:int53 message_ids:vector<int53> = Messages; getMessages chat_id:int53 message_ids:vector<int53> = Messages;
//@description Returns information about a message thread; only for messages with replies @chat_id Chat identifier @message_id Identifier of the message
getMessageThread chat_id:int53 message_id:int53 = MessageThreadInfo;
//@description Returns information about a file; this is an offline request @file_id Identifier of the file to get //@description Returns information about a file; this is an offline request @file_id Identifier of the file to get
getFile file_id:int32 = File; getFile file_id:int32 = File;

Binary file not shown.

View File

@ -6275,7 +6275,7 @@ void MessagesManager::on_update_read_message_comments(DialogId dialog_id, Messag
} }
auto m = get_message_force(d, message_id, "on_update_read_message_comments"); auto m = get_message_force(d, message_id, "on_update_read_message_comments");
if (m == nullptr) { if (m == nullptr || !m->message_id.is_server()) {
return; return;
} }
if (m->reply_info.update_max_message_ids(max_message_id, last_read_inbox_message_id, last_read_outbox_message_id)) { if (m->reply_info.update_max_message_ids(max_message_id, last_read_inbox_message_id, last_read_outbox_message_id)) {
@ -6438,7 +6438,8 @@ bool MessagesManager::is_active_message_reply_info(DialogId dialog_id, const Mes
td_api::object_ptr<td_api::messageInteractionInfo> MessagesManager::get_message_interaction_info_object( td_api::object_ptr<td_api::messageInteractionInfo> MessagesManager::get_message_interaction_info_object(
DialogId dialog_id, const Message *m) const { DialogId dialog_id, const Message *m) const {
bool is_active_reply_info = m->message_id.is_server() && is_active_message_reply_info(dialog_id, m->reply_info); bool is_active_reply_info =
m->message_id.is_valid() && m->message_id.is_server() && is_active_message_reply_info(dialog_id, m->reply_info);
if (m->view_count == 0 && m->forward_count == 0 && !is_active_reply_info) { if (m->view_count == 0 && m->forward_count == 0 && !is_active_reply_info) {
return nullptr; return nullptr;
} }
@ -6476,6 +6477,9 @@ bool MessagesManager::update_message_interaction_info(DialogId dialog_id, Messag
int32 forward_count, bool has_reply_info, int32 forward_count, bool has_reply_info,
MessageReplyInfo &&reply_info) { MessageReplyInfo &&reply_info) {
CHECK(m != nullptr); CHECK(m != nullptr);
if (m->message_id.is_valid_scheduled()) {
has_reply_info = false;
}
bool need_update_reply_info = has_reply_info && m->reply_info.need_update_to(reply_info); bool need_update_reply_info = has_reply_info && m->reply_info.need_update_to(reply_info);
if (has_reply_info && m->reply_info.channel_id == reply_info.channel_id) { if (has_reply_info && m->reply_info.channel_id == reply_info.channel_id) {
if (need_update_reply_info) { if (need_update_reply_info) {
@ -6503,7 +6507,6 @@ bool MessagesManager::update_message_interaction_info(DialogId dialog_id, Messag
if (m->reply_info.channel_id.is_valid() && reply_info.channel_id.is_valid()) { if (m->reply_info.channel_id.is_valid() && reply_info.channel_id.is_valid()) {
LOG(ERROR) << "Reply info changed from " << m->reply_info << " to " << reply_info; LOG(ERROR) << "Reply info changed from " << m->reply_info << " to " << reply_info;
} }
m->discussion_message_id = MessageId();
} }
m->reply_info = std::move(reply_info); m->reply_info = std::move(reply_info);
} }
@ -15791,55 +15794,41 @@ FullMessageId MessagesManager::get_replied_message(DialogId dialog_id, MessageId
return replied_message_id; return replied_message_id;
} }
FullMessageId MessagesManager::get_discussion_message(DialogId dialog_id, MessageId message_id, bool force, void MessagesManager::get_message_thread(DialogId dialog_id, MessageId message_id,
Promise<Unit> &&promise) { Promise<MessageThreadInfo> &&promise) {
LOG(INFO) << "Get discussion message from " << message_id << " in " << dialog_id; LOG(INFO) << "Get message thread from " << message_id << " in " << dialog_id;
Dialog *d = get_dialog_force(dialog_id); Dialog *d = get_dialog_force(dialog_id);
if (d == nullptr) { if (d == nullptr) {
promise.set_error(Status::Error(400, "Chat not found")); return promise.set_error(Status::Error(400, "Chat not found"));
return FullMessageId();
}
if (!is_broadcast_channel(dialog_id)) {
promise.set_error(Status::Error(400, "Chat is not a channel"));
return FullMessageId();
} }
if (!have_input_peer(dialog_id, AccessRights::Read)) { if (!have_input_peer(dialog_id, AccessRights::Read)) {
promise.set_error(Status::Error(400, "Can't access the chat")); return promise.set_error(Status::Error(400, "Can't access the chat"));
return FullMessageId();
} }
if (!message_id.is_valid_scheduled() && !message_id.is_valid()) { if (dialog_id.get_type() != DialogType::Channel) {
promise.set_error(Status::Error(400, "Invalid message identifier")); return promise.set_error(Status::Error(400, "Chat is not a supergroup or a channel"));
return FullMessageId();
} }
if (message_id.is_scheduled()) { if (message_id.is_scheduled()) {
promise.set_error(Status::Error(400, "Scheduled messages can't have comments")); return promise.set_error(Status::Error(400, "Scheduled messages can't have message threads"));
return FullMessageId();
} }
auto m = get_message_force(d, message_id, "get_discussion_message"); auto m = get_message_force(d, message_id, "get_message_thread");
if (m == nullptr) { if (m == nullptr) {
if (force) { return promise.set_error(Status::Error(400, "Message not found"));
promise.set_value(Unit()); }
} else {
get_message_force_from_server(d, message_id, std::move(promise)); ChannelId message_thread_channel_id;
if (m->reply_info.is_comment) {
if (!is_active_message_reply_info(dialog_id, m->reply_info)) {
return promise.set_error(Status::Error(400, "Message has no comments"));
} }
return FullMessageId(); message_thread_channel_id = m->reply_info.channel_id;
} } else {
if (!m->reply_info.is_comment) { if (!m->top_reply_message_id.is_valid()) {
promise.set_error(Status::Error(400, "Message have no comments")); return promise.set_error(Status::Error(400, "Message has no thread"));
return FullMessageId(); }
} message_thread_channel_id = dialog_id.get_channel_id();
CHECK(m->reply_info.channel_id.is_valid());
if (!is_active_message_reply_info(dialog_id, m->reply_info)) {
promise.set_value(Unit());
return FullMessageId();
}
if (m->discussion_message_id.is_valid()) {
promise.set_value(Unit());
FullMessageId result(DialogId(m->reply_info.channel_id), m->discussion_message_id);
m->discussion_message_id = MessageId(); // force server request each time
return result;
} }
CHECK(message_thread_channel_id.is_valid());
auto query_promise = auto query_promise =
PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, message_id, PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, message_id,
@ -15852,13 +15841,12 @@ FullMessageId MessagesManager::get_discussion_message(DialogId dialog_id, Messag
}); });
td_->create_handler<GetDiscussionMessageQuery>(std::move(query_promise)) td_->create_handler<GetDiscussionMessageQuery>(std::move(query_promise))
->send(dialog_id, message_id, m->reply_info.channel_id); ->send(dialog_id, message_id, message_thread_channel_id);
return FullMessageId();
} }
void MessagesManager::on_get_discussion_message(DialogId dialog_id, MessageId message_id, void MessagesManager::on_get_discussion_message(DialogId dialog_id, MessageId message_id,
vector<FullMessageId> full_message_ids, Promise<Unit> &&promise) { vector<FullMessageId> full_message_ids,
Promise<MessageThreadInfo> &&promise) {
if (G()->close_flag()) { if (G()->close_flag()) {
return promise.set_error(Status::Error(500, "Request aborted")); return promise.set_error(Status::Error(500, "Request aborted"));
} }
@ -15867,26 +15855,44 @@ void MessagesManager::on_get_discussion_message(DialogId dialog_id, MessageId me
auto m = get_message_force(d, message_id, "on_get_discussion_message"); auto m = get_message_force(d, message_id, "on_get_discussion_message");
if (m == nullptr) { if (m == nullptr) {
return promise.set_error(Status::Error(500, "Message not found")); return promise.set_error(Status::Error(400, "Message not found"));
} }
if (!m->reply_info.is_comment) {
return promise.set_error(Status::Error(400, "Message have no comments"));
}
CHECK(m->reply_info.channel_id.is_valid());
if (!is_active_message_reply_info(dialog_id, m->reply_info)) {
return promise.set_value(Unit());
}
if (full_message_ids.empty()) { if (full_message_ids.empty()) {
return promise.set_value(Unit()); return promise.set_error(Status::Error(400, "Message has no thread"));
}
auto full_message_id = full_message_ids.back();
if (full_message_id.get_dialog_id() != DialogId(m->reply_info.channel_id)) {
return promise.set_error(Status::Error(500, "Expected message in a different chat"));
} }
m->discussion_message_id = full_message_id.get_message_id(); DialogId expected_dialog_id;
promise.set_value(Unit()); if (m->reply_info.is_comment) {
if (!is_active_message_reply_info(dialog_id, m->reply_info)) {
return promise.set_error(Status::Error(400, "Message has no comments"));
}
expected_dialog_id = DialogId(m->reply_info.channel_id);
} else {
if (!m->top_reply_message_id.is_valid()) {
return promise.set_error(Status::Error(400, "Message has no thread"));
}
expected_dialog_id = dialog_id;
}
MessageThreadInfo result;
for (auto full_message_id : full_message_ids) {
if (full_message_id.get_dialog_id() != expected_dialog_id) {
return promise.set_error(Status::Error(500, "Expected messages in a different chat"));
}
result.message_ids.push_back(full_message_id.get_message_id());
}
result.dialog_id = expected_dialog_id;
promise.set_value(std::move(result));
}
td_api::object_ptr<td_api::messageThreadInfo> MessagesManager::get_message_thread_info_object(
const MessageThreadInfo &info) {
Dialog *d = get_dialog(info.dialog_id);
CHECK(d != nullptr);
auto messages = transform(info.message_ids, [this, d](MessageId message_id) {
return get_message_object(d->dialog_id, get_message_force(d, message_id, "get_message_thread_info_object"));
});
return td_api::make_object<td_api::messageThreadInfo>(std::move(messages));
} }
void MessagesManager::get_dialog_info_full(DialogId dialog_id, Promise<Unit> &&promise) { void MessagesManager::get_dialog_info_full(DialogId dialog_id, Promise<Unit> &&promise) {

View File

@ -570,10 +570,16 @@ class MessagesManager : public Actor {
FullMessageId get_replied_message(DialogId dialog_id, MessageId message_id, bool force, Promise<Unit> &&promise); FullMessageId get_replied_message(DialogId dialog_id, MessageId message_id, bool force, Promise<Unit> &&promise);
FullMessageId get_discussion_message(DialogId dialog_id, MessageId message_id, bool force, Promise<Unit> &&promise); struct MessageThreadInfo {
DialogId dialog_id;
vector<MessageId> message_ids;
};
void get_message_thread(DialogId dialog_id, MessageId message_id, Promise<MessageThreadInfo> &&promise);
td_api::object_ptr<td_api::messageThreadInfo> get_message_thread_info_object(const MessageThreadInfo &info);
void on_get_discussion_message(DialogId dialog_id, MessageId message_id, vector<FullMessageId> full_message_ids, void on_get_discussion_message(DialogId dialog_id, MessageId message_id, vector<FullMessageId> full_message_ids,
Promise<Unit> &&promise); Promise<MessageThreadInfo> &&promise);
MessageId get_dialog_pinned_message(DialogId dialog_id, Promise<Unit> &&promise); MessageId get_dialog_pinned_message(DialogId dialog_id, Promise<Unit> &&promise);
@ -1065,7 +1071,6 @@ class MessagesManager : public Actor {
int32 view_count = 0; int32 view_count = 0;
int32 forward_count = 0; int32 forward_count = 0;
MessageReplyInfo reply_info; MessageReplyInfo reply_info;
MessageId discussion_message_id;
int32 legacy_layer = 0; int32 legacy_layer = 0;

View File

@ -1050,25 +1050,31 @@ class GetRepliedMessageRequest : public RequestOnceActor {
} }
}; };
class GetDiscussionMessageRequest : public RequestOnceActor { class GetMessageThreadRequest : public RequestActor<MessagesManager::MessageThreadInfo> {
DialogId dialog_id_; DialogId dialog_id_;
MessageId message_id_; MessageId message_id_;
FullMessageId discussion_message_id_; MessagesManager::MessageThreadInfo message_thread_info_;
void do_run(Promise<Unit> &&promise) override { void do_run(Promise<MessagesManager::MessageThreadInfo> &&promise) override {
discussion_message_id_ = if (get_tries() < 2) {
td->messages_manager_->get_discussion_message(dialog_id_, message_id_, get_tries() < 3, std::move(promise)); promise.set_value(std::move(message_thread_info_));
return;
}
td->messages_manager_->get_message_thread(dialog_id_, message_id_, std::move(promise));
}
void do_set_result(MessagesManager::MessageThreadInfo &&result) override {
message_thread_info_ = std::move(result);
} }
void do_send_result() override { void do_send_result() override {
send_result(td->messages_manager_->get_message_object(discussion_message_id_)); send_result(td->messages_manager_->get_message_thread_info_object(message_thread_info_));
} }
public: public:
GetDiscussionMessageRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id, int64 message_id) GetMessageThreadRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id, int64 message_id)
: RequestOnceActor(std::move(td), request_id), dialog_id_(dialog_id), message_id_(message_id) { : RequestActor(std::move(td), request_id), dialog_id_(dialog_id), message_id_(message_id) {
set_tries(3); // 1 to get initial message, 1 to get the discussion message and 1 for result
} }
}; };
@ -5093,21 +5099,20 @@ void Td::on_request(uint64 id, const td_api::getRepliedMessage &request) {
CREATE_REQUEST(GetRepliedMessageRequest, request.chat_id_, request.message_id_); CREATE_REQUEST(GetRepliedMessageRequest, request.chat_id_, request.message_id_);
} }
void Td::on_request(uint64 id, const td_api::getDiscussionMessage &request) {
CHECK_IS_USER();
CREATE_REQUEST(GetDiscussionMessageRequest, request.chat_id_, request.message_id_);
}
void Td::on_request(uint64 id, const td_api::getChatPinnedMessage &request) { void Td::on_request(uint64 id, const td_api::getChatPinnedMessage &request) {
CREATE_REQUEST(GetChatPinnedMessageRequest, request.chat_id_); CREATE_REQUEST(GetChatPinnedMessageRequest, request.chat_id_);
} }
void Td::on_request(uint64 id, const td_api::getMessageThread &request) {
CHECK_IS_USER();
CREATE_REQUEST(GetMessageThreadRequest, request.chat_id_, request.message_id_);
}
void Td::on_request(uint64 id, const td_api::getMessages &request) { void Td::on_request(uint64 id, const td_api::getMessages &request) {
CREATE_REQUEST(GetMessagesRequest, request.chat_id_, request.message_ids_); CREATE_REQUEST(GetMessagesRequest, request.chat_id_, request.message_ids_);
} }
void Td::on_request(uint64 id, const td_api::getMessageLink &request) { void Td::on_request(uint64 id, const td_api::getMessageLink &request) {
CHECK_IS_USER();
auto r_message_link = messages_manager_->get_message_link( auto r_message_link = messages_manager_->get_message_link(
{DialogId(request.chat_id_), MessageId(request.message_id_)}, request.for_album_, request.for_comment_); {DialogId(request.chat_id_), MessageId(request.message_id_)}, request.for_album_, request.for_comment_);
if (r_message_link.is_error()) { if (r_message_link.is_error()) {

View File

@ -490,10 +490,10 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, const td_api::getRepliedMessage &request); void on_request(uint64 id, const td_api::getRepliedMessage &request);
void on_request(uint64 id, const td_api::getDiscussionMessage &request);
void on_request(uint64 id, const td_api::getChatPinnedMessage &request); void on_request(uint64 id, const td_api::getChatPinnedMessage &request);
void on_request(uint64 id, const td_api::getMessageThread &request);
void on_request(uint64 id, const td_api::getMessages &request); void on_request(uint64 id, const td_api::getMessages &request);
void on_request(uint64 id, const td_api::getMessageLink &request); void on_request(uint64 id, const td_api::getMessageLink &request);

View File

@ -2600,11 +2600,11 @@ class CliClient final : public Actor {
string message_id; string message_id;
std::tie(chat_id, message_id) = split(args); std::tie(chat_id, message_id) = split(args);
send_request(td_api::make_object<td_api::getRepliedMessage>(as_chat_id(chat_id), as_message_id(message_id))); send_request(td_api::make_object<td_api::getRepliedMessage>(as_chat_id(chat_id), as_message_id(message_id)));
} else if (op == "gdm") { } else if (op == "gmt") {
string chat_id; string chat_id;
string message_id; string message_id;
std::tie(chat_id, message_id) = split(args); std::tie(chat_id, message_id) = split(args);
send_request(td_api::make_object<td_api::getDiscussionMessage>(as_chat_id(chat_id), as_message_id(message_id))); send_request(td_api::make_object<td_api::getMessageThread>(as_chat_id(chat_id), as_message_id(message_id)));
} else if (op == "gcpm") { } else if (op == "gcpm") {
string chat_id = args; string chat_id = args;
send_request(td_api::make_object<td_api::getChatPinnedMessage>(as_chat_id(chat_id))); send_request(td_api::make_object<td_api::getChatPinnedMessage>(as_chat_id(chat_id)));