Support reactions with custom emoji.

This commit is contained in:
levlam 2022-08-16 22:42:29 +03:00
parent 02b42d7ee6
commit b14708f0f5
5 changed files with 97 additions and 22 deletions

View File

@ -808,6 +808,15 @@ messageForwardOriginChannel chat_id:int53 message_id:int53 author_signature:stri
messageForwardOriginMessageImport sender_name:string = MessageForwardOrigin;
//@class ReactionType @description Describes type of message reaction
//@description A reaction with an emoji @emoji Text representation of the reaction
reactionTypeEmoji emoji:string = ReactionType;
//@description A reaction with a custom emoji @custom_emoji_id Unique identifier of the custom emoji
reactionTypeCustomEmoji custom_emoji_id:int64 = ReactionType;
//@description Contains information about a forwarded message
//@origin Origin of a forwarded message
//@date Point in time (Unix timestamp) when the message was originally sent
@ -825,11 +834,11 @@ messageForwardInfo origin:MessageForwardOrigin date:int32 public_service_announc
messageReplyInfo reply_count:int32 recent_replier_ids:vector<MessageSender> last_read_inbox_message_id:int53 last_read_outbox_message_id:int53 last_message_id:int53 = MessageReplyInfo;
//@description Contains information about a reaction to a message
//@reaction Text representation of the reaction
//@type Type of the reaction
//@total_count Number of times the reaction was added
//@is_chosen True, if the reaction is chosen by the current user
//@recent_sender_ids Identifiers of at most 3 recent message senders, added the reaction; available in private, basic group and supergroup chats
messageReaction reaction:string total_count:int32 is_chosen:Bool recent_sender_ids:vector<MessageSender> = MessageReaction;
messageReaction type:ReactionType total_count:int32 is_chosen:Bool recent_sender_ids:vector<MessageSender> = MessageReaction;
//@description Contains information about interactions with a message
//@view_count Number of times the message was viewed
@ -839,10 +848,10 @@ messageReaction reaction:string total_count:int32 is_chosen:Bool recent_sender_i
messageInteractionInfo view_count:int32 forward_count:int32 reply_info:messageReplyInfo reactions:vector<messageReaction> = MessageInteractionInfo;
//@description Contains information about an unread reaction to a message
//@reaction Text representation of the reaction
//@type Type of the reaction
//@sender_id Identifier of the sender, added the reaction
//@is_big True, if the reaction was added with a big animation
unreadReaction reaction:string sender_id:MessageSender is_big:Bool = UnreadReaction;
unreadReaction type:ReactionType sender_id:MessageSender is_big:Bool = UnreadReaction;
//@class MessageSendingState @description Contains information about the sending state of the message
@ -2547,8 +2556,8 @@ 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<string> = PhoneNumberAuthenticationSettings;
//@description Represents a reaction applied to a message @reaction Text representation of the reaction @sender_id Identifier of the chat member, applied the reaction
addedReaction reaction:string sender_id:MessageSender = AddedReaction;
//@description Represents a reaction applied to a message @type Type of the reaction @sender_id Identifier of the chat member, applied the reaction
addedReaction type:ReactionType sender_id:MessageSender = AddedReaction;
//@description Represents a list of reactions added to a message @total_count The total number of found reactions @reactions The list of added reactions @next_offset The offset for the next request. If empty, there are no more results
addedReactions total_count:int32 reactions:vector<addedReaction> next_offset:string = AddedReactions;
@ -2560,7 +2569,7 @@ availableReaction reaction:string needs_premium:Bool = AvailableReaction;
availableReactions reactions:vector<availableReaction> = AvailableReactions;
//@description Contains stickers which must be used for reaction animation rendering
//@description Contains stickers which must be used for emoji reaction animation rendering
//@reaction Text representation of the reaction
//@title Reaction title
//@is_active True, if the reaction can be added to new messages and enabled in chats
@ -5116,17 +5125,17 @@ getMessageAvailableReactions chat_id:int53 message_id:int53 = AvailableReactions
//@description Changes chosen reaction for a message
//@chat_id Identifier of the chat to which the message belongs
//@message_id Identifier of the message
//@reaction Text representation of the new chosen reaction. Can be an empty string or the currently chosen non-big reaction to remove the reaction
//@reaction_type Type of the new chosen reaction; pass null or the currently chosen non-big reaction to remove the reaction
//@is_big Pass true if the reaction is added with a big animation
setMessageReaction chat_id:int53 message_id:int53 reaction:string is_big:Bool = Ok;
setMessageReaction chat_id:int53 message_id:int53 reaction_type:ReactionType is_big:Bool = Ok;
//@description Returns reactions added for a message, along with their sender
//@chat_id Identifier of the chat to which the message belongs
//@message_id Identifier of the message
//@reaction If non-empty, only added reactions with the specified text representation will be returned
//@reaction_type Type of the reactions to return; pass null to return all added reactions
//@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 reactions to be returned; must be positive and can't be greater than 100
getMessageAddedReactions chat_id:int53 message_id:int53 reaction:string offset:string limit:int32 = AddedReactions;
getMessageAddedReactions chat_id:int53 message_id:int53 reaction_type:ReactionType offset:string limit:int32 = AddedReactions;
//@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

View File

@ -21,20 +21,39 @@
#include "td/actor/actor.h"
#include "td/utils/algorithm.h"
#include "td/utils/as.h"
#include "td/utils/base64.h"
#include "td/utils/buffer.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/logging.h"
#include "td/utils/Status.h"
#include "td/utils/utf8.h"
#include <algorithm>
#include <utility>
namespace td {
static int64 get_custom_emoji_id(const string &reaction) {
auto r_decoded = base64_decode(Slice(&reaction[1], reaction.size() - 1));
CHECK(r_decoded.is_ok());
CHECK(r_decoded.ok().size() == 8);
return as<int64>(r_decoded.ok().c_str());
}
static string get_custom_emoji_string(int64 custom_emoji_id) {
char s[8];
as<int64>(&s) = custom_emoji_id;
return PSTRING() << '#' << base64_encode(Slice(s, 8));
}
static telegram_api::object_ptr<telegram_api::Reaction> get_input_reaction(const string &reaction) {
if (reaction.empty()) {
return telegram_api::make_object<telegram_api::reactionEmpty>();
}
if (reaction[0] == '#') {
return telegram_api::make_object<telegram_api::reactionCustomEmoji>(get_custom_emoji_id(reaction));
}
return telegram_api::make_object<telegram_api::reactionEmoji>(reaction);
}
@ -48,7 +67,37 @@ static string get_reaction_string(const telegram_api::object_ptr<telegram_api::R
case telegram_api::reactionEmoji::ID:
return static_cast<const telegram_api::reactionEmoji *>(reaction.get())->emoticon_;
case telegram_api::reactionCustomEmoji::ID:
return get_custom_emoji_string(
static_cast<const telegram_api::reactionCustomEmoji *>(reaction.get())->document_id_);
default:
UNREACHABLE();
return string();
}
}
static td_api::object_ptr<td_api::ReactionType> get_reaction_type_object(const string &reaction) {
CHECK(!reaction.empty());
if (reaction[0] == '#') {
return td_api::make_object<td_api::reactionTypeCustomEmoji>(get_custom_emoji_id(reaction));
}
return td_api::make_object<td_api::reactionTypeEmoji>(reaction);
}
string get_message_reaction_string(const td_api::object_ptr<td_api::ReactionType> &type) {
if (type == nullptr) {
return string();
}
switch (type->get_id()) {
case td_api::reactionTypeEmoji::ID: {
const string &emoji = static_cast<const td_api::reactionTypeEmoji *>(type.get())->emoji_;
if (!check_utf8(emoji)) {
return string();
}
return emoji;
}
case td_api::reactionTypeCustomEmoji::ID:
return get_custom_emoji_string(
static_cast<const td_api::reactionTypeCustomEmoji *>(type.get())->custom_emoji_id_);
default:
UNREACHABLE();
return string();
@ -234,7 +283,8 @@ class GetMessageReactionsListQuery final : public Td::ResultHandler {
auto message_sender = get_min_message_sender_object(td_, dialog_id, "GetMessageReactionsListQuery");
if (message_sender != nullptr) {
reactions.push_back(td_api::make_object<td_api::addedReaction>(reaction_str, std::move(message_sender)));
reactions.push_back(td_api::make_object<td_api::addedReaction>(get_reaction_type_object(reaction_str),
std::move(message_sender)));
}
}
@ -353,7 +403,8 @@ td_api::object_ptr<td_api::messageReaction> MessageReaction::get_message_reactio
}
}
}
return td_api::make_object<td_api::messageReaction>(reaction_, choose_count_, is_chosen_, std::move(recent_choosers));
return td_api::make_object<td_api::messageReaction>(get_reaction_type_object(reaction_), choose_count_, is_chosen_,
std::move(recent_choosers));
}
bool operator==(const MessageReaction &lhs, const MessageReaction &rhs) {
@ -374,7 +425,8 @@ td_api::object_ptr<td_api::unreadReaction> UnreadMessageReaction::get_unread_rea
if (sender_id == nullptr) {
return nullptr;
}
return td_api::make_object<td_api::unreadReaction>(reaction_, std::move(sender_id), is_big_);
return td_api::make_object<td_api::unreadReaction>(get_reaction_type_object(reaction_), std::move(sender_id),
is_big_);
}
bool operator==(const UnreadMessageReaction &lhs, const UnreadMessageReaction &rhs) {

View File

@ -173,6 +173,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, const MessageReactions
StringBuilder &operator<<(StringBuilder &string_builder, const unique_ptr<MessageReactions> &reactions);
string get_message_reaction_string(const td_api::object_ptr<td_api::ReactionType> &type);
void reload_message_reactions(Td *td, DialogId dialog_id, vector<MessageId> &&message_ids);
void set_message_reaction(Td *td, FullMessageId full_message_id, string reaction, bool is_big, Promise<Unit> &&promise);

View File

@ -5249,20 +5249,19 @@ void Td::on_request(uint64 id, const td_api::getMessageAvailableReactions &reque
void Td::on_request(uint64 id, td_api::setMessageReaction &request) {
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.reaction_);
CREATE_OK_REQUEST_PROMISE();
messages_manager_->set_message_reaction({DialogId(request.chat_id_), MessageId(request.message_id_)},
std::move(request.reaction_), request.is_big_, std::move(promise));
get_message_reaction_string(request.reaction_type_), request.is_big_,
std::move(promise));
}
void Td::on_request(uint64 id, td_api::getMessageAddedReactions &request) {
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.reaction_);
CLEAN_INPUT_STRING(request.offset_);
CREATE_REQUEST_PROMISE();
get_message_added_reactions(this, {DialogId(request.chat_id_), MessageId(request.message_id_)},
std::move(request.reaction_), std::move(request.offset_), request.limit_,
std::move(promise));
get_message_reaction_string(request.reaction_type_), std::move(request.offset_),
request.limit_, std::move(promise));
}
void Td::on_request(uint64 id, td_api::getMessagePublicForwards &request) {

View File

@ -724,6 +724,18 @@ class CliClient final : public Actor {
return td_api::make_object<td_api::location>(to_double(latitude), to_double(longitude), to_double(accuracy));
}
td_api::object_ptr<td_api::ReactionType> as_reaction_type(Slice type) const {
type = trim(type);
if (type.empty()) {
return nullptr;
}
auto r_custom_emoji_id = to_integer_safe<int64>(type);
if (r_custom_emoji_id.is_ok()) {
return td_api::make_object<td_api::reactionTypeCustomEmoji>(r_custom_emoji_id.ok());
}
return td_api::make_object<td_api::reactionTypeEmoji>(type.str());
}
static bool as_bool(string str) {
str = to_lower(trim(str));
return str == "true" || str == "1";
@ -2215,7 +2227,8 @@ class CliClient final : public Actor {
string reaction;
bool is_big;
get_args(args, chat_id, message_id, reaction, is_big);
send_request(td_api::make_object<td_api::setMessageReaction>(chat_id, message_id, reaction, is_big));
send_request(
td_api::make_object<td_api::setMessageReaction>(chat_id, message_id, as_reaction_type(reaction), is_big));
} else if (op == "gmars") {
ChatId chat_id;
MessageId message_id;
@ -2223,8 +2236,8 @@ class CliClient final : public Actor {
string offset;
string limit;
get_args(args, chat_id, message_id, reaction, offset, limit);
send_request(td_api::make_object<td_api::getMessageAddedReactions>(chat_id, message_id, reaction, offset,
as_limit(limit)));
send_request(td_api::make_object<td_api::getMessageAddedReactions>(
chat_id, message_id, as_reaction_type(reaction), offset, as_limit(limit)));
} else if (op == "gmpf") {
ChatId chat_id;
MessageId message_id;