diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index f28c4c398..b6548a4fd 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -8165,6 +8165,15 @@ deleteQuickReplyShortcutMessages shortcut_id:int32 message_ids:vector = O //@input_message_content The content of the message to be added; inputMessagePoll, inputMessageForwarded and inputMessageLocation with live_period aren't supported addQuickReplyShortcutMessage shortcut_name:string reply_to_message_id:int53 input_message_content:InputMessageContent = QuickReplyMessage; +//@description Adds a message to a quick reply shortcut. If shortcut doesn't exist and there are less than getOption("quick_reply_shortcut_count_max") shortcuts, then a new shortcut is created. +//-The shortcut must not contain more than getOption("quick_reply_shortcut_message_count_max") messages after adding the new message. Returns the added message +//@shortcut_name Name of the target shortcut +//@reply_to_message_id Identifier of a quick reply message in the same shortcut to be replied; pass 0 if none +//@query_id Identifier of the inline query +//@result_id Identifier of the inline query result +//@hide_via_bot Pass true to hide the bot, via which the message is sent. Can be used only for bots getOption("animation_search_bot_username"), getOption("photo_search_bot_username"), and getOption("venue_search_bot_username") +addQuickReplyShortcutInlineQueryResultMessage shortcut_name:string reply_to_message_id:int53 query_id:int64 result_id:string hide_via_bot:Bool = Message; + //@description Returns list of custom emojis, which can be used as forum topic icon by all users getForumTopicDefaultIcons = Stickers; diff --git a/td/telegram/QuickReplyManager.cpp b/td/telegram/QuickReplyManager.cpp index af64c4cff..1fd2a8c65 100644 --- a/td/telegram/QuickReplyManager.cpp +++ b/td/telegram/QuickReplyManager.cpp @@ -14,6 +14,7 @@ #include "td/telegram/FileReferenceManager.h" #include "td/telegram/files/FileManager.h" #include "td/telegram/Global.h" +#include "td/telegram/InlineQueriesManager.h" #include "td/telegram/logevent/LogEvent.h" #include "td/telegram/logevent/LogEventHelper.h" #include "td/telegram/MessageContent.h" @@ -281,6 +282,55 @@ class QuickReplyManager::SendQuickReplyMessageQuery final : public Td::ResultHan } }; +class QuickReplyManager::SendQuickReplyInlineMessageQuery final : public Td::ResultHandler { + int64 random_id_; + QuickReplyShortcutId shortcut_id_; + + public: + void send(const QuickReplyMessage *m) { + random_id_ = m->random_id; + shortcut_id_ = m->shortcut_id; + + int32 flags = telegram_api::messages_sendInlineBotResult::QUICK_REPLY_SHORTCUT_MASK; + if (m->hide_via_bot) { + flags |= telegram_api::messages_sendInlineBotResult::HIDE_VIA_MASK; + } + auto reply_to = + MessageInputReplyTo(m->reply_to_message_id, DialogId(), Auto(), 0).get_input_reply_to(td_, MessageId()); + if (reply_to != nullptr) { + flags |= telegram_api::messages_sendInlineBotResult::REPLY_TO_MASK; + } + + send_query(G()->net_query_creator().create( + telegram_api::messages_sendInlineBotResult( + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + telegram_api::make_object(), std::move(reply_to), m->random_id, + m->inline_query_id, m->inline_result_id, 0, nullptr, + td_->quick_reply_manager_->get_input_quick_reply_shortcut(m->shortcut_id)), + {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for SendQuickReplyInlineMessageQuery for " << random_id_ << ": " << to_string(ptr); + td_->quick_reply_manager_->process_send_quick_reply_updates(shortcut_id_, std::move(ptr), {random_id_}); + } + + void on_error(Status status) final { + LOG(INFO) << "Receive error for SendQuickReplyInlineMessageQuery: " << status; + if (G()->close_flag()) { + // do not send error, message will be re-sent after restart + return; + } + td_->quick_reply_manager_->on_failed_send_quick_reply_messages(shortcut_id_, {random_id_}, std::move(status)); + } +}; + class QuickReplyManager::SendQuickReplyMediaQuery final : public Td::ResultHandler { int64 random_id_; QuickReplyShortcutId shortcut_id_; @@ -313,7 +363,7 @@ class QuickReplyManager::SendQuickReplyMediaQuery final : public Td::ResultHandl vector> entities; const FormattedText *message_text = get_message_content_text(m->content.get()); if (message_text != nullptr) { - entities = get_input_message_entities(td_->user_manager_.get(), message_text, "SendQuickReplyMessageQuery"); + entities = get_input_message_entities(td_->user_manager_.get(), message_text, "SendQuickReplyMediaQuery"); if (!entities.empty()) { flags |= telegram_api::messages_sendMedia::ENTITIES_MASK; } @@ -434,6 +484,8 @@ void QuickReplyManager::QuickReplyMessage::store(StorerT &storer) const { bool has_try_resend_at = !is_server && try_resend_at != 0; bool has_media_album_id = media_album_id != 0; bool has_reply_markup = reply_markup != nullptr; + bool has_inline_query_id = inline_query_id != 0; + bool has_inline_result_id = !inline_result_id.empty(); BEGIN_STORE_FLAGS(); STORE_FLAG(has_edit_date); STORE_FLAG(has_random_id); @@ -452,6 +504,8 @@ void QuickReplyManager::QuickReplyMessage::store(StorerT &storer) const { STORE_FLAG(has_try_resend_at); STORE_FLAG(has_media_album_id); STORE_FLAG(has_reply_markup); + STORE_FLAG(has_inline_query_id); + STORE_FLAG(has_inline_result_id); END_STORE_FLAGS(); td::store(message_id, storer); td::store(shortcut_id, storer); @@ -489,6 +543,12 @@ void QuickReplyManager::QuickReplyMessage::store(StorerT &storer) const { if (has_reply_markup) { td::store(reply_markup, storer); } + if (has_inline_query_id) { + td::store(inline_query_id, storer); + } + if (has_inline_result_id) { + td::store(inline_result_id, storer); + } } template @@ -504,6 +564,8 @@ void QuickReplyManager::QuickReplyMessage::parse(ParserT &parser) { bool has_try_resend_at; bool has_media_album_id; bool has_reply_markup; + bool has_inline_query_id; + bool has_inline_result_id; BEGIN_PARSE_FLAGS(); PARSE_FLAG(has_edit_date); PARSE_FLAG(has_random_id); @@ -522,6 +584,8 @@ void QuickReplyManager::QuickReplyMessage::parse(ParserT &parser) { PARSE_FLAG(has_try_resend_at); PARSE_FLAG(has_media_album_id); PARSE_FLAG(has_reply_markup); + PARSE_FLAG(has_inline_query_id); + PARSE_FLAG(has_inline_result_id); END_PARSE_FLAGS(); td::parse(message_id, parser); td::parse(shortcut_id, parser); @@ -559,6 +623,12 @@ void QuickReplyManager::QuickReplyMessage::parse(ParserT &parser) { if (has_reply_markup) { td::parse(reply_markup, parser); } + if (has_inline_query_id) { + td::parse(inline_query_id, parser); + } + if (has_inline_result_id) { + td::parse(inline_result_id, parser); + } } QuickReplyManager::Shortcut::~Shortcut() = default; @@ -824,9 +894,6 @@ bool QuickReplyManager::can_resend_quick_reply_message(const QuickReplyMessage * if (m->send_error_code != 429) { return false; } - if (m->via_bot_user_id.is_valid() || m->hide_via_bot) { - return false; - } return true; } @@ -1669,11 +1736,53 @@ Result> QuickReplyManager::send_me return get_quick_reply_message_object(m, "send_message"); } +Result> QuickReplyManager::send_inline_query_result_message( + const string &shortcut_name, MessageId reply_to_message_id, int64 query_id, const string &result_id, + bool hide_via_bot) { + const InlineMessageContent *message_content = + td_->inline_queries_manager_->get_inline_message_content(query_id, result_id); + if (message_content == nullptr || query_id == 0) { + return Status::Error(400, "Inline query result not found"); + } + TRY_RESULT(s, create_new_local_shortcut(shortcut_name, 1)); + bool is_new = s->messages_.empty(); + reply_to_message_id = get_input_reply_to_message_id(s, reply_to_message_id); + + UserId via_bot_user_id; + if (!hide_via_bot) { + via_bot_user_id = td_->inline_queries_manager_->get_inline_bot_user_id(query_id); + } + auto content = + dup_message_content(td_, td_->dialog_manager_->get_my_dialog_id(), message_content->message_content.get(), + MessageContentDupType::SendViaBot, MessageCopyOptions()); + auto *m = add_local_message(s, reply_to_message_id, std::move(content), message_content->invert_media, + via_bot_user_id, hide_via_bot, message_content->disable_web_page_preview, string()); + m->reply_markup = dup_reply_markup(message_content->message_reply_markup); + m->inline_query_id = query_id; + m->inline_result_id = result_id; + + send_update_quick_reply_shortcut(s, "send_inline_query_result_message"); + send_update_quick_reply_shortcut_messages(s, "send_inline_query_result_message"); + if (is_new) { + send_update_quick_reply_shortcuts(); + } + save_quick_reply_shortcuts(); + + do_send_message(m); + + return get_quick_reply_message_object(m, "send_inline_query_result_message"); +} + void QuickReplyManager::do_send_message(const QuickReplyMessage *m, vector bad_parts) { bool is_edit = m->message_id.is_server(); auto message_full_id = QuickReplyMessageFullId(m->shortcut_id, m->message_id); LOG(INFO) << "Do " << (is_edit ? "edit" : "send") << ' ' << message_full_id; + if (!is_edit && m->inline_query_id != 0) { + td_->create_handler()->send(m); + return; + } + auto content = m->content.get(); CHECK(content != nullptr); auto content_type = content->get_type(); diff --git a/td/telegram/QuickReplyManager.h b/td/telegram/QuickReplyManager.h index ac908e409..e34ca47f0 100644 --- a/td/telegram/QuickReplyManager.h +++ b/td/telegram/QuickReplyManager.h @@ -63,6 +63,12 @@ class QuickReplyManager final : public Actor { const string &shortcut_name, MessageId reply_to_message_id, td_api::object_ptr &&input_message_content); + Result> send_inline_query_result_message(const string &shortcut_name, + MessageId reply_to_message_id, + int64 query_id, + const string &result_id, + bool hide_via_bot); + void reload_quick_reply_shortcuts(); void reload_quick_reply_messages(QuickReplyShortcutId shortcut_id, Promise &&promise); @@ -105,6 +111,9 @@ class QuickReplyManager final : public Actor { string send_emoji; // for send_message + int64 inline_query_id = 0; // for send_message + string inline_result_id; // for send_message + UserId via_bot_user_id; bool is_failed_to_send = false; @@ -171,6 +180,7 @@ class QuickReplyManager final : public Actor { class SendQuickReplyMessageQuery; class SendQuickReplyMediaQuery; + class SendQuickReplyInlineMessageQuery; class UploadMediaCallback; class UploadThumbnailCallback; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index c37444aa6..aece9a3f6 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5889,6 +5889,19 @@ void Td::on_request(uint64 id, td_api::addQuickReplyShortcutMessage &request) { } } +void Td::on_request(uint64 id, td_api::addQuickReplyShortcutInlineQueryResultMessage &request) { + CLEAN_INPUT_STRING(request.shortcut_name_); + CLEAN_INPUT_STRING(request.result_id_); + auto r_sent_message = quick_reply_manager_->send_inline_query_result_message( + request.shortcut_name_, MessageId(request.reply_to_message_id_), request.query_id_, request.result_id_, + request.hide_via_bot_); + if (r_sent_message.is_error()) { + send_closure(actor_id(this), &Td::send_error, id, r_sent_message.move_as_error()); + } else { + send_closure(actor_id(this), &Td::send_result, id, r_sent_message.move_as_ok()); + } +} + void Td::on_request(uint64 id, const td_api::getStory &request) { CHECK_IS_USER(); CREATE_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 634a0ab47..df051b637 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -901,6 +901,8 @@ class Td final : public Actor { void on_request(uint64 id, td_api::addQuickReplyShortcutMessage &request); + void on_request(uint64 id, td_api::addQuickReplyShortcutInlineQueryResultMessage &request); + void on_request(uint64 id, const td_api::getStory &request); void on_request(uint64 id, const td_api::getChatsToSendStories &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index ff5eef3f2..852ff3e2a 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -5066,8 +5066,13 @@ class CliClient final : public Actor { int64 query_id; string result_id; get_args(args, chat_id, query_id, result_id); - send_request(td_api::make_object( - chat_id, message_thread_id_, nullptr, default_message_send_options(), query_id, result_id, op == "siqrh")); + if (quick_reply_shortcut_name_.empty()) { + send_request(td_api::make_object( + chat_id, message_thread_id_, nullptr, default_message_send_options(), query_id, result_id, op == "siqrh")); + } else { + send_request(td_api::make_object( + quick_reply_shortcut_name_, reply_message_id_, query_id, result_id, op == "siqrh")); + } } else if (op == "gcqa") { ChatId chat_id; MessageId message_id;