Add td_api::getDiscussionMessage.

GitOrigin-RevId: 5adf174ae08f0cf3c430ea0222f818a54988823f
This commit is contained in:
levlam 2020-09-15 17:07:34 +03:00
parent 2cca74bf80
commit cd6cfc52ac
8 changed files with 178 additions and 2 deletions

View File

@ -3523,9 +3523,12 @@ getMessage chat_id:int53 message_id:int53 = Message;
//@description Returns information about a message, if it is available locally without sending network request. This is an offline request @chat_id Identifier of the chat the message belongs to @message_id Identifier of the message to get //@description Returns information about a message, if it is available locally without sending network request. This is an offline request @chat_id Identifier of the chat the message belongs to @message_id Identifier of the message to get
getMessageLocally chat_id:int53 message_id:int53 = Message; 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 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;

Binary file not shown.

View File

@ -36,6 +36,7 @@ MessageReplyInfo::MessageReplyInfo(tl_object_ptr<telegram_api::messageReplies> &
if (!channel_id.is_valid()) { if (!channel_id.is_valid()) {
LOG(ERROR) << "Receive invalid " << channel_id; LOG(ERROR) << "Receive invalid " << channel_id;
channel_id = ChannelId(); channel_id = ChannelId();
is_comment = false;
} }
} }
} }

View File

@ -396,6 +396,45 @@ class GetDialogUnreadMarksQuery : public Td::ResultHandler {
} }
}; };
class GetDiscussionMessageQuery : public Td::ResultHandler {
Promise<Unit> promise_;
DialogId dialog_id_;
MessageId message_id_;
public:
explicit GetDiscussionMessageQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
}
void send(DialogId dialog_id, MessageId message_id) {
dialog_id_ = dialog_id;
message_id_ = message_id;
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Read);
CHECK(input_peer != nullptr);
send_query(G()->net_query_creator().create(
telegram_api::messages_getDiscussionMessage(std::move(input_peer), message_id.get_server_message_id().get())));
}
void on_result(uint64 id, BufferSlice packet) override {
auto result_ptr = fetch_result<telegram_api::messages_getDiscussionMessage>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
}
auto ptr = result_ptr.move_as_ok();
LOG(INFO) << "Receive discussion message for " << message_id_ << " in " << dialog_id_ << ": " << to_string(ptr);
td->contacts_manager_->on_get_users(std::move(ptr->users_), "GetDiscussionMessageQuery");
td->contacts_manager_->on_get_chats(std::move(ptr->chats_), "GetDiscussionMessageQuery");
td->messages_manager_->on_get_discussion_message(dialog_id_, message_id_, std::move(ptr->message_),
MessageId(ServerMessageId(ptr->read_max_id_)),
std::move(promise_));
}
void on_error(uint64 id, Status status) override {
td->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetDiscussionMessageQuery");
promise_.set_error(std::move(status));
}
};
class GetMessagesQuery : public Td::ResultHandler { class GetMessagesQuery : public Td::ResultHandler {
Promise<Unit> promise_; Promise<Unit> promise_;
@ -6230,6 +6269,12 @@ bool MessagesManager::update_message_interaction_info(DialogId dialog_id, Messag
m->forward_count = forward_count; m->forward_count = forward_count;
} }
if (need_update_reply_info) { if (need_update_reply_info) {
if (m->reply_info.channel_id != reply_info.channel_id) {
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;
}
m->discussion_message_id = MessageId();
}
m->reply_info = std::move(reply_info); m->reply_info = std::move(reply_info);
} }
send_update_message_interaction_info(dialog_id, m); send_update_message_interaction_info(dialog_id, m);
@ -15422,6 +15467,92 @@ 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,
Promise<Unit> &&promise) {
LOG(INFO) << "Get discussion message from " << message_id << " in " << dialog_id;
Dialog *d = get_dialog_force(dialog_id);
if (d == nullptr) {
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)) {
promise.set_error(Status::Error(400, "Can't access the chat"));
return FullMessageId();
}
if (!message_id.is_valid_scheduled() && !message_id.is_valid()) {
promise.set_error(Status::Error(400, "Invalid message identifier"));
return FullMessageId();
}
if (message_id.is_scheduled()) {
promise.set_error(Status::Error(400, "Scheduled messages can't have comments"));
return FullMessageId();
}
auto m = get_message_force(d, message_id, "get_discussion_message");
if (m == nullptr) {
if (force) {
promise.set_value(Unit());
} else {
get_message_force_from_server(d, message_id, std::move(promise));
}
return FullMessageId();
}
if (!m->reply_info.is_comment) {
promise.set_error(Status::Error(400, "Message have no comments"));
return FullMessageId();
}
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;
}
td_->create_handler<GetDiscussionMessageQuery>(std::move(promise))->send(dialog_id, message_id);
return FullMessageId();
}
void MessagesManager::on_get_discussion_message(DialogId dialog_id, MessageId message_id,
tl_object_ptr<telegram_api::Message> &&message,
MessageId max_read_message_id, Promise<Unit> &&promise) {
Dialog *d = get_dialog_force(dialog_id);
CHECK(d != nullptr);
auto m = get_message_force(d, message_id, "on_get_discussion_message");
if (m == nullptr) {
return promise.set_error(Status::Error(500, "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());
}
auto full_message_id =
on_get_message(std::move(message), false, true, false, false, false, "on_get_discussion_message");
if (!full_message_id.get_message_id().is_valid()) {
return promise.set_value(Unit());
}
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();
promise.set_value(Unit());
}
void MessagesManager::get_dialog_info_full(DialogId dialog_id, Promise<Unit> &&promise) { void MessagesManager::get_dialog_info_full(DialogId dialog_id, Promise<Unit> &&promise) {
switch (dialog_id.get_type()) { switch (dialog_id.get_type()) {
case DialogType::User: case DialogType::User:

View File

@ -259,7 +259,7 @@ class MessagesManager : public Actor {
vector<tl_object_ptr<telegram_api::Message>> &&messages); vector<tl_object_ptr<telegram_api::Message>> &&messages);
void on_failed_get_message_public_forwards(int64 random_id); void on_failed_get_message_public_forwards(int64 random_id);
// if message is from_update, flags have_previous and have_next are ignored and should be both true // if message is from_update, flags have_previous and have_next are ignored and must be both true
FullMessageId on_get_message(tl_object_ptr<telegram_api::Message> message_ptr, bool from_update, FullMessageId on_get_message(tl_object_ptr<telegram_api::Message> message_ptr, bool from_update,
bool is_channel_message, bool is_scheduled, bool have_previous, bool have_next, bool is_channel_message, bool is_scheduled, bool have_previous, bool have_next,
const char *source); const char *source);
@ -554,6 +554,12 @@ 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);
void on_get_discussion_message(DialogId dialog_id, MessageId message_id,
tl_object_ptr<telegram_api::Message> &&message, MessageId max_read_message_id,
Promise<Unit> &&promise);
MessageId get_dialog_pinned_message(DialogId dialog_id, Promise<Unit> &&promise); MessageId get_dialog_pinned_message(DialogId dialog_id, Promise<Unit> &&promise);
bool get_messages(DialogId dialog_id, const vector<MessageId> &message_ids, Promise<Unit> &&promise); bool get_messages(DialogId dialog_id, const vector<MessageId> &message_ids, Promise<Unit> &&promise);
@ -1037,6 +1043,7 @@ 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,6 +1050,28 @@ class GetRepliedMessageRequest : public RequestOnceActor {
} }
}; };
class GetDiscussionMessageRequest : public RequestOnceActor {
DialogId dialog_id_;
MessageId message_id_;
FullMessageId discussion_message_id_;
void do_run(Promise<Unit> &&promise) override {
discussion_message_id_ =
td->messages_manager_->get_discussion_message(dialog_id_, message_id_, get_tries() < 3, std::move(promise));
}
void do_send_result() override {
send_result(td->messages_manager_->get_message_object(discussion_message_id_));
}
public:
GetDiscussionMessageRequest(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) {
set_tries(3); // 1 to get initial message, 1 to get the discussion message and 1 for result
}
};
class GetChatPinnedMessageRequest : public RequestOnceActor { class GetChatPinnedMessageRequest : public RequestOnceActor {
DialogId dialog_id_; DialogId dialog_id_;
@ -5094,6 +5116,11 @@ 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_);
} }

View File

@ -490,6 +490,8 @@ 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::getMessages &request); void on_request(uint64 id, const td_api::getMessages &request);

View File

@ -2604,6 +2604,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") {
string chat_id;
string message_id;
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)));
} 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)));