Merge commit 'a6463970b1b6c88d81cd0360446248abb348f1b0'

This commit is contained in:
Andrea Cavalli 2020-10-01 11:59:47 +02:00
commit 8255ff5ded
10 changed files with 539 additions and 219 deletions

View File

@ -378,7 +378,7 @@ inputChatPhotoPrevious chat_photo_id:int64 = InputChatPhoto;
//@description A static photo in JPEG format @photo Photo to be set as profile photo. Only inputFileLocal and inputFileGenerated are allowed
inputChatPhotoStatic photo:InputFile = InputChatPhoto;
//@description An animation in MPEG4 format; must be square, shorter than 10 seconds, have width between 160 and 800 and be at most 2MB in size
//@description An animation in MPEG4 format; must be square, at most 10 seconds long, have width between 160 and 800 and be at most 2MB in size
//@animation Animation to be set as profile photo. Only inputFileLocal and inputFileGenerated are allowed
//@main_frame_timestamp Timestamp of the frame, which will be used as static chat photo
inputChatPhotoAnimation animation:InputFile main_frame_timestamp:double = InputChatPhoto;
@ -3106,7 +3106,7 @@ updateMessageContent chat_id:int53 message_id:int53 new_content:MessageContent =
//@description A message was edited. Changes in the message content will come in a separate updateMessageContent @chat_id Chat identifier @message_id Message identifier @edit_date Point in time (Unix timestamp) when the message was edited @reply_markup New message reply markup; may be null
updateMessageEdited chat_id:int53 message_id:int53 edit_date:int32 reply_markup:ReplyMarkup = Update;
//@description The information about interactions with a message has changed @chat_id Chat identifier @message_id Message identifier @interaction_info New information about interactions with the message
//@description The information about interactions with a message has changed @chat_id Chat identifier @message_id Message identifier @interaction_info New information about interactions with the message; may be null
updateMessageInteractionInfo chat_id:int53 message_id:int53 interaction_info:messageInteractionInfo = Update;
//@description The message content was opened. Updates voice note messages to "listened", video note messages to "viewed" and starts the TTL timer for self-destructing messages @chat_id Chat identifier @message_id Message identifier
@ -3681,8 +3681,9 @@ removeNotificationGroup notification_group_id:int32 max_notification_id:int32 =
//@description Returns a public HTTPS link to a message. Available only for messages in supergroups and channels with a username
//@chat_id Identifier of the chat to which the message belongs
//@message_id Identifier of the message
//@for_album Pass true if a link for a whole media album should be returned
getPublicMessageLink chat_id:int53 message_id:int53 for_album:Bool = PublicMessageLink;
//@for_album Pass true to create a link for a whole media album
//@for_comment Pass true to create a link to a message as a channel message comment
getPublicMessageLink chat_id:int53 message_id:int53 for_album:Bool for_comment:Bool = PublicMessageLink;
//@description Returns a private HTTPS link to a message in a chat. Available only for already sent messages in supergroups and channels. The link will work only for members of the chat
//@chat_id Identifier of the chat to which the message belongs
@ -3717,12 +3718,11 @@ sendBotStartMessage bot_user_id:int32 chat_id:int53 parameter:string = Message;
sendInlineQueryResultMessage chat_id:int53 reply_to_message_id:int53 options:messageSendOptions query_id:int64 result_id:string hide_via_bot:Bool = Message;
//@description Forwards previously sent messages. Returns the forwarded messages in the same order as the message identifiers passed in message_ids. If a message can't be forwarded, null will be returned instead of the message
//@chat_id Identifier of the chat to which to forward messages @from_chat_id Identifier of the chat from which to forward messages @message_ids Identifiers of the messages to forward
//@chat_id Identifier of the chat to which to forward messages @from_chat_id Identifier of the chat from which to forward messages @message_ids Identifiers of the messages to forward. Message identifiers must be in a strictly increasing order
//@options Options to be used to send the messages
//@as_album True, if the messages should be grouped into an album after forwarding. For this to work, no more than 10 messages may be forwarded, and all of them must be photo or video messages
//@send_copy True, if content of the messages needs to be copied without links to the original messages. Always true if the messages are forwarded to a secret chat
//@remove_caption True, if media caption of message copies needs to be removed. Ignored if send_copy is false
forwardMessages chat_id:int53 from_chat_id:int53 message_ids:vector<int53> options:messageSendOptions as_album:Bool send_copy:Bool remove_caption:Bool = Messages;
forwardMessages chat_id:int53 from_chat_id:int53 message_ids:vector<int53> options:messageSendOptions send_copy:Bool remove_caption:Bool = Messages;
//@description Resends messages which failed to send. Can be called only for messages for which messageSendingStateFailed.can_retry is true and after specified in messageSendingStateFailed.retry_after time passed.
//-If a message is re-sent, the corresponding failed to send message is deleted. Returns the sent messages in the same order as the message identifiers passed in message_ids. If a message can't be re-sent, null will be returned instead of the message

Binary file not shown.

View File

@ -9750,6 +9750,14 @@ void ContactsManager::on_get_chat_full(tl_object_ptr<telegram_api::ChatFull> &&c
}
update_channel_full(channel, channel_id);
if (linked_channel_id.is_valid()) {
auto linked_channel_full = get_channel_full_force(linked_channel_id, "on_get_chat_full");
on_update_channel_full_linked_channel_id(linked_channel_full, linked_channel_id, channel_id);
if (linked_channel_full != nullptr) {
update_channel_full(linked_channel_full, linked_channel_id);
}
}
}
promise.set_value(Unit());
}
@ -11205,6 +11213,17 @@ ChannelId ContactsManager::get_linked_channel_id(ChannelId channel_id) const {
void ContactsManager::on_update_channel_full_linked_channel_id(ChannelFull *channel_full, ChannelId channel_id,
ChannelId linked_channel_id) {
auto old_linked_channel_id = get_linked_channel_id(channel_id);
LOG(INFO) << "Uplate linked channel in " << channel_id << " from " << old_linked_channel_id << " to "
<< linked_channel_id;
if (channel_full != nullptr && channel_full->linked_channel_id != linked_channel_id &&
channel_full->linked_channel_id.is_valid()) {
get_channel_force(channel_full->linked_channel_id);
get_channel_full_force(channel_full->linked_channel_id, "on_update_channel_full_linked_channel_id 0");
}
auto old_linked_linked_channel_id = get_linked_channel_id(linked_channel_id);
remove_linked_channel_id(channel_id);
remove_linked_channel_id(linked_channel_id);
if (channel_id.is_valid() && linked_channel_id.is_valid()) {
@ -11260,6 +11279,20 @@ void ContactsManager::on_update_channel_full_linked_channel_id(ChannelFull *chan
c->is_changed = true;
update_channel(c, channel_id);
}
if (old_linked_channel_id != linked_channel_id) {
// must be called after the linked channel is changed
td_->messages_manager_->on_dialog_linked_channel_updated(DialogId(channel_id), old_linked_channel_id,
linked_channel_id);
}
auto new_linked_linked_channel_id = get_linked_channel_id(linked_channel_id);
LOG(INFO) << "Uplate linked channel in " << linked_channel_id << " from " << old_linked_linked_channel_id << " to "
<< new_linked_linked_channel_id;
if (old_linked_linked_channel_id != new_linked_linked_channel_id) {
// must be called after the linked channel is changed
td_->messages_manager_->on_dialog_linked_channel_updated(DialogId(linked_channel_id), old_linked_linked_channel_id,
new_linked_linked_channel_id);
}
}
void ContactsManager::on_update_channel_full_location(ChannelFull *channel_full, ChannelId channel_id,

View File

@ -18,6 +18,7 @@ struct MessageCopyOptions {
bool send_copy = false;
bool replace_caption = false;
FormattedText new_caption;
MessageId reply_to_message_id;
unique_ptr<ReplyMarkup> reply_markup;
MessageCopyOptions() = default;
@ -28,11 +29,15 @@ struct MessageCopyOptions {
inline StringBuilder &operator<<(StringBuilder &string_builder, MessageCopyOptions copy_options) {
if (copy_options.send_copy) {
string_builder << "CopyOptions[replace_caption = " << copy_options.replace_caption;
}
if (copy_options.replace_caption) {
string_builder << ", new_caption = " << copy_options.new_caption;
}
if (copy_options.send_copy) {
if (copy_options.replace_caption) {
string_builder << ", new_caption = " << copy_options.new_caption;
}
if (copy_options.reply_to_message_id.is_valid()) {
string_builder << ", reply to = " << copy_options.reply_to_message_id;
}
if (copy_options.reply_markup != nullptr) {
string_builder << ", with reply markup";
}
string_builder << "]";
}
return string_builder;

View File

@ -11,7 +11,7 @@
namespace td {
MessageReplyInfo::MessageReplyInfo(tl_object_ptr<telegram_api::messageReplies> &&reply_info, bool is_bot) {
if (reply_info == nullptr) {
if (reply_info == nullptr || is_bot) {
return;
}
if (reply_info->replies_ < 0) {
@ -21,14 +21,12 @@ MessageReplyInfo::MessageReplyInfo(tl_object_ptr<telegram_api::messageReplies> &
reply_count = reply_info->replies_;
pts = reply_info->replies_pts_;
if (!is_bot) {
for (auto &peer : reply_info->recent_repliers_) {
DialogId dialog_id(peer);
if (dialog_id.is_valid()) {
recent_replier_dialog_ids.push_back(dialog_id);
} else {
LOG(ERROR) << "Receive " << dialog_id << " as a recent replier";
}
for (auto &peer : reply_info->recent_repliers_) {
DialogId dialog_id(peer);
if (dialog_id.is_valid()) {
recent_replier_dialog_ids.push_back(dialog_id);
} else {
LOG(ERROR) << "Receive " << dialog_id << " as a recent replier";
}
}
@ -46,7 +44,21 @@ bool MessageReplyInfo::need_update_to(const MessageReplyInfo &other) const {
if (other.pts < pts) {
return false;
}
return true;
return reply_count != other.reply_count || recent_replier_dialog_ids != other.recent_replier_dialog_ids;
}
void MessageReplyInfo::add_reply(DialogId replier_dialog_id) {
CHECK(!is_empty());
reply_count++;
if (replier_dialog_id.is_valid() &&
(recent_replier_dialog_ids.empty() || recent_replier_dialog_ids[0] != replier_dialog_id)) {
td::remove(recent_replier_dialog_ids, replier_dialog_id);
recent_replier_dialog_ids.insert(recent_replier_dialog_ids.begin(), replier_dialog_id);
if (recent_replier_dialog_ids.size() > 3) {
recent_replier_dialog_ids.pop_back();
}
}
}
StringBuilder &operator<<(StringBuilder &string_builder, const MessageReplyInfo &reply_info) {

View File

@ -33,6 +33,8 @@ struct MessageReplyInfo {
bool need_update_to(const MessageReplyInfo &other) const;
void add_reply(DialogId replier_dialog_id);
template <class StorerT>
void store(StorerT &storer) const {
CHECK(!is_empty());

File diff suppressed because it is too large Load Diff

View File

@ -194,6 +194,8 @@ class MessagesManager : public Actor {
static vector<int32> get_scheduled_server_message_ids(const vector<MessageId> &message_ids);
static MessageId get_message_id(const tl_object_ptr<telegram_api::Message> &message_ptr, bool is_scheduled);
DialogId get_message_dialog_id(const tl_object_ptr<telegram_api::Message> &message_ptr) const;
tl_object_ptr<telegram_api::InputPeer> get_input_peer(DialogId dialog_id, AccessRights access_rights) const;
@ -214,6 +216,8 @@ class MessagesManager : public Actor {
bool have_input_peer(DialogId dialog_id, AccessRights access_rights) const;
void on_get_empty_messages(DialogId dialog_id, vector<MessageId> empty_message_ids);
struct MessagesInfo {
vector<tl_object_ptr<telegram_api::Message>> messages;
int32 total_count = 0;
@ -402,7 +406,6 @@ class MessagesManager : public Actor {
Result<vector<MessageId>> forward_messages(DialogId to_dialog_id, DialogId from_dialog_id,
vector<MessageId> message_ids,
tl_object_ptr<td_api::messageSendOptions> &&options, bool in_game_share,
bool as_album,
vector<MessageCopyOptions> &&copy_options) TD_WARN_UNUSED_RESULT;
Result<vector<MessageId>> resend_messages(DialogId dialog_id, vector<MessageId> message_ids) TD_WARN_UNUSED_RESULT;
@ -563,7 +566,7 @@ class MessagesManager : public Actor {
bool is_message_edited_recently(FullMessageId full_message_id, int32 seconds);
std::pair<string, string> get_public_message_link(FullMessageId full_message_id, bool for_group,
std::pair<string, string> get_public_message_link(FullMessageId full_message_id, bool for_group, bool &for_comment,
Promise<Unit> &&promise);
void on_get_public_message_link(FullMessageId full_message_id, bool for_group, string url, string html);
@ -735,6 +738,9 @@ class MessagesManager : public Actor {
void on_dialog_user_is_blocked_updated(DialogId dialog_id, bool is_blocked);
void on_dialog_user_is_deleted_updated(DialogId dialog_id, bool is_deleted);
void on_dialog_linked_channel_updated(DialogId dialog_id, ChannelId old_linked_channel_id,
ChannelId new_linked_channel_id) const;
void on_resolved_username(const string &username, DialogId dialog_id);
void drop_username(const string &username);
@ -1632,8 +1638,6 @@ class MessagesManager : public Actor {
static constexpr bool DROP_UPDATES = false;
static MessageId get_message_id(const tl_object_ptr<telegram_api::Message> &message_ptr, bool is_scheduled);
FullMessageId get_full_message_id(const tl_object_ptr<telegram_api::Message> &message_ptr, bool is_scheduled) const;
static int32 get_message_date(const tl_object_ptr<telegram_api::Message> &message_ptr);
@ -1691,6 +1695,10 @@ class MessagesManager : public Actor {
const unique_ptr<MessageContent> &content, int32 ttl);
static Status can_use_message_send_options(const MessageSendOptions &options, const InputMessageContent &content);
bool is_anonymous_administrator(DialogId dialog_id) const;
bool is_anonymous_administrator(UserId sender_user_id, DialogId dialog_id, string *author_signature) const;
Message *get_message_to_send(Dialog *d, MessageId reply_to_message_id, const MessageSendOptions &options,
unique_ptr<MessageContent> &&content, bool *need_update_dialog_pos,
unique_ptr<MessageForwardInfo> forward_info = nullptr, bool is_copy = false);
@ -1735,7 +1743,8 @@ class MessagesManager : public Actor {
void delete_messages_from_updates(const vector<MessageId> &message_ids);
void delete_dialog_messages_from_updates(DialogId dialog_id, const vector<MessageId> &message_ids);
void delete_dialog_messages_from_updates(DialogId dialog_id, const vector<MessageId> &message_ids,
bool skip_update_for_not_found_messages);
void do_forward_messages(DialogId to_dialog_id, DialogId from_dialog_id, const vector<Message *> &messages,
const vector<MessageId> &message_ids, uint64 logevent_id);
@ -1765,6 +1774,8 @@ class MessagesManager : public Actor {
void do_send_message_group(int64 media_album_id);
void on_text_message_ready_to_send(DialogId dialog_id, MessageId message_id);
void on_media_message_ready_to_send(DialogId dialog_id, MessageId message_id, Promise<Message *> &&promise);
void on_yet_unsent_media_queue_updated(DialogId dialog_id);
@ -1842,6 +1853,9 @@ class MessagesManager : public Actor {
static MessageId find_message_by_date(const Message *m, int32 date);
static void find_discussed_messages(const Message *m, ChannelId old_channel_id, ChannelId new_channel_id,
vector<MessageId> &message_ids);
static void find_messages_from_user(const Message *m, UserId user_id, vector<MessageId> &message_ids);
static void find_unread_mentions(const Message *m, vector<MessageId> &message_ids);
@ -2086,6 +2100,8 @@ class MessagesManager : public Actor {
void send_update_message_edited(DialogId dialog_id, const Message *m);
void send_update_message_interaction_info(DialogId dialog_id, const Message *m) const;
void send_update_message_live_location_viewed(FullMessageId full_message_id);
void send_update_delete_messages(DialogId dialog_id, vector<int64> &&message_ids, bool is_permanent,
@ -2462,6 +2478,8 @@ class MessagesManager : public Actor {
void cancel_send_deleted_message(DialogId dialog_id, Message *m, bool is_permanently_deleted);
bool has_message_sender_user_id(DialogId dialog_id, const Message *m) const;
static bool get_message_disable_web_page_preview(const Message *m);
static int32 get_message_flags(const Message *m);
@ -2963,7 +2981,10 @@ class MessagesManager : public Actor {
std::unordered_map<int64, FoundMessages> found_fts_messages_; // random_id -> FoundMessages
std::unordered_map<int64, FoundMessages> found_message_public_forwards_; // random_id -> FoundMessages
std::unordered_map<FullMessageId, std::pair<string, string>, FullMessageIdHash> public_message_links_[2];
struct PublicMessageLinks {
std::unordered_map<MessageId, std::pair<string, string>, MessageIdHash> links_;
};
std::unordered_map<DialogId, PublicMessageLinks, DialogIdHash> public_message_links_[2];
std::unordered_map<int64, tl_object_ptr<td_api::chatEvents>> chat_events_; // random_id -> chat events

View File

@ -1093,13 +1093,14 @@ class GetMessagesRequest : public RequestOnceActor {
class GetPublicMessageLinkRequest : public RequestActor<> {
FullMessageId full_message_id_;
bool for_group_;
bool for_comment_;
string link_;
string html_;
void do_run(Promise<Unit> &&promise) override {
std::tie(link_, html_) =
td->messages_manager_->get_public_message_link(full_message_id_, for_group_, std::move(promise));
td->messages_manager_->get_public_message_link(full_message_id_, for_group_, for_comment_, std::move(promise));
}
void do_send_result() override {
@ -1107,10 +1108,13 @@ class GetPublicMessageLinkRequest : public RequestActor<> {
}
public:
GetPublicMessageLinkRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id, int64 message_id, bool for_group)
GetPublicMessageLinkRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id, int64 message_id, bool for_group,
bool for_comment)
: RequestActor(std::move(td), request_id)
, full_message_id_(DialogId(dialog_id), MessageId(message_id))
, for_group_(for_group) {
, for_group_(for_group)
, for_comment_(for_comment) {
set_tries(5); // get top message + get linked channel message + get message HTML + get linked channel message link
}
};
@ -5104,7 +5108,8 @@ void Td::on_request(uint64 id, const td_api::getMessages &request) {
void Td::on_request(uint64 id, const td_api::getPublicMessageLink &request) {
CHECK_IS_USER();
CREATE_REQUEST(GetPublicMessageLinkRequest, request.chat_id_, request.message_id_, request.for_album_);
CREATE_REQUEST(GetPublicMessageLinkRequest, request.chat_id_, request.message_id_, request.for_album_,
request.for_comment_);
}
void Td::on_request(uint64 id, const td_api::getMessageLink &request) {
@ -5791,9 +5796,9 @@ void Td::on_request(uint64 id, td_api::forwardMessages &request) {
auto message_copy_options =
transform(input_message_ids, [send_copy = request.send_copy_, remove_caption = request.remove_caption_](
MessageId) { return MessageCopyOptions(send_copy, remove_caption); });
auto r_message_ids = messages_manager_->forward_messages(dialog_id, DialogId(request.from_chat_id_),
std::move(input_message_ids), std::move(request.options_),
false, request.as_album_, std::move(message_copy_options));
auto r_message_ids =
messages_manager_->forward_messages(dialog_id, DialogId(request.from_chat_id_), std::move(input_message_ids),
std::move(request.options_), false, std::move(message_copy_options));
if (r_message_ids.is_error()) {
return send_closure(actor_id(this), &Td::send_error, id, r_message_ids.move_as_error());
}

View File

@ -2620,10 +2620,12 @@ class CliClient final : public Actor {
string chat_id;
string message_id;
string for_album;
string for_comment;
std::tie(chat_id, args) = split(args);
std::tie(message_id, for_album) = split(args);
std::tie(message_id, args) = split(args);
std::tie(for_album, for_comment) = split(args);
send_request(td_api::make_object<td_api::getPublicMessageLink>(as_chat_id(chat_id), as_message_id(message_id),
as_bool(for_album)));
as_bool(for_album), as_bool(for_comment)));
} else if (op == "gmlink") {
string chat_id;
string message_id;
@ -2722,16 +2724,14 @@ class CliClient final : public Actor {
} else if (op == "delf" || op == "DeleteFile") {
string file_id = args;
send_request(td_api::make_object<td_api::deleteFile>(as_file_id(file_id)));
} else if (op == "dm") {
} else if (op == "dm" || op == "dmr") {
string chat_id;
string message_ids;
string revoke;
std::tie(chat_id, args) = split(args);
std::tie(message_ids, revoke) = split(args);
std::tie(chat_id, message_ids) = split(args);
send_request(td_api::make_object<td_api::deleteMessages>(as_chat_id(chat_id), as_message_ids(message_ids),
as_bool(revoke)));
} else if (op == "fm" || op == "fmg" || op == "cm" || op == "cmg") {
send_request(
td_api::make_object<td_api::deleteMessages>(as_chat_id(chat_id), as_message_ids(message_ids), op == "dmr"));
} else if (op == "fm" || op == "cm") {
string chat_id;
string from_chat_id;
string message_ids;
@ -2740,8 +2740,8 @@ class CliClient final : public Actor {
auto chat = as_chat_id(chat_id);
send_request(td_api::make_object<td_api::forwardMessages>(
chat, as_chat_id(from_chat_id), as_message_ids(message_ids), default_message_send_options(), op[2] == 'g',
op[0] == 'c', Random::fast(0, 1) == 1));
chat, as_chat_id(from_chat_id), as_message_ids(message_ids), default_message_send_options(), op[0] == 'c',
Random::fast(0, 1) == 1));
} else if (op == "resend") {
string chat_id;
string message_ids;