diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 6b441a362..bccd0cc29 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -5716,7 +5716,12 @@ deleteCommands scope:BotCommandScope language_code:string = Ok; //@language_code A two-letter ISO 639-1 language code or an empty string getCommands scope:BotCommandScope language_code:string = BotCommands; -//@description Returns menu button set by the bot for the given user; for bots only @user_id Identifier of the user +//@description Sets menu button for the given user or for all users; for bots only +//@user_id Identifier of the user or 0 to set menu button for all users +//@menu_button New menu button +setMenuButton user_id:int53 menu_button:botMenuButton = Ok; + +//@description Returns menu button set by the bot for the given user; for bots only @user_id Identifier of the user or 0 to get the default menu button getMenuButton user_id:int53 = BotMenuButton; //@description Sets default administrator rights for adding the bot to basic group and supergroup chats; for bots only @default_group_administrator_rights Default administrator rights for adding the bot to basic group and supergroup chats; may be null diff --git a/td/telegram/BotMenuButton.cpp b/td/telegram/BotMenuButton.cpp index 5351daa9e..052130372 100644 --- a/td/telegram/BotMenuButton.cpp +++ b/td/telegram/BotMenuButton.cpp @@ -7,12 +7,46 @@ #include "td/telegram/BotMenuButton.h" #include "td/telegram/ContactsManager.h" +#include "td/telegram/Global.h" +#include "td/telegram/LinkManager.h" +#include "td/telegram/misc.h" #include "td/telegram/Td.h" #include "td/utils/buffer.h" namespace td { +class SetBotMenuButtonQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit SetBotMenuButtonQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(UserId user_id, telegram_api::object_ptr input_bot_menu_button) { + auto input_user = user_id.is_valid() ? td_->contacts_manager_->get_input_user(user_id).move_as_ok() + : tl_object_ptr(); + send_query(G()->net_query_creator().create( + telegram_api::bots_setBotMenuButton(std::move(input_user), std::move(input_bot_menu_button)))); + } + + 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()); + } + + if (!result_ptr.ok()) { + LOG(ERROR) << "Receive false as result of SetBotMenuButtonQuery"; + } + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + class GetBotMenuButtonQuery final : public Td::ResultHandler { Promise> promise_; @@ -79,6 +113,39 @@ td_api::object_ptr get_bot_menu_button_object(const BotMe return bot_menu_button->get_bot_menu_button_object(); } +void set_menu_button(Td *td, UserId user_id, td_api::object_ptr &&menu_button, + Promise &&promise) { + if (!user_id.is_valid() && user_id != UserId()) { + return promise.set_error(Status::Error(400, "User not found")); + } + + telegram_api::object_ptr input_bot_menu_button; + if (menu_button == nullptr) { + input_bot_menu_button = telegram_api::make_object(); + } else if (menu_button->text_.empty()) { + if (menu_button->url_ != "default") { + return promise.set_error(Status::Error(400, "Menu button text can't be empty")); + } + input_bot_menu_button = telegram_api::make_object(); + } else { + if (!clean_input_string(menu_button->text_)) { + return promise.set_error(Status::Error(400, "Menu button text must be encoded in UTF-8")); + } + if (!clean_input_string(menu_button->url_)) { + return promise.set_error(Status::Error(400, "Menu button URL must be encoded in UTF-8")); + } + auto r_url = LinkManager::check_link(menu_button->url_, true, !G()->is_test_dc()); + if (r_url.is_error()) { + return promise.set_error(Status::Error(400, PSLICE() + << "Inline keyboard button web app URL '" << menu_button->url_ + << "' is invalid: " << r_url.error().message())); + } + input_bot_menu_button = telegram_api::make_object(menu_button->text_, r_url.ok()); + } + + td->create_handler(std::move(promise))->send(user_id, std::move(input_bot_menu_button)); +} + void get_menu_button(Td *td, UserId user_id, Promise> &&promise) { if (!user_id.is_valid() && user_id != UserId()) { return promise.set_error(Status::Error(400, "User not found")); diff --git a/td/telegram/BotMenuButton.h b/td/telegram/BotMenuButton.h index afcee2e56..02ceceed0 100644 --- a/td/telegram/BotMenuButton.h +++ b/td/telegram/BotMenuButton.h @@ -76,6 +76,9 @@ unique_ptr get_bot_menu_button(telegram_api::object_ptr get_bot_menu_button_object(const BotMenuButton *bot_menu_button); +void set_menu_button(Td *td, UserId user_id, td_api::object_ptr &&menu_button, + Promise &&promise); + void get_menu_button(Td *td, UserId user_id, Promise> &&promise); } // namespace td diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 33e7e8efe..f53f15df3 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6799,6 +6799,12 @@ void Td::on_request(uint64 id, td_api::getCommands &request) { get_commands(this, std::move(request.scope_), std::move(request.language_code_), std::move(promise)); } +void Td::on_request(uint64 id, td_api::setMenuButton &request) { + CHECK_IS_BOT(); + CREATE_OK_REQUEST_PROMISE(); + set_menu_button(this, UserId(request.user_id_), std::move(request.menu_button_), std::move(promise)); +} + void Td::on_request(uint64 id, const td_api::getMenuButton &request) { CHECK_IS_BOT(); CREATE_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 48a61f304..24ffe987e 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -1002,6 +1002,8 @@ class Td final : public Actor { void on_request(uint64 id, td_api::getCommands &request); + void on_request(uint64 id, td_api::setMenuButton &request); + void on_request(uint64 id, const td_api::getMenuButton &request); void on_request(uint64 id, const td_api::setDefaultGroupAdministratorRights &request);