diff --git a/CMakeLists.txt b/CMakeLists.txt
index 994a060..74f1233 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,7 +6,7 @@ if (POLICY CMP0065)
cmake_policy(SET CMP0065 NEW)
endif()
-project(TelegramBotApi VERSION 7.0 LANGUAGES CXX)
+project(TelegramBotApi VERSION 7.10 LANGUAGES CXX)
if (POLICY CMP0069)
option(TELEGRAM_BOT_API_ENABLE_LTO "Use \"ON\" to enable Link Time Optimization.")
diff --git a/build.html b/build.html
index 0ecaa80..bb3be05 100644
--- a/build.html
+++ b/build.html
@@ -201,13 +201,16 @@
+
+
+
@@ -260,7 +263,7 @@
-
+
@@ -353,7 +356,7 @@ function onOptionsChanged() {
document.getElementById('buildCommandsDiv').style.display = 'block';
var use_clang = os_freebsd || os_openbsd;
- if (os_linux && linux_distro !== 'Alpine' && !linux_distro.includes('CentOS')) {
+ if (os_linux && linux_distro !== 'Alpine' && !linux_distro.includes('CentOS') && !linux_distro.includes('Fedora')) {
document.getElementById('buildCompilerDiv').style.display = 'block';
use_clang = document.getElementById('buildCompilerRadioClang').checked;
} else {
@@ -446,7 +449,7 @@ function onOptionsChanged() {
pre_text.push('Install Git, ' + compiler + ', make, CMake >= 3.0.2, OpenSSL-dev, zlib-dev, gperf using your package manager.');
}
if (os_freebsd) {
- pre_text.push('Note that the following instruction is for FreeBSD 11.');
+ pre_text.push('Note that the following instruction is for FreeBSD 13.');
pre_text.push('Note that the following calls to pkg
needs to be run as root
.');
}
if (os_openbsd) {
@@ -496,6 +499,19 @@ function onOptionsChanged() {
return '-10';
case 'Ubuntu 22':
return '-14';
+ case 'Ubuntu 24':
+ return '-18';
+ default:
+ return ''; // use default version
+ }
+ }
+
+ function getLibcplusplusVersionSuffix() {
+ switch (linux_distro) {
+ case 'Ubuntu 20':
+ case 'Ubuntu 22':
+ case 'Ubuntu 24':
+ return getClangVersionSuffix();
default:
return ''; // use default version
}
@@ -514,23 +530,32 @@ function onOptionsChanged() {
commands.push(sudo + 'apk update');
commands.push(sudo + 'apk upgrade');
var packages = 'alpine-sdk linux-headers git zlib-dev openssl-dev gperf cmake';
- commands.push(sudo + 'apk add --update ' + packages);
+ commands.push(sudo + 'apk add ' + packages);
break;
case 'CentOS 7':
- case 'CentOS 8':
commands.push(sudo + 'yum update -y');
- var packages = 'gcc-c++ make git zlib-devel openssl-devel';
- if (linux_distro === 'CentOS 7') {
- commands.push(sudo + 'yum install -y centos-release-scl-rh epel-release');
- commands.push(sudo + 'yum install -y devtoolset-9-gcc devtoolset-9-gcc-c++');
- cmake = 'cmake3';
- packages += ' gperf';
- } else {
- commands.push(sudo + 'dnf --enablerepo=powertools install gperf');
- }
- packages += ' ' + cmake;
+ commands.push(sudo + 'yum install -y centos-release-scl-rh epel-release');
+ commands.push(sudo + 'yum install -y devtoolset-9-gcc devtoolset-9-gcc-c++');
+ cmake = 'cmake3';
+ var packages = 'gcc-c++ make git zlib-devel openssl-devel gperf ' + cmake;
commands.push(sudo + 'yum install -y ' + packages);
break;
+ case 'CentOS 8':
+ case 'CentOS Stream 9':
+ commands.push(sudo + 'dnf update -y');
+ if (linux_distro === 'CentOS 8') {
+ commands.push(sudo + 'dnf --enablerepo=powertools install gperf');
+ } else {
+ commands.push(sudo + 'dnf --enablerepo=crb install gperf');
+ }
+ var packages = 'gcc-c++ make git zlib-devel openssl-devel cmake';
+ commands.push(sudo + 'dnf install -y ' + packages);
+ break;
+ case 'Fedora 21+':
+ commands.push(sudo + 'dnf update -y');
+ var packages = 'gperf gcc-c++ make git zlib-devel openssl-devel cmake';
+ commands.push(sudo + 'dnf install -y ' + packages);
+ break;
case 'Debian 8/9':
case 'Debian 10+':
case 'Ubuntu 14':
@@ -538,6 +563,7 @@ function onOptionsChanged() {
case 'Ubuntu 18':
case 'Ubuntu 20':
case 'Ubuntu 22':
+ case 'Ubuntu 24':
if (linux_distro.includes('Debian') && !use_root) {
commands.push('su -');
}
@@ -553,9 +579,9 @@ function onOptionsChanged() {
packages += ' cmake';
}
if (use_clang) {
- packages += ' clang' + getClangVersionSuffix() + ' libc++-dev';
- if (linux_distro === 'Debian 10+' || linux_distro === 'Ubuntu 18' || linux_distro === 'Ubuntu 20' || linux_distro === 'Ubuntu 22') {
- packages += ' libc++abi-dev';
+ 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';
}
} else {
packages += ' g++';
@@ -587,7 +613,7 @@ function onOptionsChanged() {
commands.push('su -');
}
commands.push('export PKG_PATH=http://cdn.netbsd.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r)/All');
- var packages = 'git gperf cmake openssl gcc12-libs mozilla-rootcerts-openssl';
+ var packages = 'git gperf pcre2 cmake openssl gcc12-libs mozilla-rootcerts-openssl';
commands.push('pkg_add ' + packages);
if (!use_root) {
commands.push('exit');
diff --git a/td b/td
index 27c3eae..87d8810 160000
--- a/td
+++ b/td
@@ -1 +1 @@
-Subproject commit 27c3eaeb4964bd5f18d8488e354abde1a4383e49
+Subproject commit 87d881071fe514936bb17029e96761141287d2be
diff --git a/tdlight-api-openapi.yaml b/tdlight-api-openapi.yaml
index 4ac7668..10f0ca5 100644
--- a/tdlight-api-openapi.yaml
+++ b/tdlight-api-openapi.yaml
@@ -264,6 +264,10 @@ paths:
last_name:
description: The last name of the user; 0-64 characters.
type: string
+ disable_notification:
+ description: Disables "user joined Telegram" notification for other users that have the contact in their contact list.
+ default: false
+ type: boolean
required:
- first_name
multipart/form-data:
@@ -276,6 +280,10 @@ paths:
last_name:
description: The last name of the user; 0-64 characters.
type: string
+ disable_notification:
+ description: Disables "user joined Telegram" notification for other users that have the contact in their contact list.
+ default: false
+ type: boolean
required:
- first_name
application/json:
@@ -288,6 +296,10 @@ paths:
last_name:
description: The last name of the user; 0-64 characters.
type: string
+ disable_notification:
+ description: Disables "user joined Telegram" notification for other users that have the contact in their contact list.
+ default: false
+ type: boolean
required:
- first_name
required: true
@@ -1471,6 +1483,10 @@ paths:
query:
description: Query to search for.
type: string
+ only_in_channels:
+ description: Search for messages only in channels
+ default: false
+ type: boolean
offset_date:
description: The date of the message starting from which the results should be fetched. Use 0 or any date in the future to get results from the last message.
type: integer
@@ -1505,6 +1521,10 @@ paths:
query:
description: Query to search for.
type: string
+ only_in_channels:
+ description: Search for messages only in channels
+ default: false
+ type: boolean
offset_date:
description: The date of the message starting from which the results should be fetched. Use 0 or any date in the future to get results from the last message.
type: integer
@@ -1539,6 +1559,10 @@ paths:
query:
description: Query to search for.
type: string
+ only_in_channels:
+ description: Search for messages only in channels
+ default: false
+ type: boolean
offset_date:
description: The date of the message starting from which the results should be fetched. Use 0 or any date in the future to get results from the last message.
type: integer
diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp
index e938b4a..e3062ae 100644
--- a/telegram-bot-api/Client.cpp
+++ b/telegram-bot-api/Client.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -55,6 +55,25 @@ namespace telegram_bot_api {
using td_api::make_object;
using td_api::move_object_as;
+Client::Client(td::ActorShared<> parent, const td::string &bot_token, bool is_user, bool is_test_dc, int64 tqueue_id,
+ std::shared_ptr parameters, td::ActorId stat_actor)
+ : parent_(std::move(parent))
+ , bot_token_(bot_token)
+ , bot_token_id_("")
+ , is_user_(is_user)
+ , is_test_dc_(is_test_dc)
+ , tqueue_id_(tqueue_id)
+ , parameters_(std::move(parameters))
+ , stat_actor_(std::move(stat_actor)) {
+ static auto is_inited = init_methods();
+ CHECK(is_inited);
+}
+
+Client::~Client() {
+ td::Scheduler::instance()->destroy_on_scheduler(SharedData::get_file_gc_scheduler_id(), messages_, users_, groups_,
+ supergroups_, chats_, sticker_set_names_);
+}
+
int Client::get_retry_after_time(td::Slice error_message) {
td::Slice prefix = "Too Many Requests: retry after ";
if (td::begins_with(error_message, prefix)) {
@@ -198,23 +217,8 @@ void Client::fail_query_with_error(PromisedQueryPtr &&query, object_ptrcode_, error->message_, default_message);
}
-Client::Client(td::ActorShared<> parent, const td::string &bot_token, bool is_user, bool is_test_dc, int64 tqueue_id,
- std::shared_ptr parameters, td::ActorId stat_actor)
- : parent_(std::move(parent))
- , bot_token_(bot_token)
- , bot_token_id_("")
- , is_user_(is_user)
- , is_test_dc_(is_test_dc)
- , tqueue_id_(tqueue_id)
- , parameters_(std::move(parameters))
- , stat_actor_(std::move(stat_actor)) {
- static auto is_inited = init_methods();
- CHECK(is_inited);
-}
-
-Client::~Client() {
- td::Scheduler::instance()->destroy_on_scheduler(SharedData::get_file_gc_scheduler_id(), messages_, users_, groups_,
- supergroups_, chats_, sticker_set_names_);
+bool Client::is_special_error_code(int32 error_code) {
+ return error_code == 401 || error_code == 429 || error_code >= 500;
}
bool Client::init_methods() {
@@ -243,6 +247,7 @@ bool Client::init_methods() {
methods_.emplace("sendvideo", &Client::process_send_video_query);
methods_.emplace("sendvideonote", &Client::process_send_video_note_query);
methods_.emplace("sendvoice", &Client::process_send_voice_query);
+ methods_.emplace("sendpaidmedia", &Client::process_send_paid_media_query);
methods_.emplace("sendgame", &Client::process_send_game_query);
methods_.emplace("sendinvoice", &Client::process_send_invoice_query);
methods_.emplace("sendlocation", &Client::process_send_location_query);
@@ -266,6 +271,8 @@ bool Client::init_methods() {
methods_.emplace("deletemessage", &Client::process_delete_message_query);
methods_.emplace("deletemessages", &Client::process_delete_messages_query);
methods_.emplace("createinvoicelink", &Client::process_create_invoice_link_query);
+ methods_.emplace("getstartransactions", &Client::process_get_star_transactions_query);
+ methods_.emplace("refundstarpayment", &Client::process_refund_star_payment_query);
methods_.emplace("setgamescore", &Client::process_set_game_score_query);
methods_.emplace("getgamehighscores", &Client::process_get_game_high_scores_query);
methods_.emplace("answerwebappquery", &Client::process_answer_web_app_query_query);
@@ -275,8 +282,11 @@ bool Client::init_methods() {
methods_.emplace("answerprecheckoutquery", &Client::process_answer_pre_checkout_query_query);
methods_.emplace("exportchatinvitelink", &Client::process_export_chat_invite_link_query);
methods_.emplace("createchatinvitelink", &Client::process_create_chat_invite_link_query);
+ methods_.emplace("createchatsubscriptioninvitelink", &Client::process_create_chat_subscription_invite_link_query);
methods_.emplace("editchatinvitelink", &Client::process_edit_chat_invite_link_query);
+ methods_.emplace("editchatsubscriptioninvitelink", &Client::process_edit_chat_subscription_invite_link_query);
methods_.emplace("revokechatinvitelink", &Client::process_revoke_chat_invite_link_query);
+ methods_.emplace("getbusinessconnection", &Client::process_get_business_connection_query);
methods_.emplace("getchat", &Client::process_get_chat_query);
methods_.emplace("setchatphoto", &Client::process_set_chat_photo_query);
methods_.emplace("deletechatphoto", &Client::process_delete_chat_photo_query);
@@ -322,6 +332,7 @@ bool Client::init_methods() {
methods_.emplace("uploadstickerfile", &Client::process_upload_sticker_file_query);
methods_.emplace("createnewstickerset", &Client::process_create_new_sticker_set_query);
methods_.emplace("addstickertoset", &Client::process_add_sticker_to_set_query);
+ methods_.emplace("replacestickerinset", &Client::process_replace_sticker_in_set_query);
methods_.emplace("setstickersettitle", &Client::process_set_sticker_set_title_query);
methods_.emplace("setstickersetthumb", &Client::process_set_sticker_set_thumbnail_query);
methods_.emplace("setstickersetthumbnail", &Client::process_set_sticker_set_thumbnail_query);
@@ -481,6 +492,8 @@ class Client::JsonUser final : public td::Jsonable {
object("can_join_groups", td::JsonBool(user_info->can_join_groups));
object("can_read_all_group_messages", td::JsonBool(user_info->can_read_all_group_messages));
object("supports_inline_queries", td::JsonBool(user_info->is_inline_bot));
+ object("can_connect_to_business", td::JsonBool(user_info->can_connect_to_business));
+ object("has_main_web_app", td::JsonBool(user_info->has_main_web_app));
}
}
@@ -587,6 +600,9 @@ class Client::JsonEntity final : public td::Jsonable {
case td_api::textEntityTypeBlockQuote::ID:
object("type", "blockquote");
break;
+ case td_api::textEntityTypeExpandableBlockQuote::ID:
+ object("type", "expandable_blockquote");
+ break;
default:
UNREACHABLE();
}
@@ -618,6 +634,101 @@ class Client::JsonVectorEntities final : public td::Jsonable {
const Client *client_;
};
+class Client::JsonMaskPosition final : public td::Jsonable {
+ public:
+ explicit JsonMaskPosition(const td_api::maskPosition *mask_position) : mask_position_(mask_position) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ object("point", Client::MASK_POINTS[Client::mask_point_to_index(mask_position_->point_)]);
+ object("x_shift", mask_position_->x_shift_);
+ object("y_shift", mask_position_->y_shift_);
+ object("scale", mask_position_->scale_);
+ }
+
+ private:
+ const td_api::maskPosition *mask_position_;
+};
+
+class Client::JsonSticker final : public td::Jsonable {
+ public:
+ JsonSticker(const td_api::sticker *sticker, const Client *client) : sticker_(sticker), client_(client) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ object("width", sticker_->width_);
+ object("height", sticker_->height_);
+ if (!sticker_->emoji_.empty()) {
+ object("emoji", sticker_->emoji_);
+ }
+ auto set_name = client_->get_sticker_set_name(sticker_->set_id_);
+ if (!set_name.empty()) {
+ object("set_name", set_name);
+ }
+
+ auto format = sticker_->format_->get_id();
+ object("is_animated", td::JsonBool(format == td_api::stickerFormatTgs::ID));
+ object("is_video", td::JsonBool(format == td_api::stickerFormatWebm::ID));
+
+ switch (sticker_->full_type_->get_id()) {
+ case td_api::stickerFullTypeRegular::ID: {
+ auto full_type = static_cast(sticker_->full_type_.get());
+ object("type", Client::get_sticker_type(make_object()));
+ if (full_type->premium_animation_ != nullptr) {
+ object("premium_animation", JsonFile(full_type->premium_animation_.get(), client_, false));
+ }
+ break;
+ }
+ case td_api::stickerFullTypeMask::ID: {
+ auto full_type = static_cast(sticker_->full_type_.get());
+ object("type", Client::get_sticker_type(make_object()));
+ if (full_type->mask_position_ != nullptr) {
+ object("mask_position", JsonMaskPosition(full_type->mask_position_.get()));
+ }
+ break;
+ }
+ case td_api::stickerFullTypeCustomEmoji::ID: {
+ auto full_type = static_cast(sticker_->full_type_.get());
+ object("type", Client::get_sticker_type(make_object()));
+ if (full_type->custom_emoji_id_ != 0) {
+ object("custom_emoji_id", td::to_string(full_type->custom_emoji_id_));
+ }
+ if (full_type->needs_repainting_) {
+ object("needs_repainting", td::JsonBool(full_type->needs_repainting_));
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ client_->json_store_thumbnail(object, sticker_->thumbnail_.get());
+ client_->json_store_file(object, sticker_->sticker_.get());
+ }
+
+ private:
+ const td_api::sticker *sticker_;
+ const Client *client_;
+};
+
+class Client::JsonStickers final : public td::Jsonable {
+ public:
+ JsonStickers(const td::vector> &stickers, const Client *client)
+ : stickers_(stickers), client_(client) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto array = scope->enter_array();
+ for (auto &sticker : stickers_) {
+ array << JsonSticker(sticker.get(), client_);
+ }
+ }
+
+ private:
+ const td::vector> &stickers_;
+ const Client *client_;
+};
+
class Client::JsonLocation final : public td::Jsonable {
public:
explicit JsonLocation(const td_api::location *location, double expires_in = 0.0, int32 live_period = 0,
@@ -671,6 +782,9 @@ class Client::JsonReactionType final : public td::Jsonable {
object("custom_emoji_id",
td::to_string(static_cast(reaction_type_)->custom_emoji_id_));
break;
+ case td_api::reactionTypePaid::ID:
+ object("type", "paid");
+ break;
default:
UNREACHABLE();
}
@@ -694,6 +808,94 @@ class Client::JsonReactionCount final : public td::Jsonable {
const td_api::messageReaction *message_reaction_;
};
+class Client::JsonBirthdate final : public td::Jsonable {
+ public:
+ explicit JsonBirthdate(const td_api::birthdate *birthdate) : birthdate_(birthdate) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ object("day", birthdate_->day_);
+ object("month", birthdate_->month_);
+ if (birthdate_->year_ != 0) {
+ object("year", birthdate_->year_);
+ }
+ }
+
+ private:
+ const td_api::birthdate *birthdate_;
+};
+
+class Client::JsonBusinessStartPage final : public td::Jsonable {
+ public:
+ JsonBusinessStartPage(const td_api::businessStartPage *start_page, const Client *client)
+ : start_page_(start_page), client_(client) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ if (!start_page_->title_.empty()) {
+ object("title", start_page_->title_);
+ }
+ if (!start_page_->message_.empty()) {
+ object("message", start_page_->message_);
+ }
+ if (start_page_->sticker_ != nullptr) {
+ object("sticker", JsonSticker(start_page_->sticker_.get(), client_));
+ }
+ }
+
+ private:
+ const td_api::businessStartPage *start_page_;
+ const Client *client_;
+};
+
+class Client::JsonBusinessLocation final : public td::Jsonable {
+ public:
+ explicit JsonBusinessLocation(const td_api::businessLocation *business_location)
+ : business_location_(business_location) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ if (business_location_->location_ != nullptr) {
+ object("location", JsonLocation(business_location_->location_.get()));
+ }
+ object("address", business_location_->address_);
+ }
+
+ private:
+ const td_api::businessLocation *business_location_;
+};
+
+class Client::JsonBusinessOpeningHoursInterval final : public td::Jsonable {
+ public:
+ explicit JsonBusinessOpeningHoursInterval(const td_api::businessOpeningHoursInterval *opening_hours_interval)
+ : opening_hours_interval_(opening_hours_interval) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ object("opening_minute", opening_hours_interval_->start_minute_);
+ object("closing_minute", opening_hours_interval_->end_minute_);
+ }
+
+ private:
+ const td_api::businessOpeningHoursInterval *opening_hours_interval_;
+};
+
+class Client::JsonBusinessOpeningHours final : public td::Jsonable {
+ public:
+ explicit JsonBusinessOpeningHours(const td_api::businessOpeningHours *opening_hours) : opening_hours_(opening_hours) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ object("opening_hours", td::json_array(opening_hours_->opening_hours_, [](const auto &opening_hours_interval) {
+ return JsonBusinessOpeningHoursInterval(opening_hours_interval.get());
+ }));
+ object("time_zone_name", opening_hours_->time_zone_id_);
+ }
+
+ private:
+ const td_api::businessOpeningHours *opening_hours_;
+};
+
class Client::JsonChatPermissions final : public td::Jsonable {
public:
explicit JsonChatPermissions(const td_api::chatPermissions *chat_permissions) : chat_permissions_(chat_permissions) {
@@ -758,6 +960,10 @@ class Client::JsonChatInviteLink final : public td::Jsonable {
if (chat_invite_link_->pending_join_request_count_ != 0) {
object("pending_join_request_count", chat_invite_link_->pending_join_request_count_);
}
+ if (chat_invite_link_->subscription_pricing_ != nullptr) {
+ object("subscription_period", chat_invite_link_->subscription_pricing_->period_);
+ object("subscription_price", chat_invite_link_->subscription_pricing_->star_count_);
+ }
object("creates_join_request", td::JsonBool(chat_invite_link_->creates_join_request_));
object("is_primary", td::JsonBool(chat_invite_link_->is_primary_));
object("is_revoked", td::JsonBool(chat_invite_link_->is_revoked_));
@@ -781,7 +987,8 @@ class Client::JsonMessage final : public td::Jsonable {
const td::string &source_;
const Client *client_;
- void add_caption(td::JsonObjectScope &object, const object_ptr &caption) const {
+ void add_caption(td::JsonObjectScope &object, const object_ptr &caption,
+ bool show_caption_above_media) const {
CHECK(caption != nullptr);
if (!caption->text_.empty()) {
object("caption", caption->text_);
@@ -789,6 +996,10 @@ class Client::JsonMessage final : public td::Jsonable {
if (!caption->entities_.empty()) {
object("caption_entities", JsonVectorEntities(caption->entities_, client_));
}
+
+ if (show_caption_above_media) {
+ object("show_caption_above_media", td::JsonTrue());
+ }
}
}
@@ -852,6 +1063,24 @@ class Client::JsonChat final : public td::Jsonable {
if (user_info->has_restricted_voice_and_video_messages) {
object("has_restricted_voice_and_video_messages", td::JsonTrue());
}
+ if (user_info->business_info != nullptr) {
+ auto business_info = user_info->business_info.get();
+ if (business_info->start_page_ != nullptr) {
+ object("business_intro", JsonBusinessStartPage(business_info->start_page_.get(), client_));
+ }
+ if (business_info->location_ != nullptr) {
+ object("business_location", JsonBusinessLocation(business_info->location_.get()));
+ }
+ if (business_info->opening_hours_ != nullptr) {
+ object("business_opening_hours", JsonBusinessOpeningHours(business_info->opening_hours_.get()));
+ }
+ }
+ if (user_info->birthdate != nullptr) {
+ object("birthdate", JsonBirthdate(user_info->birthdate.get()));
+ }
+ if (user_info->personal_chat_id != 0) {
+ object("personal_chat", JsonChat(user_info->personal_chat_id, client_));
+ }
}
photo = user_info->photo.get();
break;
@@ -877,7 +1106,7 @@ class Client::JsonChat final : public td::Jsonable {
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_web_page_previews_ &&
+ permissions->can_send_other_messages_ && permissions->can_add_link_previews_ &&
permissions->can_change_info_ && permissions->can_invite_users_ && permissions->can_pin_messages_;
object("all_members_are_administrators", td::JsonBool(everyone_is_administrator));
photo = group_info->photo.get();
@@ -929,6 +1158,14 @@ class Client::JsonChat final : public td::Jsonable {
LOG(ERROR) << "Not found chat sticker set " << supergroup_info->sticker_set_id;
}
}
+ if (supergroup_info->custom_emoji_sticker_set_id != 0) {
+ auto sticker_set_name = client_->get_sticker_set_name(supergroup_info->custom_emoji_sticker_set_id);
+ if (!sticker_set_name.empty()) {
+ object("custom_emoji_sticker_set_name", sticker_set_name);
+ } else {
+ LOG(ERROR) << "Not found chat custom emoji sticker set " << supergroup_info->custom_emoji_sticker_set_id;
+ }
+ }
if (supergroup_info->can_set_sticker_set) {
object("can_set_sticker_set", td::JsonTrue());
}
@@ -953,12 +1190,18 @@ class Client::JsonChat final : public td::Jsonable {
if (supergroup_info->slow_mode_delay != 0) {
object("slow_mode_delay", supergroup_info->slow_mode_delay);
}
+ if (supergroup_info->unrestrict_boost_count != 0) {
+ object("unrestrict_boost_count", supergroup_info->unrestrict_boost_count);
+ }
if (supergroup_info->linked_chat_id != 0) {
object("linked_chat_id", supergroup_info->linked_chat_id);
}
if (supergroup_info->location != nullptr) {
object("location", JsonChatLocation(supergroup_info->location.get()));
}
+ if (supergroup_info->has_paid_media_allowed && !supergroup_info->is_supergroup) {
+ object("can_send_paid_media", td::JsonTrue());
+ }
}
photo = supergroup_info->photo.get();
break;
@@ -1020,6 +1263,7 @@ class Client::JsonChat final : public td::Jsonable {
td::json_array(chat_info->available_reactions->reactions_,
[](const auto &reaction) { return JsonReactionType(reaction.get()); }));
}
+ object("max_reaction_count", chat_info->max_reaction_count);
CHECK(chat_info->accent_color_id != -1);
object("accent_color_id", chat_info->accent_color_id);
if (chat_info->background_custom_emoji_id != 0) {
@@ -1168,8 +1412,8 @@ class Client::JsonMessages final : public td::Jsonable {
class Client::JsonLinkPreviewOptions final : public td::Jsonable {
public:
- JsonLinkPreviewOptions(const td_api::linkPreviewOptions *link_preview_options, const Client *client)
- : link_preview_options_(link_preview_options), client_(client) {
+ explicit JsonLinkPreviewOptions(const td_api::linkPreviewOptions *link_preview_options)
+ : link_preview_options_(link_preview_options) {
}
void store(td::JsonValueScope *scope) const {
auto object = scope->enter_object();
@@ -1192,7 +1436,6 @@ class Client::JsonLinkPreviewOptions final : public td::Jsonable {
private:
const td_api::linkPreviewOptions *link_preview_options_;
- const Client *client_;
};
class Client::JsonAnimation final : public td::Jsonable {
@@ -1340,101 +1583,6 @@ class Client::JsonChatPhoto final : public td::Jsonable {
const Client *client_;
};
-class Client::JsonMaskPosition final : public td::Jsonable {
- public:
- explicit JsonMaskPosition(const td_api::maskPosition *mask_position) : mask_position_(mask_position) {
- }
- void store(td::JsonValueScope *scope) const {
- auto object = scope->enter_object();
- object("point", Client::MASK_POINTS[Client::mask_point_to_index(mask_position_->point_)]);
- object("x_shift", mask_position_->x_shift_);
- object("y_shift", mask_position_->y_shift_);
- object("scale", mask_position_->scale_);
- }
-
- private:
- const td_api::maskPosition *mask_position_;
-};
-
-class Client::JsonSticker final : public td::Jsonable {
- public:
- JsonSticker(const td_api::sticker *sticker, const Client *client) : sticker_(sticker), client_(client) {
- }
- void store(td::JsonValueScope *scope) const {
- auto object = scope->enter_object();
- object("width", sticker_->width_);
- object("height", sticker_->height_);
- if (!sticker_->emoji_.empty()) {
- object("emoji", sticker_->emoji_);
- }
- auto set_name = client_->get_sticker_set_name(sticker_->set_id_);
- if (!set_name.empty()) {
- object("set_name", set_name);
- }
-
- auto format = sticker_->format_->get_id();
- object("is_animated", td::JsonBool(format == td_api::stickerFormatTgs::ID));
- object("is_video", td::JsonBool(format == td_api::stickerFormatWebm::ID));
-
- switch (sticker_->full_type_->get_id()) {
- case td_api::stickerFullTypeRegular::ID: {
- auto full_type = static_cast(sticker_->full_type_.get());
- object("type", Client::get_sticker_type(make_object()));
- if (full_type->premium_animation_ != nullptr) {
- object("premium_animation", JsonFile(full_type->premium_animation_.get(), client_, false));
- }
- break;
- }
- case td_api::stickerFullTypeMask::ID: {
- auto full_type = static_cast(sticker_->full_type_.get());
- object("type", Client::get_sticker_type(make_object()));
- if (full_type->mask_position_ != nullptr) {
- object("mask_position", JsonMaskPosition(full_type->mask_position_.get()));
- }
- break;
- }
- case td_api::stickerFullTypeCustomEmoji::ID: {
- auto full_type = static_cast(sticker_->full_type_.get());
- object("type", Client::get_sticker_type(make_object()));
- if (full_type->custom_emoji_id_ != 0) {
- object("custom_emoji_id", td::to_string(full_type->custom_emoji_id_));
- }
- if (full_type->needs_repainting_) {
- object("needs_repainting", td::JsonBool(full_type->needs_repainting_));
- }
- break;
- }
- default:
- UNREACHABLE();
- break;
- }
-
- client_->json_store_thumbnail(object, sticker_->thumbnail_.get());
- client_->json_store_file(object, sticker_->sticker_.get());
- }
-
- private:
- const td_api::sticker *sticker_;
- const Client *client_;
-};
-
-class Client::JsonStickers final : public td::Jsonable {
- public:
- JsonStickers(const td::vector> &stickers, const Client *client)
- : stickers_(stickers), client_(client) {
- }
- void store(td::JsonValueScope *scope) const {
- auto array = scope->enter_array();
- for (auto &sticker : stickers_) {
- array << JsonSticker(sticker.get(), client_);
- }
- }
-
- private:
- const td::vector> &stickers_;
- const Client *client_;
-};
-
class Client::JsonVideo final : public td::Jsonable {
public:
JsonVideo(const td_api::video *video, const Client *client) : video_(video), client_(client) {
@@ -1494,6 +1642,70 @@ class Client::JsonVoiceNote final : public td::Jsonable {
const Client *client_;
};
+class Client::JsonPaidMedia final : public td::Jsonable {
+ public:
+ JsonPaidMedia(const td_api::PaidMedia *paid_media, const Client *client) : paid_media_(paid_media), client_(client) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ switch (paid_media_->get_id()) {
+ case td_api::paidMediaPreview::ID: {
+ auto media = static_cast(paid_media_);
+ object("type", "preview");
+ if (media->width_) {
+ object("width", media->width_);
+ }
+ if (media->height_) {
+ object("height", media->height_);
+ }
+ if (media->duration_) {
+ object("duration", media->duration_);
+ }
+ break;
+ }
+ case td_api::paidMediaPhoto::ID: {
+ auto media = static_cast(paid_media_);
+ object("type", "photo");
+ object("photo", JsonPhoto(media->photo_.get(), client_));
+ break;
+ }
+ case td_api::paidMediaVideo::ID: {
+ auto media = static_cast(paid_media_);
+ object("type", "video");
+ object("video", JsonVideo(media->video_.get(), client_));
+ break;
+ }
+ case td_api::paidMediaUnsupported::ID:
+ object("type", "other");
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ private:
+ const td_api::PaidMedia *paid_media_;
+ const Client *client_;
+};
+
+class Client::JsonPaidMediaInfo final : public td::Jsonable {
+ public:
+ JsonPaidMediaInfo(const td_api::messagePaidMedia *paid_media, const Client *client)
+ : paid_media_(paid_media), client_(client) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ object("star_count", paid_media_->star_count_);
+ object("paid_media", td::json_array(paid_media_->media_, [client = client_](auto &media) {
+ return JsonPaidMedia(media.get(), client);
+ }));
+ }
+
+ private:
+ const td_api::messagePaidMedia *paid_media_;
+ const Client *client_;
+};
+
class Client::JsonVenue final : public td::Jsonable {
public:
explicit JsonVenue(const td_api::venue *venue) : venue_(venue) {
@@ -1595,12 +1807,12 @@ class Client::JsonInvoice final : public td::Jsonable {
}
void store(td::JsonValueScope *scope) const {
auto object = scope->enter_object();
- object("title", invoice_->title_);
- object("description", invoice_->description_->text_);
+ object("title", invoice_->product_info_->title_);
+ object("description", invoice_->product_info_->description_->text_);
object("start_parameter", invoice_->start_parameter_);
object("currency", invoice_->currency_);
object("total_amount", invoice_->total_amount_);
- // skip photo
+ // skip product_info_->photo
// skip is_test
// skip need_shipping_address
// skip receipt_message_id
@@ -1612,17 +1824,21 @@ class Client::JsonInvoice final : public td::Jsonable {
class Client::JsonPollOption final : public td::Jsonable {
public:
- explicit JsonPollOption(const td_api::pollOption *option) : option_(option) {
+ JsonPollOption(const td_api::pollOption *option, const Client *client) : option_(option), client_(client) {
}
void store(td::JsonValueScope *scope) const {
auto object = scope->enter_object();
- object("text", option_->text_);
+ object("text", option_->text_->text_);
+ if (!option_->text_->entities_.empty()) {
+ object("text_entities", JsonVectorEntities(option_->text_->entities_, client_));
+ }
object("voter_count", option_->voter_count_);
// ignore is_chosen
}
private:
const td_api::pollOption *option_;
+ const Client *client_;
};
class Client::JsonPoll final : public td::Jsonable {
@@ -1632,8 +1848,13 @@ class Client::JsonPoll final : public td::Jsonable {
void store(td::JsonValueScope *scope) const {
auto object = scope->enter_object();
object("id", td::to_string(poll_->id_));
- object("question", poll_->question_);
- object("options", td::json_array(poll_->options_, [](auto &option) { return JsonPollOption(option.get()); }));
+ object("question", poll_->question_->text_);
+ if (!poll_->question_->entities_.empty()) {
+ object("question_entities", JsonVectorEntities(poll_->question_->entities_, client_));
+ }
+ object("options", td::json_array(poll_->options_, [client = client_](auto &option) {
+ return JsonPollOption(option.get(), client);
+ }));
object("total_voter_count", poll_->total_voter_count_);
if (poll_->open_period_ != 0 && poll_->close_date_ != 0) {
object("open_period", poll_->open_period_);
@@ -1703,6 +1924,145 @@ class Client::JsonPollAnswer final : public td::Jsonable {
const Client *client_;
};
+class Client::JsonStory final : public td::Jsonable {
+ public:
+ JsonStory(int64 chat_id, int32 story_id, const Client *client)
+ : chat_id_(chat_id), story_id_(story_id), client_(client) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ object("chat", JsonChat(chat_id_, client_));
+ object("id", story_id_);
+ }
+
+ private:
+ int64 chat_id_;
+ int32 story_id_;
+ const Client *client_;
+};
+
+class Client::JsonBackgroundFill final : public td::Jsonable {
+ public:
+ explicit JsonBackgroundFill(const td_api::BackgroundFill *background_fill) : background_fill_(background_fill) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ CHECK(background_fill_ != nullptr);
+ auto object = scope->enter_object();
+ switch (background_fill_->get_id()) {
+ case td_api::backgroundFillSolid::ID: {
+ auto fill = static_cast(background_fill_);
+ object("type", "solid");
+ object("color", fill->color_);
+ break;
+ }
+ case td_api::backgroundFillGradient::ID: {
+ auto fill = static_cast(background_fill_);
+ object("type", "gradient");
+ object("top_color", fill->top_color_);
+ object("bottom_color", fill->bottom_color_);
+ object("rotation_angle", fill->rotation_angle_);
+ break;
+ }
+ case td_api::backgroundFillFreeformGradient::ID: {
+ auto fill = static_cast(background_fill_);
+ object("type", "freeform_gradient");
+ object("colors", td::json_array(fill->colors_, [](int32 color) { return color; }));
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ private:
+ const td_api::BackgroundFill *background_fill_;
+};
+
+class Client::JsonBackgroundType final : public td::Jsonable {
+ public:
+ JsonBackgroundType(const td_api::BackgroundType *background_type, const td_api::document *document,
+ int32 dark_theme_dimming, const Client *client)
+ : background_type_(background_type)
+ , document_(document)
+ , dark_theme_dimming_(dark_theme_dimming)
+ , client_(client) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ CHECK(background_type_ != nullptr);
+ auto object = scope->enter_object();
+ switch (background_type_->get_id()) {
+ case td_api::backgroundTypeWallpaper::ID: {
+ auto type = static_cast(background_type_);
+ object("type", "wallpaper");
+ CHECK(document_ != nullptr);
+ object("document", JsonDocument(document_, client_));
+ object("dark_theme_dimming", dark_theme_dimming_);
+ if (type->is_blurred_) {
+ object("is_blurred", td::JsonTrue());
+ }
+ if (type->is_moving_) {
+ object("is_moving", td::JsonTrue());
+ }
+ break;
+ }
+ case td_api::backgroundTypePattern::ID: {
+ auto type = static_cast(background_type_);
+ object("type", "pattern");
+ CHECK(document_ != nullptr);
+ object("document", JsonDocument(document_, client_));
+ object("fill", JsonBackgroundFill(type->fill_.get()));
+ object("intensity", type->intensity_);
+ if (type->is_inverted_) {
+ object("is_inverted", td::JsonTrue());
+ }
+ if (type->is_moving_) {
+ object("is_moving", td::JsonTrue());
+ }
+ break;
+ }
+ case td_api::backgroundTypeFill::ID: {
+ auto type = static_cast(background_type_);
+ object("type", "fill");
+ object("fill", JsonBackgroundFill(type->fill_.get()));
+ object("dark_theme_dimming", dark_theme_dimming_);
+ break;
+ }
+ case td_api::backgroundTypeChatTheme::ID: {
+ auto type = static_cast(background_type_);
+ object("type", "chat_theme");
+ object("theme_name", type->theme_name_);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ private:
+ const td_api::BackgroundType *background_type_;
+ const td_api::document *document_;
+ int32 dark_theme_dimming_;
+ const Client *client_;
+};
+
+class Client::JsonChatBackground final : public td::Jsonable {
+ public:
+ JsonChatBackground(const td_api::chatBackground *chat_background, const Client *client)
+ : chat_background_(chat_background), client_(client) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ CHECK(chat_background_ != nullptr);
+ auto object = scope->enter_object();
+ auto background = chat_background_->background_.get();
+ object("type", JsonBackgroundType(background->type_.get(), background->document_.get(),
+ chat_background_->dark_theme_dimming_, client_));
+ }
+
+ private:
+ const td_api::chatBackground *chat_background_;
+ const Client *client_;
+};
+
class Client::JsonForumTopicCreated final : public td::Jsonable {
public:
explicit JsonForumTopicCreated(const td_api::messageForumTopicCreated *forum_topic_created)
@@ -1823,7 +2183,6 @@ class Client::JsonSuccessfulPaymentBot final : public td::Jsonable {
if (successful_payment_->order_info_ != nullptr) {
object("order_info", JsonOrderInfo(successful_payment_->order_info_.get()));
}
-
object("telegram_payment_charge_id", successful_payment_->telegram_payment_charge_id_);
object("provider_payment_charge_id", successful_payment_->provider_payment_charge_id_);
}
@@ -1832,6 +2191,31 @@ class Client::JsonSuccessfulPaymentBot final : public td::Jsonable {
const td_api::messagePaymentSuccessfulBot *successful_payment_;
};
+class Client::JsonRefundedPayment final : public td::Jsonable {
+ public:
+ explicit JsonRefundedPayment(const td_api::messagePaymentRefunded *refunded_payment)
+ : refunded_payment_(refunded_payment) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ object("currency", refunded_payment_->currency_);
+ object("total_amount", refunded_payment_->total_amount_);
+ if (!td::check_utf8(refunded_payment_->invoice_payload_)) {
+ LOG(WARNING) << "Receive non-UTF-8 invoice payload";
+ object("invoice_payload", td::JsonRawString(refunded_payment_->invoice_payload_));
+ } else {
+ object("invoice_payload", refunded_payment_->invoice_payload_);
+ }
+ object("telegram_payment_charge_id", refunded_payment_->telegram_payment_charge_id_);
+ if (!refunded_payment_->provider_payment_charge_id_.empty()) {
+ object("provider_payment_charge_id", refunded_payment_->provider_payment_charge_id_);
+ }
+ }
+
+ private:
+ const td_api::messagePaymentRefunded *refunded_payment_;
+};
+
class Client::JsonEncryptedPassportElement final : public td::Jsonable {
public:
JsonEncryptedPassportElement(const td_api::encryptedPassportElement *element, const Client *client)
@@ -2057,7 +2441,7 @@ class Client::JsonUserShared final : public td::Jsonable {
}
void store(td::JsonValueScope *scope) const {
auto object = scope->enter_object();
- object("user_id", users_shared_->user_ids_[0]);
+ object("user_id", users_shared_->users_[0]->user_id_);
object("request_id", users_shared_->button_id_);
}
@@ -2065,38 +2449,96 @@ class Client::JsonUserShared final : public td::Jsonable {
const td_api::messageUsersShared *users_shared_;
};
+class Client::JsonSharedUser final : public td::Jsonable {
+ public:
+ JsonSharedUser(const td_api::sharedUser *shared_user, const Client *client)
+ : shared_user_(shared_user), client_(client) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ object("user_id", shared_user_->user_id_);
+ if (!shared_user_->first_name_.empty()) {
+ object("first_name", shared_user_->first_name_);
+ }
+ if (!shared_user_->last_name_.empty()) {
+ object("last_name", shared_user_->last_name_);
+ }
+ if (!shared_user_->username_.empty()) {
+ object("username", shared_user_->username_);
+ }
+ if (shared_user_->photo_ != nullptr) {
+ object("photo", JsonPhoto(shared_user_->photo_.get(), client_));
+ }
+ }
+
+ private:
+ const td_api::sharedUser *shared_user_;
+ const Client *client_;
+};
+
class Client::JsonUsersShared final : public td::Jsonable {
public:
- explicit JsonUsersShared(const td_api::messageUsersShared *users_shared) : users_shared_(users_shared) {
+ JsonUsersShared(const td_api::messageUsersShared *users_shared, const Client *client)
+ : users_shared_(users_shared), client_(client) {
}
void store(td::JsonValueScope *scope) const {
auto object = scope->enter_object();
- object("user_ids", td::json_array(users_shared_->user_ids_, [](int64 user_id) { return user_id; }));
+ object("user_ids", td::json_array(users_shared_->users_, [](auto &user) { return user->user_id_; }));
+ object("users", td::json_array(users_shared_->users_,
+ [client = client_](auto &user) { return JsonSharedUser(user.get(), client); }));
object("request_id", users_shared_->button_id_);
}
private:
const td_api::messageUsersShared *users_shared_;
+ const Client *client_;
};
class Client::JsonChatShared final : public td::Jsonable {
public:
- explicit JsonChatShared(const td_api::messageChatShared *chat_shared) : chat_shared_(chat_shared) {
+ JsonChatShared(const td_api::messageChatShared *chat_shared, const Client *client)
+ : chat_shared_(chat_shared), client_(client) {
}
void store(td::JsonValueScope *scope) const {
auto object = scope->enter_object();
- object("chat_id", chat_shared_->chat_id_);
+ auto *shared_chat = chat_shared_->chat_.get();
+ object("chat_id", shared_chat->chat_id_);
+ if (!shared_chat->title_.empty()) {
+ object("title", shared_chat->title_);
+ }
+ if (!shared_chat->username_.empty()) {
+ object("username", shared_chat->username_);
+ }
+ if (shared_chat->photo_ != nullptr) {
+ object("photo", JsonPhoto(shared_chat->photo_.get(), client_));
+ }
object("request_id", chat_shared_->button_id_);
}
private:
const td_api::messageChatShared *chat_shared_;
+ const Client *client_;
+};
+
+class Client::JsonGiveawayCreated final : public td::Jsonable {
+ public:
+ explicit JsonGiveawayCreated(const td_api::messageGiveawayCreated *giveaway_created)
+ : giveaway_created_(giveaway_created) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ if (giveaway_created_->star_count_ > 0) {
+ object("prize_star_count", giveaway_created_->star_count_);
+ }
+ }
+
+ private:
+ const td_api::messageGiveawayCreated *giveaway_created_;
};
class Client::JsonGiveaway final : public td::Jsonable {
public:
- JsonGiveaway(const td_api::messagePremiumGiveaway *giveaway, const Client *client)
- : giveaway_(giveaway), client_(client) {
+ JsonGiveaway(const td_api::messageGiveaway *giveaway, const Client *client) : giveaway_(giveaway), client_(client) {
}
void store(td::JsonValueScope *scope) const {
auto object = scope->enter_object();
@@ -2121,19 +2563,34 @@ class Client::JsonGiveaway final : public td::Jsonable {
if (!giveaway_->parameters_->prize_description_.empty()) {
object("prize_description", giveaway_->parameters_->prize_description_);
}
- if (giveaway_->month_count_ > 0) {
- object("premium_subscription_month_count", giveaway_->month_count_);
+ switch (giveaway_->prize_->get_id()) {
+ case td_api::giveawayPrizePremium::ID: {
+ auto month_count = static_cast(giveaway_->prize_.get())->month_count_;
+ if (month_count > 0) {
+ object("premium_subscription_month_count", month_count);
+ }
+ break;
+ }
+ case td_api::giveawayPrizeStars::ID: {
+ auto star_count = static_cast(giveaway_->prize_.get())->star_count_;
+ if (star_count > 0) {
+ object("prize_star_count", star_count);
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
}
}
private:
- const td_api::messagePremiumGiveaway *giveaway_;
+ const td_api::messageGiveaway *giveaway_;
const Client *client_;
};
class Client::JsonGiveawayWinners final : public td::Jsonable {
public:
- JsonGiveawayWinners(const td_api::messagePremiumGiveawayWinners *giveaway_winners, const Client *client)
+ JsonGiveawayWinners(const td_api::messageGiveawayWinners *giveaway_winners, const Client *client)
: giveaway_winners_(giveaway_winners), client_(client) {
}
void store(td::JsonValueScope *scope) const {
@@ -2150,8 +2607,24 @@ class Client::JsonGiveawayWinners final : public td::Jsonable {
if (giveaway_winners_->was_refunded_) {
object("was_refunded", td::JsonTrue());
}
- if (giveaway_winners_->month_count_ > 0) {
- object("premium_subscription_month_count", giveaway_winners_->month_count_);
+ switch (giveaway_winners_->prize_->get_id()) {
+ case td_api::giveawayPrizePremium::ID: {
+ auto month_count =
+ static_cast(giveaway_winners_->prize_.get())->month_count_;
+ if (month_count > 0) {
+ object("premium_subscription_month_count", month_count);
+ }
+ break;
+ }
+ case td_api::giveawayPrizeStars::ID: {
+ auto star_count = static_cast(giveaway_winners_->prize_.get())->star_count_;
+ if (star_count > 0) {
+ object("prize_star_count", star_count);
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
}
if (!giveaway_winners_->prize_description_.empty()) {
object("prize_description", giveaway_winners_->prize_description_);
@@ -2164,14 +2637,13 @@ class Client::JsonGiveawayWinners final : public td::Jsonable {
}
private:
- const td_api::messagePremiumGiveawayWinners *giveaway_winners_;
+ const td_api::messageGiveawayWinners *giveaway_winners_;
const Client *client_;
};
class Client::JsonGiveawayCompleted final : public td::Jsonable {
public:
- JsonGiveawayCompleted(const td_api::messagePremiumGiveawayCompleted *giveaway_completed, int64 chat_id,
- const Client *client)
+ JsonGiveawayCompleted(const td_api::messageGiveawayCompleted *giveaway_completed, int64 chat_id, const Client *client)
: giveaway_completed_(giveaway_completed), chat_id_(chat_id), client_(client) {
}
void store(td::JsonValueScope *scope) const {
@@ -2180,6 +2652,9 @@ class Client::JsonGiveawayCompleted final : public td::Jsonable {
if (giveaway_completed_->unclaimed_prize_count_ > 0) {
object("unclaimed_prize_count", giveaway_completed_->unclaimed_prize_count_);
}
+ if (giveaway_completed_->is_star_giveaway_) {
+ object("is_star_giveaway", td::JsonTrue());
+ }
const MessageInfo *giveaway_message =
client_->get_message(chat_id_, giveaway_completed_->giveaway_message_id_, true);
if (giveaway_message != nullptr) {
@@ -2188,11 +2663,24 @@ class Client::JsonGiveawayCompleted final : public td::Jsonable {
}
private:
- const td_api::messagePremiumGiveawayCompleted *giveaway_completed_;
+ const td_api::messageGiveawayCompleted *giveaway_completed_;
int64 chat_id_;
const Client *client_;
};
+class Client::JsonChatBoostAdded final : public td::Jsonable {
+ public:
+ explicit JsonChatBoostAdded(const td_api::messageChatBoost *chat_boost) : chat_boost_(chat_boost) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ object("boost_count", chat_boost_->boost_count_);
+ }
+
+ private:
+ const td_api::messageChatBoost *chat_boost_;
+};
+
class Client::JsonWebAppInfo final : public td::Jsonable {
public:
explicit JsonWebAppInfo(const td::string &url) : url_(url) {
@@ -2337,7 +2825,7 @@ class Client::JsonExternalReplyInfo final : public td::Jsonable {
case td_api::messageText::ID: {
auto content = static_cast(reply_->content_.get());
if (content->link_preview_options_ != nullptr) {
- object("link_preview_options", JsonLinkPreviewOptions(content->link_preview_options_.get(), client_));
+ object("link_preview_options", JsonLinkPreviewOptions(content->link_preview_options_.get()));
}
break;
}
@@ -2357,6 +2845,11 @@ class Client::JsonExternalReplyInfo final : public td::Jsonable {
object("document", JsonDocument(content->document_.get(), client_));
break;
}
+ case td_api::messagePaidMedia::ID: {
+ auto content = static_cast(reply_->content_.get());
+ object("paid_media", JsonPaidMediaInfo(content, client_));
+ break;
+ }
case td_api::messagePhoto::ID: {
auto content = static_cast(reply_->content_.get());
CHECK(content->photo_ != nullptr);
@@ -2423,13 +2916,13 @@ class Client::JsonExternalReplyInfo final : public td::Jsonable {
}
case td_api::messageUnsupported::ID:
break;
- case td_api::messagePremiumGiveaway::ID: {
- auto content = static_cast(reply_->content_.get());
+ case td_api::messageGiveaway::ID: {
+ auto content = static_cast(reply_->content_.get());
object("giveaway", JsonGiveaway(content, client_));
break;
}
- case td_api::messagePremiumGiveawayWinners::ID: {
- auto content = static_cast(reply_->content_.get());
+ case td_api::messageGiveawayWinners::ID: {
+ auto content = static_cast(reply_->content_.get());
object("giveaway_winners", JsonGiveawayWinners(content, client_));
break;
}
@@ -2477,6 +2970,12 @@ class Client::JsonTextQuote final : public td::Jsonable {
void Client::JsonMessage::store(td::JsonValueScope *scope) const {
CHECK(message_ != nullptr);
auto object = scope->enter_object();
+ if (!message_->business_connection_id.empty()) {
+ object("business_connection_id", message_->business_connection_id);
+ if (message_->sender_business_bot_user_id != 0) {
+ object("sender_business_bot", JsonUser(message_->sender_business_bot_user_id, client_));
+ }
+ }
if (message_->is_scheduled) {
object("message_id", as_scheduled_message_id(message_->id));
} else {
@@ -2488,6 +2987,9 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const {
if (!message_->author_signature.empty()) {
object("author_signature", message_->author_signature);
}
+ if (message_->sender_boost_count != 0) {
+ object("sender_boost_count", message_->sender_boost_count);
+ }
if (message_->sender_chat_id != 0) {
object("sender_chat", JsonChat(message_->sender_chat_id, client_));
}
@@ -2557,7 +3059,9 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const {
auto reply_to_message_id = get_same_chat_reply_to_message_id(message_);
if (reply_to_message_id > 0) {
// internal reply
- const MessageInfo *reply_to_message = client_->get_message(message_->chat_id, reply_to_message_id, true);
+ const MessageInfo *reply_to_message = !message_->business_connection_id.empty()
+ ? message_->business_reply_to_message.get()
+ : client_->get_message(message_->chat_id, reply_to_message_id, true);
if (reply_to_message != nullptr) {
object("reply_to_message", JsonMessage(reply_to_message, false, "reply in " + source_, client_));
} else {
@@ -2572,6 +3076,10 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const {
if (message_->reply_to_message != nullptr && message_->reply_to_message->quote_ != nullptr) {
object("quote", JsonTextQuote(message_->reply_to_message->quote_.get(), client_));
}
+ if (message_->reply_to_story != nullptr) {
+ object("reply_to_story",
+ JsonStory(message_->reply_to_story->story_sender_chat_id_, message_->reply_to_story->story_id_, client_));
+ }
if (message_->media_album_id != 0) {
object("media_group_id", td::to_string(message_->media_album_id));
}
@@ -2583,7 +3091,7 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const {
object("entities", JsonVectorEntities(content->text_->entities_, client_));
}
if (content->link_preview_options_ != nullptr) {
- object("link_preview_options", JsonLinkPreviewOptions(content->link_preview_options_.get(), client_));
+ object("link_preview_options", JsonLinkPreviewOptions(content->link_preview_options_.get()));
}
break;
}
@@ -2591,27 +3099,33 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const {
auto content = static_cast(message_->content.get());
object("animation", JsonAnimation(content->animation_.get(), false, client_));
object("document", JsonAnimation(content->animation_.get(), true, client_));
- add_caption(object, content->caption_);
+ add_caption(object, content->caption_, content->show_caption_above_media_);
add_media_spoiler(object, content->has_spoiler_);
break;
}
case td_api::messageAudio::ID: {
auto content = static_cast(message_->content.get());
object("audio", JsonAudio(content->audio_.get(), client_));
- add_caption(object, content->caption_);
+ add_caption(object, content->caption_, false);
break;
}
case td_api::messageDocument::ID: {
auto content = static_cast(message_->content.get());
object("document", JsonDocument(content->document_.get(), client_));
- add_caption(object, content->caption_);
+ add_caption(object, content->caption_, false);
+ break;
+ }
+ case td_api::messagePaidMedia::ID: {
+ auto content = static_cast(message_->content.get());
+ object("paid_media", JsonPaidMediaInfo(content, client_));
+ add_caption(object, content->caption_, content->show_caption_above_media_);
break;
}
case td_api::messagePhoto::ID: {
auto content = static_cast(message_->content.get());
CHECK(content->photo_ != nullptr);
object("photo", JsonPhoto(content->photo_.get(), client_));
- add_caption(object, content->caption_);
+ add_caption(object, content->caption_, content->show_caption_above_media_);
add_media_spoiler(object, content->has_spoiler_);
break;
}
@@ -2623,7 +3137,7 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const {
case td_api::messageVideo::ID: {
auto content = static_cast(message_->content.get());
object("video", JsonVideo(content->video_.get(), client_));
- add_caption(object, content->caption_);
+ add_caption(object, content->caption_, content->show_caption_above_media_);
add_media_spoiler(object, content->has_spoiler_);
break;
}
@@ -2635,7 +3149,7 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const {
case td_api::messageVoiceNote::ID: {
auto content = static_cast(message_->content.get());
object("voice", JsonVoiceNote(content->voice_note_.get(), client_));
- add_caption(object, content->caption_);
+ add_caption(object, content->caption_, false);
break;
}
case td_api::messageContact::ID: {
@@ -2786,7 +3300,9 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const {
auto content = static_cast(message_->content.get());
auto message_id = content->message_id_;
if (message_id > 0) {
- const MessageInfo *pinned_message = client_->get_message(message_->chat_id, message_id, true);
+ const MessageInfo *pinned_message = !message_->business_connection_id.empty()
+ ? message_->business_reply_to_message.get()
+ : client_->get_message(message_->chat_id, message_id, true);
if (pinned_message != nullptr) {
object("pinned_message", JsonMessage(pinned_message, false, "pin in " + source_, client_));
} else if (need_reply_) {
@@ -2822,6 +3338,10 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const {
break;
case td_api::messageExpiredVideo::ID:
break;
+ case td_api::messageExpiredVideoNote::ID:
+ break;
+ case td_api::messageExpiredVoiceNote::ID:
+ break;
case td_api::messageCustomServiceAction::ID:
break;
case td_api::messageChatSetTheme::ID:
@@ -2892,42 +3412,63 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const {
}
case td_api::messageUsersShared::ID: {
auto content = static_cast(message_->content.get());
- if (content->user_ids_.size() == 1) {
+ if (content->users_.size() == 1) {
object("user_shared", JsonUserShared(content));
}
- object("users_shared", JsonUsersShared(content));
+ object("users_shared", JsonUsersShared(content, client_));
break;
}
case td_api::messageChatShared::ID: {
auto content = static_cast(message_->content.get());
- object("chat_shared", JsonChatShared(content));
+ object("chat_shared", JsonChatShared(content, client_));
break;
}
- case td_api::messageStory::ID:
- object("story", JsonEmptyObject());
+ case td_api::messageStory::ID: {
+ auto content = static_cast(message_->content.get());
+ object("story", JsonStory(content->story_sender_chat_id_, content->story_id_, client_));
break;
- case td_api::messageChatSetBackground::ID:
+ }
+ case td_api::messageChatSetBackground::ID: {
+ auto content = static_cast(message_->content.get());
+ object("chat_background_set", JsonChatBackground(content->background_.get(), client_));
break;
+ }
case td_api::messagePremiumGiftCode::ID:
break;
- case td_api::messagePremiumGiveawayCreated::ID:
- object("giveaway_created", JsonEmptyObject());
+ case td_api::messageGiveawayCreated::ID: {
+ auto content = static_cast(message_->content.get());
+ object("giveaway_created", JsonGiveawayCreated(content));
break;
- case td_api::messagePremiumGiveaway::ID: {
- auto content = static_cast(message_->content.get());
+ }
+ case td_api::messageGiveaway::ID: {
+ auto content = static_cast(message_->content.get());
object("giveaway", JsonGiveaway(content, client_));
break;
}
- case td_api::messagePremiumGiveawayWinners::ID: {
- auto content = static_cast(message_->content.get());
+ case td_api::messageGiveawayWinners::ID: {
+ auto content = static_cast(message_->content.get());
object("giveaway_winners", JsonGiveawayWinners(content, client_));
break;
}
- case td_api::messagePremiumGiveawayCompleted::ID: {
- auto content = static_cast(message_->content.get());
+ case td_api::messageGiveawayCompleted::ID: {
+ auto content = static_cast(message_->content.get());
object("giveaway_completed", JsonGiveawayCompleted(content, message_->chat_id, client_));
break;
}
+ case td_api::messageChatBoost::ID: {
+ auto content = static_cast(message_->content.get());
+ object("boost_added", JsonChatBoostAdded(content));
+ break;
+ }
+ case td_api::messagePaymentRefunded::ID: {
+ auto content = static_cast(message_->content.get());
+ object("refunded_payment", JsonRefundedPayment(content));
+ break;
+ }
+ case td_api::messageGiftedStars::ID:
+ break;
+ case td_api::messageGiveawayPrizeStars::ID:
+ break;
default:
UNREACHABLE();
}
@@ -2943,6 +3484,12 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const {
if (message_->is_topic_message) {
object("is_topic_message", td::JsonTrue());
}
+ if (message_->is_from_offline) {
+ object("is_from_offline", td::JsonTrue());
+ }
+ if (message_->effect_id != 0) {
+ object("effect_id", td::to_string(message_->effect_id));
+ }
}
class Client::JsonMessageId final : public td::Jsonable {
@@ -3182,6 +3729,23 @@ class Client::JsonPreCheckoutQuery final : public td::Jsonable {
const Client *client_;
};
+class Client::JsonPaidMediaPurchased final : public td::Jsonable {
+ public:
+ JsonPaidMediaPurchased(const td_api::updatePaidMediaPurchased *update, const Client *client)
+ : update_(update), client_(client) {
+ }
+
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ object("from", JsonUser(update_->user_id_, client_));
+ object("payload", update_->payload_);
+ }
+
+ private:
+ const td_api::updatePaidMediaPurchased *update_;
+ const Client *client_;
+};
+
class Client::JsonCustomJson final : public td::Jsonable {
public:
explicit JsonCustomJson(const td::string &json) : json_(json) {
@@ -3353,8 +3917,13 @@ class Client::JsonChatMember final : public td::Jsonable {
}
break;
}
- case td_api::chatMemberStatusMember::ID:
+ case td_api::chatMemberStatusMember::ID: {
+ auto member = static_cast(member_->status_.get());
+ if (member->member_until_date_ > 0) {
+ object("until_date", member->member_until_date_);
+ }
break;
+ }
case td_api::chatMemberStatusRestricted::ID:
if (chat_type_ == Client::ChatType::Supergroup) {
auto restricted = static_cast(member_->status_.get());
@@ -3443,6 +4012,9 @@ class Client::JsonChatMemberUpdated final : public td::Jsonable {
if (update_->invite_link_ != nullptr) {
object("invite_link", JsonChatInviteLink(update_->invite_link_.get(), client_));
}
+ if (update_->via_join_request_) {
+ object("via_join_request", td::JsonTrue());
+ }
if (update_->via_chat_folder_invite_link_) {
object("via_chat_folder_invite_link", td::JsonTrue());
}
@@ -3502,6 +4074,9 @@ class Client::JsonChatBoostSource final : public td::Jsonable {
const auto *source = static_cast(boost_source_);
object("source", "giveaway");
object("giveaway_message_id", as_client_message_id_unchecked(source->giveaway_message_id_));
+ if (source->star_count_ > 0) {
+ object("prize_star_count", source->star_count_);
+ }
if (source->user_id_ != 0) {
object("user", JsonUser(source->user_id_, client_));
} else if (source->is_unclaimed_) {
@@ -3655,6 +4230,187 @@ class Client::JsonMessageReactionCountUpdated final : public td::Jsonable {
const Client *client_;
};
+class Client::JsonBusinessConnection final : public td::Jsonable {
+ public:
+ JsonBusinessConnection(const BusinessConnection *connection, const Client *client)
+ : connection_(connection), client_(client) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ object("id", connection_->id_);
+ object("user", JsonUser(connection_->user_id_, client_));
+ object("user_chat_id", connection_->user_chat_id_);
+ object("date", connection_->date_);
+ object("can_reply", td::JsonBool(connection_->can_reply_));
+ object("is_enabled", td::JsonBool(connection_->is_enabled_));
+ }
+
+ private:
+ const BusinessConnection *connection_;
+ const Client *client_;
+};
+
+class Client::JsonBusinessMessagesDeleted final : public td::Jsonable {
+ public:
+ JsonBusinessMessagesDeleted(const td_api::updateBusinessMessagesDeleted *update, const Client *client)
+ : update_(update), client_(client) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ object("business_connection_id", update_->connection_id_);
+ object("chat", JsonChat(update_->chat_id_, client_));
+ object("message_ids", td::json_array(update_->message_ids_, as_client_message_id));
+ }
+
+ private:
+ const td_api::updateBusinessMessagesDeleted *update_;
+ const Client *client_;
+};
+
+class Client::JsonRevenueWithdrawalState final : public td::Jsonable {
+ public:
+ explicit JsonRevenueWithdrawalState(const td_api::RevenueWithdrawalState *state) : state_(state) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ switch (state_->get_id()) {
+ case td_api::revenueWithdrawalStatePending::ID:
+ object("type", "pending");
+ break;
+ case td_api::revenueWithdrawalStateSucceeded::ID: {
+ auto state = static_cast(state_);
+ object("type", "succeeded");
+ object("date", state->date_);
+ object("url", state->url_);
+ break;
+ }
+ case td_api::revenueWithdrawalStateFailed::ID:
+ object("type", "failed");
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ private:
+ const td_api::RevenueWithdrawalState *state_;
+};
+
+class Client::JsonStarTransactionPartner final : public td::Jsonable {
+ public:
+ JsonStarTransactionPartner(const td_api::StarTransactionPartner *source, const Client *client)
+ : source_(source), client_(client) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ switch (source_->get_id()) {
+ case td_api::starTransactionPartnerFragment::ID: {
+ auto source_fragment = static_cast(source_);
+ object("type", "fragment");
+ if (source_fragment->withdrawal_state_ != nullptr) {
+ object("withdrawal_state", JsonRevenueWithdrawalState(source_fragment->withdrawal_state_.get()));
+ }
+ break;
+ }
+ case td_api::starTransactionPartnerBot::ID: {
+ auto source_user = static_cast(source_);
+ object("type", "user");
+ object("user", JsonUser(source_user->user_id_, client_));
+ CHECK(source_user->purpose_ != nullptr);
+ switch (source_user->purpose_->get_id()) {
+ case td_api::botTransactionPurposeInvoicePayment::ID: {
+ auto purpose =
+ static_cast(source_user->purpose_.get());
+ if (!purpose->invoice_payload_.empty()) {
+ if (!td::check_utf8(purpose->invoice_payload_)) {
+ LOG(WARNING) << "Receive non-UTF-8 invoice payload";
+ object("invoice_payload", td::JsonRawString(purpose->invoice_payload_));
+ } else {
+ object("invoice_payload", purpose->invoice_payload_);
+ }
+ }
+ break;
+ }
+ case td_api::botTransactionPurposePaidMedia::ID: {
+ auto purpose = static_cast(source_user->purpose_.get());
+ object("paid_media", td::json_array(purpose->media_, [client = client_](auto &media) {
+ return JsonPaidMedia(media.get(), client);
+ }));
+ if (!purpose->payload_.empty()) {
+ object("paid_media_payload", purpose->payload_);
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case td_api::starTransactionPartnerTelegramAds::ID:
+ object("type", "telegram_ads");
+ break;
+ case td_api::starTransactionPartnerTelegram::ID:
+ case td_api::starTransactionPartnerAppStore::ID:
+ case td_api::starTransactionPartnerGooglePlay::ID:
+ case td_api::starTransactionPartnerUser::ID:
+ case td_api::starTransactionPartnerBusiness::ID:
+ case td_api::starTransactionPartnerChat::ID:
+ LOG(ERROR) << "Receive " << to_string(*source_);
+ object("type", "other");
+ break;
+ case td_api::starTransactionPartnerUnsupported::ID:
+ object("type", "other");
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ private:
+ const td_api::StarTransactionPartner *source_;
+ const Client *client_;
+};
+
+class Client::JsonStarTransaction final : public td::Jsonable {
+ public:
+ JsonStarTransaction(const td_api::starTransaction *transaction, const Client *client)
+ : transaction_(transaction), client_(client) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ object("id", transaction_->id_);
+ object("date", transaction_->date_);
+ if (transaction_->star_count_ > 0) {
+ object("amount", transaction_->star_count_);
+ object("source", JsonStarTransactionPartner(transaction_->partner_.get(), client_));
+ } else {
+ object("amount", -transaction_->star_count_);
+ object("receiver", JsonStarTransactionPartner(transaction_->partner_.get(), client_));
+ }
+ }
+
+ private:
+ const td_api::starTransaction *transaction_;
+ const Client *client_;
+};
+
+class Client::JsonStarTransactions final : public td::Jsonable {
+ public:
+ JsonStarTransactions(const td_api::starTransactions *transactions, const Client *client)
+ : transactions_(transactions), client_(client) {
+ }
+ void store(td::JsonValueScope *scope) const {
+ auto object = scope->enter_object();
+ object("transactions", td::json_array(transactions_->transactions_, [client = client_](const auto &transaction) {
+ return JsonStarTransaction(transaction.get(), client);
+ }));
+ }
+
+ private:
+ const td_api::starTransactions *transactions_;
+ const Client *client_;
+};
+
class Client::JsonUpdateTypes final : public td::Jsonable {
public:
explicit JsonUpdateTypes(td::uint32 update_types) : update_types_(update_types) {
@@ -3733,10 +4489,6 @@ class Client::JsonStickerSet final : public td::Jsonable {
client_->json_store_thumbnail(object, sticker_set_->thumbnail_.get());
}
- auto format = sticker_set_->sticker_format_->get_id();
- object("is_animated", td::JsonBool(format == td_api::stickerFormatTgs::ID));
- object("is_video", td::JsonBool(format == td_api::stickerFormatWebm::ID));
-
auto type = Client::get_sticker_type(sticker_set_->sticker_type_);
object("sticker_type", type);
object("contains_masks", td::JsonBool(type == "mask"));
@@ -4109,6 +4861,29 @@ class Client::TdOnSendMessageCallback final : public TdQueryCallback {
PromisedQueryPtr query_;
};
+class Client::TdOnReturnBusinessMessageCallback final : public TdQueryCallback {
+ public:
+ TdOnReturnBusinessMessageCallback(Client *client, td::string business_connection_id, PromisedQueryPtr query)
+ : client_(client), business_connection_id_(std::move(business_connection_id)), query_(std::move(query)) {
+ }
+
+ void on_result(object_ptr result) final {
+ if (result->get_id() == td_api::error::ID) {
+ return fail_query_with_error(std::move(query_), move_object_as(result));
+ }
+
+ CHECK(result->get_id() == td_api::businessMessage::ID);
+ auto message = client_->create_business_message(std::move(business_connection_id_),
+ move_object_as(result));
+ answer_query(JsonMessage(message.get(), true, "business message", client_), std::move(query_));
+ }
+
+ private:
+ Client *client_;
+ td::string business_connection_id_;
+ PromisedQueryPtr query_;
+};
+
class Client::TdOnSendMessageAlbumCallback final : public TdQueryCallback {
public:
TdOnSendMessageAlbumCallback(Client *client, int64 chat_id, std::size_t message_count, PromisedQueryPtr query)
@@ -4139,6 +4914,34 @@ class Client::TdOnSendMessageAlbumCallback final : public TdQueryCallback {
PromisedQueryPtr query_;
};
+class Client::TdOnSendBusinessMessageAlbumCallback final : public TdQueryCallback {
+ public:
+ TdOnSendBusinessMessageAlbumCallback(Client *client, td::string business_connection_id, PromisedQueryPtr query)
+ : client_(client), business_connection_id_(std::move(business_connection_id)), query_(std::move(query)) {
+ }
+
+ void on_result(object_ptr result) final {
+ if (result->get_id() == td_api::error::ID) {
+ return fail_query_with_error(std::move(query_), move_object_as(result));
+ }
+
+ CHECK(result->get_id() == td_api::businessMessages::ID);
+ auto messages = move_object_as(result);
+ td::vector message_strings;
+ for (auto &message : messages->messages_) {
+ auto message_info = client_->create_business_message(business_connection_id_, std::move(message));
+ message_strings.push_back(
+ td::json_encode(JsonMessage(message_info.get(), true, "sent business message", client_)));
+ }
+ answer_query(JsonMessages(message_strings), std::move(query_));
+ }
+
+ private:
+ Client *client_;
+ td::string business_connection_id_;
+ PromisedQueryPtr query_;
+};
+
class Client::TdOnForwardMessagesCallback final : public TdQueryCallback {
public:
TdOnForwardMessagesCallback(Client *client, int64 chat_id, std::size_t message_count, PromisedQueryPtr query)
@@ -4288,6 +5091,34 @@ class Client::TdOnStopPollCallback final : public TdQueryCallback {
PromisedQueryPtr query_;
};
+class Client::TdOnStopBusinessPollCallback final : public TdQueryCallback {
+ public:
+ TdOnStopBusinessPollCallback(Client *client, const td::string &business_connection_id, PromisedQueryPtr query)
+ : client_(client), business_connection_id_(business_connection_id), query_(std::move(query)) {
+ }
+
+ void on_result(object_ptr result) final {
+ if (result->get_id() == td_api::error::ID) {
+ return fail_query_with_error(std::move(query_), move_object_as(result));
+ }
+
+ CHECK(result->get_id() == td_api::businessMessage::ID);
+ auto message = client_->create_business_message(std::move(business_connection_id_),
+ move_object_as(result));
+ if (message->content->get_id() != td_api::messagePoll::ID) {
+ LOG(ERROR) << "Poll not found in a business message from connection " << business_connection_id_;
+ return fail_query_with_error(std::move(query_), 400, "message poll not found");
+ }
+ auto message_poll = static_cast(message->content.get());
+ answer_query(JsonPoll(message_poll->poll_.get(), client_), std::move(query_));
+ }
+
+ private:
+ Client *client_;
+ td::string business_connection_id_;
+ PromisedQueryPtr query_;
+};
+
class Client::TdOnOkQueryCallback final : public TdQueryCallback {
public:
explicit TdOnOkQueryCallback(PromisedQueryPtr query) : query_(std::move(query)) {
@@ -4324,7 +5155,7 @@ class Client::TdOnCheckUserCallback final : public TdQueryCallback {
auto user_info = client_->get_user_info(user->id_);
CHECK(user_info != nullptr); // it must have already been got through updates
- return client_->check_user_read_access(user_info, std::move(query_), std::move(on_success_));
+ client_->check_user_read_access(user_info, std::move(query_), std::move(on_success_));
}
private:
@@ -4375,7 +5206,7 @@ class Client::TdOnCheckChatCallback final : public TdQueryCallback {
return fail_query(400, "Bad Request: chat not found", std::move(query_));
}
- return client_->check_chat_access(chat->id_, access_rights_, chat_info, std::move(query_), std::move(on_success_));
+ client_->check_chat_access(chat->id_, access_rights_, chat_info, std::move(query_), std::move(on_success_));
}
private:
@@ -4437,6 +5268,30 @@ class Client::TdOnCheckChatNoFailCallback final : public TdQueryCallback {
OnSuccess on_success_;
};
+template
+class Client::TdOnCheckBusinessConnectionCallback final : public TdQueryCallback {
+ public:
+ TdOnCheckBusinessConnectionCallback(Client *client, PromisedQueryPtr query, OnSuccess on_success)
+ : client_(client), query_(std::move(query)), on_success_(std::move(on_success)) {
+ }
+
+ void on_result(object_ptr result) final {
+ if (result->get_id() == td_api::error::ID) {
+ return fail_query_with_error(std::move(query_), move_object_as(result),
+ "business connection not found");
+ }
+
+ CHECK(result->get_id() == td_api::businessConnection::ID);
+ auto connection = client_->add_business_connection(move_object_as(result), false);
+ on_success_(connection, std::move(query_));
+ }
+
+ private:
+ Client *client_;
+ PromisedQueryPtr query_;
+ OnSuccess on_success_;
+};
+
template
class Client::TdOnSearchStickerSetCallback final : public TdQueryCallback {
public:
@@ -4664,7 +5519,7 @@ class Client::TdOnGetChatMemberCallback final : public TdQueryCallback {
void on_result(object_ptr result) final {
if (result->get_id() == td_api::error::ID) {
- return fail_query_with_error(std::move(query_), move_object_as(result), "user not found");
+ return fail_query_with_error(std::move(query_), move_object_as(result));
}
CHECK(result->get_id() == td_api::chatMember::ID);
@@ -4777,11 +5632,15 @@ class Client::TdOnGetCallbackQueryMessageCallback final : public TdQueryCallback
class Client::TdOnGetStickerSetCallback final : public TdQueryCallback {
public:
- TdOnGetStickerSetCallback(Client *client, int64 set_id, int64 new_callback_query_user_id, int64 new_message_chat_id)
+ TdOnGetStickerSetCallback(Client *client, int64 set_id, int64 new_callback_query_user_id, int64 new_message_chat_id,
+ const td::string &new_message_business_connection_id,
+ int64 new_business_callback_query_user_id)
: client_(client)
, set_id_(set_id)
, new_callback_query_user_id_(new_callback_query_user_id)
- , new_message_chat_id_(new_message_chat_id) {
+ , new_message_chat_id_(new_message_chat_id)
+ , new_message_business_connection_id_(new_message_business_connection_id)
+ , new_business_callback_query_user_id_(new_business_callback_query_user_id) {
}
void on_result(object_ptr result) final {
@@ -4792,12 +5651,15 @@ class Client::TdOnGetStickerSetCallback final : public TdQueryCallback {
<< new_callback_query_user_id_ << "/new message in chat " << new_message_chat_id_ << ": "
<< td::oneline(to_string(error));
}
- return client_->on_get_sticker_set(set_id_, new_callback_query_user_id_, new_message_chat_id_, nullptr);
+ return client_->on_get_sticker_set(set_id_, new_callback_query_user_id_, new_message_chat_id_,
+ new_message_business_connection_id_, new_business_callback_query_user_id_,
+ nullptr);
}
- CHECK(result->get_id() == td_api::stickerSet::ID);
+ CHECK(result->get_id() == td_api::text::ID);
client_->on_get_sticker_set(set_id_, new_callback_query_user_id_, new_message_chat_id_,
- move_object_as(result));
+ new_message_business_connection_id_, new_business_callback_query_user_id_,
+ move_object_as(result));
}
private:
@@ -4805,24 +5667,30 @@ class Client::TdOnGetStickerSetCallback final : public TdQueryCallback {
int64 set_id_;
int64 new_callback_query_user_id_;
int64 new_message_chat_id_;
+ td::string new_message_business_connection_id_;
+ int64 new_business_callback_query_user_id_;
};
-class Client::TdOnGetChatStickerSetCallback final : public TdQueryCallback {
+class Client::TdOnGetChatCustomEmojiStickerSetCallback final : public TdQueryCallback {
public:
- TdOnGetChatStickerSetCallback(Client *client, int64 chat_id, int64 pinned_message_id, PromisedQueryPtr query)
- : client_(client), chat_id_(chat_id), pinned_message_id_(pinned_message_id), query_(std::move(query)) {
+ TdOnGetChatCustomEmojiStickerSetCallback(Client *client, int64 sticker_set_id, int64 chat_id, int64 pinned_message_id,
+ PromisedQueryPtr query)
+ : client_(client)
+ , sticker_set_id_(sticker_set_id)
+ , chat_id_(chat_id)
+ , pinned_message_id_(pinned_message_id)
+ , query_(std::move(query)) {
}
void on_result(object_ptr result) final {
+ auto chat_info = client_->get_chat(chat_id_);
+ CHECK(chat_info != nullptr);
+ CHECK(chat_info->type == ChatInfo::Type::Supergroup);
+ auto supergroup_info = client_->add_supergroup_info(chat_info->supergroup_id);
if (result->get_id() == td_api::error::ID) {
- auto chat_info = client_->get_chat(chat_id_);
- CHECK(chat_info != nullptr);
- CHECK(chat_info->type == ChatInfo::Type::Supergroup);
- client_->add_supergroup_info(chat_info->supergroup_id)->sticker_set_id = 0;
+ supergroup_info->custom_emoji_sticker_set_id = 0;
} else {
- CHECK(result->get_id() == td_api::stickerSet::ID);
- auto sticker_set = move_object_as(result);
- client_->on_get_sticker_set_name(sticker_set->id_, sticker_set->name_);
+ client_->on_get_sticker_set_name(sticker_set_id_, std::move(result));
}
answer_query(JsonChat(chat_id_, client_, true, pinned_message_id_), std::move(query_));
@@ -4830,6 +5698,83 @@ class Client::TdOnGetChatStickerSetCallback final : public TdQueryCallback {
private:
Client *client_;
+ int64 sticker_set_id_;
+ int64 chat_id_;
+ int64 pinned_message_id_;
+ PromisedQueryPtr query_;
+};
+
+class Client::TdOnGetChatBusinessStartPageStickerSetCallback final : public TdQueryCallback {
+ public:
+ TdOnGetChatBusinessStartPageStickerSetCallback(Client *client, int64 sticker_set_id, int64 chat_id,
+ int64 pinned_message_id, PromisedQueryPtr query)
+ : client_(client)
+ , sticker_set_id_(sticker_set_id)
+ , chat_id_(chat_id)
+ , pinned_message_id_(pinned_message_id)
+ , query_(std::move(query)) {
+ }
+
+ void on_result(object_ptr result) final {
+ auto chat_info = client_->get_chat(chat_id_);
+ CHECK(chat_info != nullptr);
+ CHECK(chat_info->type == ChatInfo::Type::Private);
+ auto user_info = client_->add_user_info(chat_info->user_id);
+ if (result->get_id() == td_api::error::ID) {
+ if (user_info->business_info != nullptr && user_info->business_info->start_page_ != nullptr &&
+ user_info->business_info->start_page_->sticker_ != nullptr) {
+ user_info->business_info->start_page_->sticker_->set_id_ = 0;
+ }
+ } else {
+ client_->on_get_sticker_set_name(sticker_set_id_, std::move(result));
+ }
+
+ answer_query(JsonChat(chat_id_, client_, true, pinned_message_id_), std::move(query_));
+ }
+
+ private:
+ Client *client_;
+ int64 sticker_set_id_;
+ int64 chat_id_;
+ int64 pinned_message_id_;
+ PromisedQueryPtr query_;
+};
+
+class Client::TdOnGetChatStickerSetCallback final : public TdQueryCallback {
+ public:
+ TdOnGetChatStickerSetCallback(Client *client, int64 sticker_set_id, int64 chat_id, int64 pinned_message_id,
+ PromisedQueryPtr query)
+ : client_(client)
+ , sticker_set_id_(sticker_set_id)
+ , chat_id_(chat_id)
+ , pinned_message_id_(pinned_message_id)
+ , query_(std::move(query)) {
+ }
+
+ void on_result(object_ptr result) final {
+ auto chat_info = client_->get_chat(chat_id_);
+ CHECK(chat_info != nullptr);
+ CHECK(chat_info->type == ChatInfo::Type::Supergroup);
+ auto supergroup_info = client_->add_supergroup_info(chat_info->supergroup_id);
+ if (result->get_id() == td_api::error::ID) {
+ supergroup_info->sticker_set_id = 0;
+ } else {
+ client_->on_get_sticker_set_name(sticker_set_id_, std::move(result));
+ }
+
+ auto sticker_set_id = supergroup_info->custom_emoji_sticker_set_id;
+ if (sticker_set_id != 0 && client_->get_sticker_set_name(sticker_set_id).empty()) {
+ return client_->send_request(make_object(sticker_set_id),
+ td::make_unique(
+ client_, sticker_set_id, chat_id_, pinned_message_id_, std::move(query_)));
+ }
+
+ answer_query(JsonChat(chat_id_, client_, true, pinned_message_id_), std::move(query_));
+ }
+
+ private:
+ Client *client_;
+ int64 sticker_set_id_;
int64 chat_id_;
int64 pinned_message_id_;
PromisedQueryPtr query_;
@@ -4845,7 +5790,7 @@ class Client::TdOnGetChatPinnedMessageCallback final : public TdQueryCallback {
int64 pinned_message_id = 0;
if (result->get_id() == td_api::error::ID) {
auto error = move_object_as(result);
- if (error->code_ == 429) {
+ if (is_special_error_code(error->code_)) {
return fail_query_with_error(std::move(query_), std::move(error));
} else if (error->code_ != 404 && error->message_ != "CHANNEL_PRIVATE") {
LOG(ERROR) << "Failed to get chat pinned message: " << to_string(error);
@@ -4866,9 +5811,31 @@ class Client::TdOnGetChatPinnedMessageCallback final : public TdQueryCallback {
auto sticker_set_id = supergroup_info->sticker_set_id;
if (sticker_set_id != 0 && client_->get_sticker_set_name(sticker_set_id).empty()) {
- return client_->send_request(
- make_object(sticker_set_id),
- td::make_unique(client_, chat_id_, pinned_message_id, std::move(query_)));
+ return client_->send_request(make_object(sticker_set_id),
+ td::make_unique(
+ client_, sticker_set_id, chat_id_, pinned_message_id, std::move(query_)));
+ }
+
+ sticker_set_id = supergroup_info->custom_emoji_sticker_set_id;
+ if (sticker_set_id != 0 && client_->get_sticker_set_name(sticker_set_id).empty()) {
+ return client_->send_request(make_object(sticker_set_id),
+ td::make_unique(
+ client_, sticker_set_id, chat_id_, pinned_message_id, std::move(query_)));
+ }
+ } else if (chat_info->type == ChatInfo::Type::Private) {
+ auto user_info = client_->get_user_info(chat_info->user_id);
+ CHECK(user_info != nullptr);
+
+ if (user_info->business_info != nullptr && user_info->business_info->start_page_ != nullptr) {
+ auto *sticker = user_info->business_info->start_page_->sticker_.get();
+ if (sticker != nullptr) {
+ auto sticker_set_id = sticker->set_id_;
+ if (sticker_set_id != 0 && client_->get_sticker_set_name(sticker_set_id).empty()) {
+ return client_->send_request(make_object(sticker_set_id),
+ td::make_unique(
+ client_, sticker_set_id, chat_id_, pinned_message_id, std::move(query_)));
+ }
+ }
}
}
@@ -4891,10 +5858,10 @@ class Client::TdOnGetChatPinnedMessageToUnpinCallback final : public TdQueryCall
int64 pinned_message_id = 0;
if (result->get_id() == td_api::error::ID) {
auto error = move_object_as(result);
- if (error->code_ == 429) {
+ if (is_special_error_code(error->code_)) {
return fail_query_with_error(std::move(query_), std::move(error));
} else {
- return fail_query_with_error(std::move(query_), make_object(400, "Message to unpin not found"));
+ return fail_query_with_error(std::move(query_), 400, "Message to unpin not found");
}
}
@@ -4949,8 +5916,7 @@ class Client::TdOnGetMyDefaultAdministratorRightsCallback final : public TdQuery
auto full_info = move_object_as(result);
if (full_info->bot_info_ == nullptr) {
LOG(ERROR) << "Have no bot info for self";
- return fail_query_with_error(std::move(query_),
- make_object(500, "Requested data is inaccessible"));
+ return fail_query_with_error(std::move(query_), 500, "Requested data is inaccessible");
}
auto bot_info = std::move(full_info->bot_info_);
const auto *rights = for_channels_ ? bot_info->default_channel_administrator_rights_.get()
@@ -5139,7 +6105,7 @@ class Client::TdOnGetSupergroupMemberCountCallback final : public TdQueryCallbac
CHECK(result->get_id() == td_api::supergroupFullInfo::ID);
auto supergroup_full_info = move_object_as(result);
- return answer_query(td::VirtuallyJsonableInt(supergroup_full_info->member_count_), std::move(query_));
+ answer_query(td::VirtuallyJsonableInt(supergroup_full_info->member_count_), std::move(query_));
}
private:
@@ -5158,7 +6124,7 @@ class Client::TdOnCreateInvoiceLinkCallback final : public TdQueryCallback {
CHECK(result->get_id() == td_api::httpUrl::ID);
auto http_url = move_object_as(result);
- return answer_query(td::VirtuallyJsonableString(http_url->url_), std::move(query_));
+ answer_query(td::VirtuallyJsonableString(http_url->url_), std::move(query_));
}
private:
@@ -5177,7 +6143,7 @@ class Client::TdOnReplacePrimaryChatInviteLinkCallback final : public TdQueryCal
CHECK(result->get_id() == td_api::chatInviteLink::ID);
auto invite_link = move_object_as(result);
- return answer_query(td::VirtuallyJsonableString(invite_link->invite_link_), std::move(query_));
+ answer_query(td::VirtuallyJsonableString(invite_link->invite_link_), std::move(query_));
}
private:
@@ -5197,12 +6163,12 @@ class Client::TdOnGetChatInviteLinkCallback final : public TdQueryCallback {
if (result->get_id() == td_api::chatInviteLink::ID) {
auto invite_link = move_object_as(result);
- return answer_query(JsonChatInviteLink(invite_link.get(), client_), std::move(query_));
+ answer_query(JsonChatInviteLink(invite_link.get(), client_), std::move(query_));
} else {
CHECK(result->get_id() == td_api::chatInviteLinks::ID);
auto invite_links = move_object_as(result);
CHECK(!invite_links->invite_links_.empty());
- return answer_query(JsonChatInviteLink(invite_links->invite_links_[0].get(), client_), std::move(query_));
+ answer_query(JsonChatInviteLink(invite_links->invite_links_[0].get(), client_), std::move(query_));
}
}
@@ -5211,6 +6177,27 @@ class Client::TdOnGetChatInviteLinkCallback final : public TdQueryCallback {
PromisedQueryPtr query_;
};
+class Client::TdOnGetStarTransactionsQueryCallback final : public TdQueryCallback {
+ public:
+ TdOnGetStarTransactionsQueryCallback(const Client *client, PromisedQueryPtr query)
+ : client_(client), query_(std::move(query)) {
+ }
+
+ void on_result(object_ptr result) final {
+ if (result->get_id() == td_api::error::ID) {
+ return fail_query_with_error(std::move(query_), move_object_as(result));
+ }
+
+ CHECK(result->get_id() == td_api::starTransactions::ID);
+ auto transactions = move_object_as(result);
+ answer_query(JsonStarTransactions(transactions.get(), client_), std::move(query_));
+ }
+
+ private:
+ const Client *client_;
+ PromisedQueryPtr query_;
+};
+
class Client::TdOnGetGameHighScoresCallback final : public TdQueryCallback {
public:
TdOnGetGameHighScoresCallback(const Client *client, PromisedQueryPtr query)
@@ -5322,8 +6309,8 @@ class Client::TdOnReturnStickerSetCallback final : public TdQueryCallback {
class Client::TdOnGetStickerSetPromiseCallback final : public TdQueryCallback {
public:
- TdOnGetStickerSetPromiseCallback(Client *client, td::Promise &&promise)
- : client_(client), promise_(std::move(promise)) {
+ TdOnGetStickerSetPromiseCallback(Client *client, int64 sticker_set_id, td::Promise &&promise)
+ : client_(client), sticker_set_id_(sticker_set_id), promise_(std::move(promise)) {
}
void on_result(object_ptr result) final {
@@ -5332,14 +6319,13 @@ class Client::TdOnGetStickerSetPromiseCallback final : public TdQueryCallback {
return promise_.set_error(td::Status::Error(error->code_, error->message_));
}
- CHECK(result->get_id() == td_api::stickerSet::ID);
- auto sticker_set = move_object_as(result);
- client_->on_get_sticker_set_name(sticker_set->id_, sticker_set->name_);
+ client_->on_get_sticker_set_name(sticker_set_id_, std::move(result));
promise_.set_value(td::Unit());
}
private:
Client *client_;
+ int64 sticker_set_id_;
td::Promise promise_;
};
@@ -5371,8 +6357,9 @@ class Client::TdOnGetStickersCallback final : public TdQueryCallback {
auto lock = mpas.get_promise();
for (auto sticker_set_id : sticker_set_ids) {
- client_->send_request(make_object(sticker_set_id),
- td::make_unique(client_, mpas.get_promise()));
+ client_->send_request(
+ make_object(sticker_set_id),
+ td::make_unique(client_, sticker_set_id, mpas.get_promise()));
}
lock.set_value(td::Unit());
}
@@ -5703,6 +6690,7 @@ ServerBotInfo Client::get_bot_info() const {
}
void Client::start_up() {
+ CHECK(start_time_ < 1e-10);
start_time_ = td::Time::now();
next_bot_updates_warning_time_ = start_time_ + 600;
webhook_set_time_ = start_time_;
@@ -5873,7 +6861,8 @@ void Client::on_get_callback_query_message(object_ptr message,
}
void Client::on_get_sticker_set(int64 set_id, int64 new_callback_query_user_id, int64 new_message_chat_id,
- object_ptr sticker_set) {
+ const td::string &new_message_business_connection_id,
+ int64 new_business_callback_query_user_id, object_ptr sticker_set_name) {
if (new_callback_query_user_id != 0) {
auto &queue = new_callback_query_queues_[new_callback_query_user_id];
CHECK(queue.has_active_request_);
@@ -5888,12 +6877,26 @@ void Client::on_get_sticker_set(int64 set_id, int64 new_callback_query_user_id,
CHECK(!queue.queue_.empty());
}
+ if (!new_message_business_connection_id.empty()) {
+ auto &queue = new_business_message_queues_[new_message_business_connection_id];
+ CHECK(queue.has_active_request_);
+ queue.has_active_request_ = false;
+
+ CHECK(!queue.queue_.empty());
+ }
+ if (new_business_callback_query_user_id != 0) {
+ auto &queue = new_business_callback_query_queues_[new_business_callback_query_user_id];
+ CHECK(queue.has_active_request_);
+ queue.has_active_request_ = false;
+
+ CHECK(!queue.queue_.empty());
+ }
CHECK(set_id != 0);
if (set_id != GREAT_MINDS_SET_ID) {
td::string &set_name = sticker_set_names_[set_id];
- if (sticker_set != nullptr) {
- set_name = std::move(sticker_set->name_);
+ if (sticker_set_name != nullptr) {
+ set_name = std::move(sticker_set_name->text_);
}
}
@@ -5903,6 +6906,12 @@ void Client::on_get_sticker_set(int64 set_id, int64 new_callback_query_user_id,
if (new_message_chat_id != 0) {
process_new_message_queue(new_message_chat_id, 2);
}
+ if (!new_message_business_connection_id.empty()) {
+ process_new_business_message_queue(new_message_business_connection_id);
+ }
+ if (new_business_callback_query_user_id != 0) {
+ process_new_business_callback_query_queue(new_business_callback_query_user_id);
+ }
}
void Client::on_get_sticker_set_name(int64 set_id, const td::string &name) {
@@ -5912,6 +6921,12 @@ void Client::on_get_sticker_set_name(int64 set_id, const td::string &name) {
}
}
+void Client::on_get_sticker_set_name(int64 set_id, object_ptr sticker_set_name) {
+ CHECK(sticker_set_name->get_id() == td_api::text::ID);
+ auto text = move_object_as(sticker_set_name);
+ on_get_sticker_set_name(set_id, text->text_);
+}
+
template
void Client::check_user_read_access(const UserInfo *user_info, PromisedQueryPtr query, OnSuccess on_success) {
CHECK(user_info != nullptr);
@@ -5924,7 +6939,7 @@ void Client::check_user_read_access(const UserInfo *user_info, PromisedQueryPtr
template
void Client::check_user(int64 user_id, PromisedQueryPtr query, OnSuccess on_success) {
const UserInfo *user_info = get_user_info(user_id);
- if (user_info != nullptr) {
+ if (user_info != nullptr && user_info->have_access) {
return check_user_read_access(user_info, std::move(query), std::move(on_success));
}
send_request(make_object(user_id),
@@ -5934,7 +6949,7 @@ void Client::check_user(int64 user_id, PromisedQueryPtr query, OnSuccess on_succ
template
void Client::check_user_no_fail(int64 user_id, PromisedQueryPtr query, OnSuccess on_success) {
const UserInfo *user_info = get_user_info(user_id);
- if (user_info != nullptr) {
+ if (user_info != nullptr && user_info->have_access) {
on_success(std::move(query));
return;
}
@@ -6030,6 +7045,12 @@ void Client::check_chat(td::Slice chat_id_str, AccessRights access_rights, Promi
auto chat_id = td::to_integer(chat_id_str);
auto chat_info = get_chat(chat_id);
+ if (chat_info != nullptr && chat_info->type == ChatInfo::Type::Private) {
+ const UserInfo *user_info = get_user_info(chat_info->user_id);
+ if (user_info == nullptr || !user_info->have_access) {
+ chat_info = nullptr;
+ }
+ }
if (chat_info != nullptr) {
return check_chat_access(chat_id, access_rights, chat_info, std::move(query), std::move(on_success));
}
@@ -6051,6 +7072,12 @@ void Client::check_chat_no_fail(td::Slice chat_id_str, PromisedQueryPtr query, O
auto chat_id = r_chat_id.move_as_ok();
auto chat_info = get_chat(chat_id);
+ if (chat_info != nullptr && chat_info->type == ChatInfo::Type::Private) {
+ const UserInfo *user_info = get_user_info(chat_info->user_id);
+ if (user_info == nullptr || !user_info->have_access) {
+ chat_info = nullptr;
+ }
+ }
if (chat_info != nullptr) {
return on_success(chat_id, std::move(query));
}
@@ -6058,6 +7085,45 @@ void Client::check_chat_no_fail(td::Slice chat_id_str, PromisedQueryPtr query, O
chat_id, std::move(query), std::move(on_success)));
}
+td::Result Client::get_business_connection_chat_id(td::Slice chat_id_str) {
+ if (chat_id_str.empty()) {
+ return td::Status::Error(400, "Bad Request: chat_id is empty");
+ }
+
+ auto r_chat_id = td::to_integer_safe(chat_id_str);
+ if (r_chat_id.is_error()) {
+ return td::Status::Error(400, "Bad Request: chat_id must be a valid Integer");
+ }
+ return r_chat_id.move_as_ok();
+}
+
+template
+void Client::check_business_connection(const td::string &business_connection_id, PromisedQueryPtr query,
+ OnSuccess on_success) {
+ auto business_connection = get_business_connection(business_connection_id);
+ if (business_connection != nullptr) {
+ return on_success(business_connection, std::move(query));
+ }
+ send_request(
+ make_object(business_connection_id),
+ td::make_unique>(this, std::move(query), std::move(on_success)));
+}
+
+template
+void Client::check_business_connection_chat_id(const td::string &business_connection_id, const td::string &chat_id_str,
+ PromisedQueryPtr query, OnSuccess on_success) {
+ auto r_chat_id = get_business_connection_chat_id(chat_id_str);
+ if (r_chat_id.is_error()) {
+ return fail_query_with_error(std::move(query), 400, r_chat_id.error().message());
+ }
+ auto chat_id = r_chat_id.move_as_ok();
+ check_business_connection(business_connection_id, std::move(query),
+ [this, chat_id, on_success = std::move(on_success)](
+ const BusinessConnection *business_connection, PromisedQueryPtr query) mutable {
+ on_success(business_connection, chat_id, std::move(query));
+ });
+}
+
template
void Client::check_bot_command_scope(BotCommandScope &&scope, PromisedQueryPtr query, OnSuccess on_success) {
CHECK(scope.scope_ != nullptr);
@@ -6194,7 +7260,7 @@ void Client::check_reply_parameters(td::Slice chat_id_str, InputReplyParameters
}
if (message_thread_id <= 0) {
- // if message thread isn't specified, then the message to reply can be only from a different chat
+ // if message thread isn't specified, then the message to be replied can be only from a different chat
if (reply_parameters.reply_in_chat_id == chat_id) {
reply_parameters.reply_in_chat_id = 0;
}
@@ -6224,13 +7290,13 @@ void Client::check_reply_parameters(td::Slice chat_id_str, InputReplyParameters
on_success = std::move(on_reply_message_resolved)](
int64 reply_in_chat_id, PromisedQueryPtr query) mutable {
if (!have_message_access(reply_in_chat_id)) {
- return fail_query_with_error(std::move(query), 400, "MESSAGE_NOT_FOUND", "message to reply not found");
+ return fail_query_with_error(std::move(query), 400, "MESSAGE_NOT_FOUND", "message to be replied not found");
}
send_request(make_object(reply_in_chat_id, reply_to_message_id),
td::make_unique>(
- this, reply_in_chat_id, reply_to_message_id, allow_sending_without_reply, "message to reply",
- std::move(query), std::move(on_success)));
+ this, reply_in_chat_id, reply_to_message_id, allow_sending_without_reply,
+ "message to be replied", std::move(query), std::move(on_success)));
};
if (reply_parameters.reply_in_chat_id.empty()) {
return on_reply_chat_resolved(chat_id, std::move(query));
@@ -6435,39 +7501,6 @@ void Client::on_update_authorization_state() {
CHECK(authorization_state_ != nullptr);
switch (authorization_state_->get_id()) {
case td_api::authorizationStateWaitTdlibParameters::ID: {
- send_request(
- make_object("ignore_inline_thumbnails", make_object(true)),
- td::make_unique());
- send_request(make_object("reuse_uploaded_photos_by_hash",
- make_object(true)),
- td::make_unique());
- send_request(
- make_object("disable_network_statistics", make_object(true)),
- td::make_unique());
- send_request(make_object("disable_time_adjustment_protection",
- make_object(true)),
- td::make_unique());
- send_request(
- make_object("disable_minithumbnails", make_object(true)),
- td::make_unique());
- send_request(
- make_object("disable_document_filenames", make_object(true)),
- td::make_unique());
- send_request(
- make_object("disable_notifications", make_object(true)),
- td::make_unique());
- send_request(make_object("ignore_update_chat_last_message",
- make_object(true)),
- td::make_unique());
- send_request(make_object("ignore_update_chat_read_inbox",
- make_object(true)),
- td::make_unique());
- send_request(make_object("ignore_update_user_chat_action",
- make_object(true)),
- td::make_unique());
- send_request(make_object("ignore_server_deletes_and_reads",
- make_object(true)),
- td::make_unique());
send_request(make_object("delete_chat_reference_after_seconds",
make_object(3600)),
td::make_unique());
@@ -6479,6 +7512,15 @@ void Client::on_update_authorization_state() {
parameters_->file_expiration_timeout_seconds_)),
td::make_unique());
+ for (td::string option : {"disable_network_statistics", "disable_time_adjustment_protection", "ignore_file_names",
+ "disable_minithumbnails", "disable_document_filenames", "disable_notifications",
+ "ignore_update_chat_last_message", "ignore_update_chat_read_inbox",
+ "ignore_update_user_chat_action", "ignore_server_deletes_and_reads",
+ "ignore_inline_thumbnails", "reuse_uploaded_photos_by_hash", "use_storage_optimizer"}) {
+ send_request(make_object(option, make_object(true)),
+ td::make_unique());
+ }
+
auto request = make_object();
request->use_test_dc_ = is_test_dc_;
request->database_directory_ = dir_;
@@ -6491,8 +7533,6 @@ void Client::on_update_authorization_state() {
request->system_language_code_ = "en";
request->device_model_ = "server";
request->application_version_ = parameters_->version_;
- request->enable_storage_optimizer_ = true;
- request->ignore_file_names_ = true;
return send_request(std::move(request), td::make_unique(this));
}
@@ -6697,9 +7737,7 @@ void Client::on_update(object_ptr result) {
chat->emoji_status_ != nullptr ? chat->emoji_status_->custom_emoji_id_ : 0;
chat_info->emoji_status_expiration_date =
chat->emoji_status_ != nullptr ? chat->emoji_status_->expiration_date_ : 0;
- if (chat->available_reactions_->get_id() == td_api::chatAvailableReactionsSome::ID) {
- chat_info->available_reactions = move_object_as(chat->available_reactions_);
- }
+ set_chat_available_reactions(chat_info, std::move(chat->available_reactions_));
chat_info->accent_color_id = chat->accent_color_id_;
chat_info->background_custom_emoji_id = chat->background_custom_emoji_id_;
chat_info->profile_accent_color_id = chat->profile_accent_color_id_;
@@ -6749,12 +7787,7 @@ void Client::on_update(object_ptr result) {
auto update = move_object_as(result);
auto chat_info = add_chat(update->chat_id_);
CHECK(chat_info->type != ChatInfo::Type::Unknown);
- if (update->available_reactions_->get_id() == td_api::chatAvailableReactionsSome::ID) {
- chat_info->available_reactions =
- move_object_as(update->available_reactions_);
- } else {
- chat_info->available_reactions = nullptr;
- }
+ set_chat_available_reactions(chat_info, std::move(update->available_reactions_));
break;
}
case td_api::updateChatAccentColors::ID: {
@@ -6788,6 +7821,9 @@ void Client::on_update(object_ptr result) {
user_info->photo =
full_info->photo_ == nullptr ? std::move(full_info->public_photo_) : std::move(full_info->photo_);
user_info->bio = full_info->bio_ != nullptr ? std::move(full_info->bio_->text_) : td::string();
+ user_info->birthdate = std::move(full_info->birthdate_);
+ user_info->business_info = std::move(full_info->business_info_);
+ 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_;
break;
@@ -6811,7 +7847,8 @@ void Client::on_update(object_ptr result) {
auto group_info = add_group_info(group_id);
group_info->photo = std::move(full_info->photo_);
group_info->description = std::move(full_info->description_);
- group_info->invite_link = full_info->invite_link_ != nullptr ? std::move(full_info->invite_link_->invite_link_) : td::string();
+ group_info->invite_link =
+ full_info->invite_link_ != nullptr ? std::move(full_info->invite_link_->invite_link_) : td::string();
break;
}
case td_api::updateSupergroup::ID: {
@@ -6827,15 +7864,19 @@ void Client::on_update(object_ptr result) {
auto supergroup_info = add_supergroup_info(supergroup_id);
supergroup_info->photo = std::move(full_info->photo_);
supergroup_info->description = std::move(full_info->description_);
- supergroup_info->invite_link = full_info->invite_link_ != nullptr ? std::move(full_info->invite_link_->invite_link_) : td::string();
+ supergroup_info->invite_link =
+ full_info->invite_link_ != nullptr ? std::move(full_info->invite_link_->invite_link_) : td::string();
supergroup_info->sticker_set_id = full_info->sticker_set_id_;
+ supergroup_info->custom_emoji_sticker_set_id = full_info->custom_emoji_sticker_set_id_;
supergroup_info->can_set_sticker_set = full_info->can_set_sticker_set_;
supergroup_info->is_all_history_available = full_info->is_all_history_available_;
supergroup_info->slow_mode_delay = full_info->slow_mode_delay_;
+ supergroup_info->unrestrict_boost_count = full_info->unrestrict_boost_count_;
supergroup_info->linked_chat_id = full_info->linked_chat_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_;
+ supergroup_info->has_paid_media_allowed = full_info->has_paid_media_allowed_;
break;
}
case td_api::updateOption::ID: {
@@ -6909,6 +7950,9 @@ void Client::on_update(object_ptr result) {
case td_api::updateNewCallbackQuery::ID:
add_new_callback_query(move_object_as(result));
break;
+ case td_api::updateNewBusinessCallbackQuery::ID:
+ add_new_business_callback_query(move_object_as(result));
+ break;
case td_api::updateNewInlineCallbackQuery::ID:
add_new_inline_callback_query(move_object_as(result));
break;
@@ -6918,6 +7962,9 @@ void Client::on_update(object_ptr result) {
case td_api::updateNewPreCheckoutQuery::ID:
add_new_pre_checkout_query(move_object_as(result));
break;
+ case td_api::updatePaidMediaPurchased::ID:
+ add_update_purchased_paid_media(move_object_as(result));
+ break;
case td_api::updateNewCustomEvent::ID:
add_new_custom_event(move_object_as(result));
break;
@@ -6939,6 +7986,18 @@ void Client::on_update(object_ptr result) {
case td_api::updateMessageReactions::ID:
add_update_message_reaction_count(move_object_as(result));
break;
+ case td_api::updateBusinessConnection::ID:
+ add_update_business_connection(move_object_as(result));
+ break;
+ case td_api::updateNewBusinessMessage::ID:
+ add_new_business_message(move_object_as(result));
+ break;
+ case td_api::updateBusinessMessageEdited::ID:
+ add_business_message_edited(move_object_as(result));
+ break;
+ case td_api::updateBusinessMessagesDeleted::ID:
+ add_update_business_messages_deleted(move_object_as(result));
+ break;
case td_api::updateConnectionState::ID: {
auto update = move_object_as(result);
if (update->state_->get_id() == td_api::connectionStateReady::ID) {
@@ -7058,9 +8117,9 @@ void Client::finish_closing() {
auto timeout = [&] {
if (next_authorization_time_ <= 0.0) {
- return 600.0;
+ return was_authorized_ && authorization_date_ < get_unix_time() - 1800 ? 1.0 : 1800.0;
}
- return td::min(next_authorization_time_ - td::Time::now(), 600.0);
+ return td::min(next_authorization_time_ - td::Time::now(), 1800.0);
}();
set_timeout_in(timeout);
LOG(INFO) << "Keep client opened for " << timeout << " seconds";
@@ -7087,8 +8146,21 @@ bool Client::to_bool(td::MutableSlice value) {
td_api::object_ptr Client::get_input_message_reply_to(
CheckedReplyParameters &&reply_parameters) {
if (reply_parameters.reply_to_message_id > 0) {
- return make_object(
- reply_parameters.reply_in_chat_id, reply_parameters.reply_to_message_id, std::move(reply_parameters.quote));
+ if (reply_parameters.reply_in_chat_id != 0) {
+ return make_object(
+ reply_parameters.reply_in_chat_id, reply_parameters.reply_to_message_id, std::move(reply_parameters.quote));
+ }
+ return make_object(reply_parameters.reply_to_message_id,
+ std::move(reply_parameters.quote));
+ }
+ return nullptr;
+}
+
+td_api::object_ptr Client::get_input_message_reply_to(
+ InputReplyParameters &&reply_parameters) {
+ if (reply_parameters.reply_in_chat_id.empty() && reply_parameters.reply_to_message_id > 0) {
+ return make_object(reply_parameters.reply_to_message_id,
+ std::move(reply_parameters.quote));
}
return nullptr;
}
@@ -7121,6 +8193,9 @@ td::Result Client::get_reply_parameters(td::JsonVa
return td::Status::Error(400, "Object expected as reply parameters");
}
auto &object = value.get_object();
+ if (object.field_count() == 0) {
+ 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(allow_sending_without_reply, object.get_optional_bool_field("allow_sending_without_reply"));
@@ -7193,9 +8268,13 @@ td::Result> Client::get_keyboard_butt
auto restrict_user_is_premium = request_user_object.has_field("user_is_premium");
TRY_RESULT(user_is_premium, request_user_object.get_optional_bool_field("user_is_premium"));
TRY_RESULT(max_quantity, request_user_object.get_optional_int_field("max_quantity", 1));
+ TRY_RESULT(request_name, request_user_object.get_optional_bool_field("request_name"));
+ TRY_RESULT(request_username, request_user_object.get_optional_bool_field("request_username"));
+ TRY_RESULT(request_photo, request_user_object.get_optional_bool_field("request_photo"));
return make_object(
text, make_object(
- id, restrict_user_is_bot, user_is_bot, restrict_user_is_premium, user_is_premium, max_quantity));
+ id, restrict_user_is_bot, user_is_bot, restrict_user_is_premium, user_is_premium, max_quantity,
+ request_name, request_username, request_photo));
}
if (object.has_field("request_chat")) {
@@ -7220,11 +8299,15 @@ td::Result> Client::get_keyboard_butt
get_chat_administrator_rights(request_chat_object.extract_field("bot_administrator_rights")));
}
TRY_RESULT(bot_is_member, request_chat_object.get_optional_bool_field("bot_is_member"));
+ TRY_RESULT(request_title, request_chat_object.get_optional_bool_field("request_title"));
+ TRY_RESULT(request_username, request_chat_object.get_optional_bool_field("request_username"));
+ TRY_RESULT(request_photo, request_chat_object.get_optional_bool_field("request_photo"));
return make_object(
- text, make_object(
- id, chat_is_channel, restrict_chat_is_forum, chat_is_forum, restrict_chat_has_username,
- chat_has_username, chat_is_created, std::move(user_administrator_rights),
- std::move(bot_administrator_rights), bot_is_member));
+ text,
+ make_object(
+ id, chat_is_channel, restrict_chat_is_forum, chat_is_forum, restrict_chat_has_username, chat_has_username,
+ chat_is_created, std::move(user_administrator_rights), std::move(bot_administrator_rights), bot_is_member,
+ request_title, request_username, request_photo));
}
return make_object(text, nullptr);
@@ -7744,7 +8827,7 @@ td::Result> Client::get_input_me
if (!td::check_utf8(payload)) {
return td::Status::Error(400, "InputInvoiceMessageContent payload must be encoded in UTF-8");
}
- TRY_RESULT(provider_token, object.get_required_string_field("provider_token"));
+ 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));
@@ -7774,7 +8857,7 @@ td::Result> Client::get_input_me
need_email_address, need_shipping_address, send_phone_number_to_provider,
send_email_address_to_provider, is_flexible),
title, description, photo_url, photo_size, photo_width, photo_height, payload, provider_token, provider_data,
- td::string(), nullptr);
+ td::string(), nullptr, nullptr);
}
if (is_input_message_content_required) {
@@ -7784,9 +8867,9 @@ td::Result> Client::get_input_me
}
td_api::object_ptr Client::get_message_send_options(bool disable_notification,
- bool protect_content,
+ bool protect_content, int64 effect_id,
td_api::object_ptr &&scheduling_state) {
- return make_object(disable_notification, false, protect_content, false, std::move(scheduling_state), 0, false);
+ return make_object(disable_notification, false, protect_content, false, std::move(scheduling_state), effect_id, 0, false);
}
td::Result> Client::get_inline_query_results_button(
@@ -7938,6 +9021,7 @@ td::Result> Client::get_inlin
TRY_RESULT(parse_mode, object.get_optional_string_field("parse_mode"));
auto entities = object.extract_field("caption_entities");
TRY_RESULT(caption, get_formatted_text(std::move(input_caption), std::move(parse_mode), std::move(entities)));
+ TRY_RESULT(show_caption_above_media, object.get_optional_bool_field("show_caption_above_media"));
TRY_RESULT(reply_markup_object, object.extract_optional_field("reply_markup", td::JsonValue::Type::Object));
object_ptr reply_markup;
@@ -8038,8 +9122,9 @@ td::Result> Client::get_inlin
}
if (input_message_content == nullptr) {
- input_message_content = make_object(
- nullptr, nullptr, td::vector(), gif_duration, gif_width, gif_height, std::move(caption), false);
+ input_message_content =
+ make_object(nullptr, nullptr, td::vector(), gif_duration, gif_width,
+ gif_height, std::move(caption), show_caption_above_media, false);
}
return make_object(
id, title, thumbnail_url, thumbnail_mime_type, gif_url, "image/gif", gif_duration, gif_width, gif_height,
@@ -8079,8 +9164,9 @@ td::Result> Client::get_inlin
}
if (input_message_content == nullptr) {
- input_message_content = make_object(
- nullptr, nullptr, td::vector(), mpeg4_duration, mpeg4_width, mpeg4_height, std::move(caption), false);
+ input_message_content =
+ make_object