diff --git a/CMakeLists.txt b/CMakeLists.txt index f023be490..442bcf96c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -395,6 +395,7 @@ set(TDLIB_SOURCE td/telegram/MessageSource.cpp td/telegram/MessageThreadDb.cpp td/telegram/MessageTtl.cpp + td/telegram/MessageViewer.cpp td/telegram/misc.cpp td/telegram/net/AuthDataShared.cpp td/telegram/net/ConnectionCreator.cpp @@ -651,6 +652,7 @@ set(TDLIB_SOURCE td/telegram/MessageThreadDb.h td/telegram/MessageThreadInfo.h td/telegram/MessageTtl.h + td/telegram/MessageViewer.h td/telegram/MinChannel.h td/telegram/misc.h td/telegram/net/AuthDataShared.h diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 982850d57..c01541578 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1001,6 +1001,13 @@ chatMessageSender sender:MessageSender needs_premium:Bool = ChatMessageSender; chatMessageSenders senders:vector = ChatMessageSenders; +//@description Represents a viewer of a message @user_id User identifier of the viewer @view_date Point in time (Unix timestamp) when the message was viewed +messageViewer user_id:int53 view_date:int32 = MessageViewer; + +//@description Represents a list of message viewers @viewers List of message viewers +messageViewers viewers:vector = MessageViewers; + + //@class MessageForwardOrigin @description Contains information about the origin of a forwarded message //@description The message was originally sent by a known user @sender_user_id Identifier of the user that originally sent the message @@ -5880,7 +5887,7 @@ getMessageThread chat_id:int53 message_id:int53 = MessageThreadInfo; //@description Returns viewers of a recent outgoing message in a basic group or a supergroup chat. For video notes and voice notes only users, opened content of the message, are returned. The method can be called if message.can_get_viewers == true //@chat_id Chat identifier //@message_id Identifier of the message -getMessageViewers chat_id:int53 message_id:int53 = Users; +getMessageViewers chat_id:int53 message_id:int53 = MessageViewers; //@description Returns information about a file; this is an offline request @file_id Identifier of the file to get getFile file_id:int32 = File; diff --git a/td/telegram/MessageViewer.cpp b/td/telegram/MessageViewer.cpp new file mode 100644 index 000000000..c6520e9ab --- /dev/null +++ b/td/telegram/MessageViewer.cpp @@ -0,0 +1,48 @@ +// +// 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/MessageViewer.h" + +#include "td/telegram/ContactsManager.h" + +#include "td/utils/algorithm.h" + +namespace td { + +MessageViewer::MessageViewer(telegram_api::object_ptr &&read_date) + : user_id_(read_date->user_id_), date_(read_date->date_) { +} + +td_api::object_ptr MessageViewer::get_message_viewer_object( + ContactsManager *contacts_manager) const { + return td_api::make_object( + contacts_manager->get_user_id_object(user_id_, "get_message_viewer_object"), date_); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageViewer &viewer) { + return string_builder << '[' << viewer.user_id_ << " at " << viewer.date_ << ']'; +} + +MessageViewers::MessageViewers(vector> &&read_dates) + : message_viewers_( + transform(std::move(read_dates), [](telegram_api::object_ptr &&read_date) { + return MessageViewer(std::move(read_date)); + })) { +} + +td_api::object_ptr MessageViewers::get_message_viewers_object( + ContactsManager *contacts_manager) const { + return td_api::make_object( + transform(message_viewers_, [contacts_manager](const MessageViewer &message_viewer) { + return message_viewer.get_message_viewer_object(contacts_manager); + })); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageViewers &viewers) { + return string_builder << viewers.message_viewers_; +} + +} // namespace td diff --git a/td/telegram/MessageViewer.h b/td/telegram/MessageViewer.h new file mode 100644 index 000000000..fb071af1b --- /dev/null +++ b/td/telegram/MessageViewer.h @@ -0,0 +1,48 @@ +// +// 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/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class ContactsManager; + +class MessageViewer { + UserId user_id_; + int32 date_ = 0; + + friend StringBuilder &operator<<(StringBuilder &string_builder, const MessageViewer &viewer); + + public: + explicit MessageViewer(telegram_api::object_ptr &&read_date); + + UserId get_user_id() const { + return user_id_; + } + + td_api::object_ptr get_message_viewer_object(ContactsManager *contacts_manager) const; +}; + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageViewer &viewer); + +struct MessageViewers { + vector message_viewers_; + + explicit MessageViewers(vector> &&read_dates); + + td_api::object_ptr get_message_viewers_object(ContactsManager *contacts_manager) const; +}; + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageViewers &viewers); + +} // namespace td diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 9526cff8f..29df19ce8 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -679,11 +679,11 @@ class UnpinAllMessagesQuery final : public Td::ResultHandler { }; class GetMessageReadParticipantsQuery final : public Td::ResultHandler { - Promise> promise_; + Promise promise_; DialogId dialog_id_; public: - explicit GetMessageReadParticipantsQuery(Promise> &&promise) : promise_(std::move(promise)) { + explicit GetMessageReadParticipantsQuery(Promise &&promise) : promise_(std::move(promise)) { } void send(DialogId dialog_id, MessageId message_id) { @@ -700,11 +700,7 @@ class GetMessageReadParticipantsQuery final : public Td::ResultHandler { return on_error(result_ptr.move_as_error()); } - auto user_ids = - transform(result_ptr.ok(), [](const telegram_api::object_ptr &user_date) { - return user_date->user_id_; - }); - promise_.set_value(UserId::get_user_ids(user_ids)); + promise_.set_value(MessageViewers(result_ptr.move_as_ok())); } void on_error(Status status) final { @@ -19009,11 +19005,11 @@ Status MessagesManager::can_get_message_viewers(DialogId dialog_id, const Messag } void MessagesManager::get_message_viewers(FullMessageId full_message_id, - Promise> &&promise) { + Promise> &&promise) { TRY_STATUS_PROMISE(promise, can_get_message_viewers(full_message_id)); auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), dialog_id = full_message_id.get_dialog_id(), - promise = std::move(promise)](Result> result) mutable { + promise = std::move(promise)](Result result) mutable { if (result.is_error()) { return promise.set_error(result.move_as_error()); } @@ -19025,11 +19021,12 @@ void MessagesManager::get_message_viewers(FullMessageId full_message_id, ->send(full_message_id.get_dialog_id(), full_message_id.get_message_id()); } -void MessagesManager::on_get_message_viewers(DialogId dialog_id, vector user_ids, bool is_recursive, - Promise> &&promise) { +void MessagesManager::on_get_message_viewers(DialogId dialog_id, MessageViewers message_viewers, bool is_recursive, + Promise> &&promise) { if (!is_recursive) { bool need_participant_list = false; - for (auto user_id : user_ids) { + for (auto message_viewer : message_viewers.message_viewers_) { + auto user_id = message_viewer.get_user_id(); if (!user_id.is_valid()) { LOG(ERROR) << "Receive invalid " << user_id << " as viewer of a message in " << dialog_id; continue; @@ -19039,11 +19036,12 @@ void MessagesManager::on_get_message_viewers(DialogId dialog_id, vector } } if (need_participant_list) { - auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, user_ids = std::move(user_ids), - promise = std::move(promise)](Unit result) mutable { - send_closure(actor_id, &MessagesManager::on_get_message_viewers, dialog_id, std::move(user_ids), true, - std::move(promise)); - }); + auto query_promise = + PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, message_viewers = std::move(message_viewers), + promise = std::move(promise)](Unit result) mutable { + send_closure(actor_id, &MessagesManager::on_get_message_viewers, dialog_id, std::move(message_viewers), + true, std::move(promise)); + }); switch (dialog_id.get_type()) { case DialogType::Chat: @@ -19060,7 +19058,7 @@ void MessagesManager::on_get_message_viewers(DialogId dialog_id, vector } } } - promise.set_value(td_->contacts_manager_->get_users_object(-1, user_ids)); + promise.set_value(message_viewers.get_message_viewers_object(td_->contacts_manager_.get())); } void MessagesManager::translate_message_text(FullMessageId full_message_id, const string &to_language_code, @@ -22634,8 +22632,9 @@ tl_object_ptr MessagesManager::get_dialog_history(DialogId dia } LOG(INFO) << "Return " << messages.size() << " messages in result to getChatHistory"; - promise.set_value(Unit()); // can return some messages - return get_messages_object(-1, std::move(messages), false); // TODO return real total_count of messages in the dialog + promise.set_value(Unit()); // can return some messages + return get_messages_object(-1, std::move(messages), + false); // TODO return real total_count of messages in the dialog } class MessagesManager::ReadHistoryOnServerLogEvent { diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index d31fb0ef4..cbd23ae16 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -41,6 +41,7 @@ #include "td/telegram/MessageSource.h" #include "td/telegram/MessageThreadInfo.h" #include "td/telegram/MessageTtl.h" +#include "td/telegram/MessageViewer.h" #include "td/telegram/net/DcId.h" #include "td/telegram/net/NetQuery.h" #include "td/telegram/Notification.h" @@ -641,7 +642,8 @@ class MessagesManager final : public Actor { DialogId dialog_id, MessageId message_id, DialogId expected_dialog_id, MessageId expected_message_id, Promise promise); - void get_message_viewers(FullMessageId full_message_id, Promise> &&promise); + void get_message_viewers(FullMessageId full_message_id, + Promise> &&promise); void translate_message_text(FullMessageId full_message_id, const string &to_language_code, Promise> &&promise); @@ -3062,8 +3064,8 @@ class MessagesManager final : public Actor { void on_get_discussion_message(DialogId dialog_id, MessageId message_id, MessageThreadInfo &&message_thread_info, Promise &&promise); - void on_get_message_viewers(DialogId dialog_id, vector user_ids, bool is_recursive, - Promise> &&promise); + void on_get_message_viewers(DialogId dialog_id, MessageViewers message_viewers, bool is_recursive, + Promise> &&promise); static MessageId get_first_database_message_id_by_index(const Dialog *d, MessageSearchFilter filter);