From 651bb7a156a9baf8139b9b04cccfdd647784a417 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 21 Feb 2023 20:44:03 +0300 Subject: [PATCH] Add inlineQueryResultsButton. --- td/generate/scheme/td_api.tl | 19 ++++--- td/telegram/InlineQueriesManager.cpp | 78 ++++++++++++++++++---------- td/telegram/InlineQueriesManager.h | 4 +- td/telegram/Td.cpp | 8 ++- 4 files changed, 68 insertions(+), 41 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 9ab1e63b0..8f9ef3332 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3539,13 +3539,19 @@ inlineQueryResultVideo id:string video:video title:string description:string = I inlineQueryResultVoiceNote id:string voice_note:voiceNote title:string = InlineQueryResult; +//@description Describes the button that opens a private chat with the bot and sends a start message to the bot with the given parameter @parameter The parameter for the bot start message +inlineQueryResultsButtonTypeSwitchToPrivateChat parameter:string = InlineQueryResultsButtonTypeSwitchToPrivateChat; + +//@description Represents a button to be shown above inline query results @text The text of the button @type Type of the button +inlineQueryResultsButton text:string type:inlineQueryResultsButtonTypeSwitchToPrivateChat = InlineQueryResultsButton; + + //@description Represents the results of the inline query. Use sendInlineQueryResultMessage to send the result of the query //@inline_query_id Unique identifier of the inline query -//@next_offset The offset for the next request. If empty, there are no more results +//@button Button to be shown above inline query results; may be null //@results Results of the query -//@switch_pm_text If non-empty, this text must be shown on the button, which opens a private chat with the bot and sends the bot a start message with the switch_pm_parameter -//@switch_pm_parameter Parameter for the bot start message -inlineQueryResults inline_query_id:int64 next_offset:string results:vector switch_pm_text:string switch_pm_parameter:string = InlineQueryResults; +//@next_offset The offset for the next request. If empty, there are no more results +inlineQueryResults inline_query_id:int64 button:inlineQueryResultsButton results:vector next_offset:string = InlineQueryResults; //@class CallbackQueryPayload @description Represents a payload of a callback query @@ -6495,12 +6501,11 @@ getInlineQueryResults bot_user_id:int53 chat_id:int53 user_location:location que //@description Sets the result of an inline query; for bots only //@inline_query_id Identifier of the inline query //@is_personal Pass true if results may be cached and returned only for the user that sent the query. By default, results may be returned to any user who sends the same query +//@button Button to be shown above inline query results; pass null if none //@results The results of the query //@cache_time Allowed time to cache the results of the query, in seconds //@next_offset Offset for the next inline query; pass an empty string if there are no more results -//@switch_pm_text If non-empty, this text must be shown on the button that opens a private chat with the bot and sends a start message to the bot with the parameter switch_pm_parameter -//@switch_pm_parameter The parameter for the bot start message -answerInlineQuery inline_query_id:int64 is_personal:Bool results:vector cache_time:int32 next_offset:string switch_pm_text:string switch_pm_parameter:string = Ok; +answerInlineQuery inline_query_id:int64 is_personal:Bool button:inlineQueryResultsButton results:vector cache_time:int32 next_offset:string = Ok; //@description Returns an HTTPS URL of a Web App to open after keyboardButtonTypeWebApp button is pressed diff --git a/td/telegram/InlineQueriesManager.cpp b/td/telegram/InlineQueriesManager.cpp index 0425993f5..772a55604 100644 --- a/td/telegram/InlineQueriesManager.cpp +++ b/td/telegram/InlineQueriesManager.cpp @@ -126,8 +126,9 @@ class SetInlineBotResultsQuery final : public Td::ResultHandler { } void send(int64 inline_query_id, bool is_gallery, bool is_personal, + telegram_api::object_ptr switch_pm, vector> &&results, int32 cache_time, - const string &next_offset, const string &switch_pm_text, const string &switch_pm_parameter) { + const string &next_offset) { int32 flags = 0; if (is_gallery) { flags |= telegram_api::messages_setInlineBotResults::GALLERY_MASK; @@ -138,14 +139,12 @@ class SetInlineBotResultsQuery final : public Td::ResultHandler { if (!next_offset.empty()) { flags |= telegram_api::messages_setInlineBotResults::NEXT_OFFSET_MASK; } - tl_object_ptr inline_bot_switch_pm; - if (!switch_pm_text.empty()) { + if (switch_pm != nullptr) { flags |= telegram_api::messages_setInlineBotResults::SWITCH_PM_MASK; - inline_bot_switch_pm = make_tl_object(switch_pm_text, switch_pm_parameter); } send_query(G()->net_query_creator().create(telegram_api::messages_setInlineBotResults( flags, false /*ignored*/, false /*ignored*/, inline_query_id, std::move(results), cache_time, next_offset, - std::move(inline_bot_switch_pm), nullptr))); + std::move(switch_pm), nullptr))); } void on_result(BufferSlice packet) final { @@ -466,25 +465,40 @@ UserId InlineQueriesManager::get_inline_bot_user_id(int64 query_id) const { } void InlineQueriesManager::answer_inline_query( - int64 inline_query_id, bool is_personal, vector> &&input_results, - int32 cache_time, const string &next_offset, const string &switch_pm_text, const string &switch_pm_parameter, - Promise &&promise) const { + int64 inline_query_id, bool is_personal, td_api::object_ptr &&button, + vector> &&input_results, int32 cache_time, + const string &next_offset, Promise &&promise) const { CHECK(td_->auth_manager_->is_bot()); - if (!switch_pm_text.empty()) { - if (switch_pm_parameter.empty()) { - return promise.set_error(Status::Error(400, "Can't use empty switch_pm_parameter")); + telegram_api::object_ptr switch_pm; + if (button != nullptr) { + if (!clean_input_string(button->text_)) { + return promise.set_error(Status::Error(400, "Strings must be encoded in UTF-8")); } - if (switch_pm_parameter.size() > 64) { - return promise.set_error(Status::Error(400, "Too long switch_pm_parameter specified")); + if (button->type_ == nullptr) { + return promise.set_error(Status::Error(400, "Button type must be non-empty")); } - if (!is_base64url_characters(switch_pm_parameter)) { - return promise.set_error(Status::Error(400, "Unallowed characters in switch_pm_parameter are used")); + switch (button->type_->get_id()) { + case td_api::inlineQueryResultsButtonTypeSwitchToPrivateChat::ID: { + auto type = td_api::move_object_as(button->type_); + if (type->parameter_.empty()) { + return promise.set_error(Status::Error(400, "Can't use empty switch_pm_parameter")); + } + if (type->parameter_.size() > 64) { + return promise.set_error(Status::Error(400, "Too long switch_pm_parameter specified")); + } + if (!is_base64url_characters(type->parameter_)) { + return promise.set_error(Status::Error(400, "Unallowed characters in switch_pm_parameter are used")); + } + switch_pm = telegram_api::make_object(button->text_, type->parameter_); + break; + } + default: + UNREACHABLE(); } } vector> results; - bool is_gallery = false; bool force_vertical = false; for (auto &input_result : input_results) { @@ -494,8 +508,8 @@ void InlineQueriesManager::answer_inline_query( } td_->create_handler(std::move(promise)) - ->send(inline_query_id, is_gallery && !force_vertical, is_personal, std::move(results), cache_time, next_offset, - switch_pm_text, switch_pm_parameter); + ->send(inline_query_id, is_gallery && !force_vertical, is_personal, std::move(switch_pm), std::move(results), + cache_time, next_offset); } void InlineQueriesManager::get_simple_web_view_url(UserId bot_user_id, string &&url, @@ -1318,6 +1332,17 @@ tl_object_ptr copy(const td_api::game &obj) { copy(obj.photo_), copy(obj.animation_)); } +template <> +tl_object_ptr copy( + const td_api::inlineQueryResultsButtonTypeSwitchToPrivateChat &obj) { + return td_api::make_object(obj.parameter_); +} + +template <> +tl_object_ptr copy(const td_api::inlineQueryResultsButton &obj) { + return td_api::make_object(obj.text_, copy(obj.type_)); +} + template <> tl_object_ptr copy(const td_api::inlineQueryResultArticle &obj) { return td_api::make_object(obj.id_, obj.url_, obj.hide_url_, obj.title_, @@ -1389,9 +1414,8 @@ static tl_object_ptr copy_result(const tl_object_ptr< template <> tl_object_ptr copy(const td_api::inlineQueryResults &obj) { - return td_api::make_object(obj.inline_query_id_, obj.next_offset_, - transform(obj.results_, copy_result), obj.switch_pm_text_, - obj.switch_pm_parameter_); + return td_api::make_object(obj.inline_query_id_, copy(obj.button_), + transform(obj.results_, copy_result), obj.next_offset_); } tl_object_ptr InlineQueriesManager::decrease_pending_request_count(uint64 query_hash) { @@ -1916,15 +1940,15 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI query_id_to_bot_user_id_[results->query_id_] = bot_user_id; - string switch_pm_text; - string switch_pm_parameter; + td_api::object_ptr button; if (results->switch_pm_ != nullptr) { - switch_pm_text = std::move(results->switch_pm_->text_); - switch_pm_parameter = std::move(results->switch_pm_->start_param_); + button = td_api::make_object( + results->switch_pm_->text_, td_api::make_object( + results->switch_pm_->start_param_)); } - it->second.results = make_tl_object( - results->query_id_, results->next_offset_, std::move(output_results), switch_pm_text, switch_pm_parameter); + it->second.results = make_tl_object(results->query_id_, std::move(button), + std::move(output_results), results->next_offset_); it->second.cache_expire_time = Time::now() + results->cache_time_; } diff --git a/td/telegram/InlineQueriesManager.h b/td/telegram/InlineQueriesManager.h index 61a8edc60..cc8bfa3c3 100644 --- a/td/telegram/InlineQueriesManager.h +++ b/td/telegram/InlineQueriesManager.h @@ -41,9 +41,9 @@ class InlineQueriesManager final : public Actor { void after_get_difference(); void answer_inline_query(int64 inline_query_id, bool is_personal, + td_api::object_ptr &&button, vector> &&input_results, int32 cache_time, - const string &next_offset, const string &switch_pm_text, const string &switch_pm_parameter, - Promise &&promise) const; + const string &next_offset, Promise &&promise) const; void get_simple_web_view_url(UserId bot_user_id, string &&url, const td_api::object_ptr &theme, string &&platform, diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 4e57ed4cc..a0b519ac1 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -7764,12 +7764,10 @@ void Td::on_request(uint64 id, td_api::getInlineQueryResults &request) { void Td::on_request(uint64 id, td_api::answerInlineQuery &request) { CHECK_IS_BOT(); CLEAN_INPUT_STRING(request.next_offset_); - CLEAN_INPUT_STRING(request.switch_pm_text_); - CLEAN_INPUT_STRING(request.switch_pm_parameter_); CREATE_OK_REQUEST_PROMISE(); - inline_queries_manager_->answer_inline_query( - request.inline_query_id_, request.is_personal_, std::move(request.results_), request.cache_time_, - request.next_offset_, request.switch_pm_text_, request.switch_pm_parameter_, std::move(promise)); + inline_queries_manager_->answer_inline_query(request.inline_query_id_, request.is_personal_, + std::move(request.button_), std::move(request.results_), + request.cache_time_, request.next_offset_, std::move(promise)); } void Td::on_request(uint64 id, td_api::getWebAppUrl &request) {