From ebb78d3c1bbfb63de2cdcbff828adf319ca9f2de Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 21 Jan 2022 16:46:16 +0300 Subject: [PATCH] Add td_api::getMessageChosenReactions. --- td/generate/scheme/td_api.tl | 30 ++++++++-- td/telegram/MessageReaction.cpp | 101 ++++++++++++++++++++++++++++++++ td/telegram/MessageReaction.h | 6 ++ td/telegram/Td.cpp | 11 ++++ td/telegram/Td.h | 2 + td/telegram/cli.cpp | 9 +++ 6 files changed, 153 insertions(+), 6 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 818db4005..ac1659f72 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -2369,8 +2369,11 @@ call id:int32 user_id:int53 is_outgoing:Bool is_video:Bool state:CallState = Cal phoneNumberAuthenticationSettings allow_flash_call:Bool allow_missed_call:Bool is_current_phone_number:Bool allow_sms_retriever_api:Bool authentication_tokens:vector = PhoneNumberAuthenticationSettings; -//@description Represents a list of animations @animations List of animations -animations animations:vector = Animations; +//@description Represents a chosen reaction for a message @reaction Text representation of the reaction @chooser_id Identifier of the chat member, chosen the reaction +chosenReaction reaction:string chooser_id:MessageSender = ChosenReaction; + +//@description Represents a list of chosen reactions for a message @total_count The total count of found reactions @reactions The list of chosen reactions @next_offset The offset for the next request. If empty, there are no more results +chosenReactions total_count:int32 reactions:vector next_offset:string = ChosenReactions; //@description Contains stickers which must be used for reaction animation rendering @@ -2387,6 +2390,10 @@ animations animations:vector = Animations; reaction reaction:string title:string is_active:Bool static_icon:sticker appear_animation:sticker select_animation:sticker activate_animation:sticker effect_animation:sticker around_animation:sticker center_animation:sticker = Reaction; +//@description Represents a list of animations @animations List of animations +animations animations:vector = Animations; + + //@class DiceStickers @description Contains animated stickers which must be used for dice animation rendering //@description A regular animated sticker @sticker The animated sticker with the dice animation @@ -4345,7 +4352,7 @@ searchMessages chat_list:ChatList query:string offset_date:int32 offset_chat_id: //@description Searches for messages in secret chats. Returns the results in reverse chronological order. For optimal performance, the number of returned messages is chosen by TDLib //@chat_id Identifier of the chat in which to search. Specify 0 to search in all secret chats //@query Query to search for. If empty, searchChatMessages must be used instead -//@offset Offset of the first entry to return as received from the previous request; use empty string to get first chunk of results +//@offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results //@limit The maximum number of messages to be returned; up to 100. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit //@filter Additional filter for messages to search; pass null to search for all messages searchSecretMessages chat_id:int53 query:string offset:string limit:int32 filter:SearchMessagesFilter = FoundMessages; @@ -4390,7 +4397,7 @@ getChatScheduledMessages chat_id:int53 = Messages; //@description Returns forwarded copies of a channel message to different public channels. For optimal performance, the number of returned messages is chosen by TDLib //@chat_id Chat identifier of the message //@message_id Message identifier -//@offset Offset of the first entry to return as received from the previous request; use empty string to get first chunk of results +//@offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results //@limit The maximum number of messages to be returned; must be positive and can't be greater than 100. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit getMessagePublicForwards chat_id:int53 message_id:int53 offset:string limit:int32 = FoundMessages; @@ -4580,6 +4587,15 @@ editInlineMessageReplyMarkup inline_message_id:string reply_markup:ReplyMarkup = editMessageSchedulingState chat_id:int53 message_id:int53 scheduling_state:MessageSchedulingState = Ok; +//@description Returns reactions chosen for a message, along with their source +//@chat_id Identifier of the chat to which the message belongs +//@message_id Identifier of the message +//@reaction If non-empty, only reactions with the specified text representation will be returned +//@offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results +//@limit The maximum number of chosen reactions to be returned; must be positive and can't be greater than 100 +getMessageChosenReactions chat_id:int53 message_id:int53 reaction:string offset:string limit:int32 = ChosenReactions; + + //@description Returns all entities (mentions, hashtags, cashtags, bot commands, bank card numbers, URLs, and email addresses) contained in the text. Can be called synchronously @text The text in which to look for entites getTextEntities text:string = TextEntities; @@ -4614,12 +4630,14 @@ getJsonString json_value:JsonValue = Text; //@description Changes the user answer to a poll. A poll in quiz mode can be answered only once -//@chat_id Identifier of the chat to which the poll belongs @message_id Identifier of the message containing the poll +//@chat_id Identifier of the chat to which the poll belongs +//@message_id Identifier of the message containing the poll //@option_ids 0-based identifiers of answer options, chosen by the user. User can choose more than 1 answer option only is the poll allows multiple answers setPollAnswer chat_id:int53 message_id:int53 option_ids:vector = Ok; //@description Returns users voted for the specified option in a non-anonymous polls. For optimal performance, the number of returned users is chosen by TDLib -//@chat_id Identifier of the chat to which the poll belongs @message_id Identifier of the message containing the poll +//@chat_id Identifier of the chat to which the poll belongs +//@message_id Identifier of the message containing the poll //@option_id 0-based identifier of the answer option //@offset Number of users to skip in the result; must be non-negative //@limit The maximum number of users to be returned; must be positive and can't be greater than 50. For optimal performance, the number of returned users is chosen by TDLib and can be smaller than the specified limit, even if the end of the voter list has not been reached diff --git a/td/telegram/MessageReaction.cpp b/td/telegram/MessageReaction.cpp index 5484d83b9..173951d15 100644 --- a/td/telegram/MessageReaction.cpp +++ b/td/telegram/MessageReaction.cpp @@ -11,12 +11,90 @@ #include "td/telegram/Td.h" #include "td/utils/algorithm.h" +#include "td/utils/buffer.h" #include "td/utils/logging.h" #include namespace td { +class GetMessageReactionsListQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + MessageId message_id_; + string reaction_; + string offset_; + + public: + explicit GetMessageReactionsListQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(FullMessageId full_message_id, string reaction, string offset, int32 limit) { + dialog_id_ = full_message_id.get_dialog_id(); + message_id_ = full_message_id.get_message_id(); + reaction_ = std::move(reaction); + offset_ = std::move(offset); + + auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + + int32 flags = 0; + if (!reaction_.empty()) { + flags |= telegram_api::messages_getMessageReactionsList::REACTION_MASK; + } + if (!offset_.empty()) { + flags |= telegram_api::messages_getMessageReactionsList::OFFSET_MASK; + } + + send_query(G()->net_query_creator().create(telegram_api::messages_getMessageReactionsList( + flags, std::move(input_peer), message_id_.get_server_message_id().get(), reaction_, offset_, limit))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetMessageReactionsListQuery: " << to_string(ptr); + + td_->contacts_manager_->on_get_users(std::move(ptr->users_), "GetMessageReactionsListQuery"); + // td_->contacts_manager_->on_get_chats(std::move(ptr->chats_), "GetMessageReactionsListQuery"); + + int32 total_count = ptr->count_; + if (total_count < static_cast(ptr->reactions_.size())) { + LOG(ERROR) << "Receive invalid total_count in " << to_string(ptr); + total_count = static_cast(ptr->reactions_.size()); + } + + vector> reactions; + for (auto &reaction : ptr->reactions_) { + UserId user_id(reaction->user_id_); + if (!user_id.is_valid() || (!reaction_.empty() && reaction_ != reaction->reaction_)) { + LOG(ERROR) << "Receive unexpected " << to_string(reaction); + continue; + } + + reactions.push_back(td_api::make_object( + reaction->reaction_, + td_api::make_object( + td_->contacts_manager_->get_user_id_object(user_id, "GetMessageReactionsListQuery")))); + } + + promise_.set_value( + td_api::make_object(total_count, std::move(reactions), ptr->next_offset_)); + } + + void on_error(Status status) final { + td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetMessageReactionsListQuery"); + promise_.set_error(std::move(status)); + } +}; + td_api::object_ptr MessageReaction::get_message_reaction_object(Td *td) const { CHECK(!is_empty()); @@ -179,4 +257,27 @@ bool MessageReactions::need_update_message_reactions(const MessageReactions *old old_reactions->need_polling_ != new_reactions->need_polling_; } +void get_message_chosen_reactions(Td *td, FullMessageId full_message_id, string reaction, string offset, int32 limit, + Promise> &&promise) { + if (!td->messages_manager_->have_message_force(full_message_id, "get_message_chosen_reactions")) { + return promise.set_error(Status::Error(400, "Message not found")); + } + + auto message_id = full_message_id.get_message_id(); + if (!message_id.is_valid() || !message_id.is_server()) { + return promise.set_value(td_api::make_object(0, Auto(), string())); + } + + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); + } + static constexpr int32 MAX_GET_CHOSEN_REACTIONS = 100; // server side limit + if (limit > MAX_GET_CHOSEN_REACTIONS) { + limit = MAX_GET_CHOSEN_REACTIONS; + } + + td->create_handler(std::move(promise)) + ->send(full_message_id, std::move(reaction), std::move(offset), limit); +} + } // namespace td diff --git a/td/telegram/MessageReaction.h b/td/telegram/MessageReaction.h index 3b06a3a8a..0282baa7c 100644 --- a/td/telegram/MessageReaction.h +++ b/td/telegram/MessageReaction.h @@ -8,10 +8,13 @@ #include "td/telegram/ChannelId.h" #include "td/telegram/DialogId.h" +#include "td/telegram/FullMessageId.h" #include "td/telegram/MinChannel.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" +#include "td/actor/PromiseFuture.h" + #include "td/utils/common.h" #include "td/utils/StringBuilder.h" @@ -114,4 +117,7 @@ struct MessageReactions { void parse(ParserT &parser); }; +void get_message_chosen_reactions(Td *td, FullMessageId full_message_id, string reaction, string offset, int32 limit, + Promise> &&promise); + } // namespace td diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 04a77c54b..b893fd4ce 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -59,6 +59,7 @@ #include "td/telegram/MessageEntity.h" #include "td/telegram/MessageId.h" #include "td/telegram/MessageLinkInfo.h" +#include "td/telegram/MessageReaction.h" #include "td/telegram/MessageSearchFilter.h" #include "td/telegram/MessageSender.h" #include "td/telegram/MessagesManager.h" @@ -5243,6 +5244,16 @@ void Td::on_request(uint64 id, const td_api::getChatScheduledMessages &request) CREATE_REQUEST(GetChatScheduledMessagesRequest, request.chat_id_); } +void Td::on_request(uint64 id, td_api::getMessageChosenReactions &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.offset_); + CLEAN_INPUT_STRING(request.reaction_); + CREATE_REQUEST_PROMISE(); + get_message_chosen_reactions(this, {DialogId(request.chat_id_), MessageId(request.message_id_)}, + std::move(request.reaction_), std::move(request.offset_), request.limit_, + std::move(promise)); +} + void Td::on_request(uint64 id, td_api::getMessagePublicForwards &request) { CHECK_IS_USER(); CLEAN_INPUT_STRING(request.offset_); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index a396664d7..f624ab2d5 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -645,6 +645,8 @@ class Td final : public Actor { void on_request(uint64 id, const td_api::getChatScheduledMessages &request); + void on_request(uint64 id, td_api::getMessageChosenReactions &request); + void on_request(uint64 id, td_api::getMessagePublicForwards &request); void on_request(uint64 id, const td_api::removeNotification &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 55552612e..1915b9d98 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2058,6 +2058,15 @@ class CliClient final : public Actor { ChatId chat_id; get_args(args, chat_id); send_request(td_api::make_object(chat_id)); + } else if (op == "gmcr") { + ChatId chat_id; + MessageId message_id; + string reaction; + string offset; + string limit; + get_args(args, chat_id, message_id, reaction, offset, limit); + send_request(td_api::make_object(chat_id, message_id, reaction, offset, + as_limit(limit))); } else if (op == "gmpf") { ChatId chat_id; MessageId message_id;