From 83403d9836f615e99afd1736414f1042589a9f31 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 11 Jan 2023 16:54:46 +0300 Subject: [PATCH] Add keyboardButtonTypeRequestChat. --- CMakeLists.txt | 3 ++ td/generate/scheme/td_api.tl | 32 +++++++++++++ td/telegram/ForumTopicInfo.hpp | 1 - td/telegram/MessagesManager.cpp | 6 +-- td/telegram/ReplyMarkup.cpp | 70 ++++++++++++++++++++++++++--- td/telegram/ReplyMarkup.h | 10 ++++- td/telegram/ReplyMarkup.hpp | 27 ++++++++++- td/telegram/RequestedDialogType.cpp | 26 +++++++++++ td/telegram/RequestedDialogType.h | 35 +++++++++++++++ td/telegram/RequestedDialogType.hpp | 27 +++++++++++ 10 files changed, 222 insertions(+), 15 deletions(-) create mode 100644 td/telegram/RequestedDialogType.cpp create mode 100644 td/telegram/RequestedDialogType.h create mode 100644 td/telegram/RequestedDialogType.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fb7c0aff8..d044e04f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -433,6 +433,7 @@ set(TDLIB_SOURCE td/telegram/RecentDialogList.cpp td/telegram/ReplyMarkup.cpp td/telegram/ReportReason.cpp + td/telegram/RequestedDialogType.cpp td/telegram/RestrictionReason.cpp td/telegram/ScopeNotificationSettings.cpp td/telegram/SecretChatActor.cpp @@ -696,6 +697,7 @@ set(TDLIB_SOURCE td/telegram/ReplyMarkup.h td/telegram/ReportReason.h td/telegram/RequestActor.h + td/telegram/RequestedDialogType.h td/telegram/RestrictionReason.h td/telegram/ScheduledServerMessageId.h td/telegram/ScopeNotificationSettings.h @@ -781,6 +783,7 @@ set(TDLIB_SOURCE td/telegram/PollManager.hpp td/telegram/PremiumGiftOption.hpp td/telegram/ReplyMarkup.hpp + td/telegram/RequestedDialogType.hpp td/telegram/ScopeNotificationSettings.hpp td/telegram/SecureValue.hpp td/telegram/SendCodeHelper.hpp diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 2a78b0672..80dd7fe0b 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1355,6 +1355,35 @@ chatActionBarSharePhoneNumber = ChatActionBar; chatActionBarJoinRequest title:string is_channel:Bool request_date:int32 = ChatActionBar; +//@class RequestedChatType @description Describes type of a chat, which is requested in keyboardButtonTypeRequestChat + +//@description A chat with a user was requested +//@restrict_is_bot True, if the user must or must not be a bot +//@is_bot True, if the user must be a bot; otherwise, the user must no be a bot. Ignored if restrict_is_bot is false +//@restrict_is_premium True, if the user must or must not be a Telegram Premium user +//@is_premium True, if the user must be a Telegram Premium user; otherwise, the user must no be a Telegram Premium user. Ignored if restrict_is_premium is false +requestedChatTypePrivate restrict_is_bot:Bool is_bot:Bool restrict_is_premium:Bool is_premium:Bool = RequestedChatType; + +//@description A basic group or a supergroup chat was requested +//@restrict_is_forum True, if the chat must or must not be a forum +//@is_forum True, if the chat must be a forum; otherwise, the chat must not be a forum. Ignored if restrict_is_forum is false +//@restrict_has_username True, if the chat must or must not have a username +//@has_username True, if the chat must have a username; otherwise, the chat must not have a username. Ignored if restrict_has_username is false +//@is_created True, if the chat must be created by the user +//@user_administrator_rights Expected user administrator rights in the chat; may be null if they aren't restricted +//@bot_administrator_rights Expected bot administrator rights in the chat; may be null if they aren't restricted +//@bot_is_member True, if the bot must be a member of the chat +requestedChatTypeGroup restrict_is_forum:Bool is_forum:Bool restrict_has_username:Bool has_username:Bool is_created:Bool user_administrator_rights:chatAdministratorRights bot_administrator_rights:chatAdministratorRights bot_is_member:Bool = RequestedChatType; + +//@description A channel chat was requested +//@restrict_has_username True, if the chat must or must not have a username +//@has_username True, if the chat must have a username; otherwise, the chat must not have a username. Ignored if restrict_has_username is false +//@is_created True, if the chat must be created by the user +//@user_administrator_rights Expected user administrator rights in the chat; may be null if they aren't restricted +//@bot_administrator_rights Expected bot administrator rights in the chat; may be null if they aren't restricted +requestedChatTypeChannel restrict_has_username:Bool has_username:Bool is_created:Bool user_administrator_rights:chatAdministratorRights bot_administrator_rights:chatAdministratorRights = RequestedChatType; + + //@class KeyboardButtonType @description Describes a keyboard button type //@description A simple button, with text that must be sent when the button is pressed @@ -1369,6 +1398,9 @@ keyboardButtonTypeRequestLocation = KeyboardButtonType; //@description A button that allows the user to create and send a poll when pressed; available only in private chats @force_regular If true, only regular polls must be allowed to create @force_quiz If true, only polls in quiz mode must be allowed to create keyboardButtonTypeRequestPoll force_regular:Bool force_quiz:Bool = KeyboardButtonType; +//@description A button that requests a chat to be chosen by the user; available only in private chats @chat_type Type of the requested chat @id Unique button identifier +keyboardButtonTypeRequestChat chat_type:RequestedChatType id:int32 = KeyboardButtonType; + //@description A button that opens a Web App by calling getWebAppUrl @url An HTTP URL to pass to getWebAppUrl keyboardButtonTypeWebApp url:string = KeyboardButtonType; diff --git a/td/telegram/ForumTopicInfo.hpp b/td/telegram/ForumTopicInfo.hpp index afa53fd97..298d0652d 100644 --- a/td/telegram/ForumTopicInfo.hpp +++ b/td/telegram/ForumTopicInfo.hpp @@ -10,7 +10,6 @@ #include "td/telegram/ForumTopicIcon.hpp" -#include "td/utils/common.h" #include "td/utils/tl_helpers.h" namespace td { diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index b7f706e96..8a901b09f 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -27427,8 +27427,8 @@ Result MessagesManager::send_inline_query_result_message(DialogId dia if (!hide_via_bot) { m->via_bot_user_id = td_->inline_queries_manager_->get_inline_bot_user_id(query_id); } - if (content->message_reply_markup != nullptr && !to_secret) { - m->reply_markup = make_unique(*content->message_reply_markup); + if (!to_secret) { + m->reply_markup = dup_reply_markup(content->message_reply_markup); } m->disable_web_page_preview = content->disable_web_page_preview; m->clear_draft = !hide_via_bot; @@ -29136,7 +29136,7 @@ void MessagesManager::fix_forwarded_message(Message *m, DialogId to_dialog_id, c } } if (need_reply_markup) { - m->reply_markup = make_unique(*forwarded_message->reply_markup); + m->reply_markup = dup_reply_markup(forwarded_message->reply_markup); for (auto &row : m->reply_markup->inline_keyboard) { for (auto &button : row) { if (button.type == InlineKeyboardButton::Type::SwitchInlineCurrentDialog) { diff --git a/td/telegram/ReplyMarkup.cpp b/td/telegram/ReplyMarkup.cpp index 7cebc7b41..dbf669bd2 100644 --- a/td/telegram/ReplyMarkup.cpp +++ b/td/telegram/ReplyMarkup.cpp @@ -14,6 +14,7 @@ #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" +#include "td/utils/algorithm.h" #include "td/utils/buffer.h" #include "td/utils/format.h" #include "td/utils/logging.h" @@ -30,7 +31,7 @@ static constexpr int32 REPLY_MARKUP_FLAG_HAS_PLACEHOLDER = 1 << 3; static constexpr int32 REPLY_MARKUP_FLAG_IS_PERSISTENT = 1 << 4; static bool operator==(const KeyboardButton &lhs, const KeyboardButton &rhs) { - return lhs.type == rhs.type && lhs.text == rhs.text; + return lhs.type == rhs.type && lhs.text == rhs.text && lhs.url == rhs.url && lhs.button_id == rhs.button_id; } static StringBuilder &operator<<(StringBuilder &string_builder, const KeyboardButton &keyboard_button) { @@ -55,7 +56,10 @@ static StringBuilder &operator<<(StringBuilder &string_builder, const KeyboardBu string_builder << "RequestPollRegular"; break; case KeyboardButton::Type::WebView: - string_builder << "WebView"; + string_builder << "WebApp"; + break; + case KeyboardButton::Type::RequestDialog: + string_builder << "RequestChat"; break; default: UNREACHABLE(); @@ -236,8 +240,14 @@ static KeyboardButton get_keyboard_button(tl_object_ptr(keyboard_button_ptr); + button.type = KeyboardButton::Type::RequestDialog; + button.text = std::move(keyboard_button->text_); + button.requested_dialog_type = td::make_unique(std::move(keyboard_button->peer_type_)); + button.button_id = std::move(keyboard_button->button_id_); break; + } default: LOG(ERROR) << "Unsupported keyboard button: " << to_string(keyboard_button_ptr); } @@ -489,10 +499,23 @@ static Result get_keyboard_button(tl_object_ptrurl_); break; } + case td_api::keyboardButtonTypeRequestChat::ID: { + if (!request_buttons_allowed) { + return Status::Error(400, "Chat can be requested in private chats only"); + } + auto button_type = move_tl_object_as(button->type_); + if (button_type->chat_type_ == nullptr) { + return Status::Error(400, "Requested chat type must be non-null"); + } + current_button.type = KeyboardButton::Type::RequestDialog; + current_button.requested_dialog_type = td::make_unique(std::move(button_type->chat_type_)); + current_button.button_id = button_type->id_; + break; + } default: UNREACHABLE(); } - return current_button; + return std::move(current_button); } static Result get_inline_keyboard_button(tl_object_ptr &&button, @@ -618,7 +641,7 @@ static Result get_inline_keyboard_button(tl_object_ptr> get_reply_markup(tl_object_ptr &&reply_markup_ptr, bool is_bot, @@ -667,7 +690,7 @@ Result> get_reply_markup(tl_object_ptrkeyboard.push_back(row_buttons); + reply_markup->keyboard.push_back(std::move(row_buttons)); } if (total_button_count >= 300) { break; @@ -704,7 +727,7 @@ Result> get_reply_markup(tl_object_ptrinline_keyboard.push_back(row_buttons); + reply_markup->inline_keyboard.push_back(std::move(row_buttons)); } if (total_button_count >= 300) { break; @@ -735,6 +758,31 @@ Result> get_reply_markup(tl_object_ptr dup_reply_markup(const unique_ptr &reply_markup) { + if (reply_markup == nullptr) { + return nullptr; + } + auto result = make_unique(); + result->type = reply_markup->type; + result->is_personal = reply_markup->is_personal; + result->is_persistent = reply_markup->is_persistent; + result->need_resize_keyboard = reply_markup->need_resize_keyboard; + result->keyboard = td::transform(reply_markup->keyboard, [](const vector &row) { + return td::transform(row, [](const KeyboardButton &button) { + KeyboardButton result; + result.type = button.type; + result.text = button.text; + result.url = button.url; + result.requested_dialog_type = td::make_unique(*button.requested_dialog_type); + result.button_id = button.button_id; + return result; + }); + }); + result->placeholder = reply_markup->placeholder; + result->inline_keyboard = reply_markup->inline_keyboard; + return result; +} + static tl_object_ptr get_input_keyboard_button(const KeyboardButton &keyboard_button) { switch (keyboard_button.type) { case KeyboardButton::Type::Text: @@ -751,6 +799,10 @@ static tl_object_ptr get_input_keyboard_button(con return make_tl_object(1, false, keyboard_button.text); case KeyboardButton::Type::WebView: return make_tl_object(keyboard_button.text, keyboard_button.url); + case KeyboardButton::Type::RequestDialog: + return make_tl_object( + keyboard_button.text, keyboard_button.button_id, + keyboard_button.requested_dialog_type->get_input_request_peer_type_object()); default: UNREACHABLE(); return nullptr; @@ -893,6 +945,10 @@ static tl_object_ptr get_keyboard_button_object(const Ke case KeyboardButton::Type::WebView: type = make_tl_object(keyboard_button.url); break; + case KeyboardButton::Type::RequestDialog: + type = make_tl_object( + keyboard_button.requested_dialog_type->get_requested_chat_type_object(), keyboard_button.button_id); + break; default: UNREACHABLE(); return nullptr; diff --git a/td/telegram/ReplyMarkup.h b/td/telegram/ReplyMarkup.h index 0e6c20d29..7e2d7babe 100644 --- a/td/telegram/ReplyMarkup.h +++ b/td/telegram/ReplyMarkup.h @@ -6,6 +6,7 @@ // #pragma once +#include "td/telegram/RequestedDialogType.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" @@ -28,11 +29,14 @@ struct KeyboardButton { RequestPoll, RequestPollQuiz, RequestPollRegular, - WebView + WebView, + RequestDialog }; Type type; string text; - string url; // WebView only + string url; // WebView only + unique_ptr requested_dialog_type; // RequestDialog only + int32 button_id = 0; // RequestDialog only }; struct InlineKeyboardButton { @@ -91,6 +95,8 @@ Result> get_reply_markup(tl_object_ptr dup_reply_markup(const unique_ptr &reply_markup); + tl_object_ptr get_input_reply_markup(ContactsManager *contacts_manager, const unique_ptr &reply_markup); diff --git a/td/telegram/ReplyMarkup.hpp b/td/telegram/ReplyMarkup.hpp index d5645889b..0165e3fba 100644 --- a/td/telegram/ReplyMarkup.hpp +++ b/td/telegram/ReplyMarkup.hpp @@ -7,6 +7,7 @@ #pragma once #include "td/telegram/ReplyMarkup.h" +#include "td/telegram/RequestedDialogType.hpp" #include "td/telegram/Version.h" #include "td/utils/tl_helpers.h" @@ -14,37 +15,59 @@ namespace td { template -void store(KeyboardButton button, StorerT &storer) { +void store(const KeyboardButton &button, StorerT &storer) { bool has_url = !button.url.empty(); + bool has_requested_dialog_type = button.requested_dialog_type != nullptr; + bool has_button_id = button.button_id != 0; BEGIN_STORE_FLAGS(); STORE_FLAG(has_url); + STORE_FLAG(has_requested_dialog_type); + STORE_FLAG(has_button_id); END_STORE_FLAGS(); store(button.type, storer); store(button.text, storer); if (has_url) { store(button.url, storer); } + if (has_requested_dialog_type) { + store(button.requested_dialog_type, storer); + } + if (has_button_id) { + store(button.button_id, storer); + } } template void parse(KeyboardButton &button, ParserT &parser) { bool has_url; + bool has_requested_dialog_type; + bool has_button_id; if (parser.version() >= static_cast(Version::AddKeyboardButtonFlags)) { BEGIN_PARSE_FLAGS(); PARSE_FLAG(has_url); + PARSE_FLAG(has_requested_dialog_type); + PARSE_FLAG(has_button_id); END_PARSE_FLAGS(); } else { has_url = false; + has_requested_dialog_type = false; + has_button_id = false; } parse(button.type, parser); parse(button.text, parser); if (has_url) { parse(button.url, parser); } + if (has_requested_dialog_type) { + parse(button.requested_dialog_type, parser); + } + if (has_button_id) { + parse(button.button_id, parser); + } } template -void store(InlineKeyboardButton button, StorerT &storer) { +void store(const InlineKeyboardButton &button, StorerT &storer) { bool has_id = button.id != 0; bool has_user_id = button.user_id.is_valid(); bool has_forward_text = !button.forward_text.empty(); diff --git a/td/telegram/RequestedDialogType.cpp b/td/telegram/RequestedDialogType.cpp new file mode 100644 index 000000000..6be4b3bca --- /dev/null +++ b/td/telegram/RequestedDialogType.cpp @@ -0,0 +1,26 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// +// 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/RequestedDialogType.h" + +namespace td { + +RequestedDialogType::RequestedDialogType(td_api::object_ptr &&chat_type) { +} + +RequestedDialogType::RequestedDialogType(telegram_api::object_ptr &&chat_type) { +} + +td_api::object_ptr RequestedDialogType::get_requested_chat_type_object() const { + return td_api::make_object(); +} + +telegram_api::object_ptr RequestedDialogType::get_input_request_peer_type_object() + const { + return telegram_api::make_object(0, false, false); +} + +} // namespace td diff --git a/td/telegram/RequestedDialogType.h b/td/telegram/RequestedDialogType.h new file mode 100644 index 000000000..0a5617dab --- /dev/null +++ b/td/telegram/RequestedDialogType.h @@ -0,0 +1,35 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// +// 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) +// +#pragma once + +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" + +namespace td { + +class RequestedDialogType { + public: + RequestedDialogType() = default; + + explicit RequestedDialogType(td_api::object_ptr &&chat_type); + + explicit RequestedDialogType(telegram_api::object_ptr &&peer_type); + + td_api::object_ptr get_requested_chat_type_object() const; + + telegram_api::object_ptr get_input_request_peer_type_object() const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +} // namespace td diff --git a/td/telegram/RequestedDialogType.hpp b/td/telegram/RequestedDialogType.hpp new file mode 100644 index 000000000..cd41a3fe8 --- /dev/null +++ b/td/telegram/RequestedDialogType.hpp @@ -0,0 +1,27 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// +// 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) +// +#pragma once + +#include "td/telegram/RequestedDialogType.h" + +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void RequestedDialogType::store(StorerT &storer) const { + BEGIN_STORE_FLAGS(); + END_STORE_FLAGS(); +} + +template +void RequestedDialogType::parse(ParserT &parser) { + BEGIN_PARSE_FLAGS(); + END_PARSE_FLAGS(); +} + +} // namespace td