Add keyboardButtonTypeRequestChat.

This commit is contained in:
levlam 2023-01-11 16:54:46 +03:00
parent 06a432a373
commit 83403d9836
10 changed files with 222 additions and 15 deletions

View File

@ -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

View File

@ -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;

View File

@ -10,7 +10,6 @@
#include "td/telegram/ForumTopicIcon.hpp"
#include "td/utils/common.h"
#include "td/utils/tl_helpers.h"
namespace td {

View File

@ -27427,8 +27427,8 @@ Result<MessageId> 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<ReplyMarkup>(*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<ReplyMarkup>(*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) {

View File

@ -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<telegram_api::KeyboardBu
button.url = r_url.move_as_ok();
break;
}
case telegram_api::keyboardButtonRequestPeer::ID:
case telegram_api::keyboardButtonRequestPeer::ID: {
auto keyboard_button = move_tl_object_as<telegram_api::keyboardButtonRequestPeer>(keyboard_button_ptr);
button.type = KeyboardButton::Type::RequestDialog;
button.text = std::move(keyboard_button->text_);
button.requested_dialog_type = td::make_unique<RequestedDialogType>(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<KeyboardButton> get_keyboard_button(tl_object_ptr<td_api::keyboard
current_button.url = std::move(button_type->url_);
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<td_api::keyboardButtonTypeRequestChat>(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<RequestedDialogType>(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<InlineKeyboardButton> get_inline_keyboard_button(tl_object_ptr<td_api::inlineKeyboardButton> &&button,
@ -618,7 +641,7 @@ static Result<InlineKeyboardButton> get_inline_keyboard_button(tl_object_ptr<td_
UNREACHABLE();
}
return current_button;
return std::move(current_button);
}
Result<unique_ptr<ReplyMarkup>> get_reply_markup(tl_object_ptr<td_api::ReplyMarkup> &&reply_markup_ptr, bool is_bot,
@ -667,7 +690,7 @@ Result<unique_ptr<ReplyMarkup>> get_reply_markup(tl_object_ptr<td_api::ReplyMark
}
}
if (!row_buttons.empty()) {
reply_markup->keyboard.push_back(row_buttons);
reply_markup->keyboard.push_back(std::move(row_buttons));
}
if (total_button_count >= 300) {
break;
@ -704,7 +727,7 @@ Result<unique_ptr<ReplyMarkup>> get_reply_markup(tl_object_ptr<td_api::ReplyMark
}
}
if (!row_buttons.empty()) {
reply_markup->inline_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<unique_ptr<ReplyMarkup>> get_reply_markup(tl_object_ptr<td_api::ReplyMark
return std::move(reply_markup);
}
unique_ptr<ReplyMarkup> dup_reply_markup(const unique_ptr<ReplyMarkup> &reply_markup) {
if (reply_markup == nullptr) {
return nullptr;
}
auto result = make_unique<ReplyMarkup>();
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<KeyboardButton> &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<RequestedDialogType>(*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<telegram_api::KeyboardButton> get_input_keyboard_button(const KeyboardButton &keyboard_button) {
switch (keyboard_button.type) {
case KeyboardButton::Type::Text:
@ -751,6 +799,10 @@ static tl_object_ptr<telegram_api::KeyboardButton> get_input_keyboard_button(con
return make_tl_object<telegram_api::keyboardButtonRequestPoll>(1, false, keyboard_button.text);
case KeyboardButton::Type::WebView:
return make_tl_object<telegram_api::keyboardButtonSimpleWebView>(keyboard_button.text, keyboard_button.url);
case KeyboardButton::Type::RequestDialog:
return make_tl_object<telegram_api::keyboardButtonRequestPeer>(
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<td_api::keyboardButton> get_keyboard_button_object(const Ke
case KeyboardButton::Type::WebView:
type = make_tl_object<td_api::keyboardButtonTypeWebApp>(keyboard_button.url);
break;
case KeyboardButton::Type::RequestDialog:
type = make_tl_object<td_api::keyboardButtonTypeRequestChat>(
keyboard_button.requested_dialog_type->get_requested_chat_type_object(), keyboard_button.button_id);
break;
default:
UNREACHABLE();
return nullptr;

View File

@ -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<RequestedDialogType> requested_dialog_type; // RequestDialog only
int32 button_id = 0; // RequestDialog only
};
struct InlineKeyboardButton {
@ -91,6 +95,8 @@ Result<unique_ptr<ReplyMarkup>> get_reply_markup(tl_object_ptr<td_api::ReplyMark
bool only_inline_keyboard, bool request_buttons_allowed,
bool switch_inline_buttons_allowed) TD_WARN_UNUSED_RESULT;
unique_ptr<ReplyMarkup> dup_reply_markup(const unique_ptr<ReplyMarkup> &reply_markup);
tl_object_ptr<telegram_api::ReplyMarkup> get_input_reply_markup(ContactsManager *contacts_manager,
const unique_ptr<ReplyMarkup> &reply_markup);

View File

@ -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 <class StorerT>
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 <class ParserT>
void parse(KeyboardButton &button, ParserT &parser) {
bool has_url;
bool has_requested_dialog_type;
bool has_button_id;
if (parser.version() >= static_cast<int32>(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 <class StorerT>
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();

View File

@ -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<td_api::RequestedChatType> &&chat_type) {
}
RequestedDialogType::RequestedDialogType(telegram_api::object_ptr<telegram_api::RequestPeerType> &&chat_type) {
}
td_api::object_ptr<td_api::RequestedChatType> RequestedDialogType::get_requested_chat_type_object() const {
return td_api::make_object<td_api::requestedChatTypePrivate>();
}
telegram_api::object_ptr<telegram_api::RequestPeerType> RequestedDialogType::get_input_request_peer_type_object()
const {
return telegram_api::make_object<telegram_api::requestPeerTypeUser>(0, false, false);
}
} // namespace td

View File

@ -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<td_api::RequestedChatType> &&chat_type);
explicit RequestedDialogType(telegram_api::object_ptr<telegram_api::RequestPeerType> &&peer_type);
td_api::object_ptr<td_api::RequestedChatType> get_requested_chat_type_object() const;
telegram_api::object_ptr<telegram_api::RequestPeerType> get_input_request_peer_type_object() const;
template <class StorerT>
void store(StorerT &storer) const;
template <class ParserT>
void parse(ParserT &parser);
};
} // namespace td

View File

@ -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 <class StorerT>
void RequestedDialogType::store(StorerT &storer) const {
BEGIN_STORE_FLAGS();
END_STORE_FLAGS();
}
template <class ParserT>
void RequestedDialogType::parse(ParserT &parser) {
BEGIN_PARSE_FLAGS();
END_PARSE_FLAGS();
}
} // namespace td