From 304280df690a169660ec31c4319cc14af14b90bb Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 4 Aug 2021 07:57:27 +0300 Subject: [PATCH] Add message.can_get_media_timestamp_links. --- td/generate/scheme/td_api.tl | 5 +- td/telegram/MessagesManager.cpp | 83 ++++++++++++++++++++++----------- td/telegram/MessagesManager.h | 2 + td/telegram/WebPagesManager.cpp | 2 +- 4 files changed, 62 insertions(+), 30 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 7678b79a6..22f39d57c 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -759,6 +759,7 @@ messageSendingStateFailed error_code:int32 error_message:string can_retry:Bool r //@can_be_deleted_for_all_users True, if the message can be deleted for all users //@can_get_statistics True, if the message statistics are available //@can_get_message_thread True, if the message thread info is available +//@can_get_media_timestamp_links True, if media timestamp links can be generated for media timestamp entities in the message text, caption or web page description //@is_channel_post True, if the message is a channel post. All messages to channels are channel posts, all other messages are not channel posts //@contains_unread_mention True, if the message contains an unread mention for the current user //@date Point in time (Unix timestamp) when the message was sent @@ -776,7 +777,7 @@ messageSendingStateFailed error_code:int32 error_message:string can_retry:Bool r //@restriction_reason If non-empty, contains a human-readable description of the reason why access to this message must be restricted //@content Content of the message //@reply_markup Reply markup for the message; may be null -message id:int53 sender:MessageSender chat_id:int53 sending_state:MessageSendingState scheduling_state:MessageSchedulingState is_outgoing:Bool is_pinned:Bool can_be_edited:Bool can_be_forwarded:Bool can_be_deleted_only_for_self:Bool can_be_deleted_for_all_users:Bool can_get_statistics:Bool can_get_message_thread:Bool is_channel_post:Bool contains_unread_mention:Bool date:int32 edit_date:int32 forward_info:messageForwardInfo interaction_info:messageInteractionInfo reply_in_chat_id:int53 reply_to_message_id:int53 message_thread_id:int53 ttl:int32 ttl_expires_in:double via_bot_user_id:int32 author_signature:string media_album_id:int64 restriction_reason:string content:MessageContent reply_markup:ReplyMarkup = Message; +message id:int53 sender:MessageSender chat_id:int53 sending_state:MessageSendingState scheduling_state:MessageSchedulingState is_outgoing:Bool is_pinned:Bool can_be_edited:Bool can_be_forwarded:Bool can_be_deleted_only_for_self:Bool can_be_deleted_for_all_users:Bool can_get_statistics:Bool can_get_message_thread:Bool can_get_media_timestamp_links:Bool is_channel_post:Bool contains_unread_mention:Bool date:int32 edit_date:int32 forward_info:messageForwardInfo interaction_info:messageInteractionInfo reply_in_chat_id:int53 reply_to_message_id:int53 message_thread_id:int53 ttl:int32 ttl_expires_in:double via_bot_user_id:int32 author_signature:string media_album_id:int64 restriction_reason:string content:MessageContent reply_markup:ReplyMarkup = Message; //@description Contains a list of messages @total_count Approximate total count of messages found @messages List of messages; messages may be null messages total_count:int32 messages:vector = Messages; @@ -4172,7 +4173,7 @@ removeNotification notification_group_id:int32 notification_id:int32 = Ok; removeNotificationGroup notification_group_id:int32 max_notification_id:int32 = Ok; -//@description Returns an HTTPS link to a message in a chat. Available only for already sent messages in supergroups and channels. This is an offline request +//@description Returns an HTTPS link to a message in a chat. Available only for already sent messages in supergroups and channels, or if message.can_get_media_timestamp_links and a media timestamp link is generated. This is an offline request //@chat_id Identifier of the chat to which the message belongs //@message_id Identifier of the message //@media_timestamp If not 0, timestamp from which the video/audio/video note/voice note playing should start, in seconds. The media can be in the message content or in its web page preview diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index d409b921a..438be4c8f 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -696,7 +696,9 @@ class ExportChannelMessageLinkQuery final : public Td::ResultHandler { for_group_ = for_group; ignore_result_ = ignore_result; auto input_channel = td->contacts_manager_->get_input_channel(channel_id); - CHECK(input_channel != nullptr); + if (input_channel == nullptr) { + return on_error(0, Status::Error(400, "Can't access the chat")); + } int32 flags = 0; if (for_group) { flags |= telegram_api::channels_exportMessageLink::GROUPED_MASK; @@ -17294,6 +17296,35 @@ bool MessagesManager::is_message_edited_recently(FullMessageId full_message_id, return m->edit_date >= G()->unix_time() - seconds; } +Status MessagesManager::can_get_media_timestamp_link(DialogId dialog_id, const Message *m) { + if (m == nullptr) { + return Status::Error(400, "Message not found"); + } + + if (dialog_id.get_type() != DialogType::Channel) { + auto forward_info = m->forward_info.get(); + if (!can_message_content_have_media_timestamp(m->content.get()) || forward_info == nullptr || + forward_info->is_imported || is_forward_info_sender_hidden(forward_info) || + !forward_info->message_id.is_valid() || !m->forward_info->message_id.is_server() || + !forward_info->sender_dialog_id.is_valid() || + forward_info->sender_dialog_id.get_type() != DialogType::Channel) { + return Status::Error(400, "Message links are available only for messages in supergroups and channel chats"); + } + return Status::OK(); + } + + if (m->message_id.is_yet_unsent()) { + return Status::Error(400, "Message is not sent yet"); + } + if (m->message_id.is_scheduled()) { + return Status::Error(400, "Message is scheduled"); + } + if (!m->message_id.is_server()) { + return Status::Error(400, "Message is local"); + } + return Status::OK(); +} + Result> MessagesManager::get_message_link(FullMessageId full_message_id, int32 media_timestamp, bool for_group, bool for_comment) { auto dialog_id = full_message_id.get_dialog_id(); @@ -17304,26 +17335,23 @@ Result> MessagesManager::get_message_link(FullMessageId if (!have_input_peer(dialog_id, AccessRights::Read)) { return Status::Error(400, "Can't access the chat"); } - if (dialog_id.get_type() != DialogType::Channel) { - return Status::Error(400, "Public message links are available only for messages in supergroups and channel chats"); - } auto *m = get_message_force(d, full_message_id.get_message_id(), "get_message_link"); - if (m == nullptr) { - return Status::Error(400, "Message not found"); - } - if (m->message_id.is_yet_unsent()) { - return Status::Error(400, "Message is not sent yet"); - } - if (m->message_id.is_scheduled()) { - return Status::Error(400, "Message is scheduled"); - } - if (!m->message_id.is_server()) { - return Status::Error(400, "Message is local"); - } + TRY_STATUS(can_get_media_timestamp_link(dialog_id, m)); + auto message_id = m->message_id; + if (dialog_id.get_type() != DialogType::Channel) { + CHECK(m != nullptr); + CHECK(m->forward_info != nullptr); + CHECK(m->forward_info->sender_dialog_id.get_type() == DialogType::Channel); - if (m->media_album_id == 0) { - for_group = true; // default is true + dialog_id = m->forward_info->sender_dialog_id; + message_id = m->forward_info->message_id; + for_group = false; + for_comment = false; + } else { + if (m->media_album_id == 0) { + for_group = true; // default is true + } } if (!m->top_thread_message_id.is_valid() || !m->top_thread_message_id.is_server()) { @@ -17340,6 +17368,7 @@ Result> MessagesManager::get_message_link(FullMessageId media_timestamp = 0; } if (media_timestamp != 0) { + for_group = false; auto duration = get_message_content_duration(m->content.get(), td_); if (duration != 0 && media_timestamp > duration) { media_timestamp = 0; @@ -17348,7 +17377,7 @@ Result> MessagesManager::get_message_link(FullMessageId if (!td_->auth_manager_->is_bot()) { td_->create_handler(Promise()) - ->send(dialog_id.get_channel_id(), m->message_id, for_group, true); + ->send(dialog_id.get_channel_id(), message_id, for_group, true); } SliceBuilder sb; @@ -17368,7 +17397,7 @@ Result> MessagesManager::get_message_link(FullMessageId linked_message_id.is_server() && have_input_peer(linked_dialog_id, AccessRights::Read) && !channel_username.empty()) { sb << channel_username << '/' << linked_message_id.get_server_message_id().get() - << "?comment=" << m->message_id.get_server_message_id().get(); + << "?comment=" << message_id.get_server_message_id().get(); if (!for_group) { sb << "&single"; } @@ -17384,8 +17413,7 @@ Result> MessagesManager::get_message_link(FullMessageId bool is_public = !dialog_username.empty(); if (m->content->get_type() == MessageContentType::VideoNote && is_broadcast_channel(dialog_id) && is_public) { return std::make_pair( - PSTRING() << "https://telesco.pe/" << dialog_username << '/' << m->message_id.get_server_message_id().get(), - true); + PSTRING() << "https://telesco.pe/" << dialog_username << '/' << message_id.get_server_message_id().get(), true); } if (is_public) { @@ -17393,7 +17421,7 @@ Result> MessagesManager::get_message_link(FullMessageId } else { sb << "c/" << dialog_id.get_channel_id().get(); } - sb << '/' << m->message_id.get_server_message_id().get(); + sb << '/' << message_id.get_server_message_id().get(); char separator = '?'; if (for_comment) { @@ -22800,6 +22828,7 @@ tl_object_ptr MessagesManager::get_message_object(DialogId dial bool can_be_forwarded = for_event_log ? false : can_forward_message(dialog_id, m); bool can_get_statistics = for_event_log ? false : can_get_message_statistics(dialog_id, m); bool can_get_message_thread = for_event_log ? false : get_top_thread_full_message_id(dialog_id, m).is_ok(); + bool can_get_media_timestamp_links = for_event_log ? false : can_get_media_timestamp_link(dialog_id, m).is_ok(); auto via_bot_user_id = td_->contacts_manager_->get_user_id_object(m->via_bot_user_id, "via_bot_user_id"); auto media_album_id = for_event_log ? static_cast(0) : m->media_album_id; auto reply_to_message_id = for_event_log ? static_cast(0) : m->reply_to_message_id.get(); @@ -22817,10 +22846,10 @@ tl_object_ptr MessagesManager::get_message_object(DialogId dial m->message_id.get(), get_message_sender_object_const(m->sender_user_id, m->sender_dialog_id, source.c_str()), dialog_id.get(), std::move(sending_state), std::move(scheduling_state), is_outgoing, is_pinned, can_be_edited, can_be_forwarded, can_delete_for_self, can_delete_for_all_users, can_get_statistics, can_get_message_thread, - m->is_channel_post, contains_unread_mention, date, edit_date, get_message_forward_info_object(m->forward_info), - get_message_interaction_info_object(dialog_id, m), reply_in_dialog_id.get(), reply_to_message_id, - top_thread_message_id, ttl, ttl_expires_in, via_bot_user_id, m->author_signature, media_album_id, - get_restriction_reason_description(m->restriction_reasons), + can_get_media_timestamp_links, m->is_channel_post, contains_unread_mention, date, edit_date, + get_message_forward_info_object(m->forward_info), get_message_interaction_info_object(dialog_id, m), + reply_in_dialog_id.get(), reply_to_message_id, top_thread_message_id, ttl, ttl_expires_in, via_bot_user_id, + m->author_signature, media_album_id, get_restriction_reason_description(m->restriction_reasons), get_message_content_object(m->content.get(), td_, dialog_id, live_location_date, m->is_content_secret, skip_bot_commands), get_reply_markup_object(m->reply_markup)); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 4ede96d8c..106d30ef5 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -1776,6 +1776,8 @@ class MessagesManager final : public Actor { Status can_pin_messages(DialogId dialog_id) const; + static Status can_get_media_timestamp_link(DialogId dialog_id, const Message *m); + 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, diff --git a/td/telegram/WebPagesManager.cpp b/td/telegram/WebPagesManager.cpp index f4c6933d5..4bd43d72b 100644 --- a/td/telegram/WebPagesManager.cpp +++ b/td/telegram/WebPagesManager.cpp @@ -1185,7 +1185,7 @@ tl_object_ptr WebPagesManager::get_web_page_object(WebPageId we FormattedText description; description.text = web_page->description; - description.entities = find_entities(web_page->description, true, true); + description.entities = find_entities(web_page->description, true, false); auto r_url = parse_url(web_page->display_url); if (r_url.is_ok()) {