Add td_api::getMessageViewers.
This commit is contained in:
parent
944e8a3c64
commit
a4f66c69cb
@ -4081,6 +4081,9 @@ getMessages chat_id:int53 message_ids:vector<int53> = Messages;
|
||||
//@description Returns information about a message thread. Can be used only if message.can_get_message_thread == true @chat_id Chat identifier @message_id Identifier of the message
|
||||
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;
|
||||
|
||||
//@description Returns information about a file; this is an offline request @file_id Identifier of the file to get
|
||||
getFile file_id:int32 = File;
|
||||
|
||||
|
@ -14103,6 +14103,14 @@ void ContactsManager::send_get_chat_full_query(ChatId chat_id, Promise<Unit> &&p
|
||||
get_chat_full_queries_.add_query(chat_id.get(), std::move(send_query), std::move(promise));
|
||||
}
|
||||
|
||||
int32 ContactsManager::get_chat_participant_count(ChatId chat_id) const {
|
||||
auto c = get_chat(chat_id);
|
||||
if (c == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return c->participant_count;
|
||||
}
|
||||
|
||||
bool ContactsManager::get_chat_is_active(ChatId chat_id) const {
|
||||
auto c = get_chat(chat_id);
|
||||
if (c == nullptr) {
|
||||
|
@ -475,6 +475,7 @@ class ContactsManager final : public Actor {
|
||||
FileSourceId get_chat_full_file_source_id(ChatId chat_id);
|
||||
void reload_chat_full(ChatId chat_id, Promise<Unit> &&promise);
|
||||
|
||||
int32 get_chat_participant_count(ChatId channel_id) const;
|
||||
bool get_chat_is_active(ChatId chat_id) const;
|
||||
ChannelId get_chat_migrated_to_channel_id(ChatId chat_id) const;
|
||||
DialogParticipantStatus get_chat_status(ChatId chat_id) const;
|
||||
|
@ -679,6 +679,37 @@ class UnpinAllMessagesQuery final : public Td::ResultHandler {
|
||||
}
|
||||
};
|
||||
|
||||
class GetMessageReadParticipantsQuery final : public Td::ResultHandler {
|
||||
Promise<vector<UserId>> promise_;
|
||||
DialogId dialog_id_;
|
||||
|
||||
public:
|
||||
explicit GetMessageReadParticipantsQuery(Promise<vector<UserId>> &&promise) : promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void send(DialogId dialog_id, MessageId message_id) {
|
||||
dialog_id_ = dialog_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_getMessageReadParticipants(
|
||||
std::move(input_peer), message_id.get_server_message_id().get())));
|
||||
}
|
||||
|
||||
void on_result(uint64 id, BufferSlice packet) final {
|
||||
auto result_ptr = fetch_result<telegram_api::messages_getMessageReadParticipants>(packet);
|
||||
if (result_ptr.is_error()) {
|
||||
return on_error(id, result_ptr.move_as_error());
|
||||
}
|
||||
|
||||
promise_.set_value(UserId::get_user_ids(result_ptr.ok()));
|
||||
}
|
||||
|
||||
void on_error(uint64 id, Status status) final {
|
||||
td->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetMessageReadParticipantsQuery");
|
||||
promise_.set_error(std::move(status));
|
||||
}
|
||||
};
|
||||
|
||||
class ExportChannelMessageLinkQuery final : public Td::ResultHandler {
|
||||
Promise<Unit> promise_;
|
||||
ChannelId channel_id_;
|
||||
@ -17067,6 +17098,131 @@ td_api::object_ptr<td_api::messageThreadInfo> MessagesManager::get_message_threa
|
||||
std::move(messages), std::move(draft_message));
|
||||
}
|
||||
|
||||
Status MessagesManager::can_get_message_viewers(FullMessageId full_message_id) {
|
||||
auto dialog_id = full_message_id.get_dialog_id();
|
||||
Dialog *d = get_dialog_force(dialog_id, "get_message_viewers");
|
||||
if (d == nullptr) {
|
||||
return Status::Error(400, "Chat not found");
|
||||
}
|
||||
|
||||
auto m = get_message_force(d, full_message_id.get_message_id(), "get_message_viewers");
|
||||
if (m == nullptr) {
|
||||
return Status::Error(400, "Message not found");
|
||||
}
|
||||
|
||||
return can_get_message_viewers(dialog_id, m);
|
||||
}
|
||||
|
||||
Status MessagesManager::can_get_message_viewers(DialogId dialog_id, const Message *m) const {
|
||||
if (!m->is_outgoing) {
|
||||
return Status::Error(400, "Can't get viewers of incoming messages");
|
||||
}
|
||||
if (m->date < G()->unix_time() - 7 * 86400) {
|
||||
return Status::Error(400, "Message is too old");
|
||||
}
|
||||
|
||||
int32 participant_count = 0;
|
||||
switch (dialog_id.get_type()) {
|
||||
case DialogType::User:
|
||||
return Status::Error(400, "Can't get message viewers in private chats");
|
||||
case DialogType::Chat:
|
||||
if (!td_->contacts_manager_->get_chat_is_active(dialog_id.get_chat_id())) {
|
||||
return Status::Error(400, "Chat is deactivated");
|
||||
}
|
||||
participant_count = td_->contacts_manager_->get_chat_participant_count(dialog_id.get_chat_id());
|
||||
break;
|
||||
case DialogType::Channel:
|
||||
if (is_broadcast_channel(dialog_id)) {
|
||||
return Status::Error(400, "Can't get message viewers in channel chats");
|
||||
}
|
||||
participant_count = td_->contacts_manager_->get_channel_participant_count(dialog_id.get_channel_id());
|
||||
break;
|
||||
case DialogType::SecretChat:
|
||||
return Status::Error(400, "Can't get message viewers in secret chats");
|
||||
case DialogType::None:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return Status::OK();
|
||||
}
|
||||
if (!have_input_peer(dialog_id, AccessRights::Read)) {
|
||||
return Status::Error(400, "Can't access the chat");
|
||||
}
|
||||
if (participant_count == 0) {
|
||||
return Status::Error(400, "Chat is empty or have unknown number of members");
|
||||
}
|
||||
if (participant_count > 50) {
|
||||
return Status::Error(400, "Chat is too big");
|
||||
}
|
||||
|
||||
if (m->message_id.is_scheduled()) {
|
||||
return Status::Error(400, "Scheduled messages can't have viewers");
|
||||
}
|
||||
if (m->message_id.is_yet_unsent()) {
|
||||
return Status::Error(400, "Yet unsent messages can't have viewers");
|
||||
}
|
||||
if (m->message_id.is_local()) {
|
||||
return Status::Error(400, "Local messages can't have viewers");
|
||||
}
|
||||
CHECK(m->message_id.is_server());
|
||||
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
void MessagesManager::get_message_viewers(FullMessageId full_message_id,
|
||||
Promise<td_api::object_ptr<td_api::users>> &&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<vector<UserId>> result) mutable {
|
||||
if (result.is_error()) {
|
||||
return promise.set_error(result.move_as_error());
|
||||
}
|
||||
send_closure(actor_id, &MessagesManager::on_get_message_viewers, dialog_id, result.move_as_ok(), false,
|
||||
std::move(promise));
|
||||
});
|
||||
|
||||
td_->create_handler<GetMessageReadParticipantsQuery>(std::move(query_promise))
|
||||
->send(full_message_id.get_dialog_id(), full_message_id.get_message_id());
|
||||
}
|
||||
|
||||
void MessagesManager::on_get_message_viewers(DialogId dialog_id, vector<UserId> user_ids, bool is_recursive,
|
||||
Promise<td_api::object_ptr<td_api::users>> &&promise) {
|
||||
if (!is_recursive) {
|
||||
bool need_participant_list = false;
|
||||
for (auto user_id : user_ids) {
|
||||
if (!user_id.is_valid()) {
|
||||
LOG(ERROR) << "Receive invalid " << user_id << " as viewer of a message in " << dialog_id;
|
||||
continue;
|
||||
}
|
||||
if (!td_->contacts_manager_->have_user_force(user_id)) {
|
||||
need_participant_list = true;
|
||||
}
|
||||
}
|
||||
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));
|
||||
});
|
||||
|
||||
switch (dialog_id.get_type()) {
|
||||
case DialogType::Chat:
|
||||
return td_->contacts_manager_->reload_chat_full(dialog_id.get_chat_id(), std::move(query_promise));
|
||||
case DialogType::Channel:
|
||||
return td_->contacts_manager_->get_channel_participants(
|
||||
dialog_id.get_channel_id(), td_api::make_object<td_api::supergroupMembersFilterRecent>(), string(), 0,
|
||||
200, 200, PromiseCreator::lambda([query_promise = std::move(query_promise)](DialogParticipants) mutable {
|
||||
query_promise.set_value(Unit());
|
||||
}));
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
promise.set_value(td_->contacts_manager_->get_users_object(-1, user_ids));
|
||||
}
|
||||
|
||||
void MessagesManager::get_dialog_info_full(DialogId dialog_id, Promise<Unit> &&promise, const char *source) {
|
||||
switch (dialog_id.get_type()) {
|
||||
case DialogType::User:
|
||||
|
@ -578,6 +578,8 @@ class MessagesManager final : public Actor {
|
||||
DialogId dialog_id, MessageId message_id, DialogId expected_dialog_id,
|
||||
MessageId expected_message_id, Promise<MessageThreadInfo> promise);
|
||||
|
||||
void get_message_viewers(FullMessageId full_message_id, Promise<td_api::object_ptr<td_api::users>> &&promise);
|
||||
|
||||
bool is_message_edited_recently(FullMessageId full_message_id, int32 seconds);
|
||||
|
||||
bool is_deleted_secret_chat(DialogId dialog_id) const;
|
||||
@ -1795,6 +1797,10 @@ class MessagesManager final : public Actor {
|
||||
|
||||
static Status can_get_media_timestamp_link(DialogId dialog_id, const Message *m);
|
||||
|
||||
Status can_get_message_viewers(FullMessageId full_message_id) TD_WARN_UNUSED_RESULT;
|
||||
|
||||
Status can_get_message_viewers(DialogId dialog_id, const Message *m) const TD_WARN_UNUSED_RESULT;
|
||||
|
||||
void cancel_edit_message_media(DialogId dialog_id, Message *m, Slice error_message);
|
||||
|
||||
void on_message_media_edited(DialogId dialog_id, MessageId message_id, FileId file_id, FileId thumbnail_file_id,
|
||||
@ -2742,6 +2748,9 @@ class MessagesManager final : public Actor {
|
||||
void on_get_discussion_message(DialogId dialog_id, MessageId message_id, MessageThreadInfo &&message_thread_info,
|
||||
Promise<MessageThreadInfo> &&promise);
|
||||
|
||||
void on_get_message_viewers(DialogId dialog_id, vector<UserId> user_ids, bool is_recursive,
|
||||
Promise<td_api::object_ptr<td_api::users>> &&promise);
|
||||
|
||||
static MessageId get_first_database_message_id_by_index(const Dialog *d, MessageSearchFilter filter);
|
||||
|
||||
void on_search_dialog_messages_db_result(int64 random_id, DialogId dialog_id, MessageId from_message_id,
|
||||
|
@ -5010,6 +5010,13 @@ void Td::on_request(uint64 id, const td_api::getMessageThread &request) {
|
||||
CREATE_REQUEST(GetMessageThreadRequest, request.chat_id_, request.message_id_);
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::getMessageViewers &request) {
|
||||
CHECK_IS_USER();
|
||||
CREATE_REQUEST_PROMISE();
|
||||
messages_manager_->get_message_viewers({DialogId(request.chat_id_), MessageId(request.message_id_)},
|
||||
std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::getMessageLink &request) {
|
||||
auto r_message_link =
|
||||
messages_manager_->get_message_link({DialogId(request.chat_id_), MessageId(request.message_id_)},
|
||||
|
@ -516,6 +516,8 @@ class Td final : public Actor {
|
||||
|
||||
void on_request(uint64 id, const td_api::getMessageThread &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::getMessageViewers &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::getMessages &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::getChatSponsoredMessages &request);
|
||||
|
@ -2590,6 +2590,11 @@ class CliClient final : public Actor {
|
||||
string message_id;
|
||||
get_args(args, chat_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 == "gmv") {
|
||||
string chat_id;
|
||||
string message_id;
|
||||
get_args(args, chat_id, message_id);
|
||||
send_request(td_api::make_object<td_api::getMessageViewers>(as_chat_id(chat_id), as_message_id(message_id)));
|
||||
} else if (op == "gcpm") {
|
||||
string chat_id = args;
|
||||
send_request(td_api::make_object<td_api::getChatPinnedMessage>(as_chat_id(chat_id)));
|
||||
|
Loading…
Reference in New Issue
Block a user