Add inlineKeyboardButtonTypeUser.
This commit is contained in:
parent
6ace4fdf36
commit
ae987f2211
@ -1070,6 +1070,9 @@ inlineKeyboardButtonTypeSwitchInline query:string in_current_chat:Bool = InlineK
|
||||
//@description A button to buy something. This button must be in the first column and row of the keyboard and can be attached only to a message with content of the type messageInvoice
|
||||
inlineKeyboardButtonTypeBuy = InlineKeyboardButtonType;
|
||||
|
||||
//@description A button to open a chat with a user @user_id User identifier
|
||||
inlineKeyboardButtonTypeUser user_id:int53 = InlineKeyboardButtonType;
|
||||
|
||||
|
||||
//@description Represents a single button in an inline keyboard @text Text of the button @type Type of the button
|
||||
inlineKeyboardButton text:string type:InlineKeyboardButtonType = InlineKeyboardButton;
|
||||
|
@ -23833,6 +23833,7 @@ void MessagesManager::add_message_dependencies(Dependencies &dependencies, const
|
||||
add_message_sender_dependencies(dependencies, recent_replier_dialog_id);
|
||||
}
|
||||
add_message_content_dependencies(dependencies, m->content.get());
|
||||
add_reply_markup_dependencies(dependencies, m->reply_markup.get());
|
||||
}
|
||||
|
||||
class MessagesManager::SendMessageLogEvent {
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "td/telegram/ReplyMarkup.h"
|
||||
|
||||
#include "td/telegram/ContactsManager.h"
|
||||
#include "td/telegram/Dependencies.h"
|
||||
#include "td/telegram/Global.h"
|
||||
#include "td/telegram/LinkManager.h"
|
||||
#include "td/telegram/misc.h"
|
||||
@ -90,6 +91,9 @@ static StringBuilder &operator<<(StringBuilder &string_builder, const InlineKeyb
|
||||
case InlineKeyboardButton::Type::CallbackWithPassword:
|
||||
string_builder << "CallbackWithPassword";
|
||||
break;
|
||||
case InlineKeyboardButton::Type::User:
|
||||
string_builder << "User " << keyboard_button.user_id.get();
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -264,9 +268,14 @@ static InlineKeyboardButton get_inline_keyboard_button(
|
||||
button.id = keyboard_button->button_id_;
|
||||
button.text = std::move(keyboard_button->text_);
|
||||
button.data = std::move(keyboard_button->url_);
|
||||
if ((keyboard_button->flags_ & telegram_api::keyboardButtonUrlAuth::FWD_TEXT_MASK) != 0) {
|
||||
button.forward_text = std::move(keyboard_button->fwd_text_);
|
||||
}
|
||||
button.forward_text = std::move(keyboard_button->fwd_text_);
|
||||
break;
|
||||
}
|
||||
case telegram_api::keyboardButtonUserProfile::ID: {
|
||||
auto keyboard_button = move_tl_object_as<telegram_api::keyboardButtonUserProfile>(keyboard_button_ptr);
|
||||
button.type = InlineKeyboardButton::Type::User;
|
||||
button.text = std::move(keyboard_button->text_);
|
||||
button.user_id = UserId(keyboard_button->user_id_);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -434,42 +443,42 @@ static Result<InlineKeyboardButton> get_inline_keyboard_button(tl_object_ptr<td_
|
||||
int32 button_type_id = button->type_->get_id();
|
||||
switch (button_type_id) {
|
||||
case td_api::inlineKeyboardButtonTypeUrl::ID: {
|
||||
current_button.type = InlineKeyboardButton::Type::Url;
|
||||
auto r_url =
|
||||
LinkManager::check_link(static_cast<const td_api::inlineKeyboardButtonTypeUrl *>(button->type_.get())->url_);
|
||||
auto button_type = move_tl_object_as<td_api::inlineKeyboardButtonTypeUrl>(button->type_);
|
||||
auto r_url = LinkManager::check_link(button_type->url_);
|
||||
if (r_url.is_error()) {
|
||||
return Status::Error(400, "Inline keyboard button URL is invalid");
|
||||
}
|
||||
current_button.type = InlineKeyboardButton::Type::Url;
|
||||
current_button.data = r_url.move_as_ok();
|
||||
if (!clean_input_string(current_button.data)) {
|
||||
return Status::Error(400, "Inline keyboard button URL must be encoded in UTF-8");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case td_api::inlineKeyboardButtonTypeCallback::ID:
|
||||
case td_api::inlineKeyboardButtonTypeCallback::ID: {
|
||||
auto button_type = move_tl_object_as<td_api::inlineKeyboardButtonTypeCallback>(button->type_);
|
||||
current_button.type = InlineKeyboardButton::Type::Callback;
|
||||
current_button.data =
|
||||
std::move(static_cast<td_api::inlineKeyboardButtonTypeCallback *>(button->type_.get())->data_);
|
||||
current_button.data = std::move(button_type->data_);
|
||||
break;
|
||||
}
|
||||
case td_api::inlineKeyboardButtonTypeCallbackGame::ID:
|
||||
current_button.type = InlineKeyboardButton::Type::CallbackGame;
|
||||
break;
|
||||
case td_api::inlineKeyboardButtonTypeCallbackWithPassword::ID:
|
||||
return Status::Error(400, "Can't use CallbackWithPassword inline button");
|
||||
case td_api::inlineKeyboardButtonTypeSwitchInline::ID: {
|
||||
auto switch_inline_button = move_tl_object_as<td_api::inlineKeyboardButtonTypeSwitchInline>(button->type_);
|
||||
auto button_type = move_tl_object_as<td_api::inlineKeyboardButtonTypeSwitchInline>(button->type_);
|
||||
if (!switch_inline_buttons_allowed) {
|
||||
const char *button_name =
|
||||
switch_inline_button->in_current_chat_ ? "switch_inline_query_current_chat" : "switch_inline_query";
|
||||
button_type->in_current_chat_ ? "switch_inline_query_current_chat" : "switch_inline_query";
|
||||
return Status::Error(400, PSLICE() << "Can't use " << button_name
|
||||
<< " in a channel chat, because a user will not be able to use the button "
|
||||
"without knowing bot's username");
|
||||
}
|
||||
|
||||
current_button.type = switch_inline_button->in_current_chat_
|
||||
? InlineKeyboardButton::Type::SwitchInlineCurrentDialog
|
||||
: InlineKeyboardButton::Type::SwitchInline;
|
||||
current_button.data = std::move(switch_inline_button->query_);
|
||||
current_button.type = button_type->in_current_chat_ ? InlineKeyboardButton::Type::SwitchInlineCurrentDialog
|
||||
: InlineKeyboardButton::Type::SwitchInline;
|
||||
current_button.data = std::move(button_type->query_);
|
||||
if (!clean_input_string(current_button.data)) {
|
||||
return Status::Error(400, "Inline keyboard button switch inline query must be encoded in UTF-8");
|
||||
}
|
||||
@ -479,26 +488,36 @@ static Result<InlineKeyboardButton> get_inline_keyboard_button(tl_object_ptr<td_
|
||||
current_button.type = InlineKeyboardButton::Type::Buy;
|
||||
break;
|
||||
case td_api::inlineKeyboardButtonTypeLoginUrl::ID: {
|
||||
current_button.type = InlineKeyboardButton::Type::UrlAuth;
|
||||
auto login_url = td_api::move_object_as<td_api::inlineKeyboardButtonTypeLoginUrl>(button->type_);
|
||||
auto r_url = LinkManager::check_link(login_url->url_);
|
||||
auto button_type = td_api::move_object_as<td_api::inlineKeyboardButtonTypeLoginUrl>(button->type_);
|
||||
auto r_url = LinkManager::check_link(button_type->url_);
|
||||
if (r_url.is_error()) {
|
||||
return Status::Error(400, "Inline keyboard button login URL is invalid");
|
||||
}
|
||||
current_button.type = InlineKeyboardButton::Type::UrlAuth;
|
||||
current_button.data = r_url.move_as_ok();
|
||||
current_button.forward_text = std::move(login_url->forward_text_);
|
||||
current_button.forward_text = std::move(button_type->forward_text_);
|
||||
if (!clean_input_string(current_button.data)) {
|
||||
return Status::Error(400, "Inline keyboard button login URL must be encoded in UTF-8");
|
||||
}
|
||||
if (!clean_input_string(current_button.forward_text)) {
|
||||
return Status::Error(400, "Inline keyboard button forward text must be encoded in UTF-8");
|
||||
}
|
||||
current_button.id = login_url->id_;
|
||||
if (current_button.id == 0 || current_button.id == std::numeric_limits<int64>::min()) {
|
||||
current_button.id = button_type->id_;
|
||||
if (current_button.id == std::numeric_limits<int64>::min() ||
|
||||
!UserId(current_button.id >= 0 ? current_button.id : -current_button.id).is_valid()) {
|
||||
return Status::Error(400, "Invalid bot_user_id specified");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case td_api::inlineKeyboardButtonTypeUser::ID: {
|
||||
auto button_type = td_api::move_object_as<td_api::inlineKeyboardButtonTypeUser>(button->type_);
|
||||
current_button.type = InlineKeyboardButton::Type::User;
|
||||
current_button.user_id = UserId(button_type->user_id_);
|
||||
if (!current_button.user_id.is_valid()) {
|
||||
return Status::Error(400, "Invalid user_id specified");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -683,6 +702,14 @@ static tl_object_ptr<telegram_api::KeyboardButton> get_inline_keyboard_button(
|
||||
case InlineKeyboardButton::Type::CallbackWithPassword:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
case InlineKeyboardButton::Type::User: {
|
||||
auto input_user = G()->td().get_actor_unsafe()->contacts_manager_->get_input_user(keyboard_button.user_id);
|
||||
if (input_user == nullptr) {
|
||||
LOG(ERROR) << "Failed to get InputUser for " << keyboard_button.user_id;
|
||||
input_user = make_tl_object<telegram_api::inputUserEmpty>();
|
||||
}
|
||||
return make_tl_object<telegram_api::inputKeyboardButtonUserProfile>(keyboard_button.text, std::move(input_user));
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
@ -796,6 +823,11 @@ static tl_object_ptr<td_api::inlineKeyboardButton> get_inline_keyboard_button_ob
|
||||
case InlineKeyboardButton::Type::CallbackWithPassword:
|
||||
type = make_tl_object<td_api::inlineKeyboardButtonTypeCallbackWithPassword>(keyboard_button.data);
|
||||
break;
|
||||
case InlineKeyboardButton::Type::User:
|
||||
type = make_tl_object<td_api::inlineKeyboardButtonTypeUser>(
|
||||
G()->td().get_actor_unsafe()->contacts_manager_->get_user_id_object(keyboard_button.user_id,
|
||||
"get_inline_keyboard_button_object"));
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
@ -860,4 +892,17 @@ tl_object_ptr<td_api::ReplyMarkup> get_reply_markup_object(const unique_ptr<Repl
|
||||
return reply_markup->get_reply_markup_object();
|
||||
}
|
||||
|
||||
void add_reply_markup_dependencies(Dependencies &dependencies, const ReplyMarkup *reply_markup) {
|
||||
if (reply_markup == nullptr) {
|
||||
return;
|
||||
}
|
||||
for (auto &row : reply_markup->inline_keyboard) {
|
||||
for (auto &button : row) {
|
||||
if (button.user_id.is_valid()) {
|
||||
dependencies.user_ids.insert(button.user_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "td/telegram/td_api.h"
|
||||
#include "td/telegram/telegram_api.h"
|
||||
#include "td/telegram/UserId.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/Status.h"
|
||||
@ -15,6 +16,8 @@
|
||||
|
||||
namespace td {
|
||||
|
||||
struct Dependencies;
|
||||
|
||||
struct KeyboardButton {
|
||||
// append only
|
||||
enum class Type : int32 {
|
||||
@ -39,10 +42,12 @@ struct InlineKeyboardButton {
|
||||
SwitchInlineCurrentDialog,
|
||||
Buy,
|
||||
UrlAuth,
|
||||
CallbackWithPassword
|
||||
CallbackWithPassword,
|
||||
User
|
||||
};
|
||||
Type type;
|
||||
int64 id = 0; // UrlAuth only, button_id or (2 * request_write_access - 1) * bot_user_id
|
||||
int64 id = 0; // UrlAuth only, button_id or (2 * request_write_access - 1) * bot_user_id
|
||||
UserId user_id; // User only
|
||||
string text;
|
||||
string forward_text; // UrlAuth only
|
||||
string data;
|
||||
@ -85,4 +90,6 @@ tl_object_ptr<telegram_api::ReplyMarkup> get_input_reply_markup(const unique_ptr
|
||||
|
||||
tl_object_ptr<td_api::ReplyMarkup> get_reply_markup_object(const unique_ptr<ReplyMarkup> &reply_markup);
|
||||
|
||||
void add_reply_markup_dependencies(Dependencies &dependencies, const ReplyMarkup *reply_markup);
|
||||
|
||||
} // namespace td
|
||||
|
@ -15,40 +15,91 @@ namespace td {
|
||||
|
||||
template <class StorerT>
|
||||
void store(KeyboardButton button, StorerT &storer) {
|
||||
BEGIN_STORE_FLAGS();
|
||||
END_STORE_FLAGS();
|
||||
store(button.type, storer);
|
||||
store(button.text, storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void parse(KeyboardButton &button, ParserT &parser) {
|
||||
if (parser.version() >= static_cast<int32>(Version::AddKeyboardButtonFlags)) {
|
||||
BEGIN_PARSE_FLAGS();
|
||||
END_PARSE_FLAGS();
|
||||
}
|
||||
parse(button.type, parser);
|
||||
parse(button.text, parser);
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void store(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();
|
||||
bool has_data = !button.data.empty();
|
||||
BEGIN_STORE_FLAGS();
|
||||
STORE_FLAG(has_id);
|
||||
STORE_FLAG(has_user_id);
|
||||
STORE_FLAG(has_forward_text);
|
||||
STORE_FLAG(has_data);
|
||||
END_STORE_FLAGS();
|
||||
store(button.type, storer);
|
||||
if (button.type == InlineKeyboardButton::Type::UrlAuth) {
|
||||
if (has_id) {
|
||||
store(button.id, storer);
|
||||
}
|
||||
if (has_user_id) {
|
||||
store(button.user_id, storer);
|
||||
}
|
||||
store(button.text, storer);
|
||||
store(button.data, storer);
|
||||
if (has_forward_text) {
|
||||
store(button.forward_text, storer);
|
||||
}
|
||||
if (has_data) {
|
||||
store(button.data, storer);
|
||||
}
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void parse(InlineKeyboardButton &button, ParserT &parser) {
|
||||
parse(button.type, parser);
|
||||
if (button.type == InlineKeyboardButton::Type::UrlAuth) {
|
||||
if (parser.version() >= static_cast<int32>(Version::Support64BitIds)) {
|
||||
if (parser.version() >= static_cast<int32>(Version::AddKeyboardButtonFlags)) {
|
||||
bool has_id;
|
||||
bool has_user_id;
|
||||
bool has_forward_text;
|
||||
bool has_data;
|
||||
BEGIN_PARSE_FLAGS();
|
||||
PARSE_FLAG(has_id);
|
||||
PARSE_FLAG(has_user_id);
|
||||
PARSE_FLAG(has_forward_text);
|
||||
PARSE_FLAG(has_data);
|
||||
END_PARSE_FLAGS();
|
||||
parse(button.type, parser);
|
||||
if (has_id) {
|
||||
parse(button.id, parser);
|
||||
} else {
|
||||
int32 old_id;
|
||||
parse(old_id, parser);
|
||||
button.id = old_id;
|
||||
}
|
||||
if (has_user_id) {
|
||||
parse(button.user_id, parser);
|
||||
}
|
||||
parse(button.text, parser);
|
||||
if (has_forward_text) {
|
||||
parse(button.forward_text, parser);
|
||||
}
|
||||
if (has_data) {
|
||||
parse(button.data, parser);
|
||||
}
|
||||
} else {
|
||||
parse(button.type, parser);
|
||||
if (button.type == InlineKeyboardButton::Type::UrlAuth) {
|
||||
if (parser.version() >= static_cast<int32>(Version::Support64BitIds)) {
|
||||
parse(button.id, parser);
|
||||
} else {
|
||||
int32 old_id;
|
||||
parse(old_id, parser);
|
||||
button.id = old_id;
|
||||
}
|
||||
}
|
||||
parse(button.text, parser);
|
||||
parse(button.data, parser);
|
||||
}
|
||||
parse(button.text, parser);
|
||||
parse(button.data, parser);
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
|
@ -536,6 +536,24 @@ bool UpdatesManager::is_acceptable_message_entities(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UpdatesManager::is_acceptable_reply_markup(const tl_object_ptr<telegram_api::ReplyMarkup> &reply_markup) const {
|
||||
if (reply_markup == nullptr || reply_markup->get_id() != telegram_api::replyInlineMarkup::ID) {
|
||||
return true;
|
||||
}
|
||||
for (const auto &row : static_cast<const telegram_api::replyInlineMarkup *>(reply_markup.get())->rows_) {
|
||||
for (const auto &button : row->buttons_) {
|
||||
if (button->get_id() == telegram_api::keyboardButtonUserProfile::ID) {
|
||||
auto user_profile_button = static_cast<const telegram_api::keyboardButtonUserProfile *>(button.get());
|
||||
UserId user_id(user_profile_button->user_id_);
|
||||
if (!is_acceptable_user(user_id) || !td_->contacts_manager_->have_input_user(user_id)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UpdatesManager::is_acceptable_message_reply_header(
|
||||
const telegram_api::object_ptr<telegram_api::messageReplyHeader> &header) const {
|
||||
if (header == nullptr) {
|
||||
|
@ -356,6 +356,8 @@ class UpdatesManager final : public Actor {
|
||||
|
||||
bool is_acceptable_message_entities(const vector<tl_object_ptr<telegram_api::MessageEntity>> &message_entities) const;
|
||||
|
||||
bool is_acceptable_reply_markup(const tl_object_ptr<telegram_api::ReplyMarkup> &reply_markup) const;
|
||||
|
||||
bool is_acceptable_message_reply_header(
|
||||
const telegram_api::object_ptr<telegram_api::messageReplyHeader> &header) const;
|
||||
|
||||
|
@ -48,6 +48,7 @@ enum class Version : int32 {
|
||||
RemovePhotoVolumeAndLocalId,
|
||||
Support64BitIds,
|
||||
AddInviteLinksRequiringApproval,
|
||||
AddKeyboardButtonFlags, // 35
|
||||
Next
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user