Add class RepliedMessageInfo.

This commit is contained in:
levlam 2023-10-24 12:04:45 +03:00
parent abca2962f2
commit cb70dd7831
8 changed files with 178 additions and 103 deletions

View File

@ -454,6 +454,7 @@ set(TDLIB_SOURCE
td/telegram/ReactionManager.cpp
td/telegram/ReactionType.cpp
td/telegram/RecentDialogList.cpp
td/telegram/RepliedMessageInfo.cpp
td/telegram/ReplyMarkup.cpp
td/telegram/ReportReason.cpp
td/telegram/RequestedDialogType.cpp
@ -763,6 +764,7 @@ set(TDLIB_SOURCE
td/telegram/ReactionManager.h
td/telegram/ReactionType.h
td/telegram/RecentDialogList.h
td/telegram/RepliedMessageInfo.h
td/telegram/ReplyMarkup.h
td/telegram/ReportReason.h
td/telegram/RequestActor.h

View File

@ -5716,8 +5716,8 @@ unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const
}
unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<telegram_api::MessageAction> &&action_ptr,
DialogId owner_dialog_id, DialogId reply_in_dialog_id,
MessageId reply_to_message_id) {
DialogId owner_dialog_id,
const RepliedMessageInfo &replied_message_info) {
CHECK(action_ptr != nullptr);
switch (action_ptr->get_id()) {
@ -5812,12 +5812,7 @@ unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<tele
return td::make_unique<MessageChannelMigrateFrom>(std::move(action->title_), chat_id);
}
case telegram_api::messageActionPinMessage::ID: {
if (reply_in_dialog_id.is_valid() && reply_in_dialog_id != owner_dialog_id) {
LOG(ERROR) << "Receive pinned message with " << reply_to_message_id << " in " << owner_dialog_id
<< " in another " << reply_in_dialog_id;
reply_to_message_id = MessageId();
reply_in_dialog_id = DialogId();
}
auto reply_to_message_id = replied_message_info.get_same_chat_reply_to_message_id();
if (!reply_to_message_id.is_valid()) {
// possible in basic groups
LOG(INFO) << "Receive pinned message with " << reply_to_message_id << " in " << owner_dialog_id;
@ -5826,12 +5821,7 @@ unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<tele
return make_unique<MessagePinMessage>(reply_to_message_id);
}
case telegram_api::messageActionGameScore::ID: {
if (reply_in_dialog_id.is_valid() && reply_in_dialog_id != owner_dialog_id) {
LOG(ERROR) << "Receive game score with " << reply_to_message_id << " in " << owner_dialog_id << " in another "
<< reply_in_dialog_id;
reply_to_message_id = MessageId();
reply_in_dialog_id = DialogId();
}
auto reply_to_message_id = replied_message_info.get_same_chat_reply_to_message_id();
if (!reply_to_message_id.is_valid()) {
// possible in basic groups
LOG(INFO) << "Receive game score with " << reply_to_message_id << " in " << owner_dialog_id;
@ -5856,20 +5846,20 @@ unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<tele
break;
}
auto action = move_tl_object_as<telegram_api::messageActionPaymentSent>(action_ptr);
if (!reply_to_message_id.is_valid()) {
if (reply_to_message_id != MessageId()) {
LOG(ERROR) << "Receive successful payment message with " << reply_to_message_id << " in " << owner_dialog_id;
auto message_full_id = replied_message_info.get_reply_message_full_id();
if (!message_full_id.get_message_id().is_valid()) {
if (message_full_id.get_message_id() != MessageId()) {
LOG(ERROR) << "Receive successful payment message with " << message_full_id << " in " << owner_dialog_id;
}
reply_in_dialog_id = DialogId();
reply_to_message_id = MessageId();
message_full_id = {};
}
if (action->total_amount_ <= 0 || !check_currency_amount(action->total_amount_)) {
LOG(ERROR) << "Receive invalid total amount " << action->total_amount_;
action->total_amount_ = 0;
}
return td::make_unique<MessagePaymentSuccessful>(
reply_in_dialog_id, reply_to_message_id, std::move(action->currency_), action->total_amount_,
std::move(action->invoice_slug_), action->recurring_used_, action->recurring_init_);
message_full_id.get_dialog_id(), message_full_id.get_message_id(), std::move(action->currency_),
action->total_amount_, std::move(action->invoice_slug_), action->recurring_used_, action->recurring_init_);
}
case telegram_api::messageActionPaymentSentMe::ID: {
if (!td->auth_manager_->is_bot()) {
@ -6069,17 +6059,15 @@ unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<tele
return make_unique<MessageSetBackground>(MessageId(), std::move(background_info));
}
case telegram_api::messageActionSetSameChatWallPaper::ID: {
if (reply_in_dialog_id.is_valid() && reply_in_dialog_id != owner_dialog_id) {
LOG(ERROR) << "Receive old background message with " << reply_to_message_id << " in " << owner_dialog_id
<< " in another " << reply_in_dialog_id;
reply_to_message_id = MessageId();
reply_in_dialog_id = DialogId();
}
auto action = move_tl_object_as<telegram_api::messageActionSetSameChatWallPaper>(action_ptr);
BackgroundInfo background_info(td, std::move(action->wallpaper_));
if (!background_info.is_valid()) {
break;
}
auto reply_to_message_id = replied_message_info.get_same_chat_reply_to_message_id();
if (!reply_to_message_id.is_valid()) {
reply_to_message_id = MessageId();
}
return make_unique<MessageSetBackground>(reply_to_message_id, std::move(background_info));
}
case telegram_api::messageActionGiveawayLaunch::ID:

View File

@ -18,6 +18,7 @@
#include "td/telegram/MessageFullId.h"
#include "td/telegram/MessageId.h"
#include "td/telegram/Photo.h"
#include "td/telegram/RepliedMessageInfo.h"
#include "td/telegram/ReplyMarkup.h"
#include "td/telegram/secret_api.h"
#include "td/telegram/SecretInputMedia.h"
@ -221,8 +222,8 @@ unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const
MessageContentDupType type, MessageCopyOptions &&copy_options);
unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<telegram_api::MessageAction> &&action_ptr,
DialogId owner_dialog_id, DialogId reply_in_dialog_id,
MessageId reply_to_message_id);
DialogId owner_dialog_id,
const RepliedMessageInfo &replied_message_info);
tl_object_ptr<td_api::MessageContent> get_message_content_object(const MessageContent *content, Td *td,
DialogId dialog_id, int32 message_date,

View File

@ -34,68 +34,24 @@ MessageReplyHeader::MessageReplyHeader(Td *td, tl_object_ptr<telegram_api::Messa
}
CHECK(reply_header_ptr->get_id() == telegram_api::messageReplyHeader::ID);
auto reply_header = telegram_api::move_object_as<telegram_api::messageReplyHeader>(reply_header_ptr);
if (reply_header->reply_to_scheduled_) {
reply_to_message_id_ = MessageId(ScheduledServerMessageId(reply_header->reply_to_msg_id_), date);
if (message_id.is_scheduled()) {
auto reply_to_peer_id = std::move(reply_header->reply_to_peer_id_);
if (reply_to_peer_id != nullptr) {
reply_in_dialog_id_ = DialogId(reply_to_peer_id);
LOG(ERROR) << "Receive reply to " << MessageFullId{reply_in_dialog_id_, reply_to_message_id_} << " in "
<< MessageFullId{dialog_id, message_id};
reply_to_message_id_ = MessageId();
reply_in_dialog_id_ = DialogId();
}
} else {
LOG(ERROR) << "Receive reply to " << reply_to_message_id_ << " in " << MessageFullId{dialog_id, message_id};
reply_to_message_id_ = MessageId();
}
if (reply_header->reply_from_ != nullptr || reply_header->reply_media_ != nullptr ||
!reply_header->quote_text_.empty() || !reply_header->quote_entities_.empty()) {
LOG(ERROR) << "Receive reply from other chat " << to_string(reply_header) << " in "
<< MessageFullId{dialog_id, message_id};
}
} else {
if (reply_header->reply_to_msg_id_ != 0) {
reply_to_message_id_ = MessageId(ServerMessageId(reply_header->reply_to_msg_id_));
auto reply_to_peer_id = std::move(reply_header->reply_to_peer_id_);
if (reply_to_peer_id != nullptr) {
reply_in_dialog_id_ = DialogId(reply_to_peer_id);
if (!reply_in_dialog_id_.is_valid()) {
LOG(ERROR) << "Receive reply in invalid " << to_string(reply_to_peer_id);
reply_to_message_id_ = MessageId();
reply_in_dialog_id_ = DialogId();
}
if (reply_in_dialog_id_ == dialog_id) {
reply_in_dialog_id_ = DialogId(); // just in case
}
}
if (!reply_to_message_id_.is_valid()) {
LOG(ERROR) << "Receive " << to_string(reply_header) << " in " << MessageFullId{dialog_id, message_id};
reply_to_message_id_ = MessageId();
reply_in_dialog_id_ = DialogId();
}
} else if (reply_header->reply_to_peer_id_ != nullptr) {
LOG(ERROR) << "Receive " << to_string(reply_header) << " in " << MessageFullId{dialog_id, message_id};
}
if (reply_header->reply_from_ != nullptr) {
reply_date_ = reply_header->reply_from_->date_;
if (reply_header->reply_from_->channel_post_ != 0) {
LOG(ERROR) << "Receive " << to_string(reply_header) << " in " << MessageFullId{dialog_id, message_id};
} else {
auto r_reply_origin = MessageOrigin::get_message_origin(td, std::move(reply_header->reply_from_));
if (r_reply_origin.is_error()) {
reply_date_ = 0;
}
}
}
}
if (!message_id.is_scheduled() && can_have_thread) {
if ((reply_header->flags_ & telegram_api::messageReplyHeader::REPLY_TO_TOP_ID_MASK) != 0) {
top_thread_message_id_ = MessageId(ServerMessageId(reply_header->reply_to_top_id_));
} else if (reply_to_message_id_.is_valid() && !reply_in_dialog_id_.is_valid() && reply_date_ == 0) {
top_thread_message_id_ = reply_to_message_id_;
}
is_topic_message_ = top_thread_message_id_.is_valid() && reply_header->forum_topic_;
is_topic_message_ = reply_header->forum_topic_;
}
replied_message_info_ = RepliedMessageInfo(td, std::move(reply_header), dialog_id, message_id, date);
if (!message_id.is_scheduled() && can_have_thread && !top_thread_message_id_.is_valid()) {
auto same_chat_reply_to_message_id = replied_message_info_.get_same_chat_reply_to_message_id();
if (same_chat_reply_to_message_id.is_valid()) {
CHECK(same_chat_reply_to_message_id.is_server());
top_thread_message_id_ = same_chat_reply_to_message_id;
} else {
is_topic_message_ = false;
}
}
}

View File

@ -6,9 +6,8 @@
//
#pragma once
#include "td/telegram/DialogId.h"
#include "td/telegram/MessageId.h"
#include "td/telegram/MessageOrigin.h"
#include "td/telegram/RepliedMessageInfo.h"
#include "td/telegram/StoryFullId.h"
#include "td/telegram/telegram_api.h"
@ -19,10 +18,8 @@ namespace td {
class Td;
struct MessageReplyHeader {
MessageId reply_to_message_id_;
DialogId reply_in_dialog_id_;
int32 reply_date_ = 0; // for replies in other chats
MessageOrigin reply_origin_; // for replies in other chats
RepliedMessageInfo replied_message_info_;
MessageId top_thread_message_id_;
bool is_topic_message_ = false;

View File

@ -61,6 +61,7 @@
#include "td/telegram/PollId.h"
#include "td/telegram/PublicDialogType.h"
#include "td/telegram/ReactionManager.h"
#include "td/telegram/RepliedMessageInfo.h"
#include "td/telegram/ReplyMarkup.h"
#include "td/telegram/ReplyMarkup.hpp"
#include "td/telegram/ReportReason.h"
@ -14024,17 +14025,17 @@ void MessagesManager::on_get_secret_message(SecretChatId secret_chat_id, UserId
auto lock_promise = pending_secret_message->load_data_multipromise.get_promise();
if ((message->flags_ & secret_api::decryptedMessage::REPLY_TO_RANDOM_ID_MASK) != 0) {
message_info.reply_header.reply_to_message_id_ =
get_message_id_by_random_id(d, message->reply_to_random_id_, "on_get_secret_message");
if (!message_info.reply_header.reply_to_message_id_.is_valid()) {
auto reply_to_message_id = get_message_id_by_random_id(d, message->reply_to_random_id_, "on_get_secret_message");
if (!reply_to_message_id.is_valid()) {
auto dialog_it = pending_secret_message_ids_.find(message_info.dialog_id);
if (dialog_it != pending_secret_message_ids_.end()) {
auto message_it = dialog_it->second.find(message->reply_to_random_id_);
if (message_it != dialog_it->second.end()) {
message_info.reply_header.reply_to_message_id_ = message_it->second;
reply_to_message_id = message_it->second;
}
}
}
message_info.reply_header.replied_message_info_ = RepliedMessageInfo(reply_to_message_id);
}
if (!clean_input_string(message->via_bot_name_)) {
@ -14318,10 +14319,8 @@ MessagesManager::MessageInfo MessagesManager::parse_telegram_api_message(
message_info.reply_header = MessageReplyHeader(td_, std::move(message->reply_to_), message_info.dialog_id,
message_info.message_id, message_info.date, can_have_thread);
message_info.content = get_action_message_content(td_, std::move(message->action_), message_info.dialog_id,
message_info.reply_header.reply_in_dialog_id_,
message_info.reply_header.reply_to_message_id_);
message_info.reply_header.reply_in_dialog_id_ = DialogId();
message_info.reply_header.reply_to_message_id_ = MessageId();
message_info.reply_header.replied_message_info_);
message_info.reply_header.replied_message_info_ = RepliedMessageInfo();
message_info.reply_header.story_full_id_ = StoryFullId();
break;
}
@ -14428,8 +14427,9 @@ std::pair<DialogId, unique_ptr<MessagesManager::Message>> MessagesManager::creat
date = 1;
}
MessageId reply_to_message_id = message_info.reply_header.reply_to_message_id_;
DialogId reply_in_dialog_id = message_info.reply_header.reply_in_dialog_id_;
auto reply_message_full_id = message_info.reply_header.replied_message_info_.get_reply_message_full_id();
MessageId reply_to_message_id = reply_message_full_id.get_message_id();
DialogId reply_in_dialog_id = reply_message_full_id.get_dialog_id();
MessageId top_thread_message_id = message_info.reply_header.top_thread_message_id_;
bool is_topic_message = message_info.reply_header.is_topic_message_;
fix_server_reply_to_message_id(dialog_id, message_id, reply_in_dialog_id, reply_to_message_id);

View File

@ -0,0 +1,87 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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)
//
#include "td/telegram/RepliedMessageInfo.h"
#include "td/telegram/MessageFullId.h"
#include "td/telegram/ScheduledServerMessageId.h"
#include "td/telegram/ServerMessageId.h"
#include "td/telegram/StoryId.h"
#include "td/telegram/UserId.h"
#include "td/utils/logging.h"
namespace td {
RepliedMessageInfo::RepliedMessageInfo(Td *td, tl_object_ptr<telegram_api::messageReplyHeader> &&reply_header,
DialogId dialog_id, MessageId message_id, int32 date) {
CHECK(reply_header != nullptr);
if (reply_header->reply_to_scheduled_) {
reply_to_message_id_ = MessageId(ScheduledServerMessageId(reply_header->reply_to_msg_id_), date);
if (message_id.is_scheduled()) {
auto reply_to_peer_id = std::move(reply_header->reply_to_peer_id_);
if (reply_to_peer_id != nullptr) {
reply_in_dialog_id_ = DialogId(reply_to_peer_id);
LOG(ERROR) << "Receive reply to " << MessageFullId{reply_in_dialog_id_, reply_to_message_id_} << " in "
<< MessageFullId{dialog_id, message_id};
reply_to_message_id_ = MessageId();
reply_in_dialog_id_ = DialogId();
}
} else {
LOG(ERROR) << "Receive reply to " << reply_to_message_id_ << " in " << MessageFullId{dialog_id, message_id};
reply_to_message_id_ = MessageId();
}
if (reply_header->reply_from_ != nullptr || reply_header->reply_media_ != nullptr ||
!reply_header->quote_text_.empty() || !reply_header->quote_entities_.empty()) {
LOG(ERROR) << "Receive reply from other chat " << to_string(reply_header) << " in "
<< MessageFullId{dialog_id, message_id};
}
} else {
if (reply_header->reply_to_msg_id_ != 0) {
reply_to_message_id_ = MessageId(ServerMessageId(reply_header->reply_to_msg_id_));
auto reply_to_peer_id = std::move(reply_header->reply_to_peer_id_);
if (reply_to_peer_id != nullptr) {
reply_in_dialog_id_ = DialogId(reply_to_peer_id);
if (!reply_in_dialog_id_.is_valid()) {
LOG(ERROR) << "Receive reply in invalid " << to_string(reply_to_peer_id);
reply_to_message_id_ = MessageId();
reply_in_dialog_id_ = DialogId();
}
if (reply_in_dialog_id_ == dialog_id) {
reply_in_dialog_id_ = DialogId(); // just in case
}
}
if (!reply_to_message_id_.is_valid()) {
LOG(ERROR) << "Receive " << to_string(reply_header) << " in " << MessageFullId{dialog_id, message_id};
reply_to_message_id_ = MessageId();
reply_in_dialog_id_ = DialogId();
}
} else if (reply_header->reply_to_peer_id_ != nullptr) {
LOG(ERROR) << "Receive " << to_string(reply_header) << " in " << MessageFullId{dialog_id, message_id};
}
if (reply_header->reply_from_ != nullptr) {
reply_date_ = reply_header->reply_from_->date_;
if (reply_header->reply_from_->channel_post_ != 0) {
LOG(ERROR) << "Receive " << to_string(reply_header) << " in " << MessageFullId{dialog_id, message_id};
} else {
auto r_reply_origin = MessageOrigin::get_message_origin(td, std::move(reply_header->reply_from_));
if (r_reply_origin.is_error()) {
reply_date_ = 0;
}
}
}
}
}
MessageId RepliedMessageInfo::get_same_chat_reply_to_message_id() const {
return is_same_chat_reply() ? reply_to_message_id_ : MessageId();
}
MessageFullId RepliedMessageInfo::get_reply_message_full_id() const {
return {reply_in_dialog_id_, reply_to_message_id_};
}
} // namespace td

View File

@ -0,0 +1,44 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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/DialogId.h"
#include "td/telegram/MessageId.h"
#include "td/telegram/MessageOrigin.h"
#include "td/telegram/telegram_api.h"
#include "td/utils/common.h"
namespace td {
class Td;
class RepliedMessageInfo {
public:
MessageId reply_to_message_id_;
DialogId reply_in_dialog_id_; // DialogId() if reply is to a message in the same chat
int32 reply_date_ = 0; // for replies in other chats
MessageOrigin reply_origin_; // for replies in other chats
RepliedMessageInfo() = default;
explicit RepliedMessageInfo(MessageId reply_to_message_id) : reply_to_message_id_(reply_to_message_id) {
}
RepliedMessageInfo(Td *td, tl_object_ptr<telegram_api::messageReplyHeader> &&reply_header, DialogId dialog_id,
MessageId message_id, int32 date);
bool is_same_chat_reply() const {
return reply_in_dialog_id_ == DialogId() && reply_date_ == 0;
}
MessageId get_same_chat_reply_to_message_id() const;
MessageFullId get_reply_message_full_id() const;
};
} // namespace td