diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index ca05d738e..b598ec40c 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1459,6 +1459,13 @@ messageCalendarDay total_count:int32 message:message = MessageCalendarDay; messageCalendar total_count:int32 days:vector = MessageCalendar; +//@description Describes a message from a business account as received by a bot @message The message @reply_to_message Message that is replied by the message in the same chat; may be null if none +businessMessage message:message reply_to_message:message = BusinessMessage; + +//@description Contains a list of messages from a business account as received by a bot @messages List of business messages +businessMessages messages:vector = BusinessMessages; + + //@class MessageSource @description Describes source of a message //@description The message is from a chat history @@ -6939,10 +6946,10 @@ updateAutosaveSettings scope:AutosaveSettingsScope settings:scopeAutosaveSetting updateBusinessConnection connection:businessConnection = Update; //@description A new message was added to a business account; for bots only @connection_id Unique identifier of the business connection @message The new message -updateNewBusinessMessage connection_id:string message:message = Update; +updateNewBusinessMessage connection_id:string message:businessMessage = Update; //@description A message in a business account was edited; for bots only @connection_id Unique identifier of the business connection @message The edited message -updateBusinessMessageEdited connection_id:string message:message = Update; +updateBusinessMessageEdited connection_id:string message:businessMessage = Update; //@description Messages in a business account were deleted; for bots only //@connection_id Unique identifier of the business connection @@ -7829,7 +7836,7 @@ editMessageSchedulingState chat_id:int53 message_id:int53 scheduling_state:Messa //@protect_content Pass true if the content of the message must be protected from forwarding and saving //@reply_markup Markup for replying to the message; pass null if none //@input_message_content The content of the message to be sent -sendBusinessMessage business_connection_id:string chat_id:int53 reply_to:InputMessageReplyTo disable_notification:Bool protect_content:Bool reply_markup:ReplyMarkup input_message_content:InputMessageContent = Message; +sendBusinessMessage business_connection_id:string chat_id:int53 reply_to:InputMessageReplyTo disable_notification:Bool protect_content:Bool reply_markup:ReplyMarkup input_message_content:InputMessageContent = BusinessMessage; //@description Sends 2-10 messages grouped together into an album on behalf of a business account; for bots only. Currently, only audio, document, photo and video messages can be grouped into an album. //-Documents and audio files can be only grouped in an album with messages of the same type. Returns sent messages @@ -7839,7 +7846,7 @@ sendBusinessMessage business_connection_id:string chat_id:int53 reply_to:InputMe //@disable_notification Pass true to disable notification for the message //@protect_content Pass true if the content of the message must be protected from forwarding and saving //@input_message_contents Contents of messages to be sent. At most 10 messages can be added to an album -sendBusinessMessageAlbum business_connection_id:string chat_id:int53 reply_to:InputMessageReplyTo disable_notification:Bool protect_content:Bool input_message_contents:vector = Messages; +sendBusinessMessageAlbum business_connection_id:string chat_id:int53 reply_to:InputMessageReplyTo disable_notification:Bool protect_content:Bool input_message_contents:vector = BusinessMessages; //@description Checks validness of a name for a quick reply shortcut. Can be called synchronously @name The name of the shortcut; 1-32 characters diff --git a/td/telegram/BusinessConnectionManager.cpp b/td/telegram/BusinessConnectionManager.cpp index ba43330b2..c920f5e5f 100644 --- a/td/telegram/BusinessConnectionManager.cpp +++ b/td/telegram/BusinessConnectionManager.cpp @@ -115,11 +115,11 @@ struct BusinessConnectionManager::PendingMessage { }; class BusinessConnectionManager::SendBusinessMessageQuery final : public Td::ResultHandler { - Promise> promise_; + Promise> promise_; unique_ptr message_; public: - explicit SendBusinessMessageQuery(Promise> &&promise) + explicit SendBusinessMessageQuery(Promise> &&promise) : promise_(std::move(promise)) { } @@ -188,11 +188,11 @@ class BusinessConnectionManager::SendBusinessMessageQuery final : public Td::Res }; class BusinessConnectionManager::SendBusinessMediaQuery final : public Td::ResultHandler { - Promise> promise_; + Promise> promise_; unique_ptr message_; public: - explicit SendBusinessMediaQuery(Promise> &&promise) + explicit SendBusinessMediaQuery(Promise> &&promise) : promise_(std::move(promise)) { } @@ -259,11 +259,11 @@ class BusinessConnectionManager::SendBusinessMediaQuery final : public Td::Resul }; class BusinessConnectionManager::SendBusinessMultiMediaQuery final : public Td::ResultHandler { - Promise> promise_; + Promise> promise_; vector> messages_; public: - explicit SendBusinessMultiMediaQuery(Promise> &&promise) + explicit SendBusinessMultiMediaQuery(Promise> &&promise) : promise_(std::move(promise)) { } @@ -487,12 +487,14 @@ void BusinessConnectionManager::on_update_bot_business_connect( } void BusinessConnectionManager::on_update_bot_new_business_message( - const BusinessConnectionId &connection_id, telegram_api::object_ptr &&message) { + const BusinessConnectionId &connection_id, telegram_api::object_ptr &&message, + telegram_api::object_ptr &&reply_to_message) { if (!td_->auth_manager_->is_bot() || !connection_id.is_valid()) { LOG(ERROR) << "Receive " << to_string(message); return; } - auto message_object = td_->messages_manager_->get_business_message_object(std::move(message)); + auto message_object = + td_->messages_manager_->get_business_message_object(std::move(message), std::move(reply_to_message)); if (message_object == nullptr) { return; } @@ -501,12 +503,14 @@ void BusinessConnectionManager::on_update_bot_new_business_message( } void BusinessConnectionManager::on_update_bot_edit_business_message( - const BusinessConnectionId &connection_id, telegram_api::object_ptr &&message) { + const BusinessConnectionId &connection_id, telegram_api::object_ptr &&message, + telegram_api::object_ptr &&reply_to_message) { if (!td_->auth_manager_->is_bot() || !connection_id.is_valid()) { LOG(ERROR) << "Receive " << to_string(message); return; } - auto message_object = td_->messages_manager_->get_business_message_object(std::move(message)); + auto message_object = + td_->messages_manager_->get_business_message_object(std::move(message), std::move(reply_to_message)); if (message_object == nullptr) { return; } @@ -687,7 +691,7 @@ void BusinessConnectionManager::send_message(BusinessConnectionId business_conne bool disable_notification, bool protect_content, td_api::object_ptr &&reply_markup, td_api::object_ptr &&input_message_content, - Promise> &&promise) { + Promise> &&promise) { TRY_STATUS_PROMISE(promise, check_business_connection(business_connection_id, dialog_id)); TRY_RESULT_PROMISE(promise, input_content, process_input_message_content(dialog_id, std::move(input_message_content))); @@ -703,7 +707,7 @@ void BusinessConnectionManager::send_message(BusinessConnectionId business_conne } void BusinessConnectionManager::do_send_message(unique_ptr &&message, - Promise> &&promise) { + Promise> &&promise) { LOG(INFO) << "Send business message to " << message->dialog_id_; const auto *content = message->content_.get(); @@ -786,7 +790,7 @@ void BusinessConnectionManager::upload_media(unique_ptr &&messag void BusinessConnectionManager::complete_send_media(unique_ptr &&message, telegram_api::object_ptr &&input_media, - Promise> &&promise) { + Promise> &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); CHECK(message != nullptr); CHECK(input_media != nullptr); @@ -956,7 +960,7 @@ void BusinessConnectionManager::send_message_album( BusinessConnectionId business_connection_id, DialogId dialog_id, td_api::object_ptr &&reply_to, bool disable_notification, bool protect_content, vector> &&input_message_contents, - Promise> &&promise) { + Promise> &&promise) { if (input_message_contents.size() > MAX_GROUPED_MESSAGES) { return promise.set_error(Status::Error(400, "Too many messages to send as an album")); } diff --git a/td/telegram/BusinessConnectionManager.h b/td/telegram/BusinessConnectionManager.h index 8e8501800..cfdf51671 100644 --- a/td/telegram/BusinessConnectionManager.h +++ b/td/telegram/BusinessConnectionManager.h @@ -46,10 +46,12 @@ class BusinessConnectionManager final : public Actor { void on_update_bot_business_connect(telegram_api::object_ptr &&connection); void on_update_bot_new_business_message(const BusinessConnectionId &connection_id, - telegram_api::object_ptr &&message); + telegram_api::object_ptr &&message, + telegram_api::object_ptr &&reply_to_message); void on_update_bot_edit_business_message(const BusinessConnectionId &connection_id, - telegram_api::object_ptr &&message); + telegram_api::object_ptr &&message, + telegram_api::object_ptr &&reply_to_message); void on_update_bot_delete_business_messages(const BusinessConnectionId &connection_id, DialogId dialog_id, vector &&messages); @@ -61,13 +63,13 @@ class BusinessConnectionManager final : public Actor { td_api::object_ptr &&reply_to, bool disable_notification, bool protect_content, td_api::object_ptr &&reply_markup, td_api::object_ptr &&input_message_content, - Promise> &&promise); + Promise> &&promise); void send_message_album(BusinessConnectionId business_connection_id, DialogId dialog_id, td_api::object_ptr &&reply_to, bool disable_notification, bool protect_content, vector> &&input_message_contents, - Promise> &&promise); + Promise> &&promise); private: static constexpr size_t MAX_GROUPED_MESSAGES = 10; // server side limit @@ -95,7 +97,7 @@ class BusinessConnectionManager final : public Actor { struct MediaGroupSendRequest { size_t finished_count_ = 0; vector> upload_results_; - Promise> promise_; + Promise> promise_; }; void tear_down() final; @@ -115,7 +117,8 @@ class BusinessConnectionManager final : public Actor { unique_ptr &&reply_markup, InputMessageContent &&input_content) const; - void do_send_message(unique_ptr &&message, Promise> &&promise); + void do_send_message(unique_ptr &&message, + Promise> &&promise); static FileId get_message_file_id(const unique_ptr &message); @@ -126,7 +129,7 @@ class BusinessConnectionManager final : public Actor { void complete_send_media(unique_ptr &&message, telegram_api::object_ptr &&input_media, - Promise> &&promise); + Promise> &&promise); void on_upload_media(FileId file_id, telegram_api::object_ptr input_file); diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 5c0104a49..91459be7a 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -22675,31 +22675,45 @@ td_api::object_ptr MessagesManager::get_dialog_event_log_messag get_restriction_reason_description(m->restriction_reasons), std::move(content), std::move(reply_markup)); } -td_api::object_ptr MessagesManager::get_business_message_object( +td_api::object_ptr MessagesManager::get_business_message_object( + telegram_api::object_ptr &&message, + telegram_api::object_ptr &&reply_to_message) { + auto message_object = get_business_message_message_object(std::move(message)); + if (message_object == nullptr) { + LOG(ERROR) << "Failed to create a business message"; + return nullptr; + } + return td_api::make_object(std::move(message_object), + get_business_message_message_object(std::move(reply_to_message))); +} + +td_api::object_ptr MessagesManager::get_business_message_message_object( telegram_api::object_ptr &&message) { CHECK(td_->auth_manager_->is_bot()); - auto dialog_message = - create_message(td_, parse_telegram_api_message(td_, std::move(message), false, "get_business_message_object"), - false, true, "get_business_message_object"); + if (message == nullptr) { + return nullptr; + } + auto dialog_message = create_message( + td_, parse_telegram_api_message(td_, std::move(message), false, "get_business_message_message_object"), false, + true, "get_business_message_message_object"); const Message *m = dialog_message.second.get(); if (m == nullptr) { - LOG(ERROR) << "Failed to create a business message"; return nullptr; } auto dialog_id = dialog_message.first; - force_create_dialog(dialog_id, "get_business_message_object chat", true); + force_create_dialog(dialog_id, "get_business_message_message_object chat", true); - auto sender = - get_message_sender_object_const(td_, m->sender_user_id, m->sender_dialog_id, "get_business_message_object"); + auto sender = get_message_sender_object_const(td_, m->sender_user_id, m->sender_dialog_id, + "get_business_message_message_object"); auto forward_info = m->forward_info == nullptr ? nullptr : m->forward_info->get_message_forward_info_object(td_, false); auto import_info = m->forward_info == nullptr ? nullptr : m->forward_info->get_message_import_info_object(); auto can_be_saved = can_save_message(dialog_id, m); - auto via_bot_user_id = - td_->contacts_manager_->get_user_id_object(m->via_bot_user_id, "get_business_message_object via_bot_user_id"); + auto via_bot_user_id = td_->contacts_manager_->get_user_id_object( + m->via_bot_user_id, "get_business_message_message_object via_bot_user_id"); auto via_business_bot_user_id = td_->contacts_manager_->get_user_id_object( - m->via_business_bot_user_id, "get_business_message_object via_business_bot_user_id"); + m->via_business_bot_user_id, "get_business_message_message_object via_business_bot_user_id"); auto reply_to = [&]() -> td_api::object_ptr { if (!m->replied_message_info.is_empty()) { return m->replied_message_info.get_message_reply_to_message_object(td_, dialog_id); @@ -22707,7 +22721,7 @@ td_api::object_ptr MessagesManager::get_business_message_object if (m->reply_to_story_full_id.is_valid()) { return td_api::make_object( get_chat_id_object(m->reply_to_story_full_id.get_dialog_id(), - "get_business_message_object messageReplyToStory"), + "get_business_message_message_object messageReplyToStory"), m->reply_to_story_full_id.get_story_id().get()); } return nullptr; @@ -22717,9 +22731,9 @@ td_api::object_ptr MessagesManager::get_business_message_object auto self_destruct_type = m->ttl.get_message_self_destruct_type_object(); return td_api::make_object( - m->message_id.get(), std::move(sender), get_chat_id_object(dialog_id, "get_business_message_object"), nullptr, - nullptr, m->is_outgoing, false, false, false, false, can_be_saved, false, false, false, false, false, false, - false, false, false, false, false, false, false, m->date, m->edit_date, std::move(forward_info), + m->message_id.get(), std::move(sender), get_chat_id_object(dialog_id, "get_business_message_message_object"), + nullptr, nullptr, m->is_outgoing, false, false, false, false, can_be_saved, false, false, false, false, false, + false, false, false, false, false, false, false, false, m->date, m->edit_date, std::move(forward_info), std::move(import_info), nullptr, Auto(), std::move(reply_to), 0, 0, std::move(self_destruct_type), 0.0, 0.0, via_bot_user_id, via_business_bot_user_id, 0, string(), m->media_album_id, get_restriction_reason_description(m->restriction_reasons), std::move(content), std::move(reply_markup)); @@ -22804,7 +22818,7 @@ td_api::object_ptr MessagesManager::get_message_object(DialogId auto via_bot_user_id = td_->contacts_manager_->get_user_id_object(m->via_bot_user_id, "get_message_object via_bot_user_id"); auto via_business_bot_user_id = td_->contacts_manager_->get_user_id_object( - m->via_business_bot_user_id, "get_business_message_object via_business_bot_user_id"); + m->via_business_bot_user_id, "get_message_object via_business_bot_user_id"); auto reply_to = [&]() -> td_api::object_ptr { if (!m->replied_message_info.is_empty()) { if (!is_bot && m->is_topic_message && diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 7b985a16f..ec7e9128d 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -787,8 +787,9 @@ class MessagesManager final : public Actor { td_api::object_ptr get_dialog_event_log_message_object( DialogId dialog_id, tl_object_ptr &&message, DialogId &sender_dialog_id); - td_api::object_ptr get_business_message_object( - telegram_api::object_ptr &&message); + td_api::object_ptr get_business_message_object( + telegram_api::object_ptr &&message, + telegram_api::object_ptr &&reply_to_message); td_api::object_ptr get_message_object(MessageFullId message_full_id, const char *source); @@ -2394,6 +2395,9 @@ class MessagesManager final : public Actor { vector> &&messages, bool skip_not_found); + td_api::object_ptr get_business_message_message_object( + telegram_api::object_ptr &&message); + vector sort_dialogs_by_order(const vector &dialog_ids, int32 limit) const; static bool need_unread_counter(int64 dialog_order); diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index e73f8e23e..625da96b6 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -3096,13 +3096,15 @@ void UpdatesManager::process_qts_update(tl_object_ptr &&up case telegram_api::updateBotNewBusinessMessage::ID: { auto update = move_tl_object_as(update_ptr); td_->business_connection_manager_->on_update_bot_new_business_message( - BusinessConnectionId(std::move(update->connection_id_)), std::move(update->message_)); + BusinessConnectionId(std::move(update->connection_id_)), std::move(update->message_), + std::move(update->reply_to_message_)); break; } case telegram_api::updateBotEditBusinessMessage::ID: { auto update = move_tl_object_as(update_ptr); td_->business_connection_manager_->on_update_bot_edit_business_message( - BusinessConnectionId(std::move(update->connection_id_)), std::move(update->message_)); + BusinessConnectionId(std::move(update->connection_id_)), std::move(update->message_), + std::move(update->reply_to_message_)); break; } case telegram_api::updateBotDeleteBusinessMessage::ID: { diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index fc9b7d15a..e37b128b4 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -1507,7 +1507,7 @@ class CliClient final : public Actor { } case td_api::updateNewBusinessMessage::ID: { const auto *update = static_cast(result.get()); - const auto *message = update->message_.get(); + const auto *message = update->message_->message_.get(); if (!message->is_outgoing_ && use_test_dc_) { auto old_business_connection_id = std::move(business_connection_id_); business_connection_id_ = update->connection_id_;