aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--build.html10
m---------td0
-rw-r--r--telegram-bot-api/Client.cpp1417
-rw-r--r--telegram-bot-api/Client.h156
-rw-r--r--telegram-bot-api/telegram-bot-api.cpp2
6 files changed, 1038 insertions, 549 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9bed12b..6cd450d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
-project(TelegramBotApi VERSION 10.1 LANGUAGES CXX)
+project(TelegramBotApi VERSION 10.2 LANGUAGES CXX)
add_subdirectory(td EXCLUDE_FROM_ALL)
diff --git a/build.html b/build.html
index 1b0fdeb..a971488 100644
--- a/build.html
+++ b/build.html
@@ -208,6 +208,7 @@
<option>Ubuntu 20</option>
<option>Ubuntu 22</option>
<option>Ubuntu 24</option>
+ <option>Ubuntu 26</option>
<option>Other</option>
</select>
<p></p>
@@ -496,6 +497,8 @@ function onOptionsChanged() {
return '-14';
case 'Ubuntu 24':
return '-18';
+ case 'Ubuntu 26':
+ return '-21';
default:
return ''; // use default version
}
@@ -506,6 +509,7 @@ function onOptionsChanged() {
case 'Ubuntu 20':
case 'Ubuntu 22':
case 'Ubuntu 24':
+ case 'Ubuntu 26':
return getClangVersionSuffix();
default:
return ''; // use default version
@@ -556,6 +560,7 @@ function onOptionsChanged() {
case 'Ubuntu 20':
case 'Ubuntu 22':
case 'Ubuntu 24':
+ case 'Ubuntu 26':
if (linux_distro.includes('Debian') && !use_root) {
commands.push('su -');
}
@@ -563,10 +568,7 @@ function onOptionsChanged() {
commands.push(sudo + 'apt-get upgrade');
var packages = 'make git zlib1g-dev libssl-dev gperf cmake';
if (use_clang) {
- packages += ' clang' + getClangVersionSuffix() + ' libc++' + getLibcplusplusVersionSuffix() + '-dev';
- if (linux_distro === 'Debian 10+' || linux_distro === 'Ubuntu 18' || linux_distro === 'Ubuntu 20' || linux_distro === 'Ubuntu 22' || linux_distro === 'Ubuntu 24') {
- packages += ' libc++abi' + getLibcplusplusVersionSuffix() + '-dev';
- }
+ packages += ' clang' + getClangVersionSuffix() + ' libc++' + getLibcplusplusVersionSuffix() + '-dev libc++abi' + getLibcplusplusVersionSuffix() + '-dev';
} else {
packages += ' g++';
}
diff --git a/td b/td
-Subproject a8f21f5230172634becc1739050ef23ecd6ea29
+Subproject a9966eb3704a3351568c28013fed67d797c1782
diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp
index 068a505..0d16d48 100644
--- a/telegram-bot-api/Client.cpp
+++ b/telegram-bot-api/Client.cpp
@@ -54,7 +54,7 @@ Client::Client(td::ActorShared<> parent, const td::string &bot_token, bool is_te
Client::~Client() {
td::Scheduler::instance()->destroy_on_scheduler(SharedData::get_file_gc_scheduler_id(), messages_, users_, groups_,
- supergroups_, chats_, sticker_set_names_);
+ supergroups_, chats_, communities_, sticker_set_names_);
}
int Client::get_retry_after_time(td::Slice error_message) {
@@ -269,8 +269,13 @@ bool Client::init_methods() {
methods_.emplace("editmessagecaption", &Client::process_edit_message_caption_query);
methods_.emplace("editmessagechecklist", &Client::process_edit_message_checklist_query);
methods_.emplace("editmessagereplymarkup", &Client::process_edit_message_reply_markup_query);
+ methods_.emplace("editephemeralmessagetext", &Client::process_edit_ephemeral_message_text_query);
+ methods_.emplace("editephemeralmessagemedia", &Client::process_edit_ephemeral_message_media_query);
+ methods_.emplace("editephemeralmessagecaption", &Client::process_edit_ephemeral_message_caption_query);
+ methods_.emplace("editephemeralmessagereplymarkup", &Client::process_edit_ephemeral_message_reply_markup_query);
methods_.emplace("deletemessage", &Client::process_delete_message_query);
methods_.emplace("deletemessages", &Client::process_delete_messages_query);
+ methods_.emplace("deleteephemeralmessage", &Client::process_delete_ephemeral_message_query);
methods_.emplace("deletemessagereaction", &Client::process_delete_message_reaction_query);
methods_.emplace("deleteallmessagereactions", &Client::process_delete_all_message_reactions_query);
methods_.emplace("poststory", &Client::process_post_story_query);
@@ -460,6 +465,23 @@ class Client::JsonDatedFiles final : public td::Jsonable {
const Client *client_;
};
+class Client::JsonCommunity final : public td::Jsonable {
+ public:
+ JsonCommunity(int64 community_id, const Client *client) : community_id_(community_id), client_(client) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ auto community_info = client_->get_community_info(community_id_);
+ CHECK(community_info != nullptr);
+ object("id", community_id_);
+ object("name", community_info->name);
+ }
+
+ private:
+ int64 community_id_;
+ const Client *client_;
+};
+
class Client::JsonUser final : public td::Jsonable {
public:
JsonUser(int64 user_id, const Client *client, bool full_bot_info = false)
@@ -684,8 +706,8 @@ class Client::JsonRichText final : public td::Jsonable {
*scope << td::JsonString(text->text_);
return;
}
- if (text_id == td_api::richTextIcon::ID) {
- LOG(ERROR) << "Receive richTextIcon";
+ if (text_id == td_api::richTextIcon::ID || text_id == td_api::richTextDiff::ID) {
+ LOG(ERROR) << "Receive " << to_string(*text_);
*scope << td::JsonString(td::Slice());
return;
}
@@ -1579,6 +1601,9 @@ class Client::JsonChat final : public td::Jsonable {
if (user_info->personal_chat_id != 0) {
object("personal_chat", JsonChat(user_info->personal_chat_id, client_));
}
+ if (user_info->community_id != 0) {
+ object("community", JsonCommunity(user_info->community_id, client_));
+ }
if (user_info->rating != nullptr) {
object("rating", JsonUserRating(user_info->rating.get()));
}
@@ -1588,19 +1613,25 @@ class Client::JsonChat final : public td::Jsonable {
if (user_info->paid_message_star_count > 0) {
object("paid_message_star_count", user_info->paid_message_star_count);
}
+ photo = user_info->photo.get();
}
- photo = user_info->photo.get();
break;
}
case ChatInfo::Type::Group: {
object("title", chat_info->title);
object("type", "group");
-
const auto *permissions = chat_info->permissions.get();
-
- auto group_info = client_->get_group_info(chat_info->group_id);
- CHECK(group_info != nullptr);
+ auto everyone_is_administrator =
+ permissions->can_send_basic_messages_ && permissions->can_send_audios_ &&
+ permissions->can_send_documents_ && permissions->can_send_photos_ && permissions->can_send_videos_ &&
+ permissions->can_send_video_notes_ && permissions->can_send_voice_notes_ && permissions->can_send_polls_ &&
+ permissions->can_send_other_messages_ && permissions->can_add_link_previews_ &&
+ permissions->can_react_to_messages_ && permissions->can_edit_tag_ && permissions->can_change_info_ &&
+ permissions->can_invite_users_ && permissions->can_pin_messages_;
+ object("all_members_are_administrators", td::JsonBool(everyone_is_administrator));
if (is_full_) {
+ auto group_info = client_->get_group_info(chat_info->group_id);
+ CHECK(group_info != nullptr);
if (!group_info->description.empty()) {
object("description", group_info->description);
}
@@ -1608,17 +1639,9 @@ class Client::JsonChat final : public td::Jsonable {
object("invite_link", group_info->invite_link);
}
object("permissions", JsonChatPermissions(permissions));
+ object("accepted_gift_types", JsonAcceptedGiftTypes(false, false, false, false, false));
+ photo = group_info->photo.get();
}
- auto everyone_is_administrator =
- permissions->can_send_basic_messages_ && permissions->can_send_audios_ &&
- permissions->can_send_documents_ && permissions->can_send_photos_ && permissions->can_send_videos_ &&
- permissions->can_send_video_notes_ && permissions->can_send_voice_notes_ && permissions->can_send_polls_ &&
- permissions->can_send_other_messages_ && permissions->can_add_link_previews_ &&
- permissions->can_react_to_messages_ && permissions->can_edit_tag_ && permissions->can_change_info_ &&
- permissions->can_invite_users_ && permissions->can_pin_messages_;
- object("all_members_are_administrators", td::JsonBool(everyone_is_administrator));
- object("accepted_gift_types", JsonAcceptedGiftTypes(false, false, false, false, false));
- photo = group_info->photo.get();
break;
}
case ChatInfo::Type::Supergroup: {
@@ -1705,6 +1728,9 @@ class Client::JsonChat final : public td::Jsonable {
if (supergroup_info->guard_bot_user_id != 0) {
object("guard_bot", JsonUser(supergroup_info->guard_bot_user_id, client_));
}
+ if (supergroup_info->community_id != 0) {
+ object("community", JsonCommunity(supergroup_info->community_id, client_));
+ }
if (supergroup_info->location != nullptr) {
object("location", JsonChatLocation(supergroup_info->location.get()));
}
@@ -1718,8 +1744,8 @@ class Client::JsonChat final : public td::Jsonable {
if (supergroup_info->paid_message_star_count) {
object("paid_message_star_count", supergroup_info->paid_message_star_count);
}
+ photo = supergroup_info->photo.get();
}
- photo = supergroup_info->photo.get();
break;
}
case ChatInfo::Type::Unknown:
@@ -2004,11 +2030,10 @@ class Client::JsonSuggestedPostPrice final : public td::Jsonable {
object("currency", "XTR");
object("amount", static_cast<const td_api::suggestedPostPriceStar *>(suggested_post_price_)->star_count_);
break;
- case td_api::suggestedPostPriceTon::ID:
+ case td_api::suggestedPostPriceGram::ID:
object("currency", "TON");
- object(
- "amount",
- static_cast<const td_api::suggestedPostPriceTon *>(suggested_post_price_)->toncoin_cent_count_ * 10000000);
+ object("amount",
+ static_cast<const td_api::suggestedPostPriceGram *>(suggested_post_price_)->gram_cent_count_ * 10000000);
break;
default:
UNREACHABLE();
@@ -3067,7 +3092,7 @@ class Client::JsonSuggestedPostPaid final : public td::Jsonable {
object("star_amount", JsonStarAmount(suggested_post_paid_->star_amount_.get()));
} else {
object("currency", "TON");
- object("amount", suggested_post_paid_->ton_amount_);
+ object("amount", suggested_post_paid_->gram_amount_);
}
}
@@ -3534,10 +3559,10 @@ class Client::JsonUniqueGiftMessage final : public td::Jsonable {
object("last_resale_amount", price->star_count_);
break;
}
- case td_api::giftResalePriceTon::ID: {
- auto price = static_cast<const td_api::giftResalePriceTon *>(origin->price_.get());
+ case td_api::giftResalePriceGram::ID: {
+ auto price = static_cast<const td_api::giftResalePriceGram *>(origin->price_.get());
object("last_resale_currency", "TON");
- object("last_resale_amount", price->toncoin_cent_count_ * 10000000);
+ object("last_resale_amount", price->gram_cent_count_ * 10000000);
break;
}
default:
@@ -3904,6 +3929,46 @@ class Client::JsonManagedBotUpdated final : public td::Jsonable {
const Client *client_;
};
+class Client::JsonBotSubscriptionUpdated final : public td::Jsonable {
+ public:
+ JsonBotSubscriptionUpdated(const td_api::updateUserSubscription *update_user_subscription, const Client *client)
+ : update_user_subscription_(update_user_subscription), client_(client) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ object("user", JsonUser(update_user_subscription_->user_id_, client_));
+ object("invoice_payload", update_user_subscription_->payload_);
+ if (update_user_subscription_->is_canceled_) {
+ object("state", "canceled");
+ } else if (update_user_subscription_->is_restored_) {
+ object("state", "active");
+ } else if (update_user_subscription_->is_payment_failed_) {
+ object("state", "failed");
+ } else {
+ UNREACHABLE();
+ }
+ }
+
+ private:
+ const td_api::updateUserSubscription *update_user_subscription_;
+ const Client *client_;
+};
+
+class Client::JsonCommunityChatAdded final : public td::Jsonable {
+ public:
+ JsonCommunityChatAdded(const td_api::messageChatAddedToCommunity *chat_added_to_community, const Client *client)
+ : chat_added_to_community_(chat_added_to_community), client_(client) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ object("community", JsonCommunity(chat_added_to_community_->community_id_, client_));
+ }
+
+ private:
+ const td_api::messageChatAddedToCommunity *chat_added_to_community_;
+ const Client *client_;
+};
+
class Client::JsonGiveawayCreated final : public td::Jsonable {
public:
explicit JsonGiveawayCreated(const td_api::messageGiveawayCreated *giveaway_created)
@@ -4676,7 +4741,10 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const {
object("sender_business_bot", JsonUser(message_->sender_business_bot_user_id, client_));
}
}
- object("message_id", message_->is_scheduled ? 0 : as_client_message_id(message_->id));
+ object("message_id", as_client_message_id_unchecked(message_->id));
+ if (message_->ephemeral_message_id != 0) {
+ object("ephemeral_message_id", message_->ephemeral_message_id);
+ }
if (message_->sender_user_id != 0) {
object("from", JsonUser(message_->sender_user_id, client_));
}
@@ -4695,6 +4763,9 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const {
if (forum_topic_id != 0) {
object("message_thread_id", forum_topic_id);
}
+ if (message_->receiver_id != nullptr) {
+ client_->json_store_message_sender(object, message_->receiver_id, "receiver_user", "receiver_chat");
+ }
if (message_->initial_send_date > 0) {
CHECK(message_->forward_origin != nullptr);
object("forward_origin", JsonMessageOrigin(message_->forward_origin.get(), message_->initial_send_date, client_));
@@ -5285,6 +5356,14 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const {
object("rich_message", JsonRichMessage(content->message_.get(), client_));
break;
}
+ case td_api::messageChatAddedToCommunity::ID: {
+ auto content = static_cast<const td_api::messageChatAddedToCommunity *>(message_->content.get());
+ object("community_chat_added", JsonCommunityChatAdded(content, client_));
+ break;
+ }
+ case td_api::messageChatRemovedFromCommunity::ID:
+ object("community_chat_removed", JsonEmptyObject());
+ break;
default:
UNREACHABLE();
}
@@ -5612,6 +5691,9 @@ class Client::JsonBotCommand final : public td::Jsonable {
auto object = scope->enter_object();
object("command", command_->command_);
object("description", command_->description_);
+ if (command_->is_ephemeral_) {
+ object("is_ephemeral", td::JsonTrue());
+ }
}
private:
@@ -6504,7 +6586,7 @@ class Client::JsonStarTransactions final : public td::Jsonable {
class Client::JsonUpdateTypes final : public td::Jsonable {
public:
- explicit JsonUpdateTypes(td::uint32 update_types) : update_types_(update_types) {
+ explicit JsonUpdateTypes(td::uint64 update_types) : update_types_(update_types) {
}
void store(td::JsonValueScope *scope) const {
auto array = scope->enter_array();
@@ -6519,7 +6601,7 @@ class Client::JsonUpdateTypes final : public td::Jsonable {
}
private:
- td::uint32 update_types_;
+ td::uint64 update_types_;
};
class Client::JsonWebhookInfo final : public td::Jsonable {
@@ -9060,6 +9142,11 @@ void Client::check_reply_parameters(td::Slice chat_id_str, InputReplyParameters
chat_id_str, forum_topic_id, direct_messages_topic_id, std::move(query),
[this, reply_parameters = std::move(reply_parameters), on_success = std::move(on_success)](
int64 chat_id, object_ptr<td_api::MessageTopic> &&topic_id, PromisedQueryPtr query) mutable {
+ if (reply_parameters.reply_to_ephemeral_message_id > 0) {
+ CheckedReplyParameters checked_reply_parameters;
+ checked_reply_parameters.reply_to_ephemeral_message_id = reply_parameters.reply_to_ephemeral_message_id;
+ return on_success(chat_id, std::move(topic_id), std::move(checked_reply_parameters), std::move(query));
+ }
auto on_reply_message_resolved =
[this, chat_id, topic_id = std::move(topic_id), quote = std::move(reply_parameters.quote),
checklist_task_id = reply_parameters.checklist_task_id,
@@ -9622,6 +9709,7 @@ void Client::on_update(object_ptr<td_api::Object> result) {
user_info->personal_chat_id = full_info->personal_chat_id_;
user_info->has_private_forwards = full_info->has_private_forwards_;
user_info->has_restricted_voice_and_video_messages = full_info->has_restricted_voice_and_video_note_messages_;
+ user_info->community_id = full_info->community_id_;
break;
}
case td_api::updateBasicGroup::ID: {
@@ -9647,6 +9735,12 @@ void Client::on_update(object_ptr<td_api::Object> result) {
add_supergroup(supergroup_info, std::move(update->supergroup_));
break;
}
+ case td_api::updateCommunity::ID: {
+ auto update = move_object_as<td_api::updateCommunity>(result);
+ auto *community_info = add_community_info(update->community_->id_);
+ add_community(community_info, std::move(update->community_));
+ break;
+ }
case td_api::updateSupergroupFullInfo::ID: {
auto update = move_object_as<td_api::updateSupergroupFullInfo>(result);
auto supergroup_id = update->supergroup_id_;
@@ -9666,6 +9760,7 @@ void Client::on_update(object_ptr<td_api::Object> result) {
supergroup_info->linked_chat_id = full_info->linked_chat_id_;
supergroup_info->direct_messages_chat_id = full_info->direct_messages_chat_id_;
supergroup_info->guard_bot_user_id = full_info->guard_bot_user_id_;
+ supergroup_info->community_id = full_info->community_id_;
supergroup_info->location = std::move(full_info->location_);
supergroup_info->has_hidden_members = full_info->has_hidden_members_;
supergroup_info->has_aggressive_anti_spam_enabled = full_info->has_aggressive_anti_spam_enabled_;
@@ -9709,7 +9804,7 @@ void Client::on_update(object_ptr<td_api::Object> result) {
} else {
CHECK(update->value_->get_id() == td_api::optionValueInteger::ID);
allowed_update_types_ =
- static_cast<td::uint32>(move_object_as<td_api::optionValueInteger>(update->value_)->value_);
+ static_cast<td::uint64>(move_object_as<td_api::optionValueInteger>(update->value_)->value_);
}
}
if (name == "unix_time" && update->value_->get_id() != td_api::optionValueEmpty::ID) {
@@ -9761,6 +9856,9 @@ void Client::on_update(object_ptr<td_api::Object> result) {
case td_api::updateManagedBot::ID:
add_update_managed_bot(move_object_as<td_api::updateManagedBot>(result));
break;
+ case td_api::updateUserSubscription::ID:
+ add_update_subscription(move_object_as<td_api::updateUserSubscription>(result));
+ break;
case td_api::updateNewCustomEvent::ID:
add_new_custom_event(move_object_as<td_api::updateNewCustomEvent>(result));
break;
@@ -9941,8 +10039,56 @@ bool Client::to_bool(td::MutableSlice value) {
return value == "true" || value == "yes" || value == "1";
}
+template <class T>
+td::Result<td::vector<T>> Client::get_array(td::JsonValue &&values, td::Slice class_name,
+ td::Result<T> (*func)(td::JsonValue &&value)) {
+ td::vector<T> items;
+ if (values.type() != td::JsonValue::Type::Array) {
+ if (values.type() == td::JsonValue::Type::Null) {
+ return std::move(items);
+ }
+ return td::Status::Error(400, PSLICE() << "Expected an Array of " << class_name);
+ }
+
+ for (auto &value : values.get_array()) {
+ auto r_item = func(std::move(value));
+ if (r_item.is_error()) {
+ return td::Status::Error(400, PSLICE() << "Can't parse " << class_name << ": " << r_item.error().message());
+ }
+ items.push_back(r_item.move_as_ok());
+ }
+
+ return std::move(items);
+}
+
+template <class T>
+td::Result<td::vector<td_api::object_ptr<T>>> Client::get_array_generic(
+ td::JsonValue &&values, td::Slice class_name,
+ const std::function<td::Result<object_ptr<T>>(td::JsonValue &&value)> &func) {
+ td::vector<object_ptr<T>> items;
+ if (values.type() != td::JsonValue::Type::Array) {
+ if (values.type() == td::JsonValue::Type::Null) {
+ return std::move(items);
+ }
+ return td::Status::Error(400, PSLICE() << "Expected an Array of " << class_name);
+ }
+
+ for (auto &value : values.get_array()) {
+ auto r_item = func(std::move(value));
+ if (r_item.is_error()) {
+ return td::Status::Error(400, PSLICE() << "Can't parse " << class_name << ": " << r_item.error().message());
+ }
+ items.push_back(r_item.move_as_ok());
+ }
+
+ return std::move(items);
+}
+
td_api::object_ptr<td_api::InputMessageReplyTo> Client::get_input_message_reply_to(
CheckedReplyParameters &&reply_parameters) {
+ if (reply_parameters.reply_to_ephemeral_message_id > 0) {
+ return make_object<td_api::inputMessageReplyToEphemeralMessage>(reply_parameters.reply_to_ephemeral_message_id);
+ }
if (reply_parameters.reply_to_message_id > 0) {
if (reply_parameters.reply_in_chat_id != 0) {
return make_object<td_api::inputMessageReplyToExternalMessage>(
@@ -9956,7 +10102,7 @@ td_api::object_ptr<td_api::InputMessageReplyTo> Client::get_input_message_reply_
return nullptr;
}
-td_api::object_ptr<td_api::InputMessageReplyTo> Client::get_input_message_reply_to(
+td_api::object_ptr<td_api::InputMessageReplyTo> Client::get_input_message_reply_to_unchecked(
InputReplyParameters &&reply_parameters) {
if (reply_parameters.reply_in_chat_id.empty() && reply_parameters.reply_to_message_id > 0) {
return make_object<td_api::inputMessageReplyToMessage>(
@@ -9998,7 +10144,7 @@ td::Result<Client::InputReplyParameters> Client::get_reply_parameters(td::JsonVa
return InputReplyParameters();
}
TRY_RESULT(chat_id, object.get_optional_string_field("chat_id"));
- TRY_RESULT(message_id, object.get_required_int_field("message_id"));
+ TRY_RESULT(message_id, object.get_optional_int_field("message_id"));
TRY_RESULT(allow_sending_without_reply, object.get_optional_bool_field("allow_sending_without_reply"));
TRY_RESULT(input_quote, object.get_optional_string_field("quote"));
TRY_RESULT(parse_mode, object.get_optional_string_field("quote_parse_mode"));
@@ -10007,10 +10153,12 @@ td::Result<Client::InputReplyParameters> Client::get_reply_parameters(td::JsonVa
TRY_RESULT(quote_position, object.get_optional_int_field("quote_position"));
TRY_RESULT(checklist_task_id, object.get_optional_int_field("checklist_task_id"));
TRY_RESULT(poll_option_id, object.get_optional_string_field("poll_option_id"));
+ TRY_RESULT(ephemeral_message_id, object.get_optional_int_field("ephemeral_message_id"));
InputReplyParameters result;
result.reply_in_chat_id = std::move(chat_id);
result.reply_to_message_id = as_tdlib_message_id(td::max(message_id, 0));
+ result.reply_to_ephemeral_message_id = td::max(ephemeral_message_id, 0);
result.allow_sending_without_reply = allow_sending_without_reply;
result.quote = make_object<td_api::inputTextQuote>(std::move(quote), quote_position);
result.checklist_task_id = checklist_task_id;
@@ -10135,7 +10283,7 @@ td::Result<td_api::object_ptr<td_api::KeyboardButtonType>> Client::get_keyboard_
return nullptr;
}
-td::Result<td_api::object_ptr<td_api::keyboardButton>> Client::get_keyboard_button(td::JsonValue &button) {
+td::Result<td_api::object_ptr<td_api::keyboardButton>> Client::get_keyboard_button(td::JsonValue &&button) {
if (button.type() == td::JsonValue::Type::Object) {
auto &object = button.get_object();
@@ -10153,7 +10301,7 @@ td::Result<td_api::object_ptr<td_api::keyboardButton>> Client::get_keyboard_butt
}
td::Result<td_api::object_ptr<td_api::inlineKeyboardButton>> Client::get_inline_keyboard_button(
- td::JsonValue &button, BotUserIds &bot_user_ids) {
+ td::JsonValue &&button, BotUserIds &bot_user_ids) {
if (button.type() != td::JsonValue::Type::Object) {
return td::Status::Error(400, "InlineKeyboardButton must be an Object");
}
@@ -10303,18 +10451,7 @@ td::Result<td_api::object_ptr<td_api::ReplyMarkup>> Client::get_reply_markup(td:
TRY_RESULT(keyboard, object.extract_optional_field("keyboard", td::JsonValue::Type::Array));
if (keyboard.type() == td::JsonValue::Type::Array) {
for (auto &row : keyboard.get_array()) {
- td::vector<object_ptr<td_api::keyboardButton>> new_row;
- if (row.type() != td::JsonValue::Type::Array) {
- return td::Status::Error(400, "Field \"keyboard\" must be an Array of Arrays");
- }
- for (auto &button : row.get_array()) {
- auto r_button = get_keyboard_button(button);
- if (r_button.is_error()) {
- return td::Status::Error(400, PSLICE() << "Can't parse keyboard button: " << r_button.error().message());
- }
- new_row.push_back(r_button.move_as_ok());
- }
-
+ TRY_RESULT(new_row, get_array(std::move(row), "KeyboardButton", get_keyboard_button));
rows.push_back(std::move(new_row));
}
}
@@ -10322,22 +10459,12 @@ td::Result<td_api::object_ptr<td_api::ReplyMarkup>> Client::get_reply_markup(td:
td::vector<td::vector<object_ptr<td_api::inlineKeyboardButton>>> inline_rows;
TRY_RESULT(inline_keyboard, object.extract_optional_field("inline_keyboard", td::JsonValue::Type::Array));
if (inline_keyboard.type() == td::JsonValue::Type::Array) {
- for (auto &inline_row : inline_keyboard.get_array()) {
- td::vector<object_ptr<td_api::inlineKeyboardButton>> new_inline_row;
- if (inline_row.type() != td::JsonValue::Type::Array) {
- return td::Status::Error(400,
- "Field \"inline_keyboard\" of the InlineKeyboardMarkup must be an Array of Arrays");
- }
- for (auto &button : inline_row.get_array()) {
- auto r_button = get_inline_keyboard_button(button, bot_user_ids);
- if (r_button.is_error()) {
- return td::Status::Error(400, PSLICE()
- << "Can't parse inline keyboard button: " << r_button.error().message());
- }
- new_inline_row.push_back(r_button.move_as_ok());
- }
-
- inline_rows.push_back(std::move(new_inline_row));
+ for (auto &row : inline_keyboard.get_array()) {
+ TRY_RESULT(new_row, get_array_generic<td_api::inlineKeyboardButton>(
+ std::move(row), "InlineKeyboardButton", [&](td::JsonValue &&button) {
+ return get_inline_keyboard_button(std::move(button), bot_user_ids);
+ }));
+ inline_rows.push_back(std::move(new_row));
}
}
@@ -10385,9 +10512,9 @@ td::Result<td_api::object_ptr<td_api::SuggestedPostPrice>> Client::get_suggested
}
if (currency == "TON") {
if (amount % 10000000 != 0) {
- return td::Status::Error(400, "Suggested post price must be divisible by 10000000 nanotoncoins");
+ return td::Status::Error(400, "Suggested post price must be divisible by 10000000 nanograms");
}
- return make_object<td_api::suggestedPostPriceTon>(amount / 10000000);
+ return make_object<td_api::suggestedPostPriceGram>(amount / 10000000);
}
return td::Status::Error(400, "Invalid suggested post price currency specified");
}
@@ -10426,7 +10553,7 @@ td::Result<td_api::object_ptr<td_api::inputSuggestedPostInfo>> Client::get_input
return make_object<td_api::inputSuggestedPostInfo>(std::move(price), send_date);
}
-td::Result<td_api::object_ptr<td_api::labeledPricePart>> Client::get_labeled_price_part(td::JsonValue &value) {
+td::Result<td_api::object_ptr<td_api::labeledPricePart>> Client::get_labeled_price_part(td::JsonValue &&value) {
if (value.type() != td::JsonValue::Type::Object) {
return td::Status::Error(400, "LabeledPrice must be an Object");
}
@@ -10443,51 +10570,31 @@ td::Result<td_api::object_ptr<td_api::labeledPricePart>> Client::get_labeled_pri
}
td::Result<td::vector<td_api::object_ptr<td_api::labeledPricePart>>> Client::get_labeled_price_parts(
- td::JsonValue &value) {
- if (value.type() != td::JsonValue::Type::Array) {
- return td::Status::Error(400, "Expected an Array of labeled prices");
- }
+ td::JsonValue &&value) {
+ return get_array(std::move(value), "LabeledPrice", get_labeled_price_part);
+}
- td::vector<object_ptr<td_api::labeledPricePart>> prices;
- for (auto &price : value.get_array()) {
- auto r_labeled_price = get_labeled_price_part(price);
- if (r_labeled_price.is_error()) {
- return td::Status::Error(400, PSLICE() << "Can't parse labeled price: " << r_labeled_price.error().message());
- }
- prices.push_back(r_labeled_price.move_as_ok());
+td::Result<td::int64> Client::get_suggested_tip_amount(td::JsonValue &&value) {
+ td::Slice number;
+ if (value.type() == td::JsonValue::Type::Number) {
+ number = value.get_number();
+ } else if (value.type() == td::JsonValue::Type::String) {
+ number = value.get_string();
+ } else {
+ return td::Status::Error(400, "Suggested tip amount must be of type Number or String");
}
- if (prices.empty()) {
- return td::Status::Error(400, "There must be at least one price");
+ auto parsed_amount = td::to_integer_safe<int64>(number);
+ if (parsed_amount.is_error()) {
+ return td::Status::Error(400, "Can't parse suggested tip amount as Number");
}
-
- return std::move(prices);
+ return parsed_amount.ok();
}
-td::Result<td::vector<td::int64>> Client::get_suggested_tip_amounts(td::JsonValue &value) {
- if (value.type() != td::JsonValue::Type::Array) {
- return td::Status::Error(400, "Expected an Array of suggested tip amounts");
- }
-
- td::vector<int64> suggested_tip_amounts;
- for (auto &amount : value.get_array()) {
- td::Slice number;
- if (amount.type() == td::JsonValue::Type::Number) {
- number = amount.get_number();
- } else if (amount.type() == td::JsonValue::Type::String) {
- number = amount.get_string();
- } else {
- return td::Status::Error(400, "Suggested tip amount must be of type Number or String");
- }
- auto parsed_amount = td::to_integer_safe<int64>(number);
- if (parsed_amount.is_error()) {
- return td::Status::Error(400, "Can't parse suggested tip amount as Number");
- }
- suggested_tip_amounts.push_back(parsed_amount.ok());
- }
- return std::move(suggested_tip_amounts);
+td::Result<td::vector<td::int64>> Client::get_suggested_tip_amounts(td::JsonValue &&value) {
+ return get_array(std::move(value), "suggested tip amount", get_suggested_tip_amount);
}
-td::Result<td_api::object_ptr<td_api::shippingOption>> Client::get_shipping_option(td::JsonValue &option) {
+td::Result<td_api::object_ptr<td_api::shippingOption>> Client::get_shipping_option(td::JsonValue &&option) {
if (option.type() != td::JsonValue::Type::Object) {
return td::Status::Error(400, "ShippingOption must be an Object");
}
@@ -10506,7 +10613,7 @@ td::Result<td_api::object_ptr<td_api::shippingOption>> Client::get_shipping_opti
TRY_RESULT(prices_json, object.extract_required_field("prices", td::JsonValue::Type::Array));
- auto r_prices = get_labeled_price_parts(prices_json);
+ auto r_prices = get_labeled_price_parts(std::move(prices_json));
if (r_prices.is_error()) {
return td::Status::Error(400, PSLICE() << "Can't parse shipping option prices: " << r_prices.error().message());
}
@@ -10524,27 +10631,7 @@ td::Result<td::vector<td_api::object_ptr<td_api::shippingOption>>> Client::get_s
return td::Status::Error(400, "Can't parse shipping options JSON object");
}
- return get_shipping_options(r_value.move_as_ok());
-}
-
-td::Result<td::vector<td_api::object_ptr<td_api::shippingOption>>> Client::get_shipping_options(td::JsonValue &&value) {
- if (value.type() != td::JsonValue::Type::Array) {
- return td::Status::Error(400, "Expected an Array of shipping options");
- }
-
- td::vector<object_ptr<td_api::shippingOption>> options;
- for (auto &option : value.get_array()) {
- auto r_shipping_option = get_shipping_option(option);
- if (r_shipping_option.is_error()) {
- return td::Status::Error(400, PSLICE() << "Can't parse shipping option: " << r_shipping_option.error().message());
- }
- options.push_back(r_shipping_option.move_as_ok());
- }
- if (options.empty()) {
- return td::Status::Error(400, "There must be at least one shipping option");
- }
-
- return std::move(options);
+ return get_array(r_value.move_as_ok(), "ShippingOption", get_shipping_option);
}
td_api::object_ptr<td_api::ChatAction> Client::get_chat_action(const Query *query) {
@@ -10674,13 +10761,10 @@ td::Result<td_api::object_ptr<td_api::inputThumbnail>> Client::get_input_thumbna
}
td::Result<td_api::object_ptr<td_api::InputMessageContent>> Client::get_input_message_content(
- td::JsonValue &input_message_content, bool is_input_message_content_required) {
- CHECK(input_message_content.type() == td::JsonValue::Type::Object);
- auto &object = input_message_content.get_object();
-
+ const Query *query, td::JsonObject &object, bool is_input_message_content_required) const {
if (object.has_field("rich_message")) {
TRY_RESULT(rich_message, object.extract_required_field("rich_message", td::JsonValue::Type::Object));
- TRY_RESULT(input_rich_message, get_input_rich_message(std::move(rich_message)));
+ TRY_RESULT(input_rich_message, get_input_rich_message(query, std::move(rich_message)));
return make_object<td_api::inputMessageRichMessage>(std::move(input_rich_message), false);
}
@@ -10741,15 +10825,10 @@ td::Result<td_api::object_ptr<td_api::InputMessageContent>> Client::get_input_me
TRY_RESULT(provider_token, object.get_optional_string_field("provider_token"));
TRY_RESULT(currency, object.get_required_string_field("currency"));
TRY_RESULT(prices_object, object.extract_required_field("prices", td::JsonValue::Type::Array));
- TRY_RESULT(prices, get_labeled_price_parts(prices_object));
+ TRY_RESULT(prices, get_labeled_price_parts(std::move(prices_object)));
TRY_RESULT(provider_data, object.get_optional_string_field("provider_data"));
TRY_RESULT(max_tip_amount, object.get_optional_long_field("max_tip_amount"));
- td::vector<int64> suggested_tip_amounts;
- TRY_RESULT(suggested_tip_amounts_array,
- object.extract_optional_field("suggested_tip_amounts", td::JsonValue::Type::Array));
- if (suggested_tip_amounts_array.type() == td::JsonValue::Type::Array) {
- TRY_RESULT_ASSIGN(suggested_tip_amounts, get_suggested_tip_amounts(suggested_tip_amounts_array));
- }
+ TRY_RESULT(suggested_tip_amounts, get_suggested_tip_amounts(object.extract_field("suggested_tip_amounts")));
TRY_RESULT(photo_url, object.get_optional_string_field("photo_url"));
TRY_RESULT(photo_size, object.get_optional_int_field("photo_size"));
TRY_RESULT(photo_width, object.get_optional_int_field("photo_width"));
@@ -10834,7 +10913,7 @@ td::Result<td_api::object_ptr<td_api::inlineQueryResultsButton>> Client::get_inl
}
td::Result<td::vector<td_api::object_ptr<td_api::InputInlineQueryResult>>> Client::get_inline_query_results(
- const Query *query, BotUserIds &bot_user_ids) {
+ const Query *query, BotUserIds &bot_user_ids) const {
auto results_encoded = query->arg("results");
if (results_encoded.empty()) {
return td::vector<object_ptr<td_api::InputInlineQueryResult>>();
@@ -10847,37 +10926,13 @@ td::Result<td::vector<td_api::object_ptr<td_api::InputInlineQueryResult>>> Clien
400, PSLICE() << "Can't parse JSON encoded inline query results: " << r_values.error().message());
}
- return get_inline_query_results(r_values.move_as_ok(), bot_user_ids);
-}
-
-td::Result<td::vector<td_api::object_ptr<td_api::InputInlineQueryResult>>> Client::get_inline_query_results(
- td::JsonValue &&values, BotUserIds &bot_user_ids) {
- if (values.type() == td::JsonValue::Type::Null) {
- return td::vector<object_ptr<td_api::InputInlineQueryResult>>();
- }
- if (values.type() != td::JsonValue::Type::Array) {
- return td::Status::Error(400, "Expected an Array of inline query results");
- }
- constexpr std::size_t MAX_INLINE_QUERY_RESULT_COUNT = 50;
- if (values.get_array().size() > MAX_INLINE_QUERY_RESULT_COUNT) {
- return td::Status::Error(400, "Too many inline query results specified");
- }
-
- td::vector<object_ptr<td_api::InputInlineQueryResult>> inline_query_results;
- for (auto &value : values.get_array()) {
- auto r_inline_query_result = get_inline_query_result(std::move(value), bot_user_ids);
- if (r_inline_query_result.is_error()) {
- return td::Status::Error(
- 400, PSLICE() << "Can't parse inline query result: " << r_inline_query_result.error().message());
- }
- inline_query_results.push_back(r_inline_query_result.move_as_ok());
- }
-
- return std::move(inline_query_results);
+ return get_array_generic<td_api::InputInlineQueryResult>(
+ r_values.move_as_ok(), "InlineQueryResult",
+ [&](td::JsonValue &&value) { return get_inline_query_result(query, std::move(value), bot_user_ids); });
}
td::Result<td_api::object_ptr<td_api::InputInlineQueryResult>> Client::get_inline_query_result(
- const Query *query, BotUserIds &bot_user_ids) {
+ const Query *query, BotUserIds &bot_user_ids) const {
auto result_encoded = query->arg("result");
if (result_encoded.empty()) {
return td::Status::Error(400, "Result isn't specified");
@@ -10890,11 +10945,11 @@ td::Result<td_api::object_ptr<td_api::InputInlineQueryResult>> Client::get_inlin
400, PSLICE() << "Can't parse JSON encoded web view query results " << r_value.error().message());
}
- return get_inline_query_result(r_value.move_as_ok(), bot_user_ids);
+ return get_inline_query_result(query, r_value.move_as_ok(), bot_user_ids);
}
td::Result<td_api::object_ptr<td_api::InputInlineQueryResult>> Client::get_inline_query_result(
- td::JsonValue &&value, BotUserIds &bot_user_ids) {
+ const Query *query, td::JsonValue &&value, BotUserIds &bot_user_ids) const {
if (value.type() != td::JsonValue::Type::Object) {
return td::Status::Error(400, "Inline query result must be an object");
}
@@ -10926,8 +10981,9 @@ td::Result<td_api::object_ptr<td_api::InputInlineQueryResult>> Client::get_inlin
input_message_content = std::move(input_message_text);
}
} else {
+ auto &input_message_content_object = input_message_content_obj.get_object();
TRY_RESULT(input_message_content_result,
- get_input_message_content(input_message_content_obj, is_input_message_content_required));
+ get_input_message_content(query, input_message_content_object, is_input_message_content_required));
input_message_content = std::move(input_message_content_result);
}
TRY_RESULT(input_caption, object.get_optional_string_field("caption"));
@@ -11107,7 +11163,7 @@ td::Result<td_api::object_ptr<td_api::InputInlineQueryResult>> Client::get_inlin
TRY_RESULT(sticker_file_id, object.get_required_string_field("sticker_file_id"));
if (input_message_content == nullptr) {
- input_message_content = make_object<td_api::inputMessageSticker>(nullptr, nullptr, 0, 0, td::string());
+ input_message_content = make_object<td_api::inputMessageSticker>(nullptr, td::string());
}
return make_object<td_api::inputInlineQueryResultSticker>(id, "", sticker_file_id, 0, 0, std::move(reply_markup),
std::move(input_message_content));
@@ -11154,8 +11210,7 @@ td::Result<td_api::object_ptr<td_api::InputInlineQueryResult>> Client::get_inlin
}
if (input_message_content == nullptr) {
- input_message_content = make_object<td_api::inputMessageVoiceNote>(
- nullptr, voice_note_duration, "" /* waveform */, std::move(caption), nullptr);
+ input_message_content = make_object<td_api::inputMessageVoiceNote>(nullptr, std::move(caption), nullptr);
}
return make_object<td_api::inputInlineQueryResultVoiceNote>(
id, title, voice_note_url, voice_note_duration, std::move(reply_markup), std::move(input_message_content));
@@ -11236,8 +11291,9 @@ td::Result<td_api::object_ptr<td_api::botCommand>> Client::get_bot_command(td::J
TRY_RESULT(command, object.get_required_string_field("command"));
TRY_RESULT(description, object.get_required_string_field("description"));
+ TRY_RESULT(is_ephemeral, object.get_optional_bool_field("is_ephemeral"));
- return make_object<td_api::botCommand>(command, description);
+ return make_object<td_api::botCommand>(command, description, is_ephemeral);
}
td::Result<td::vector<td_api::object_ptr<td_api::botCommand>>> Client::get_bot_commands(const Query *query) {
@@ -11252,20 +11308,7 @@ td::Result<td::vector<td_api::object_ptr<td_api::botCommand>>> Client::get_bot_c
return td::Status::Error(400, "Can't parse commands JSON object");
}
- auto value = r_value.move_as_ok();
- if (value.type() != td::JsonValue::Type::Array) {
- return td::Status::Error(400, "Expected an Array of BotCommand");
- }
-
- td::vector<object_ptr<td_api::botCommand>> bot_commands;
- for (auto &command : value.get_array()) {
- auto r_bot_command = get_bot_command(std::move(command));
- if (r_bot_command.is_error()) {
- return td::Status::Error(400, PSLICE() << "Can't parse BotCommand: " << r_bot_command.error().message());
- }
- bot_commands.push_back(r_bot_command.move_as_ok());
- }
- return std::move(bot_commands);
+ return get_array(r_value.move_as_ok(), "BotCommand", get_bot_command);
}
td::Result<td_api::object_ptr<td_api::botMenuButton>> Client::get_bot_menu_button(td::JsonValue &&value) {
@@ -11504,9 +11547,8 @@ td::Result<td_api::object_ptr<td_api::StickerFormat>> Client::get_sticker_format
return td::Status::Error(400, "Invalid sticker format specified");
}
-td::Result<td_api::object_ptr<td_api::inputSticker>> Client::get_input_sticker(const Query *query,
- td::JsonValue &&value,
- td::Slice default_sticker_format) const {
+td::Result<td_api::object_ptr<td_api::newSticker>> Client::get_new_sticker(const Query *query, td::JsonValue &&value,
+ td::Slice default_sticker_format) const {
if (value.type() != td::JsonValue::Type::Object) {
return td::Status::Error(400, "InputSticker must be an Object");
}
@@ -11541,11 +11583,11 @@ td::Result<td_api::object_ptr<td_api::inputSticker>> Client::get_input_sticker(c
input_keywords.push_back(keyword.get_string().str());
}
}
- return make_object<td_api::inputSticker>(std::move(input_file), std::move(sticker_format), emojis,
- std::move(mask_position), std::move(input_keywords));
+ return make_object<td_api::newSticker>(std::move(input_file), std::move(sticker_format), emojis,
+ std::move(mask_position), std::move(input_keywords));
}
-td::Result<td_api::object_ptr<td_api::inputSticker>> Client::get_input_sticker(const Query *query) const {
+td::Result<td_api::object_ptr<td_api::newSticker>> Client::get_new_sticker(const Query *query) const {
if (query->has_arg("sticker") || query->file("sticker") != nullptr) {
auto sticker = query->arg("sticker");
LOG(INFO) << "Parsing JSON object: " << sticker;
@@ -11555,17 +11597,17 @@ td::Result<td_api::object_ptr<td_api::inputSticker>> Client::get_input_sticker(c
return td::Status::Error(400, "Can't parse sticker JSON object");
}
- auto r_sticker = get_input_sticker(query, r_value.move_as_ok(), "auto");
+ auto r_sticker = get_new_sticker(query, r_value.move_as_ok(), "auto");
if (r_sticker.is_error()) {
return td::Status::Error(400, PSLICE() << "Can't parse sticker: " << r_sticker.error().message());
}
return r_sticker.move_as_ok();
}
- return get_legacy_input_sticker(query);
+ return get_legacy_new_sticker(query);
}
-td::Result<td_api::object_ptr<td_api::inputSticker>> Client::get_legacy_input_sticker(const Query *query) const {
+td::Result<td_api::object_ptr<td_api::newSticker>> Client::get_legacy_new_sticker(const Query *query) const {
auto emojis = query->arg("emojis");
auto sticker = get_input_file(query, "png_sticker");
object_ptr<td_api::StickerFormat> sticker_format;
@@ -11593,11 +11635,11 @@ td::Result<td_api::object_ptr<td_api::inputSticker>> Client::get_legacy_input_st
}
}
- return make_object<td_api::inputSticker>(std::move(sticker), std::move(sticker_format), emojis.str(),
- std::move(mask_position), td::vector<td::string>());
+ return make_object<td_api::newSticker>(std::move(sticker), std::move(sticker_format), emojis.str(),
+ std::move(mask_position), td::vector<td::string>());
}
-td::Result<td::vector<td_api::object_ptr<td_api::inputSticker>>> Client::get_input_stickers(const Query *query) const {
+td::Result<td::vector<td_api::object_ptr<td_api::newSticker>>> Client::get_new_stickers(const Query *query) const {
if (query->has_arg("stickers")) {
auto sticker_format_str = query->arg("sticker_format");
auto stickers = query->arg("stickers");
@@ -11607,32 +11649,16 @@ td::Result<td::vector<td_api::object_ptr<td_api::inputSticker>>> Client::get_inp
LOG(INFO) << "Can't parse JSON object: " << r_value.error();
return td::Status::Error(400, "Can't parse stickers JSON object");
}
- auto value = r_value.move_as_ok();
-
- if (value.type() != td::JsonValue::Type::Array) {
- return td::Status::Error(400, "Expected an Array of InputSticker");
- }
-
- constexpr std::size_t MAX_STICKER_COUNT = 50;
- if (value.get_array().size() > MAX_STICKER_COUNT) {
- return td::Status::Error(400, "Too many stickers specified");
- }
- td::vector<object_ptr<td_api::inputSticker>> input_stickers;
- for (auto &input_sticker : value.get_array()) {
- auto r_input_sticker = get_input_sticker(query, std::move(input_sticker), sticker_format_str);
- if (r_input_sticker.is_error()) {
- return td::Status::Error(400, PSLICE() << "Can't parse InputSticker: " << r_input_sticker.error().message());
- }
- input_stickers.push_back(r_input_sticker.move_as_ok());
- }
- return std::move(input_stickers);
+ return get_array_generic<td_api::newSticker>(r_value.move_as_ok(), "InputSticker", [&](td::JsonValue &&value) {
+ return get_new_sticker(query, std::move(value), sticker_format_str);
+ });
}
- TRY_RESULT(input_sticker, get_legacy_input_sticker(query));
+ TRY_RESULT(new_sticker, get_legacy_new_sticker(query));
- td::vector<object_ptr<td_api::inputSticker>> stickers;
- stickers.push_back(std::move(input_sticker));
+ td::vector<object_ptr<td_api::newSticker>> stickers;
+ stickers.push_back(std::move(new_sticker));
return std::move(stickers);
}
@@ -11741,20 +11767,7 @@ td::Result<td::vector<td_api::object_ptr<td_api::inputPassportElementError>>> Cl
return td::Status::Error(400, "Can't parse errors JSON object");
}
- auto value = r_value.move_as_ok();
- if (value.type() != td::JsonValue::Type::Array) {
- return td::Status::Error(400, "Expected an Array of PassportElementError");
- }
-
- td::vector<object_ptr<td_api::inputPassportElementError>> errors;
- for (auto &input_error : value.get_array()) {
- auto r_error = get_passport_element_error(std::move(input_error));
- if (r_error.is_error()) {
- return td::Status::Error(400, PSLICE() << "Can't parse PassportElementError: " << r_error.error().message());
- }
- errors.push_back(r_error.move_as_ok());
- }
- return std::move(errors);
+ return get_array(r_value.move_as_ok(), "PassportElementError", get_passport_element_error);
}
td::JsonValue Client::get_input_entities(const Query *query, td::Slice field_name) {
@@ -11961,7 +11974,360 @@ td::Result<td_api::object_ptr<td_api::inputMessageText>> Client::get_input_messa
return make_object<td_api::inputMessageText>(std::move(formatted_text), std::move(link_preview_options), false);
}
-td::Result<td_api::object_ptr<td_api::inputRichMessage>> Client::get_input_rich_message(const Query *query) {
+td::Result<td_api::object_ptr<td_api::pageBlockCaption>> Client::get_page_block_caption(td::JsonValue &&value) {
+ switch (value.type()) {
+ case td::JsonValue::Type::Null:
+ return nullptr;
+ case td::JsonValue::Type::Object: {
+ auto &object = value.get_object();
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ TRY_RESULT(credit, get_rich_text(object.extract_field("credit")));
+ return make_object<td_api::pageBlockCaption>(std::move(text), std::move(credit));
+ }
+ default:
+ return td::Status::Error(400, "RichBlockCaption must be an object");
+ }
+}
+
+td::Result<td_api::object_ptr<td_api::pageBlockTableCell>> Client::get_page_block_table_cell(td::JsonValue &&value) {
+ if (value.type() != td::JsonValue::Type::Object) {
+ return td::Status::Error(400, "RichBlockTableCell must be an object");
+ }
+
+ auto &object = value.get_object();
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ TRY_RESULT(is_header, object.get_optional_bool_field("is_header"));
+ TRY_RESULT(colspan, object.get_optional_int_field("colspan"));
+ TRY_RESULT(rowspan, object.get_optional_int_field("rowspan"));
+
+ object_ptr<td_api::PageBlockHorizontalAlignment> align;
+ TRY_RESULT(align_str, object.get_optional_string_field("align"));
+ if (align_str == "left" || (align_str.empty() && !is_header)) {
+ align = make_object<td_api::pageBlockHorizontalAlignmentLeft>();
+ } else if (align_str == "center" || (align_str.empty() && is_header)) {
+ align = make_object<td_api::pageBlockHorizontalAlignmentCenter>();
+ } else if (align_str == "right") {
+ align = make_object<td_api::pageBlockHorizontalAlignmentRight>();
+ } else {
+ return td::Status::Error(400, "Invalid horizontal alignment specified");
+ }
+
+ object_ptr<td_api::PageBlockVerticalAlignment> valign;
+ TRY_RESULT(valign_str, object.get_optional_string_field("valign"));
+ if (valign_str == "top") {
+ valign = make_object<td_api::pageBlockVerticalAlignmentTop>();
+ } else if (valign_str == "middle" || valign_str.empty()) {
+ valign = make_object<td_api::pageBlockVerticalAlignmentMiddle>();
+ } else if (valign_str == "bottom") {
+ valign = make_object<td_api::pageBlockVerticalAlignmentBottom>();
+ } else {
+ return td::Status::Error(400, "Invalid vertical alignment specified");
+ }
+
+ return make_object<td_api::pageBlockTableCell>(std::move(text), is_header, colspan, rowspan, std::move(align),
+ std::move(valign));
+}
+
+td::Result<td_api::object_ptr<td_api::RichText>> Client::get_rich_text(td::JsonValue &&value) {
+ switch (value.type()) {
+ case td::JsonValue::Type::Null:
+ return nullptr;
+ case td::JsonValue::Type::String:
+ return make_object<td_api::richTextPlain>(value.get_string().str());
+ case td::JsonValue::Type::Array: {
+ td::vector<object_ptr<td_api::RichText>> texts;
+ for (auto &input_text : value.get_array()) {
+ TRY_RESULT(text, get_rich_text(std::move(input_text)));
+ texts.push_back(std::move(text));
+ }
+ return make_object<td_api::richTexts>(std::move(texts));
+ }
+ case td::JsonValue::Type::Object: {
+ auto &object = value.get_object();
+ TRY_RESULT(type, object.get_required_string_field("type"));
+ if (type == "bold") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ return make_object<td_api::richTextBold>(std::move(text));
+ }
+ if (type == "italic") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ return make_object<td_api::richTextItalic>(std::move(text));
+ }
+ if (type == "underline") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ return make_object<td_api::richTextUnderline>(std::move(text));
+ }
+ if (type == "strikethrough") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ return make_object<td_api::richTextStrikethrough>(std::move(text));
+ }
+ if (type == "spoiler") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ return make_object<td_api::richTextSpoiler>(std::move(text));
+ }
+ if (type == "date_time") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ TRY_RESULT(unix_time, object.get_required_int_field("unix_time"));
+ TRY_RESULT(format, object.get_optional_string_field("date_time_format"));
+ TRY_RESULT(formatting_type, get_date_time_formatting_type(format));
+ return make_object<td_api::richTextDateTime>(std::move(text), unix_time, std::move(formatting_type));
+ }
+ if (type == "mention") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ return make_object<td_api::richTextMention>(std::move(text), td::string());
+ }
+ if (type == "hashtag") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ return make_object<td_api::richTextHashtag>(std::move(text), td::string());
+ }
+ if (type == "cashtag") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ return make_object<td_api::richTextCashtag>(std::move(text), td::string());
+ }
+ if (type == "bot_command") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ return make_object<td_api::richTextBotCommand>(std::move(text), td::string());
+ }
+ if (type == "code") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ return make_object<td_api::richTextFixed>(std::move(text));
+ }
+ if (type == "text_mention") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ TRY_RESULT(user, object.extract_required_field("user", td::JsonValue::Type::Object));
+ CHECK(user.type() == td::JsonValue::Type::Object);
+ const auto &user_object = user.get_object();
+ TRY_RESULT(user_id, user_object.get_required_long_field("id"));
+ return make_object<td_api::richTextMentionName>(std::move(text), user_id);
+ }
+ if (type == "url") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ TRY_RESULT(url, object.get_required_string_field("url"));
+ return make_object<td_api::richTextUrl>(std::move(text), url, false);
+ }
+ if (type == "email_address") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ TRY_RESULT(email_address, object.get_required_string_field("email_address"));
+ return make_object<td_api::richTextEmailAddress>(std::move(text), email_address);
+ }
+ if (type == "bank_card_number") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ return make_object<td_api::richTextBankCardNumber>(std::move(text), td::string());
+ }
+ if (type == "subscript") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ return make_object<td_api::richTextSubscript>(std::move(text));
+ }
+ if (type == "superscript") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ return make_object<td_api::richTextSuperscript>(std::move(text));
+ }
+ if (type == "marked") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ return make_object<td_api::richTextMarked>(std::move(text));
+ }
+ if (type == "phone_number") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ TRY_RESULT(phone_number, object.get_required_string_field("phone_number"));
+ return make_object<td_api::richTextPhoneNumber>(std::move(text), phone_number);
+ }
+ if (type == "custom_emoji") {
+ TRY_RESULT(custom_emoji_id, object.get_required_long_field("custom_emoji_id"));
+ TRY_RESULT(alternative_text, object.get_required_string_field("alternative_text"));
+ return make_object<td_api::richTextCustomEmoji>(custom_emoji_id, alternative_text);
+ }
+ if (type == "mathematical_expression") {
+ TRY_RESULT(expression, object.get_required_string_field("expression"));
+ return make_object<td_api::richTextMathematicalExpression>(expression);
+ }
+ if (type == "reference") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ TRY_RESULT(name, object.get_required_string_field("name"));
+ return make_object<td_api::richTextReference>(name, std::move(text));
+ }
+ if (type == "reference_link") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ TRY_RESULT(reference_name, object.get_required_string_field("reference_name"));
+ return make_object<td_api::richTextReferenceLink>(std::move(text), reference_name, td::string());
+ }
+ if (type == "anchor") {
+ TRY_RESULT(name, object.get_required_string_field("name"));
+ return make_object<td_api::richTextAnchor>(name);
+ }
+ if (type == "anchor_link") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ TRY_RESULT(anchor_name, object.get_required_string_field("anchor_name"));
+ return make_object<td_api::richTextAnchorLink>(std::move(text), anchor_name, td::string());
+ }
+ return td::Status::Error(400, "Unsupported rich text type");
+ }
+ default:
+ return td::Status::Error(400, "Invalid rich text specified");
+ }
+}
+
+td::Result<td_api::object_ptr<td_api::inputPageBlockListItem>> Client::get_input_page_block_list_item(
+ const Query *query, td::JsonValue &&value) const {
+ if (value.type() != td::JsonValue::Type::Object) {
+ return td::Status::Error(400, "Object expected as InputRichBlockListItem");
+ }
+ auto &object = value.get_object();
+ TRY_RESULT(blocks, get_input_page_blocks(query, object.extract_field("blocks")));
+ TRY_RESULT(has_checkbox, object.get_optional_bool_field("has_checkbox"));
+ TRY_RESULT(is_checked, object.get_optional_bool_field("is_checked"));
+ TRY_RESULT(item_value, object.get_optional_int_field("value"));
+ TRY_RESULT(type, object.get_optional_string_field("type"));
+ return make_object<td_api::inputPageBlockListItem>(std::move(blocks), has_checkbox, is_checked, item_value, type);
+}
+
+td::Result<td_api::object_ptr<td_api::InputPageBlock>> Client::get_input_page_block(const Query *query,
+ td::JsonValue &&value) const {
+ if (value.type() != td::JsonValue::Type::Object) {
+ return td::Status::Error(400, "Object expected as InputRichMessageBlock");
+ }
+ auto &object = value.get_object();
+ TRY_RESULT(type, object.get_required_string_field("type"));
+ if (type == "heading") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ TRY_RESULT(size, object.get_required_int_field("size"));
+ return make_object<td_api::inputPageBlockSectionHeading>(std::move(text), size);
+ }
+ if (type == "paragraph") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ return make_object<td_api::inputPageBlockParagraph>(std::move(text));
+ }
+ if (type == "pre") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ TRY_RESULT(language, object.get_optional_string_field("language"));
+ return make_object<td_api::inputPageBlockPreformatted>(std::move(text), language);
+ }
+ if (type == "footer") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ return make_object<td_api::inputPageBlockFooter>(std::move(text));
+ }
+ if (type == "thinking") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ return make_object<td_api::inputPageBlockThinking>(std::move(text));
+ }
+ if (type == "divider") {
+ return make_object<td_api::inputPageBlockDivider>();
+ }
+ if (type == "mathematical_expression") {
+ TRY_RESULT(expression, object.get_required_string_field("expression"));
+ return make_object<td_api::inputPageBlockMathematicalExpression>(expression);
+ }
+ if (type == "anchor") {
+ TRY_RESULT(name, object.get_required_string_field("name"));
+ return make_object<td_api::inputPageBlockAnchor>(name);
+ }
+ if (type == "list") {
+ TRY_RESULT(items, get_array_generic<td_api::inputPageBlockListItem>(
+ object.extract_field("items"), "InputRichBlockListItem", [&](td::JsonValue &&item) {
+ return get_input_page_block_list_item(query, std::move(item));
+ }));
+ return make_object<td_api::inputPageBlockList>(std::move(items));
+ }
+ if (type == "blockquote") {
+ TRY_RESULT(blocks, get_input_page_blocks(query, object.extract_field("blocks")));
+ TRY_RESULT(credit, get_rich_text(object.extract_field("credit")));
+ return make_object<td_api::inputPageBlockBlockQuote>(std::move(blocks), std::move(credit));
+ }
+ if (type == "pullquote") {
+ TRY_RESULT(text, get_rich_text(object.extract_field("text")));
+ TRY_RESULT(credit, get_rich_text(object.extract_field("credit")));
+ return make_object<td_api::inputPageBlockPullQuote>(std::move(text), std::move(credit));
+ }
+ if (type == "collage") {
+ TRY_RESULT(blocks, get_input_page_blocks(query, object.extract_field("blocks")));
+ TRY_RESULT(caption, get_page_block_caption(object.extract_field("caption")));
+ return make_object<td_api::inputPageBlockCollage>(std::move(blocks), std::move(caption));
+ }
+ if (type == "slideshow") {
+ TRY_RESULT(blocks, get_input_page_blocks(query, object.extract_field("blocks")));
+ TRY_RESULT(caption, get_page_block_caption(object.extract_field("caption")));
+ return make_object<td_api::inputPageBlockSlideshow>(std::move(blocks), std::move(caption));
+ }
+ if (type == "table") {
+ td::vector<td::vector<object_ptr<td_api::pageBlockTableCell>>> cells;
+ TRY_RESULT(cells_array, object.extract_required_field("cells", td::JsonValue::Type::Array));
+ for (auto &row : cells_array.get_array()) {
+ TRY_RESULT(new_row, get_array(std::move(row), "PageBlockTableCell", get_page_block_table_cell));
+ cells.push_back(std::move(new_row));
+ }
+ TRY_RESULT(caption, get_rich_text(object.extract_field("caption")));
+ TRY_RESULT(is_bordered, object.get_optional_bool_field("is_bordered"));
+ TRY_RESULT(is_striped, object.get_optional_bool_field("is_striped"));
+ return make_object<td_api::inputPageBlockTable>(std::move(caption), std::move(cells), is_bordered, is_striped);
+ }
+ if (type == "details") {
+ TRY_RESULT(summary, get_rich_text(object.extract_field("summary")));
+ TRY_RESULT(blocks, get_input_page_blocks(query, object.extract_field("blocks")));
+ TRY_RESULT(is_open, object.get_optional_bool_field("is_open"));
+ return make_object<td_api::inputPageBlockDetails>(std::move(summary), std::move(blocks), is_open);
+ }
+ if (type == "map") {
+ TRY_RESULT(location_field, object.extract_required_field("location", td::JsonValue::Type::Object));
+ auto &location_object = location_field.get_object();
+ TRY_RESULT(location, get_location(location_object));
+ TRY_RESULT(zoom, object.get_optional_int_field("zoom"));
+ TRY_RESULT(width, object.get_optional_int_field("width"));
+ TRY_RESULT(height, object.get_optional_int_field("height"));
+ TRY_RESULT(caption, get_page_block_caption(object.extract_field("caption")));
+ return make_object<td_api::inputPageBlockMap>(std::move(location), zoom, width, height, std::move(caption));
+ }
+ if (type != "animation" && type != "audio" && type != "photo" && type != "video" && type != "voice_note") {
+ return td::Status::Error(400, PSLICE() << "type \"" << type << "\" is unsupported");
+ }
+ TRY_RESULT(media_field, object.extract_required_field(type, td::JsonValue::Type::Object));
+ auto &media_object = media_field.get_object();
+ TRY_RESULT(media_type, media_object.get_required_string_field("type"));
+ if (media_type != type) {
+ return td::Status::Error(400, PSLICE()
+ << "Unexpected media type \"" << media_type << "\" for block \"" << type << "\"");
+ }
+ TRY_RESULT(input_message_content, get_input_media(query, media_object, type, nullptr, false, false, false, true));
+ TRY_RESULT(caption, get_page_block_caption(object.extract_field("caption")));
+ TRY_RESULT(has_spoiler, media_object.get_optional_bool_field("has_spoiler"));
+ if (type == "animation") {
+ CHECK(input_message_content->get_id() == td_api::inputMessageAnimation::ID);
+ return make_object<td_api::inputPageBlockAnimation>(
+ std::move(static_cast<td_api::inputMessageAnimation *>(input_message_content.get())->animation_),
+ std::move(caption), has_spoiler);
+ }
+ if (type == "audio") {
+ CHECK(input_message_content->get_id() == td_api::inputMessageAudio::ID);
+ return make_object<td_api::inputPageBlockAudio>(
+ std::move(static_cast<td_api::inputMessageAudio *>(input_message_content.get())->audio_), std::move(caption));
+ }
+ if (type == "photo") {
+ CHECK(input_message_content->get_id() == td_api::inputMessagePhoto::ID);
+ return make_object<td_api::inputPageBlockPhoto>(
+ std::move(static_cast<td_api::inputMessagePhoto *>(input_message_content.get())->photo_), std::move(caption),
+ has_spoiler);
+ }
+ if (type == "video") {
+ CHECK(input_message_content->get_id() == td_api::inputMessageVideo::ID);
+ return make_object<td_api::inputPageBlockVideo>(
+ std::move(static_cast<td_api::inputMessageVideo *>(input_message_content.get())->video_), std::move(caption),
+ has_spoiler);
+ }
+ if (type == "voice_note") {
+ CHECK(input_message_content->get_id() == td_api::inputMessageVoiceNote::ID);
+ return make_object<td_api::inputPageBlockVoiceNote>(
+ std::move(static_cast<td_api::inputMessageVoiceNote *>(input_message_content.get())->voice_note_),
+ std::move(caption));
+ }
+ UNREACHABLE();
+}
+
+td::Result<td::vector<td_api::object_ptr<td_api::InputPageBlock>>> Client::get_input_page_blocks(
+ const Query *query, td::JsonValue &&value) const {
+ return get_array_generic<td_api::InputPageBlock>(std::move(value), "InputRichBlock", [&](td::JsonValue &&block) {
+ return get_input_page_block(query, std::move(block));
+ });
+}
+
+td::Result<td_api::object_ptr<td_api::inputRichMessage>> Client::get_input_rich_message(const Query *query) const {
auto rich_message = query->arg("rich_message");
if (rich_message.empty()) {
return td::Status::Error(400, "Rich message must be non-empty");
@@ -11974,10 +12340,11 @@ td::Result<td_api::object_ptr<td_api::inputRichMessage>> Client::get_input_rich_
return td::Status::Error(400, "Can't parse rich message JSON object");
}
- return get_input_rich_message(r_value.move_as_ok());
+ return get_input_rich_message(query, r_value.move_as_ok());
}
-td::Result<td_api::object_ptr<td_api::inputRichMessage>> Client::get_input_rich_message(td::JsonValue &&value) {
+td::Result<td_api::object_ptr<td_api::inputRichMessage>> Client::get_input_rich_message(const Query *query,
+ td::JsonValue &&value) const {
if (value.type() != td::JsonValue::Type::Object) {
return td::Status::Error(400, "Object expected as rich message");
}
@@ -11985,12 +12352,17 @@ td::Result<td_api::object_ptr<td_api::inputRichMessage>> Client::get_input_rich_
TRY_RESULT(is_rtl, object.get_optional_bool_field("is_rtl"));
TRY_RESULT(skip_entity_detection, object.get_optional_bool_field("skip_entity_detection"));
auto result = make_object<td_api::inputRichMessage>(nullptr, is_rtl, !skip_entity_detection);
- if (object.has_field("markdown")) {
+ if (object.has_field("blocks")) {
+ TRY_RESULT(blocks, get_input_page_blocks(query, object.extract_field("blocks")));
+ result->source_ = make_object<td_api::richMessageSourceBlocks>(std::move(blocks));
+ } else if (object.has_field("markdown")) {
TRY_RESULT(text, object.get_required_string_field("markdown"));
- result->source_ = make_object<td_api::richMessageSourceMarkdown>(text);
+ TRY_RESULT(media, get_input_rich_message_medias(query, object.extract_field("media")));
+ result->source_ = make_object<td_api::richMessageSourceMarkdown>(text, std::move(media));
} else if (object.has_field("html")) {
TRY_RESULT(text, object.get_required_string_field("html"));
- result->source_ = make_object<td_api::richMessageSourceHtml>(text);
+ TRY_RESULT(media, get_input_rich_message_medias(query, object.extract_field("media")));
+ result->source_ = make_object<td_api::richMessageSourceHtml>(text, std::move(media));
} else {
return td::Status::Error(400, "Rich message must be non-empty");
}
@@ -12184,8 +12556,73 @@ td::Result<td_api::object_ptr<td_api::chatPermissions>> Client::get_chat_permiss
can_edit_tag, can_change_info, can_invite_users, can_pin_messages, can_manage_topics);
}
+td::Result<td_api::object_ptr<td_api::inputAnimation>> Client::get_input_animation(
+ const td::JsonObject &object, object_ptr<td_api::InputFile> &&input_file,
+ object_ptr<td_api::inputThumbnail> &&input_thumbnail) {
+ TRY_RESULT(width, object.get_optional_int_field("width"));
+ TRY_RESULT(height, object.get_optional_int_field("height"));
+ TRY_RESULT(duration, object.get_optional_int_field("duration"));
+ width = td::clamp(width, 0, MAX_LENGTH);
+ height = td::clamp(height, 0, MAX_LENGTH);
+ duration = td::clamp(duration, 0, MAX_DURATION);
+ return make_object<td_api::inputAnimation>(std::move(input_file), std::move(input_thumbnail), td::vector<int32>(),
+ duration, width, height);
+}
+
+td::Result<td_api::object_ptr<td_api::inputAudio>> Client::get_input_audio(
+ const td::JsonObject &object, object_ptr<td_api::InputFile> &&input_file,
+ object_ptr<td_api::inputThumbnail> &&input_thumbnail) {
+ TRY_RESULT(duration, object.get_optional_int_field("duration"));
+ TRY_RESULT(title, object.get_optional_string_field("title"));
+ TRY_RESULT(performer, object.get_optional_string_field("performer"));
+ duration = td::clamp(duration, 0, MAX_DURATION);
+ return make_object<td_api::inputAudio>(std::move(input_file), std::move(input_thumbnail), duration, title, performer);
+}
+
+td::Result<td_api::object_ptr<td_api::inputPhoto>> Client::get_input_photo(const Query *query,
+ const td::JsonObject &object,
+ object_ptr<td_api::InputFile> &&input_file,
+ bool is_live) const {
+ if (is_live) {
+ TRY_RESULT(photo, object.get_optional_string_field("photo"));
+ auto input_photo = get_input_file(query, td::Slice(), photo, false);
+ if (input_photo == nullptr) {
+ return td::Status::Error("photo not found");
+ }
+ return make_object<td_api::inputPhoto>(std::move(input_photo), nullptr, std::move(input_file), td::vector<int32>(),
+ 0, 0);
+ }
+ return make_object<td_api::inputPhoto>(std::move(input_file), nullptr, nullptr, td::vector<int32>(), 0, 0);
+}
+
+td::Result<td_api::object_ptr<td_api::inputVideo>> Client::get_input_video(
+ const Query *query, const td::JsonObject &object, object_ptr<td_api::InputFile> &&input_file,
+ object_ptr<td_api::inputThumbnail> &&input_thumbnail) const {
+ TRY_RESULT(width, object.get_optional_int_field("width"));
+ TRY_RESULT(height, object.get_optional_int_field("height"));
+ TRY_RESULT(duration, object.get_optional_int_field("duration"));
+ TRY_RESULT(cover, object.get_optional_string_field("cover"));
+ TRY_RESULT(start_timestamp, object.get_optional_int_field("start_timestamp"));
+ TRY_RESULT(supports_streaming, object.get_optional_bool_field("supports_streaming"));
+ auto input_cover = get_input_file(query, td::Slice(), cover, false);
+ width = td::clamp(width, 0, MAX_LENGTH);
+ height = td::clamp(height, 0, MAX_LENGTH);
+ duration = td::clamp(duration, 0, MAX_DURATION);
+ start_timestamp = td::clamp(start_timestamp, 0, MAX_DURATION);
+ return make_object<td_api::inputVideo>(std::move(input_file), std::move(input_thumbnail), std::move(input_cover),
+ start_timestamp, td::vector<int32>(), duration, width, height,
+ supports_streaming);
+}
+
+td::Result<td_api::object_ptr<td_api::inputVoiceNote>> Client::get_input_voice_note(
+ const td::JsonObject &object, object_ptr<td_api::InputFile> &&input_file) {
+ TRY_RESULT(duration, object.get_optional_int_field("duration"));
+ duration = td::clamp(duration, 0, MAX_DURATION);
+ return make_object<td_api::inputVoiceNote>(std::move(input_file), duration, td::string());
+}
+
td::Result<td_api::object_ptr<td_api::inputChecklistTask>> Client::get_input_checklist_task(
- td::JsonValue &&input_task) const {
+ td::JsonValue &&input_task) {
if (input_task.type() != td::JsonValue::Type::Object) {
return td::Status::Error("expected an Object");
}
@@ -12200,23 +12637,6 @@ td::Result<td_api::object_ptr<td_api::inputChecklistTask>> Client::get_input_che
return make_object<td_api::inputChecklistTask>(id, std::move(text));
}
-td::Result<td::vector<td_api::object_ptr<td_api::inputChecklistTask>>> Client::get_input_checklist_tasks(
- td::JsonValue &&value) const {
- if (value.type() != td::JsonValue::Type::Array) {
- return td::Status::Error(400, "Expected an Array of InputChecklistTask");
- }
-
- td::vector<object_ptr<td_api::inputChecklistTask>> tasks;
- for (auto &input_task : value.get_array()) {
- auto r_task = get_input_checklist_task(std::move(input_task));
- if (r_task.is_error()) {
- return td::Status::Error(400, PSLICE() << "Can't parse InputChecklistTask: " << r_task.error().message());
- }
- tasks.push_back(r_task.move_as_ok());
- }
- return std::move(tasks);
-}
-
td::Result<td_api::object_ptr<td_api::inputChecklist>> Client::get_input_checklist(
const Query *query, td::JsonValue &&input_checklist) const {
if (input_checklist.type() != td::JsonValue::Type::Object) {
@@ -12231,7 +12651,7 @@ td::Result<td_api::object_ptr<td_api::inputChecklist>> Client::get_input_checkli
TRY_RESULT(others_can_add_tasks, object.get_optional_bool_field("others_can_add_tasks"));
TRY_RESULT(others_can_mark_tasks_as_done, object.get_optional_bool_field("others_can_mark_tasks_as_done"));
TRY_RESULT(input_tasks, object.extract_required_field("tasks", td::JsonValue::Type::Array));
- TRY_RESULT(tasks, get_input_checklist_tasks(std::move(input_tasks)));
+ TRY_RESULT(tasks, get_array(std::move(input_tasks), "InputChecklistTask", get_input_checklist_task));
return make_object<td_api::inputChecklist>(std::move(title), std::move(tasks), others_can_add_tasks,
others_can_mark_tasks_as_done);
@@ -12272,13 +12692,14 @@ td::Result<td_api::object_ptr<td_api::InputMessageContent>> Client::get_input_me
TRY_RESULT(has_spoiler, object.get_optional_bool_field("has_spoiler"));
TRY_RESULT(type, object.get_required_string_field("type"));
- return get_input_media(query, object, type, std::move(caption), show_caption_above_media, has_spoiler, for_album);
+ return get_input_media(query, object, type, std::move(caption), show_caption_above_media, has_spoiler, for_album,
+ false);
}
td::Result<td_api::object_ptr<td_api::InputMessageContent>> Client::get_input_media(
const Query *query, const td::JsonObject &object, const td::string &type,
- object_ptr<td_api::formattedText> &&caption, bool show_caption_above_media, bool has_spoiler,
- bool for_album) const {
+ object_ptr<td_api::formattedText> &&caption, bool show_caption_above_media, bool has_spoiler, bool for_album,
+ bool for_rich_message) const {
TRY_RESULT(media, object.get_optional_string_field("media"));
auto input_file = get_input_file(query, td::Slice(), media, false);
@@ -12287,72 +12708,45 @@ td::Result<td_api::object_ptr<td_api::InputMessageContent>> Client::get_input_me
}
TRY_RESULT(input_thumbnail, get_input_thumbnail(query, object, true));
- if (type == "photo") {
- return make_object<td_api::inputMessagePhoto>(
- make_object<td_api::inputPhoto>(std::move(input_file), nullptr, nullptr, td::vector<int32>(), 0, 0),
- std::move(caption), show_caption_above_media, nullptr, has_spoiler);
- }
- if (type == "live_photo") {
- TRY_RESULT(photo, object.get_optional_string_field("photo"));
- auto input_photo = get_input_file(query, td::Slice(), photo, false);
- if (input_photo == nullptr) {
- return td::Status::Error("photo not found");
- }
- return make_object<td_api::inputMessagePhoto>(
- make_object<td_api::inputPhoto>(std::move(input_photo), nullptr, std::move(input_file), td::vector<int32>(), 0,
- 0),
- std::move(caption), show_caption_above_media, nullptr, has_spoiler);
+ if (type == "photo" || type == "live_photo") {
+ TRY_RESULT(input_photo, get_input_photo(query, object, std::move(input_file), type == "live_photo"));
+ return make_object<td_api::inputMessagePhoto>(std::move(input_photo), std::move(caption), show_caption_above_media,
+ nullptr, has_spoiler);
}
if (type == "video") {
- TRY_RESULT(width, object.get_optional_int_field("width"));
- TRY_RESULT(height, object.get_optional_int_field("height"));
- TRY_RESULT(duration, object.get_optional_int_field("duration"));
- TRY_RESULT(cover, object.get_optional_string_field("cover"));
- TRY_RESULT(start_timestamp, object.get_optional_int_field("start_timestamp"));
- TRY_RESULT(supports_streaming, object.get_optional_bool_field("supports_streaming"));
- auto input_cover = get_input_file(query, td::Slice(), cover, false);
- width = td::clamp(width, 0, MAX_LENGTH);
- height = td::clamp(height, 0, MAX_LENGTH);
- duration = td::clamp(duration, 0, MAX_DURATION);
- start_timestamp = td::clamp(start_timestamp, 0, MAX_DURATION);
-
- return make_object<td_api::inputMessageVideo>(
- make_object<td_api::inputVideo>(std::move(input_file), std::move(input_thumbnail), std::move(input_cover),
- start_timestamp, td::vector<int32>(), duration, width, height,
- supports_streaming),
- std::move(caption), show_caption_above_media, nullptr, has_spoiler);
+ TRY_RESULT(input_video, get_input_video(query, object, std::move(input_file), std::move(input_thumbnail)));
+ return make_object<td_api::inputMessageVideo>(std::move(input_video), std::move(caption), show_caption_above_media,
+ nullptr, has_spoiler);
}
if (type == "animation") {
if (for_album) {
return td::Status::Error(PSLICE() << "type \"" << type << "\" can't be used in sendMediaGroup");
}
- TRY_RESULT(width, object.get_optional_int_field("width"));
- TRY_RESULT(height, object.get_optional_int_field("height"));
- TRY_RESULT(duration, object.get_optional_int_field("duration"));
- width = td::clamp(width, 0, MAX_LENGTH);
- height = td::clamp(height, 0, MAX_LENGTH);
- duration = td::clamp(duration, 0, MAX_DURATION);
- return make_object<td_api::inputMessageAnimation>(
- make_object<td_api::inputAnimation>(std::move(input_file), std::move(input_thumbnail), td::vector<int32>(),
- duration, width, height),
- std::move(caption), show_caption_above_media, has_spoiler);
+ TRY_RESULT(input_animation, get_input_animation(object, std::move(input_file), std::move(input_thumbnail)));
+ return make_object<td_api::inputMessageAnimation>(std::move(input_animation), std::move(caption),
+ show_caption_above_media, has_spoiler);
}
if (type == "audio") {
- TRY_RESULT(duration, object.get_optional_int_field("duration"));
- TRY_RESULT(title, object.get_optional_string_field("title"));
- TRY_RESULT(performer, object.get_optional_string_field("performer"));
- duration = td::clamp(duration, 0, MAX_DURATION);
- return make_object<td_api::inputMessageAudio>(
- make_object<td_api::inputAudio>(std::move(input_file), std::move(input_thumbnail), duration, title, performer),
- std::move(caption));
+ TRY_RESULT(input_audio, get_input_audio(object, std::move(input_file), std::move(input_thumbnail)));
+ return make_object<td_api::inputMessageAudio>(std::move(input_audio), std::move(caption));
}
if (type == "document") {
+ if (for_rich_message) {
+ return td::Status::Error(PSLICE() << "type \"" << type << "\" is not allowed");
+ }
TRY_RESULT(disable_content_type_detection, object.get_optional_bool_field("disable_content_type_detection"));
return make_object<td_api::inputMessageDocument>(
make_object<td_api::inputDocument>(std::move(input_file), std::move(input_thumbnail),
disable_content_type_detection || for_album),
std::move(caption));
}
+ if (type == "voice_note") {
+ if (!for_rich_message) {
+ return td::Status::Error(PSLICE() << "type \"" << type << "\" is not allowed");
+ }
+ TRY_RESULT(input_voice_note, get_input_voice_note(object, std::move(input_file)));
+ return make_object<td_api::inputMessageVoiceNote>(std::move(input_voice_note), std::move(caption), nullptr);
+ }
return td::Status::Error(PSLICE() << "type \"" << type << "\" is unsupported");
}
@@ -12411,60 +12805,29 @@ td::Result<td_api::object_ptr<td_api::InputPollMedia>> Client::get_input_poll_me
}
TRY_RESULT(input_thumbnail, get_input_thumbnail(query, object, true));
- if (type == "photo") {
- return make_object<td_api::inputPollMediaPhoto>(
- make_object<td_api::inputPhoto>(std::move(input_file), nullptr, nullptr, td::vector<int32>(), 0, 0));
- }
- if (type == "live_photo") {
- TRY_RESULT(photo, object.get_optional_string_field("photo"));
- auto input_photo = get_input_file(query, td::Slice(), photo, false);
- if (input_photo == nullptr) {
- return td::Status::Error("photo not found");
- }
- return make_object<td_api::inputPollMediaPhoto>(make_object<td_api::inputPhoto>(
- std::move(input_photo), nullptr, std::move(input_file), td::vector<int32>(), 0, 0));
+ if (type == "photo" || type == "live_photo") {
+ TRY_RESULT(input_photo, get_input_photo(query, object, std::move(input_file), type == "live_photo"));
+ return make_object<td_api::inputPollMediaPhoto>(std::move(input_photo));
}
if (type == "video") {
- TRY_RESULT(width, object.get_optional_int_field("width"));
- TRY_RESULT(height, object.get_optional_int_field("height"));
- TRY_RESULT(duration, object.get_optional_int_field("duration"));
- TRY_RESULT(cover, object.get_optional_string_field("cover"));
- TRY_RESULT(start_timestamp, object.get_optional_int_field("start_timestamp"));
- TRY_RESULT(supports_streaming, object.get_optional_bool_field("supports_streaming"));
- auto input_cover = get_input_file(query, td::Slice(), cover, false);
- width = td::clamp(width, 0, MAX_LENGTH);
- height = td::clamp(height, 0, MAX_LENGTH);
- duration = td::clamp(duration, 0, MAX_DURATION);
- start_timestamp = td::clamp(start_timestamp, 0, MAX_DURATION);
-
- return make_object<td_api::inputPollMediaVideo>(make_object<td_api::inputVideo>(
- std::move(input_file), std::move(input_thumbnail), std::move(input_cover), start_timestamp, td::vector<int32>(),
- duration, width, height, supports_streaming));
+ TRY_RESULT(input_video, get_input_video(query, object, std::move(input_file), std::move(input_thumbnail)));
+ return make_object<td_api::inputPollMediaVideo>(std::move(input_video));
}
if (type == "animation") {
- TRY_RESULT(width, object.get_optional_int_field("width"));
- TRY_RESULT(height, object.get_optional_int_field("height"));
- TRY_RESULT(duration, object.get_optional_int_field("duration"));
- width = td::clamp(width, 0, MAX_LENGTH);
- height = td::clamp(height, 0, MAX_LENGTH);
- duration = td::clamp(duration, 0, MAX_DURATION);
- return make_object<td_api::inputPollMediaAnimation>(make_object<td_api::inputAnimation>(
- std::move(input_file), std::move(input_thumbnail), td::vector<int32>(), duration, width, height));
+ TRY_RESULT(input_animation, get_input_animation(object, std::move(input_file), std::move(input_thumbnail)));
+ return make_object<td_api::inputPollMediaAnimation>(std::move(input_animation));
}
if (for_option ? type != "sticker" : type != "audio" && type != "document") {
return td::Status::Error(PSLICE() << "type \"" << type << "\" is unsupported");
}
if (type == "sticker") {
- return make_object<td_api::inputPollMediaSticker>(std::move(input_file), std::move(input_thumbnail), 0, 0);
+ return make_object<td_api::inputPollMediaSticker>(
+ make_object<td_api::inputSticker>(std::move(input_file), std::move(input_thumbnail), 0, 0));
}
if (type == "audio") {
- TRY_RESULT(duration, object.get_optional_int_field("duration"));
- TRY_RESULT(title, object.get_optional_string_field("title"));
- TRY_RESULT(performer, object.get_optional_string_field("performer"));
- duration = td::clamp(duration, 0, MAX_DURATION);
- return make_object<td_api::inputPollMediaAudio>(
- make_object<td_api::inputAudio>(std::move(input_file), std::move(input_thumbnail), duration, title, performer));
+ TRY_RESULT(input_audio, get_input_audio(object, std::move(input_file), std::move(input_thumbnail)));
+ return make_object<td_api::inputPollMediaAudio>(std::move(input_audio));
}
if (type == "document") {
TRY_RESULT(disable_content_type_detection, object.get_optional_bool_field("disable_content_type_detection"));
@@ -12496,6 +12859,28 @@ td::Result<td_api::object_ptr<td_api::InputPollMedia>> Client::get_input_poll_me
return r_input_message_content.move_as_ok();
}
+td::Result<td_api::object_ptr<td_api::inputRichMessageMedia>> Client::get_input_rich_message_media(
+ const Query *query, td::JsonValue &&input_media) const {
+ if (input_media.type() != td::JsonValue::Type::Object) {
+ return td::Status::Error("expected an Object");
+ }
+
+ auto &object = input_media.get_object();
+ TRY_RESULT(id, object.get_required_string_field("id"));
+ TRY_RESULT(media, object.extract_required_field("media", td::JsonValue::Type::Object));
+ auto &media_object = media.get_object();
+ TRY_RESULT(type, media_object.get_required_string_field("type"));
+ TRY_RESULT(input_message_content, get_input_media(query, media_object, type, nullptr, false, false, false, true));
+ return make_object<td_api::inputRichMessageMedia>(id, std::move(input_message_content));
+}
+
+td::Result<td::vector<td_api::object_ptr<td_api::inputRichMessageMedia>>> Client::get_input_rich_message_medias(
+ const Query *query, td::JsonValue &&value) const {
+ return get_array_generic<td_api::inputRichMessageMedia>(
+ std::move(value), "InputRichMessageMedia",
+ [&](td::JsonValue &&input_media) { return get_input_rich_message_media(query, std::move(input_media)); });
+}
+
td::Result<td::vector<td_api::object_ptr<td_api::InputMessageContent>>> Client::get_input_message_contents(
const Query *query, td::Slice field_name) const {
TRY_RESULT(media, get_required_string_arg(query, field_name));
@@ -12507,25 +12892,9 @@ td::Result<td::vector<td_api::object_ptr<td_api::InputMessageContent>>> Client::
return td::Status::Error(400, "Can't parse media JSON object");
}
- return get_input_message_contents(query, r_value.move_as_ok());
-}
-
-td::Result<td::vector<td_api::object_ptr<td_api::InputMessageContent>>> Client::get_input_message_contents(
- const Query *query, td::JsonValue &&value) const {
- if (value.type() != td::JsonValue::Type::Array) {
- return td::Status::Error(400, "Expected an Array of InputMedia");
- }
-
- td::vector<object_ptr<td_api::InputMessageContent>> contents;
- for (auto &input_media : value.get_array()) {
- auto r_input_message_content = get_input_media(query, std::move(input_media), true);
- if (r_input_message_content.is_error()) {
- return td::Status::Error(400, PSLICE()
- << "Can't parse InputMedia: " << r_input_message_content.error().message());
- }
- contents.push_back(r_input_message_content.move_as_ok());
- }
- return std::move(contents);
+ return get_array_generic<td_api::InputMessageContent>(r_value.move_as_ok(), "InputMedia", [&](td::JsonValue &&value) {
+ return get_input_media(query, std::move(value), true);
+ });
}
td::Result<td_api::object_ptr<td_api::inputPaidMedia>> Client::get_input_paid_media(const Query *query,
@@ -12605,24 +12974,9 @@ td::Result<td::vector<td_api::object_ptr<td_api::inputPaidMedia>>> Client::get_p
return td::Status::Error(400, "Can't parse paid media JSON object");
}
- return get_paid_media(query, r_value.move_as_ok());
-}
-
-td::Result<td::vector<td_api::object_ptr<td_api::inputPaidMedia>>> Client::get_paid_media(const Query *query,
- td::JsonValue &&value) const {
- if (value.type() != td::JsonValue::Type::Array) {
- return td::Status::Error(400, "Expected an Array of InputPaidMedia");
- }
-
- td::vector<object_ptr<td_api::inputPaidMedia>> paid_media;
- for (auto &input_media : value.get_array()) {
- auto r_paid_media = get_input_paid_media(query, std::move(input_media));
- if (r_paid_media.is_error()) {
- return td::Status::Error(400, PSLICE() << "Can't parse InputPaidMedia: " << r_paid_media.error().message());
- }
- paid_media.push_back(r_paid_media.move_as_ok());
- }
- return std::move(paid_media);
+ return get_array_generic<td_api::inputPaidMedia>(
+ r_value.move_as_ok(), "InputPaidMedia",
+ [&](td::JsonValue &&input_media) { return get_input_paid_media(query, std::move(input_media)); });
}
td::Result<td_api::object_ptr<td_api::inputMessageInvoice>> Client::get_input_message_invoice(
@@ -12644,7 +12998,7 @@ td::Result<td_api::object_ptr<td_api::inputMessageInvoice>> Client::get_input_me
return td::Status::Error(400, "Can't parse prices JSON object");
}
- TRY_RESULT(prices, get_labeled_price_parts(r_labeled_price_parts_value.ok_ref()));
+ TRY_RESULT(prices, get_labeled_price_parts(r_labeled_price_parts_value.move_as_ok()));
int64 max_tip_amount = 0;
td::vector<int64> suggested_tip_amounts;
@@ -12665,7 +13019,7 @@ td::Result<td_api::object_ptr<td_api::inputMessageInvoice>> Client::get_input_me
return td::Status::Error(400, "Can't parse suggested_tip_amounts JSON object");
}
- TRY_RESULT_ASSIGN(suggested_tip_amounts, get_suggested_tip_amounts(r_suggested_tip_amounts_value.ok_ref()));
+ TRY_RESULT_ASSIGN(suggested_tip_amounts, get_suggested_tip_amounts(r_suggested_tip_amounts_value.move_as_ok()));
}
}
@@ -12713,34 +13067,29 @@ td::Result<td::vector<td_api::object_ptr<td_api::inputPollOption>>> Client::get_
return td::Status::Error(400, "Can't parse options JSON object");
}
- auto value = r_value.move_as_ok();
- if (value.type() != td::JsonValue::Type::Array) {
- return td::Status::Error(400, "Expected an Array of String as options");
- }
-
- td::vector<object_ptr<td_api::inputPollOption>> options;
- for (auto &input_option : value.get_array()) {
- if (input_option.type() != td::JsonValue::Type::String) {
- if (input_option.type() == td::JsonValue::Type::Object) {
- auto &object = input_option.get_object();
- TRY_RESULT(text, object.get_required_string_field("text"));
- TRY_RESULT(parse_mode, object.get_optional_string_field("text_parse_mode"));
- TRY_RESULT(option_text,
- get_formatted_text(std::move(text), std::move(parse_mode), object.extract_field("text_entities")));
- auto r_media = get_input_poll_media(query, object.extract_field("media"), true);
- if (r_media.is_error()) {
- return td::Status::Error(400, PSLICE() << "Failed to parse poll option media: " << r_media.error().message());
- }
- options.push_back(make_object<td_api::inputPollOption>(std::move(option_text), r_media.move_as_ok()));
- continue;
- }
+ return get_array_generic<td_api::inputPollOption>(
+ r_value.move_as_ok(), "InputPollOption",
+ [&](td::JsonValue &&input_option) -> td::Result<object_ptr<td_api::inputPollOption>> {
+ if (input_option.type() != td::JsonValue::Type::String) {
+ if (input_option.type() == td::JsonValue::Type::Object) {
+ auto &object = input_option.get_object();
+ TRY_RESULT(text, object.get_required_string_field("text"));
+ TRY_RESULT(parse_mode, object.get_optional_string_field("text_parse_mode"));
+ TRY_RESULT(option_text, get_formatted_text(std::move(text), std::move(parse_mode),
+ object.extract_field("text_entities")));
+ auto r_media = get_input_poll_media(query, object.extract_field("media"), true);
+ if (r_media.is_error()) {
+ return td::Status::Error(400, PSLICE()
+ << "Failed to parse poll option media: " << r_media.error().message());
+ }
+ return make_object<td_api::inputPollOption>(std::move(option_text), r_media.move_as_ok());
+ }
- return td::Status::Error(400, "Expected an option to be of type String");
- }
- options.push_back(make_object<td_api::inputPollOption>(
- make_object<td_api::formattedText>(input_option.get_string().str(), td::Auto()), nullptr));
- }
- return std::move(options);
+ return td::Status::Error(400, "Expected InputPollOption to be an Object");
+ }
+ return make_object<td_api::inputPollOption>(
+ make_object<td_api::formattedText>(input_option.get_string().str(), td::Auto()), nullptr);
+ });
}
td::Result<td_api::object_ptr<td_api::ReactionType>> Client::get_reaction_type(td::JsonValue &&value) {
@@ -12774,20 +13123,7 @@ td::Result<td::vector<td_api::object_ptr<td_api::ReactionType>>> Client::get_rea
return td::Status::Error(400, "Can't parse reaction types JSON object");
}
- auto value = r_value.move_as_ok();
- if (value.type() != td::JsonValue::Type::Array) {
- return td::Status::Error(400, "Expected an Array of ReactionType");
- }
-
- td::vector<object_ptr<td_api::ReactionType>> reaction_types;
- for (auto &type : value.get_array()) {
- auto r_reaction_type = get_reaction_type(std::move(type));
- if (r_reaction_type.is_error()) {
- return td::Status::Error(400, PSLICE() << "Can't parse ReactionType: " << r_reaction_type.error().message());
- }
- reaction_types.push_back(r_reaction_type.move_as_ok());
- }
- return std::move(reaction_types);
+ return get_array(r_value.move_as_ok(), "ReactionType", get_reaction_type);
}
td::Result<td_api::object_ptr<td_api::InputStoryAreaType>> Client::get_input_story_area_type(td::JsonValue &&value) {
@@ -12876,19 +13212,7 @@ td::Result<td_api::object_ptr<td_api::inputStoryAreas>> Client::get_input_story_
return td::Status::Error(400, "Can't parse story areas JSON object");
}
- auto value = r_value.move_as_ok();
- if (value.type() != td::JsonValue::Type::Array) {
- return td::Status::Error(400, "Expected an Array of InputStoryArea");
- }
-
- td::vector<object_ptr<td_api::inputStoryArea>> input_story_areas;
- for (auto &area : value.get_array()) {
- auto r_input_story_area = get_input_story_area(std::move(area));
- if (r_input_story_area.is_error()) {
- return td::Status::Error(400, PSLICE() << "Can't parse InputStoryArea: " << r_input_story_area.error().message());
- }
- input_story_areas.push_back(r_input_story_area.move_as_ok());
- }
+ TRY_RESULT(input_story_areas, get_array(r_value.move_as_ok(), "InputStoryArea", get_input_story_area));
return make_object<td_api::inputStoryAreas>(std::move(input_story_areas));
}
@@ -13674,7 +13998,8 @@ td::Status Client::process_send_sticker_query(PromisedQueryPtr &query) {
return td::Status::Error(400, "There is no sticker in the request");
}
auto emoji = query->arg("emoji");
- do_send_message(make_object<td_api::inputMessageSticker>(std::move(sticker), nullptr, 0, 0, emoji.str()),
+ do_send_message(make_object<td_api::inputMessageSticker>(
+ make_object<td_api::inputSticker>(std::move(sticker), nullptr, 0, 0), emoji.str()),
std::move(query));
return td::Status::OK();
}
@@ -13711,9 +14036,10 @@ td::Status Client::process_send_video_note_query(PromisedQueryPtr &query) {
auto thumbnail = get_input_thumbnail(query.get());
int32 duration = get_integer_arg(query.get(), "duration", 0, 0, MAX_DURATION);
int32 length = get_integer_arg(query.get(), "length", 0, 0, MAX_LENGTH);
- do_send_message(make_object<td_api::inputMessageVideoNote>(std::move(video_note), std::move(thumbnail), duration,
- length, nullptr),
- std::move(query));
+ do_send_message(
+ make_object<td_api::inputMessageVideoNote>(
+ make_object<td_api::inputVideoNote>(std::move(video_note), std::move(thumbnail), duration, length), nullptr),
+ std::move(query));
return td::Status::OK();
}
@@ -13725,7 +14051,8 @@ td::Status Client::process_send_voice_query(PromisedQueryPtr &query) {
int32 duration = get_integer_arg(query.get(), "duration", 0, 0, MAX_DURATION);
TRY_RESULT(caption, get_caption(query.get()));
do_send_message(
- make_object<td_api::inputMessageVoiceNote>(std::move(voice_note), duration, "", std::move(caption), nullptr),
+ make_object<td_api::inputMessageVoiceNote>(
+ make_object<td_api::inputVoiceNote>(std::move(voice_note), duration, ""), std::move(caption), nullptr),
std::move(query));
return td::Status::OK();
}
@@ -14092,12 +14419,12 @@ td::Status Client::process_send_media_group_query(PromisedQueryPtr &query) {
[this, reply_parameters = std::move(reply_parameters), disable_notification, protect_content, effect_id,
input_message_contents = std::move(input_message_contents), reply_markup = std::move(reply_markup)](
const BusinessConnection *business_connection, int64 chat_id, PromisedQueryPtr query) mutable {
- send_request(
- make_object<td_api::sendBusinessMessageAlbum>(
- business_connection->id_, chat_id, get_input_message_reply_to(std::move(reply_parameters)),
- disable_notification, protect_content, effect_id, std::move(input_message_contents)),
- td::make_unique<TdOnSendBusinessMessageAlbumCallback>(this, business_connection->id_,
- std::move(query)));
+ send_request(make_object<td_api::sendBusinessMessageAlbum>(
+ business_connection->id_, chat_id,
+ get_input_message_reply_to_unchecked(std::move(reply_parameters)),
+ disable_notification, protect_content, effect_id, std::move(input_message_contents)),
+ td::make_unique<TdOnSendBusinessMessageAlbumCallback>(this, business_connection->id_,
+ std::move(query)));
});
}
@@ -14496,18 +14823,28 @@ td::Status Client::process_edit_message_reply_markup_query(PromisedQueryPtr &que
return td::Status::OK();
}
-td::Status Client::process_delete_message_query(PromisedQueryPtr &query) {
- auto chat_id = query->arg("chat_id");
- auto message_id = get_message_id(query.get());
+td::Status Client::process_edit_ephemeral_message_text_query(PromisedQueryPtr &query) {
+ TRY_RESULT(input_message_text, get_input_message_text(query.get()));
+ return do_edit_ephemeral_message(std::move(input_message_text), query);
+}
- if (chat_id.empty()) {
- return td::Status::Error(400, "Chat identifier is not specified");
- }
+td::Status Client::process_edit_ephemeral_message_media_query(PromisedQueryPtr &query) {
+ TRY_RESULT(input_media, get_input_media(query.get(), "media"));
+ return do_edit_ephemeral_message(std::move(input_media), query);
+}
- if (message_id == 0) {
- return td::Status::Error(400, "Message identifier is not specified");
- }
+td::Status Client::process_edit_ephemeral_message_caption_query(PromisedQueryPtr &query) {
+ TRY_RESULT(caption, get_caption(query.get()));
+ return do_edit_ephemeral_message(make_object<td_api::inputMessageText>(std::move(caption), nullptr, false), query);
+}
+td::Status Client::process_edit_ephemeral_message_reply_markup_query(PromisedQueryPtr &query) {
+ return do_edit_ephemeral_message(nullptr, query);
+}
+
+td::Status Client::process_delete_message_query(PromisedQueryPtr &query) {
+ auto chat_id = query->arg("chat_id");
+ auto message_id = get_message_id(query.get());
check_message(chat_id, message_id, false, AccessRights::Write, "message to delete", std::move(query),
[this](int64 chat_id, int64 message_id, PromisedQueryPtr query) {
send_request(make_object<td_api::deleteMessages>(chat_id, td::vector<int64>{message_id}, true),
@@ -14519,9 +14856,6 @@ td::Status Client::process_delete_message_query(PromisedQueryPtr &query) {
td::Status Client::process_delete_messages_query(PromisedQueryPtr &query) {
auto chat_id = query->arg("chat_id");
TRY_RESULT(message_ids, get_message_ids(query.get(), 100));
- if (message_ids.empty()) {
- return td::Status::Error(400, "Message identifiers are not specified");
- }
check_messages(chat_id, std::move(message_ids), true, AccessRights::Write, "message to delete", std::move(query),
[this](int64 chat_id, td::vector<int64> message_ids, PromisedQueryPtr query) {
send_request(make_object<td_api::deleteMessages>(chat_id, std::move(message_ids), true),
@@ -14530,6 +14864,19 @@ td::Status Client::process_delete_messages_query(PromisedQueryPtr &query) {
return td::Status::OK();
}
+td::Status Client::process_delete_ephemeral_message_query(PromisedQueryPtr &query) {
+ auto chat_id = query->arg("chat_id");
+ TRY_RESULT(receiver_user_id, get_user_id(query.get(), "receiver_user_id"));
+ auto ephemeral_message_id = get_integer_arg(query.get(), "ephemeral_message_id", 0);
+ check_chat(chat_id, AccessRights::Read, std::move(query),
+ [this, receiver_user_id, ephemeral_message_id](int64 chat_id, PromisedQueryPtr query) {
+ send_request(
+ make_object<td_api::deleteEphemeralMessage>(chat_id, receiver_user_id, ephemeral_message_id),
+ td::make_unique<TdOnOkQueryCallback>(std::move(query)));
+ });
+ return td::Status::OK();
+}
+
td::Status Client::process_delete_message_reaction_query(PromisedQueryPtr &query) {
auto chat_id = query->arg("chat_id");
auto message_id = get_message_id(query.get());
@@ -15040,7 +15387,7 @@ td::Status Client::process_save_prepared_keyboard_button_query(PromisedQueryPtr
return td::Status::Error(400, "Can't parse keyboard button JSON object");
}
auto value = r_value.move_as_ok();
- auto r_button = get_keyboard_button(value);
+ auto r_button = get_keyboard_button(std::move(value));
if (r_button.is_error()) {
return td::Status::Error(400, PSLICE() << "Can't parse keyboard button: " << r_button.error().message());
}
@@ -16249,7 +16596,7 @@ td::Status Client::process_create_new_sticker_set_query(PromisedQueryPtr &query)
auto name = query->arg("name");
auto title = query->arg("title");
auto needs_repainting = to_bool(query->arg("needs_repainting"));
- TRY_RESULT(stickers, get_input_stickers(query.get()));
+ TRY_RESULT(stickers, get_new_stickers(query.get()));
TRY_RESULT(sticker_type, get_sticker_type(query->arg("sticker_type")));
if (to_bool(query->arg("contains_masks"))) {
@@ -16270,7 +16617,7 @@ td::Status Client::process_create_new_sticker_set_query(PromisedQueryPtr &query)
td::Status Client::process_add_sticker_to_set_query(PromisedQueryPtr &query) {
TRY_RESULT(user_id, get_user_id(query.get()));
auto name = query->arg("name");
- TRY_RESULT(sticker, get_input_sticker(query.get()));
+ TRY_RESULT(sticker, get_new_sticker(query.get()));
check_user(user_id, std::move(query),
[this, user_id, name, sticker = std::move(sticker)](PromisedQueryPtr query) mutable {
@@ -16284,7 +16631,7 @@ td::Status Client::process_replace_sticker_in_set_query(PromisedQueryPtr &query)
TRY_RESULT(user_id, get_user_id(query.get()));
auto name = query->arg("name");
TRY_RESULT(input_file, get_sticker_input_file(query.get(), "old_sticker"));
- TRY_RESULT(sticker, get_input_sticker(query.get()));
+ TRY_RESULT(sticker, get_new_sticker(query.get()));
check_user(user_id, std::move(query),
[this, user_id, name, input_file = std::move(input_file),
@@ -16853,6 +17200,15 @@ void Client::do_send_message(object_ptr<td_api::InputMessageContent> input_messa
auto chat_id = query->arg("chat_id");
auto forum_topic_id = get_forum_topic_id(query.get(), "message_thread_id");
auto business_connection_id = query->arg("business_connection_id");
+ int64 receiver_user_id = 0;
+ if (query->has_arg("receiver_user_id")) {
+ auto r_receiver_user_id = get_user_id(query.get(), "receiver_user_id");
+ if (r_receiver_user_id.is_error()) {
+ return fail_query_with_error(std::move(query), 400, r_receiver_user_id.error().message());
+ }
+ receiver_user_id = r_receiver_user_id.move_as_ok();
+ }
+ auto callback_query_id = td::to_integer<int64>(query->arg("callback_query_id"));
auto r_reply_parameters = get_reply_parameters(query.get());
if (r_reply_parameters.is_error()) {
return fail_query_with_error(std::move(query), 400, r_reply_parameters.error().message());
@@ -16878,26 +17234,27 @@ void Client::do_send_message(object_ptr<td_api::InputMessageContent> input_messa
resolve_reply_markup_bot_usernames(
std::move(reply_markup), std::move(query),
[this, chat_id_str = chat_id.str(), forum_topic_id, direct_messages_topic_id,
- business_connection_id = business_connection_id.str(), reply_parameters = std::move(reply_parameters),
- disable_notification, protect_content, allow_paid_broadcast, effect_id, send_options = std::move(send_options),
- input_message_content = std::move(input_message_content)](object_ptr<td_api::ReplyMarkup> reply_markup,
- PromisedQueryPtr query) mutable {
+ business_connection_id = business_connection_id.str(), receiver_user_id, callback_query_id,
+ reply_parameters = std::move(reply_parameters), disable_notification, protect_content, allow_paid_broadcast,
+ effect_id, send_options = std::move(send_options), input_message_content = std::move(input_message_content)](
+ object_ptr<td_api::ReplyMarkup> reply_markup, PromisedQueryPtr query) mutable {
if (!business_connection_id.empty()) {
return check_business_connection_chat_id(
business_connection_id, chat_id_str, std::move(query),
[this, reply_parameters = std::move(reply_parameters), disable_notification, protect_content, effect_id,
reply_markup = std::move(reply_markup), input_message_content = std::move(input_message_content)](
const BusinessConnection *business_connection, int64 chat_id, PromisedQueryPtr query) mutable {
- send_request(make_object<td_api::sendBusinessMessage>(
- business_connection->id_, chat_id,
- get_input_message_reply_to(std::move(reply_parameters)), disable_notification,
- protect_content, effect_id, std::move(reply_markup), std::move(input_message_content)),
- td::make_unique<TdOnReturnBusinessMessageCallback>(this, business_connection->id_,
- std::move(query)));
+ send_request(
+ make_object<td_api::sendBusinessMessage>(
+ business_connection->id_, chat_id,
+ get_input_message_reply_to_unchecked(std::move(reply_parameters)), disable_notification,
+ protect_content, effect_id, std::move(reply_markup), std::move(input_message_content)),
+ td::make_unique<TdOnReturnBusinessMessageCallback>(this, business_connection->id_,
+ std::move(query)));
});
}
- auto on_success = [this, send_options = std::move(send_options),
+ auto on_success = [this, receiver_user_id, callback_query_id, send_options = std::move(send_options),
input_message_content = std::move(input_message_content),
reply_markup = std::move(reply_markup)](
int64 chat_id, object_ptr<td_api::MessageTopic> topic_id,
@@ -16908,6 +17265,14 @@ void Client::do_send_message(object_ptr<td_api::InputMessageContent> input_messa
}
count++;
+ if (receiver_user_id != 0) {
+ return send_request(make_object<td_api::sendEphemeralMessage>(
+ chat_id, std::move(topic_id), receiver_user_id, callback_query_id,
+ get_input_message_reply_to(std::move(reply_parameters)), 0, false,
+ std::move(reply_markup), std::move(input_message_content)),
+ td::make_unique<TdOnSendMessageCallback>(this, chat_id, std::move(query)));
+ }
+
send_request(make_object<td_api::sendMessage>(
chat_id, std::move(topic_id), get_input_message_reply_to(std::move(reply_parameters)),
std::move(send_options), std::move(reply_markup), std::move(input_message_content)),
@@ -16956,6 +17321,31 @@ void Client::on_sent_story(object_ptr<td_api::story> &&story, PromisedQueryPtr q
CHECK(emplace_result.second);
}
+td::Status Client::do_edit_ephemeral_message(object_ptr<td_api::InputMessageContent> input_message_content,
+ PromisedQueryPtr &query) {
+ auto chat_id = query->arg("chat_id");
+ TRY_RESULT(receiver_user_id, get_user_id(query.get(), "receiver_user_id"));
+ auto ephemeral_message_id = get_integer_arg(query.get(), "ephemeral_message_id", 0);
+ TRY_RESULT(reply_markup, get_reply_markup(query.get(), bot_user_ids_));
+
+ resolve_reply_markup_bot_usernames(
+ std::move(reply_markup), std::move(query),
+ [this, chat_id_str = chat_id.str(), receiver_user_id, ephemeral_message_id,
+ input_message_content = std::move(input_message_content)](object_ptr<td_api::ReplyMarkup> reply_markup,
+ PromisedQueryPtr query) mutable {
+ check_chat(
+ chat_id_str, AccessRights::Edit, std::move(query),
+ [this, receiver_user_id, ephemeral_message_id, input_message_content = std::move(input_message_content),
+ reply_markup = std::move(reply_markup)](int64 chat_id, PromisedQueryPtr query) mutable {
+ send_request(
+ make_object<td_api::editEphemeralMessage>(chat_id, receiver_user_id, ephemeral_message_id,
+ std::move(reply_markup), std::move(input_message_content)),
+ td::make_unique<TdOnOkQueryCallback>(std::move(query)));
+ });
+ });
+ return td::Status::OK();
+}
+
void Client::abort_long_poll(bool from_set_webhook) {
if (long_poll_query_) {
td::Slice message;
@@ -17289,6 +17679,22 @@ const Client::ChatInfo *Client::get_chat(int64 chat_id) const {
return chats_.get_pointer(chat_id);
}
+void Client::add_community(CommunityInfo *community_info, object_ptr<td_api::community> &&community) {
+ community_info->name = std::move(community->name_);
+}
+
+Client::CommunityInfo *Client::add_community_info(int64 community_id) {
+ auto &community_info = communities_[community_id];
+ if (community_info == nullptr) {
+ community_info = td::make_unique<CommunityInfo>();
+ }
+ return community_info.get();
+}
+
+const Client::CommunityInfo *Client::get_community_info(int64 community_id) const {
+ return communities_.get_pointer(community_id);
+}
+
void Client::set_chat_available_reactions(ChatInfo *chat_info,
object_ptr<td_api::ChatAvailableReactions> &&available_reactions) {
CHECK(chat_info != nullptr);
@@ -17615,13 +18021,15 @@ td::Slice Client::get_update_type_name(UpdateType update_type) {
return td::Slice("managed_bot");
case UpdateType::GuestMessage:
return td::Slice("guest_message");
+ case UpdateType::Subscription:
+ return td::Slice("subscription");
default:
UNREACHABLE();
return td::Slice();
}
}
-td::uint32 Client::get_allowed_update_types(td::MutableSlice allowed_updates, bool is_internal) {
+td::uint64 Client::get_allowed_update_types(td::MutableSlice allowed_updates, bool is_internal) {
if (allowed_updates.empty()) {
return 0;
}
@@ -17633,11 +18041,11 @@ td::uint32 Client::get_allowed_update_types(td::MutableSlice allowed_updates, bo
return 0;
}
- td::uint32 result = 0;
+ td::uint64 result = 0;
auto value = r_value.move_as_ok();
if (value.type() != td::JsonValue::Type::Array) {
if (value.type() == td::JsonValue::Type::Number && is_internal) {
- auto r_number = td::to_integer_safe<td::uint32>(value.get_number());
+ auto r_number = td::to_integer_safe<td::uint64>(value.get_number());
if (r_number.is_ok() && r_number.ok() > 0) {
return r_number.ok();
}
@@ -17652,7 +18060,7 @@ td::uint32 Client::get_allowed_update_types(td::MutableSlice allowed_updates, bo
to_lower_inplace(type_name);
for (int32 i = 0; i < static_cast<int32>(UpdateType::Size); i++) {
if (get_update_type_name(static_cast<UpdateType>(i)) == type_name) {
- result |= (1 << i);
+ result |= (static_cast<td::uint64>(1) << i);
}
}
}
@@ -17671,7 +18079,7 @@ bool Client::update_allowed_update_types(const Query *query) {
if (allowed_update_types == DEFAULT_ALLOWED_UPDATE_TYPES) {
value = make_object<td_api::optionValueEmpty>();
} else {
- value = make_object<td_api::optionValueInteger>(allowed_update_types);
+ value = make_object<td_api::optionValueInteger>(static_cast<int64>(allowed_update_types));
}
send_request(make_object<td_api::setOption>("xallowed_update_types", std::move(value)),
td::make_unique<TdOnOkCallback>());
@@ -17887,11 +18295,12 @@ void Client::process_new_callback_query_queue(int64 user_id, int state) {
CHECK(state == 3);
CHECK(user_id == query->sender_user_id_);
- add_update(UpdateType::CallbackQuery,
- JsonCallbackQuery(query->id_, user_id, chat_id, message_id, message_info, query->chat_instance_,
- query->payload_.get(), this),
- 150, user_id + (static_cast<int64>(3) << 33));
-
+ if (message_info != nullptr || as_tdlib_message_id(as_client_message_id_unchecked(message_id)) == message_id) {
+ add_update(UpdateType::CallbackQuery,
+ JsonCallbackQuery(query->id_, user_id, chat_id, message_id, message_info, query->chat_instance_,
+ query->payload_.get(), this),
+ 150, user_id + (static_cast<int64>(3) << 33));
+ }
queue.queue_.pop();
state = 0;
}
@@ -17989,6 +18398,12 @@ void Client::add_update_managed_bot(object_ptr<td_api::updateManagedBot> &&query
query->user_id_ + (static_cast<int64>(13) << 33));
}
+void Client::add_update_subscription(object_ptr<td_api::updateUserSubscription> &&query) {
+ CHECK(query != nullptr);
+ add_update(UpdateType::Subscription, JsonBotSubscriptionUpdated(query.get(), this), 86400,
+ query->user_id_ + (static_cast<int64>(14) << 33));
+}
+
void Client::add_new_custom_event(object_ptr<td_api::updateNewCustomEvent> &&event) {
CHECK(event != nullptr);
add_update(UpdateType::CustomEvent, JsonCustomJson(event->event_), 600, 0);
@@ -18413,9 +18828,9 @@ bool Client::are_equal_suggested_post_prices(const td_api::SuggestedPostPrice *l
case td_api::suggestedPostPriceStar::ID:
return static_cast<const td_api::suggestedPostPriceStar *>(lhs)->star_count_ ==
static_cast<const td_api::suggestedPostPriceStar *>(rhs)->star_count_;
- case td_api::suggestedPostPriceTon::ID:
- return static_cast<const td_api::suggestedPostPriceTon *>(lhs)->toncoin_cent_count_ ==
- static_cast<const td_api::suggestedPostPriceTon *>(rhs)->toncoin_cent_count_;
+ case td_api::suggestedPostPriceGram::ID:
+ return static_cast<const td_api::suggestedPostPriceGram *>(lhs)->gram_cent_count_ ==
+ static_cast<const td_api::suggestedPostPriceGram *>(rhs)->gram_cent_count_;
default:
UNREACHABLE();
return false;
@@ -18868,6 +19283,8 @@ td::unique_ptr<Client::MessageInfo> Client::create_message(object_ptr<td_api::me
int64 chat_id = message->chat_id_;
message_info->id = message->id_;
message_info->chat_id = chat_id;
+ message_info->receiver_id = std::move(message->receiver_id_);
+ message_info->ephemeral_message_id = message->ephemeral_message_id_;
message_info->date = message->date_;
message_info->edit_date = message->edit_date_;
message_info->media_album_id = message->media_album_id_;
@@ -18924,7 +19341,7 @@ td::unique_ptr<Client::MessageInfo> Client::create_message(object_ptr<td_api::me
message_info->sender_tag = std::move(message->sender_tag_);
message_info->paid_message_star_count = message->paid_message_star_count_;
message_info->effect_id = message->effect_id_;
- message_info->is_paid_post = message->is_paid_star_suggested_post_ || message->is_paid_ton_suggested_post_;
+ message_info->is_paid_post = message->is_paid_star_suggested_post_ || message->is_paid_gram_suggested_post_;
message_info->is_outgoing = message->is_outgoing_;
message_info->is_self_destruct = message->self_destruct_type_ != nullptr;
message_info->is_imported = message->import_info_ != nullptr;
diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h
index bf60e99..60f8acf 100644
--- a/telegram-bot-api/Client.h
+++ b/telegram-bot-api/Client.h
@@ -29,6 +29,7 @@
#include "td/utils/Status.h"
#include "td/utils/WaitFreeHashMap.h"
+#include <functional>
#include <limits>
#include <memory>
#include <queue>
@@ -89,6 +90,7 @@ class Client final : public WebhookActor::Callback {
class JsonFile;
class JsonDatedFile;
class JsonDatedFiles;
+ class JsonCommunity;
class JsonUser;
class JsonUsers;
class JsonReactionType;
@@ -244,6 +246,8 @@ class Client final : public WebhookActor::Callback {
class JsonChatShared;
class JsonManagedBotCreated;
class JsonManagedBotUpdated;
+ class JsonCommunityChatAdded;
+ class JsonBotSubscriptionUpdated;
class JsonGiveawayCreated;
class JsonGiveaway;
class JsonGiveawayWinners;
@@ -352,6 +356,7 @@ class Client final : public WebhookActor::Callback {
struct InputReplyParameters {
td::string reply_in_chat_id;
int64 reply_to_message_id = 0;
+ int32 reply_to_ephemeral_message_id = 0;
bool allow_sending_without_reply = false;
object_ptr<td_api::inputTextQuote> quote;
int32 checklist_task_id = 0;
@@ -361,6 +366,7 @@ class Client final : public WebhookActor::Callback {
struct CheckedReplyParameters {
int64 reply_in_chat_id = 0;
int64 reply_to_message_id = 0;
+ int32 reply_to_ephemeral_message_id = 0;
object_ptr<td_api::inputTextQuote> quote;
int32 checklist_task_id = 0;
td::string poll_option_id;
@@ -497,9 +503,19 @@ class Client final : public WebhookActor::Callback {
static bool is_reply_in_same_topic(const object_ptr<td_api::MessageTopic> &reply_topic_id,
const object_ptr<td_api::MessageTopic> &topic_id);
+ template <class T>
+ static td::Result<td::vector<T>> get_array(td::JsonValue &&values, td::Slice class_name,
+ td::Result<T> (*func)(td::JsonValue &&value));
+
+ template <class T>
+ static td::Result<td::vector<object_ptr<T>>> get_array_generic(
+ td::JsonValue &&values, td::Slice class_name,
+ const std::function<td::Result<object_ptr<T>>(td::JsonValue &&value)> &func);
+
static object_ptr<td_api::InputMessageReplyTo> get_input_message_reply_to(CheckedReplyParameters &&reply_parameters);
- static object_ptr<td_api::InputMessageReplyTo> get_input_message_reply_to(InputReplyParameters &&reply_parameters);
+ static object_ptr<td_api::InputMessageReplyTo> get_input_message_reply_to_unchecked(
+ InputReplyParameters &&reply_parameters);
static td::Result<InputReplyParameters> get_reply_parameters(const Query *query);
@@ -509,12 +525,12 @@ class Client final : public WebhookActor::Callback {
static td::Result<object_ptr<td_api::KeyboardButtonType>> get_keyboard_button_type(td::JsonObject &object);
- static td::Result<object_ptr<td_api::keyboardButton>> get_keyboard_button(td::JsonValue &button);
+ static td::Result<object_ptr<td_api::keyboardButton>> get_keyboard_button(td::JsonValue &&button);
static td::Result<object_ptr<td_api::InlineKeyboardButtonType>> get_inline_keyboard_button_type(
td::JsonObject &object, BotUserIds &bot_user_ids);
- static td::Result<object_ptr<td_api::inlineKeyboardButton>> get_inline_keyboard_button(td::JsonValue &button,
+ static td::Result<object_ptr<td_api::inlineKeyboardButton>> get_inline_keyboard_button(td::JsonValue &&button,
BotUserIds &bot_user_ids);
static td::Result<object_ptr<td_api::ReplyMarkup>> get_reply_markup(const Query *query, BotUserIds &bot_user_ids);
@@ -527,20 +543,20 @@ class Client final : public WebhookActor::Callback {
static td::Result<object_ptr<td_api::inputSuggestedPostInfo>> get_input_suggested_post_info(td::JsonValue &&value);
- static td::Result<object_ptr<td_api::labeledPricePart>> get_labeled_price_part(td::JsonValue &value);
+ static td::Result<object_ptr<td_api::labeledPricePart>> get_labeled_price_part(td::JsonValue &&value);
- static td::Result<td::vector<object_ptr<td_api::labeledPricePart>>> get_labeled_price_parts(td::JsonValue &value);
+ static td::Result<td::vector<object_ptr<td_api::labeledPricePart>>> get_labeled_price_parts(td::JsonValue &&value);
- static td::Result<td::vector<int64>> get_suggested_tip_amounts(td::JsonValue &value);
+ static td::Result<int64> get_suggested_tip_amount(td::JsonValue &&value);
- static td::Result<object_ptr<td_api::shippingOption>> get_shipping_option(td::JsonValue &option);
+ static td::Result<td::vector<int64>> get_suggested_tip_amounts(td::JsonValue &&value);
- static td::Result<td::vector<object_ptr<td_api::shippingOption>>> get_shipping_options(const Query *query);
+ static td::Result<object_ptr<td_api::shippingOption>> get_shipping_option(td::JsonValue &&option);
- static td::Result<td::vector<object_ptr<td_api::shippingOption>>> get_shipping_options(td::JsonValue &&value);
+ static td::Result<td::vector<object_ptr<td_api::shippingOption>>> get_shipping_options(const Query *query);
- static td::Result<object_ptr<td_api::InputMessageContent>> get_input_message_content(
- td::JsonValue &input_message_content, bool is_input_message_content_required);
+ td::Result<object_ptr<td_api::InputMessageContent>> get_input_message_content(
+ const Query *query, td::JsonObject &object, bool is_input_message_content_required) const;
static object_ptr<td_api::ChatAction> get_chat_action(const Query *query);
@@ -562,17 +578,15 @@ class Client final : public WebhookActor::Callback {
static td::Result<object_ptr<td_api::inlineQueryResultsButton>> get_inline_query_results_button(
td::MutableSlice value);
- static td::Result<object_ptr<td_api::InputInlineQueryResult>> get_inline_query_result(const Query *query,
- BotUserIds &bot_user_ids);
+ td::Result<object_ptr<td_api::InputInlineQueryResult>> get_inline_query_result(const Query *query,
+ BotUserIds &bot_user_ids) const;
- static td::Result<object_ptr<td_api::InputInlineQueryResult>> get_inline_query_result(td::JsonValue &&value,
- BotUserIds &bot_user_ids);
+ td::Result<object_ptr<td_api::InputInlineQueryResult>> get_inline_query_result(const Query *query,
+ td::JsonValue &&value,
+ BotUserIds &bot_user_ids) const;
- static td::Result<td::vector<object_ptr<td_api::InputInlineQueryResult>>> get_inline_query_results(
- const Query *query, BotUserIds &bot_user_ids);
-
- static td::Result<td::vector<object_ptr<td_api::InputInlineQueryResult>>> get_inline_query_results(
- td::JsonValue &&value, BotUserIds &bot_user_ids);
+ td::Result<td::vector<object_ptr<td_api::InputInlineQueryResult>>> get_inline_query_results(
+ const Query *query, BotUserIds &bot_user_ids) const;
struct BotCommandScope {
object_ptr<td_api::BotCommandScope> scope_;
@@ -615,14 +629,14 @@ class Client final : public WebhookActor::Callback {
static td::Result<object_ptr<td_api::StickerFormat>> get_sticker_format(td::Slice sticker_format);
- td::Result<object_ptr<td_api::inputSticker>> get_legacy_input_sticker(const Query *query) const;
+ td::Result<object_ptr<td_api::newSticker>> get_legacy_new_sticker(const Query *query) const;
- td::Result<object_ptr<td_api::inputSticker>> get_input_sticker(const Query *query) const;
+ td::Result<object_ptr<td_api::newSticker>> get_new_sticker(const Query *query) const;
- td::Result<object_ptr<td_api::inputSticker>> get_input_sticker(const Query *query, td::JsonValue &&value,
- td::Slice default_sticker_format) const;
+ td::Result<object_ptr<td_api::newSticker>> get_new_sticker(const Query *query, td::JsonValue &&value,
+ td::Slice default_sticker_format) const;
- td::Result<td::vector<object_ptr<td_api::inputSticker>>> get_input_stickers(const Query *query) const;
+ td::Result<td::vector<object_ptr<td_api::newSticker>>> get_new_stickers(const Query *query) const;
static td::Result<object_ptr<td_api::InputFile>> get_sticker_input_file(const Query *query,
td::Slice field_name = "sticker");
@@ -660,9 +674,24 @@ class Client final : public WebhookActor::Callback {
td::string text, object_ptr<td_api::linkPreviewOptions> link_preview_options, td::string parse_mode,
td::JsonValue &&input_entities);
- static td::Result<object_ptr<td_api::inputRichMessage>> get_input_rich_message(const Query *query);
+ static td::Result<object_ptr<td_api::pageBlockCaption>> get_page_block_caption(td::JsonValue &&value);
+
+ static td::Result<object_ptr<td_api::pageBlockTableCell>> get_page_block_table_cell(td::JsonValue &&value);
- static td::Result<object_ptr<td_api::inputRichMessage>> get_input_rich_message(td::JsonValue &&value);
+ static td::Result<object_ptr<td_api::RichText>> get_rich_text(td::JsonValue &&value);
+
+ td::Result<td_api::object_ptr<td_api::inputPageBlockListItem>> get_input_page_block_list_item(
+ const Query *query, td::JsonValue &&value) const;
+
+ td::Result<object_ptr<td_api::InputPageBlock>> get_input_page_block(const Query *query, td::JsonValue &&value) const;
+
+ td::Result<td::vector<object_ptr<td_api::InputPageBlock>>> get_input_page_blocks(const Query *query,
+ td::JsonValue &&value) const;
+
+ td::Result<object_ptr<td_api::inputRichMessage>> get_input_rich_message(const Query *query) const;
+
+ td::Result<object_ptr<td_api::inputRichMessage>> get_input_rich_message(const Query *query,
+ td::JsonValue &&value) const;
static td::Result<object_ptr<td_api::location>> get_location(const Query *query);
@@ -673,9 +702,26 @@ class Client final : public WebhookActor::Callback {
static td::Result<object_ptr<td_api::chatPermissions>> get_chat_permissions(const Query *query, bool &allow_legacy,
bool use_independent_chat_permissions);
- td::Result<object_ptr<td_api::inputChecklistTask>> get_input_checklist_task(td::JsonValue &&input_task) const;
+ static td::Result<object_ptr<td_api::inputAnimation>> get_input_animation(
+ const td::JsonObject &object, object_ptr<td_api::InputFile> &&input_file,
+ object_ptr<td_api::inputThumbnail> &&input_thumbnail);
+
+ static td::Result<object_ptr<td_api::inputAudio>> get_input_audio(
+ const td::JsonObject &object, object_ptr<td_api::InputFile> &&input_file,
+ object_ptr<td_api::inputThumbnail> &&input_thumbnail);
+
+ td::Result<object_ptr<td_api::inputPhoto>> get_input_photo(const Query *query, const td::JsonObject &object,
+ object_ptr<td_api::InputFile> &&input_file,
+ bool is_live) const;
- td::Result<td::vector<object_ptr<td_api::inputChecklistTask>>> get_input_checklist_tasks(td::JsonValue &&value) const;
+ td::Result<object_ptr<td_api::inputVideo>> get_input_video(
+ const Query *query, const td::JsonObject &object, object_ptr<td_api::InputFile> &&input_file,
+ object_ptr<td_api::inputThumbnail> &&input_thumbnail) const;
+
+ static td::Result<object_ptr<td_api::inputVoiceNote>> get_input_voice_note(
+ const td::JsonObject &object, object_ptr<td_api::InputFile> &&input_file);
+
+ static td::Result<object_ptr<td_api::inputChecklistTask>> get_input_checklist_task(td::JsonValue &&input_task);
td::Result<object_ptr<td_api::inputChecklist>> get_input_checklist(const Query *query,
td::JsonValue &&input_checklist) const;
@@ -689,7 +735,7 @@ class Client final : public WebhookActor::Callback {
const td::string &type,
object_ptr<td_api::formattedText> &&caption,
bool show_caption_above_media, bool has_spoiler,
- bool for_album) const;
+ bool for_album, bool for_rich_message) const;
td::Result<object_ptr<td_api::InputMessageContent>> get_input_media(const Query *query, td::Slice field_name) const;
@@ -698,12 +744,15 @@ class Client final : public WebhookActor::Callback {
td::Result<object_ptr<td_api::InputPollMedia>> get_input_poll_media(const Query *query, td::Slice field_name) const;
- td::Result<td::vector<object_ptr<td_api::InputMessageContent>>> get_input_message_contents(
- const Query *query, td::Slice field_name) const;
+ td::Result<object_ptr<td_api::inputRichMessageMedia>> get_input_rich_message_media(const Query *query,
+ td::JsonValue &&input_media) const;
- td::Result<td::vector<object_ptr<td_api::InputMessageContent>>> get_input_message_contents(
+ td::Result<td::vector<object_ptr<td_api::inputRichMessageMedia>>> get_input_rich_message_medias(
const Query *query, td::JsonValue &&value) const;
+ td::Result<td::vector<object_ptr<td_api::InputMessageContent>>> get_input_message_contents(
+ const Query *query, td::Slice field_name) const;
+
td::Result<object_ptr<td_api::inputPaidMedia>> get_input_paid_media(const Query *query,
td::JsonValue &&input_media) const;
@@ -712,9 +761,6 @@ class Client final : public WebhookActor::Callback {
td::Result<td::vector<object_ptr<td_api::inputPaidMedia>>> get_paid_media(const Query *query,
td::Slice field_name) const;
- td::Result<td::vector<object_ptr<td_api::inputPaidMedia>>> get_paid_media(const Query *query,
- td::JsonValue &&value) const;
-
td::Result<object_ptr<td_api::inputMessageInvoice>> get_input_message_invoice(const Query *query) const;
static object_ptr<td_api::messageSendOptions> get_message_send_options(
@@ -841,8 +887,13 @@ class Client final : public WebhookActor::Callback {
td::Status process_edit_message_caption_query(PromisedQueryPtr &query);
td::Status process_edit_message_checklist_query(PromisedQueryPtr &query);
td::Status process_edit_message_reply_markup_query(PromisedQueryPtr &query);
+ td::Status process_edit_ephemeral_message_text_query(PromisedQueryPtr &query);
+ td::Status process_edit_ephemeral_message_media_query(PromisedQueryPtr &query);
+ td::Status process_edit_ephemeral_message_caption_query(PromisedQueryPtr &query);
+ td::Status process_edit_ephemeral_message_reply_markup_query(PromisedQueryPtr &query);
td::Status process_delete_message_query(PromisedQueryPtr &query);
td::Status process_delete_messages_query(PromisedQueryPtr &query);
+ td::Status process_delete_ephemeral_message_query(PromisedQueryPtr &query);
td::Status process_delete_message_reaction_query(PromisedQueryPtr &query);
td::Status process_delete_all_message_reactions_query(PromisedQueryPtr &query);
td::Status process_post_story_query(PromisedQueryPtr &query);
@@ -982,7 +1033,7 @@ class Client final : public WebhookActor::Callback {
void on_webhook_closed(td::Status status);
- void delete_last_send_message_time(td::int64 file_size, double max_delay);
+ void delete_last_send_message_time(int64 file_size, double max_delay);
void do_send_message(object_ptr<td_api::InputMessageContent> input_message_content, PromisedQueryPtr query,
bool force = false);
@@ -993,6 +1044,9 @@ class Client final : public WebhookActor::Callback {
void on_sent_story(object_ptr<td_api::story> &&story, PromisedQueryPtr query);
+ td::Status do_edit_ephemeral_message(object_ptr<td_api::InputMessageContent> input_message_content,
+ PromisedQueryPtr &query);
+
void do_get_file(object_ptr<td_api::file> file, PromisedQueryPtr query);
bool is_file_being_downloaded(int32 file_id) const;
@@ -1071,6 +1125,7 @@ class Client final : public WebhookActor::Callback {
object_ptr<td_api::audio> first_profile_audio;
int64 personal_chat_id = 0;
int64 paid_message_star_count = 0;
+ int64 community_id = 0;
bool have_access = false;
bool can_join_groups = false;
@@ -1121,6 +1176,7 @@ class Client final : public WebhookActor::Callback {
int64 direct_messages_chat_id = 0;
int64 paid_message_star_count = 0;
int64 guard_bot_user_id = 0;
+ int64 community_id = 0;
object_ptr<td_api::chatLocation> location;
object_ptr<td_api::ChatMemberStatus> status;
bool is_supergroup = false;
@@ -1166,6 +1222,13 @@ class Client final : public WebhookActor::Callback {
ChatInfo *add_chat(int64 chat_id);
const ChatInfo *get_chat(int64 chat_id) const;
+ struct CommunityInfo {
+ td::string name;
+ };
+ static void add_community(CommunityInfo *community_info, object_ptr<td_api::community> &&community);
+ CommunityInfo *add_community_info(int64 community_id);
+ const CommunityInfo *get_community_info(int64 community_id) const;
+
void set_chat_available_reactions(ChatInfo *chat_info,
object_ptr<td_api::ChatAvailableReactions> &&available_reactions);
@@ -1180,10 +1243,12 @@ class Client final : public WebhookActor::Callback {
int64 sender_user_id = 0;
int64 sender_chat_id = 0;
int64 chat_id = 0;
+ object_ptr<td_api::MessageSender> receiver_id;
int32 date = 0;
int32 edit_date = 0;
int32 initial_send_date = 0;
int32 sender_boost_count = 0;
+ int32 ephemeral_message_id = 0;
int64 paid_message_star_count = 0;
int64 guest_query_id = 0;
object_ptr<td_api::MessageOrigin> forward_origin;
@@ -1394,6 +1459,8 @@ class Client final : public WebhookActor::Callback {
void add_update_managed_bot(object_ptr<td_api::updateManagedBot> &&query);
+ void add_update_subscription(object_ptr<td_api::updateUserSubscription> &&query);
+
void add_new_custom_event(object_ptr<td_api::updateNewCustomEvent> &&event);
void add_new_custom_query(object_ptr<td_api::updateNewCustomQuery> &&query);
@@ -1441,12 +1508,13 @@ class Client final : public WebhookActor::Callback {
PurchasedPaidMedia,
ManagedBot,
GuestMessage,
+ Subscription,
Size
};
static td::Slice get_update_type_name(UpdateType update_type);
- static td::uint32 get_allowed_update_types(td::MutableSlice allowed_updates, bool is_internal);
+ static td::uint64 get_allowed_update_types(td::MutableSlice allowed_updates, bool is_internal);
bool update_allowed_update_types(const Query *query);
@@ -1477,10 +1545,11 @@ class Client final : public WebhookActor::Callback {
bool have_message_access(int64 chat_id) const;
// by default ChatMember, MessageReaction, and MessageReactionCount updates are disabled
- static constexpr td::uint32 DEFAULT_ALLOWED_UPDATE_TYPES =
- (1 << static_cast<int32>(UpdateType::Size)) - 1 - (1 << static_cast<int32>(UpdateType::ChatMember)) -
- (1 << static_cast<int32>(UpdateType::MessageReaction)) -
- (1 << static_cast<int32>(UpdateType::MessageReactionCount));
+ static constexpr td::uint64 DEFAULT_ALLOWED_UPDATE_TYPES =
+ (static_cast<td::uint64>(1) << static_cast<int32>(UpdateType::Size)) - 1 -
+ (static_cast<td::uint64>(1) << static_cast<int32>(UpdateType::ChatMember)) -
+ (static_cast<td::uint64>(1) << static_cast<int32>(UpdateType::MessageReaction)) -
+ (static_cast<td::uint64>(1) << static_cast<int32>(UpdateType::MessageReactionCount));
object_ptr<td_api::AuthorizationState> authorization_state_;
bool was_authorized_ = false;
@@ -1516,6 +1585,7 @@ class Client final : public WebhookActor::Callback {
td::WaitFreeHashMap<int64, td::unique_ptr<GroupInfo>> groups_;
td::WaitFreeHashMap<int64, td::unique_ptr<SupergroupInfo>> supergroups_;
td::WaitFreeHashMap<int64, td::unique_ptr<ChatInfo>> chats_;
+ td::WaitFreeHashMap<int64, td::unique_ptr<CommunityInfo>> communities_;
td::WaitFreeHashMap<td::string, td::unique_ptr<BusinessConnection>> business_connections_;
td::FlatHashMap<int32, td::vector<PromisedQueryPtr>> file_download_listeners_;
@@ -1645,7 +1715,7 @@ class Client final : public WebhookActor::Callback {
double next_bot_updates_warning_time_ = 0;
bool was_bot_updates_warning_ = false;
- td::uint32 allowed_update_types_ = DEFAULT_ALLOWED_UPDATE_TYPES;
+ td::uint64 allowed_update_types_ = DEFAULT_ALLOWED_UPDATE_TYPES;
bool has_webhook_certificate_ = false;
enum class WebhookQueryType { Cancel, Verify };
diff --git a/telegram-bot-api/telegram-bot-api.cpp b/telegram-bot-api/telegram-bot-api.cpp
index 6aa0562..15504b1 100644
--- a/telegram-bot-api/telegram-bot-api.cpp
+++ b/telegram-bot-api/telegram-bot-api.cpp
@@ -165,7 +165,7 @@ int main(int argc, char *argv[]) {
auto start_time = td::Time::now();
auto shared_data = std::make_shared<SharedData>();
auto parameters = std::make_unique<ClientParameters>();
- parameters->version_ = "10.1";
+ parameters->version_ = "10.2";
parameters->shared_data_ = shared_data;
parameters->start_time_ = start_time;
auto net_query_stats = td::create_net_query_stats();