// // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // 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) // #include "td/telegram/BotMenuButton.h" #include "td/telegram/AuthManager.h" #include "td/telegram/Global.h" #include "td/telegram/LinkManager.h" #include "td/telegram/misc.h" #include "td/telegram/Td.h" #include "td/telegram/telegram_api.h" #include "td/telegram/UserManager.h" #include "td/utils/buffer.h" #include "td/utils/logging.h" #include "td/utils/SliceBuilder.h" #include "td/utils/Status.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_->user_manager_->get_input_user(user_id).move_as_ok() : make_tl_object(); 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_; public: explicit GetBotMenuButtonQuery(Promise> &&promise) : promise_(std::move(promise)) { } void send(UserId user_id) { auto input_user = user_id.is_valid() ? td_->user_manager_->get_input_user(user_id).move_as_ok() : make_tl_object(); send_query(G()->net_query_creator().create(telegram_api::bots_getBotMenuButton(std::move(input_user)))); } 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 GetBotMenuButtonQuery: " << to_string(ptr); auto bot_menu_button = get_bot_menu_button(std::move(ptr)); promise_.set_value(bot_menu_button == nullptr ? td_api::make_object() : bot_menu_button->get_bot_menu_button_object(td_)); } void on_error(Status status) final { promise_.set_error(std::move(status)); } }; unique_ptr get_bot_menu_button(telegram_api::object_ptr &&bot_menu_button) { if (bot_menu_button == nullptr) { return nullptr; } switch (bot_menu_button->get_id()) { case telegram_api::botMenuButtonCommands::ID: return nullptr; case telegram_api::botMenuButtonDefault::ID: return td::make_unique(string(), "default"); case telegram_api::botMenuButton::ID: { auto button = telegram_api::move_object_as(bot_menu_button); if (button->text_.empty()) { LOG(ERROR) << "Receive bot menu button with empty text: " << to_string(button); return nullptr; } return td::make_unique(std::move(button->text_), std::move(button->url_)); } default: UNREACHABLE(); return nullptr; } } td_api::object_ptr BotMenuButton::get_bot_menu_button_object(Td *td) const { bool is_bot = td->auth_manager_->is_bot(); return td_api::make_object(text_, is_bot ? url_ : "menu://" + url_); } bool operator==(const BotMenuButton &lhs, const BotMenuButton &rhs) { return lhs.text_ == rhs.text_ && lhs.url_ == rhs.url_; } td_api::object_ptr get_bot_menu_button_object(Td *td, const BotMenuButton *bot_menu_button) { if (bot_menu_button == nullptr) { return nullptr; } return bot_menu_button->get_bot_menu_button_object(td); } 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 must be non-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() << "Menu button Web App " << 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")); } td->create_handler(std::move(promise))->send(user_id); } } // namespace td