// // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2026 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once #include "td/telegram/BackgroundInfo.h" #include "td/telegram/ChannelId.h" #include "td/telegram/ChatTheme.h" #include "td/telegram/DialogId.h" #include "td/telegram/EncryptedFile.h" #include "td/telegram/files/FileId.h" #include "td/telegram/files/FileUploadId.h" #include "td/telegram/ForumTopicId.h" #include "td/telegram/InputGroupCallId.h" #include "td/telegram/InputMedia.h" #include "td/telegram/logevent/LogEvent.h" #include "td/telegram/MessageContentDupType.h" #include "td/telegram/MessageContentType.h" #include "td/telegram/MessageCopyOptions.h" #include "td/telegram/MessageCover.h" #include "td/telegram/MessageEntity.h" #include "td/telegram/MessageFullId.h" #include "td/telegram/MessageId.h" #include "td/telegram/MessageSelfDestructType.h" #include "td/telegram/Photo.h" #include "td/telegram/PollId.h" #include "td/telegram/QuickReplyMessageFullId.h" #include "td/telegram/ReplyMarkup.h" #include "td/telegram/secret_api.h" #include "td/telegram/SecretInputMedia.h" #include "td/telegram/StickerType.h" #include "td/telegram/StoryFullId.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" #include "td/telegram/TopDialogCategory.h" #include "td/telegram/UserId.h" #include "td/telegram/WebPageId.h" #include "td/utils/buffer.h" #include "td/utils/common.h" #include "td/utils/Promise.h" #include "td/utils/Status.h" #include namespace td { class Dependencies; class Game; class MultiPromiseActor; struct Photo; class RepliedMessageInfo; class RichMessage; class Td; class Venue; // Do not forget to update merge_message_contents and compare_message_contents when one of the inheritors of this class changes class MessageContent { public: MessageContent() = default; MessageContent(const MessageContent &) = default; MessageContent &operator=(const MessageContent &) = default; MessageContent(MessageContent &&) = default; MessageContent &operator=(MessageContent &&) = default; virtual MessageContentType get_type() const = 0; virtual ~MessageContent() = default; }; struct InputMessageContent { unique_ptr content; bool disable_web_page_preview = false; bool invert_media = false; bool clear_draft = false; MessageSelfDestructType ttl; UserId via_bot_user_id; string emoji; InputMessageContent(unique_ptr &&content, bool disable_web_page_preview, bool invert_media, bool clear_draft, MessageSelfDestructType ttl, UserId via_bot_user_id, string emoji) : content(std::move(content)) , disable_web_page_preview(disable_web_page_preview) , invert_media(invert_media) , clear_draft(clear_draft) , ttl(ttl) , via_bot_user_id(via_bot_user_id) , emoji(std::move(emoji)) { } }; struct InlineMessageContent { unique_ptr message_content; unique_ptr message_reply_markup; bool disable_web_page_preview = false; bool invert_media = false; }; void store_message_content(const MessageContent *content, LogEventStorerCalcLength &storer); void store_message_content(const MessageContent *content, LogEventStorerUnsafe &storer); void parse_message_content(unique_ptr &content, LogEventParser &parser); InlineMessageContent create_inline_message_content(Td *td, FileId file_id, tl_object_ptr &&bot_inline_message, int32 allowed_media_content_id, Photo *photo, Game *game); unique_ptr create_empty_text_message_content(); unique_ptr create_text_message_content(string text, vector entities, WebPageId web_page_id, bool force_small_media, bool force_large_media, bool skip_confitmation, string &&web_page_url); unique_ptr create_animation_message_content(FileId animation_file_id); unique_ptr create_audio_message_content(FileId audio_file_id); unique_ptr create_photo_message_content(Photo photo, FileId video_file_id); unique_ptr create_video_message_content(FileId file_id, Photo cover, int32 start_timestamp); unique_ptr create_voice_note_message_content(FileId voice_note_file_id); unique_ptr create_contact_registered_message_content(); unique_ptr create_screenshot_taken_message_content(); unique_ptr create_chat_set_ttl_message_content(int32 ttl, UserId from_user_id); td_api::object_ptr extract_input_caption( td_api::object_ptr &input_message_content); bool extract_input_invert_media(const td_api::object_ptr &input_message_content); Result get_input_message_content( DialogId dialog_id, tl_object_ptr &&input_message_content, Td *td, bool is_premium); Result> get_input_poll_media(DialogId dialog_id, td_api::object_ptr &&input_poll_media, Td *td, bool for_option); Status check_message_group_message_contents(const vector &message_contents); bool can_message_content_have_input_media(const Td *td, const MessageContent *content, bool is_server); SecretInputMedia get_message_content_secret_input_media( const MessageContent *content, Td *td, telegram_api::object_ptr input_file, BufferSlice thumbnail, int32 layer); InputMedia get_message_content_multi_input_media( const MessageContent *content, Td *td, vector> &&input_media); InputMedia get_message_content_input_media(const MessageContent *content, int32 media_pos, Td *td, telegram_api::object_ptr input_file, telegram_api::object_ptr input_thumbnail, FileUploadId file_upload_id, FileUploadId thumbnail_file_upload_id, MessageSelfDestructType ttl, const string &emoji, bool force); InputMedia get_message_content_input_media(const MessageContent *content, Td *td, MessageSelfDestructType ttl, const string &emoji, bool force, int32 media_pos); telegram_api::object_ptr get_message_content_input_media_web_page( const Td *td, const MessageContent *content); bool is_uploaded_input_media(telegram_api::object_ptr &input_media, bool disallow_animation); void delete_message_content_thumbnail(Td *td, MessageContent *content, int32 media_pos); Status can_send_message_content(DialogId dialog_id, const MessageContent *content, bool is_forward, bool check_permissions, const Td *td); bool can_forward_message_content(const Td *td, const MessageContent *content, bool is_copy); bool update_opened_message_content(MessageContent *content); int32 get_message_content_index_mask(const MessageContent *content, const Td *td, bool is_outgoing); vector> get_individual_message_contents(Td *td, const MessageContent *content); StickerType get_message_content_sticker_type(const Td *td, const MessageContent *content); MessageId get_message_content_pinned_message_id(const MessageContent *content); BackgroundInfo get_message_content_my_background_info(const MessageContent *content, bool is_outgoing); ChatTheme get_message_content_chat_theme(const MessageContent *content); MessageFullId get_message_content_replied_message_full_id(DialogId dialog_id, const MessageContent *content); std::pair get_message_content_group_call_info(const MessageContent *content); vector get_message_content_min_user_ids(const Td *td, const MessageContent *message_content); vector get_message_content_min_channel_ids(const Td *td, const MessageContent *message_content); vector get_message_content_added_user_ids(const MessageContent *content); UserId get_message_content_deleted_user_id(const MessageContent *content); telegram_api::object_ptr get_message_content_input_phone_call( const MessageContent *content); int32 get_message_content_live_location_period(const MessageContent *content); PollId get_message_content_poll_id(const MessageContent *content); bool get_message_content_poll_is_anonymous(const Td *td, const MessageContent *content); bool get_message_content_poll_is_closed(const Td *td, const MessageContent *content); bool get_message_content_poll_can_add_option(const Td *td, const MessageContent *content); bool get_message_content_poll_can_view_stats(const Td *td, const MessageContent *content); bool get_message_content_poll_has_unread_votes(const Td *td, const MessageContent *content); void remove_message_content_poll_has_unread_votes(Td *td, const MessageContent *content); void get_message_content_poll_option_properties(Td *td, const MessageContent *content, const string &option_id, DialogId dialog_id, MessageId message_id, bool can_be_replied, bool can_be_replied_in_another_chat, bool can_get_link, bool is_forward, bool is_outgoing, Promise> &&promise); bool get_message_content_to_do_list_others_can_append(const MessageContent *content); bool get_message_content_to_do_list_can_append_items(const Td *td, const MessageContent *content, int32 item_count); bool get_message_content_to_do_list_others_can_complete(const MessageContent *content); const Photo *get_message_content_photo(const MessageContent *content); const Venue *get_message_content_venue(const MessageContent *content); WebPageId get_message_content_web_page_id(const MessageContent *content); bool has_message_content_web_page(const MessageContent *content); void remove_message_content_web_page(MessageContent *content); bool can_message_content_have_media_timestamp(const MessageContent *content); void merge_message_contents(Td *td, const MessageContent *old_content, MessageContent *new_content, bool need_message_changed_warning, DialogId dialog_id, bool need_merge_files, bool &is_content_changed, bool &need_update); bool merge_message_content_file_id(Td *td, MessageContent *message_content, FileId new_file_id); void compare_message_contents(Td *td, const MessageContent *lhs_content, const MessageContent *rhs_content, bool &is_content_changed, bool &need_update); void merge_and_compare_message_contents(Td *td, MessageContent *old_content, MessageContent *new_content, bool need_message_changed_warning, DialogId dialog_id, bool need_merge_files, const vector &old_file_upload_ids, MessageSelfDestructType ttl, double ttl_expires_at, bool *is_content_secret, bool &is_content_changed, bool &need_update); void register_message_content(Td *td, const MessageContent *content, MessageFullId message_full_id, int32 message_date, const char *source); void reregister_message_content(Td *td, const MessageContent *old_content, const MessageContent *new_content, MessageFullId message_full_id, int32 message_date, const char *source); void unregister_message_content(Td *td, const MessageContent *content, MessageFullId message_full_id, const char *source); void register_reply_message_content(Td *td, const MessageContent *content); void unregister_reply_message_content(Td *td, const MessageContent *content); void register_quick_reply_message_content(Td *td, const MessageContent *content, QuickReplyMessageFullId message_full_id, const char *source); void unregister_quick_reply_message_content(Td *td, const MessageContent *content, QuickReplyMessageFullId message_full_id, const char *source); unique_ptr get_secret_message_content( Td *td, string message_text, unique_ptr file, tl_object_ptr &&media_ptr, vector> &&secret_entities, DialogId owner_dialog_id, MultiPromiseActor &load_data_multipromise, bool is_premium); unique_ptr get_message_content(Td *td, FormattedText message_text, telegram_api::object_ptr &&rich_message, telegram_api::object_ptr &&media_ptr, DialogId owner_dialog_id, int32 message_date, bool is_content_read, UserId via_bot_user_id, MessageSelfDestructType *ttl, bool *disable_web_page_preview, const char *source); unique_ptr get_uploaded_message_content( Td *td, const MessageContent *old_content, int32 media_pos, telegram_api::object_ptr &&media_ptr, DialogId owner_dialog_id, int32 message_date, bool &is_content_changed, bool &need_update, const char *source); unique_ptr dup_message_content(Td *td, DialogId dialog_id, const MessageContent *content, MessageContentDupType type, MessageCopyOptions &©_options); unique_ptr get_action_message_content(Td *td, tl_object_ptr &&action_ptr, DialogId owner_dialog_id, int32 message_date, const RepliedMessageInfo &replied_message_info, bool is_business_message); td_api::object_ptr get_message_content_object( const MessageContent *content, Td *td, DialogId dialog_id, MessageId message_id, DialogId initial_dialog_id, bool is_real_message_content, bool is_outgoing, bool is_forward, DialogId sender_dialog_id, int32 message_date, int32 initial_date, bool is_content_secret, bool skip_bot_commands, int32 max_media_timestamp, bool invert_media, bool disable_web_page_preview, const char *source); td_api::object_ptr get_poll_media_object(const MessageContent *content, Td *td); td_api::object_ptr get_message_content_upgrade_gift_result_object( const MessageContent *content, Td *td, DialogId dialog_id, MessageId message_id); td_api::object_ptr get_message_content_craft_gift_result_object(const MessageContent *content, Td *td, MessageId message_id); bool get_message_content_has_bot_commands(const MessageContent *content); FormattedText *get_message_content_text_mutable(MessageContent *content); const FormattedText *get_message_content_text(const MessageContent *content); const FormattedText *get_message_content_caption(const MessageContent *content); const RichMessage *get_message_content_rich_message(const MessageContent *content); int64 get_message_content_star_count(const MessageContent *content); int32 get_message_content_duration(const MessageContent *content, const Td *td); int32 get_message_content_media_duration(const MessageContent *content, const Td *td); bool has_message_content_cover(const MessageContent *content); vector get_message_content_need_to_upload_covers(Td *td, const MessageContent *content); FileId get_message_content_any_file_id(const MessageContent *content); vector get_message_content_any_file_ids(const Td *td, const MessageContent *content); FileId get_message_content_cover_any_file_id(const MessageContent *content); vector get_message_content_cover_any_file_ids(const Td *td, const MessageContent *content); FileId get_message_content_thumbnail_file_id(const MessageContent *content, const Td *td); vector get_message_content_thumbnail_file_ids(const MessageContent *content, const Td *td); vector get_message_content_file_ids(const MessageContent *content, const Td *td); StoryFullId get_message_content_story_full_id(const Td *td, const MessageContent *content); string get_message_content_search_text(const Td *td, const MessageContent *content); int64 get_message_content_stake_ton_count(const MessageContent *content); int64 get_message_content_prize_ton_count(const MessageContent *content); bool update_message_content_extended_media( MessageContent *content, vector> extended_media, DialogId owner_dialog_id, Td *td); bool need_poll_message_content_extended_media(const MessageContent *content); bool need_poll_conference_call_message_content(const MessageContent *content); void set_message_content_video_start_timestamp(MessageContent *content, int32 start_timestamp); void get_message_content_animated_emoji_click_sticker(const MessageContent *content, MessageFullId message_full_id, Td *td, Promise> &&promise); void on_message_content_animated_emoji_clicked(const MessageContent *content, MessageFullId message_full_id, Td *td, string &&emoji, string &&data); bool need_reget_message_content(const Td *td, const MessageContent *content); bool need_delay_message_content_notification(const MessageContent *content, UserId my_user_id); void update_expired_message_content(unique_ptr &content); void update_failed_to_send_message_content(Td *td, unique_ptr &content); void add_message_content_dependencies(Dependencies &dependencies, const MessageContent *message_content, UserId my_user_id, bool is_bot); void apply_updates_from_service_message_content(Td *td, const MessageContent *content, DialogId dialog_id, ForumTopicId forum_topic_id, DialogId sender_dialog_id); void on_sent_message_content(Td *td, const MessageContent *content); void move_message_content_sticker_set_to_top(Td *td, const MessageContent *content); void on_dialog_used(TopDialogCategory category, DialogId dialog_id, int32 date); void update_used_hashtags(Td *td, const MessageContent *content); } // namespace td