From 5951bfbab8b1274437c613c1c48d91be2a050371 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 14 May 2024 17:28:42 +0300 Subject: [PATCH 01/37] Port build instructions generator changes. --- build.html | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/build.html b/build.html index 38bf606..e1d7c7a 100644 --- a/build.html +++ b/build.html @@ -208,6 +208,7 @@ +

@@ -260,7 +261,7 @@
- +

@@ -446,7 +447,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 +497,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,7 +528,7 @@ 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': @@ -538,6 +552,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 +568,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 +602,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'); From 14ea0576cd1c04c20f1b5f575eea56d9ddc96651 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 20 May 2024 14:13:18 +0300 Subject: [PATCH 02/37] Update TDLib to 1.8.30. --- td | 2 +- telegram-bot-api/Client.cpp | 44 +++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/td b/td index af69dd4..fab354a 160000 --- a/td +++ b/td @@ -1 +1 @@ -Subproject commit af69dd4397b6dc1bf23ba0fd0bf429fcba6454f6 +Subproject commit fab354add5a257a8121a4a7f1ff6b1b9fa9a9073 diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 33c3943..fe04e63 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -542,7 +542,8 @@ class Client::JsonVectorEntities final : public td::Jsonable { auto array = scope->enter_array(); for (auto &entity : entities_) { auto entity_type = entity->type_->get_id(); - if (entity_type != td_api::textEntityTypeBankCardNumber::ID && + if (entity_type != td_api::textEntityTypeExpandableBlockQuote::ID && + entity_type != td_api::textEntityTypeBankCardNumber::ID && entity_type != td_api::textEntityTypeMediaTimestamp::ID) { array << JsonEntity(entity.get(), client_); } @@ -1614,12 +1615,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 @@ -7717,7 +7718,7 @@ td::Result> Client::get_input_me td_api::object_ptr Client::get_message_send_options(bool disable_notification, bool protect_content) { - return make_object(disable_notification, false, protect_content, false, nullptr, 0, + return make_object(disable_notification, false, protect_content, false, nullptr, 0, 0, false); } @@ -7971,7 +7972,7 @@ 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); + nullptr, nullptr, td::vector(), gif_duration, gif_width, gif_height, std::move(caption), false, false); } return make_object( id, title, thumbnail_url, thumbnail_mime_type, gif_url, "image/gif", gif_duration, gif_width, gif_height, @@ -8011,8 +8012,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(nullptr, nullptr, td::vector(), mpeg4_duration, mpeg4_width, + mpeg4_height, std::move(caption), false, false); } return make_object( id, title, thumbnail_url, thumbnail_mime_type, mpeg4_url, "video/mp4", mpeg4_duration, mpeg4_width, @@ -8030,7 +8032,7 @@ td::Result> Client::get_inlin if (input_message_content == nullptr) { input_message_content = make_object(nullptr, nullptr, td::vector(), 0, 0, - std::move(caption), nullptr, false); + std::move(caption), false, nullptr, false); } return make_object(id, title, description, thumbnail_url, photo_url, photo_width, photo_height, std::move(reply_markup), @@ -8097,7 +8099,7 @@ td::Result> Client::get_inlin if (input_message_content == nullptr) { input_message_content = make_object(nullptr, nullptr, td::vector(), video_duration, video_width, - video_height, false, std::move(caption), nullptr, false); + video_height, false, std::move(caption), false, nullptr, false); } return make_object(id, title, description, thumbnail_url, video_url, mime_type, video_width, video_height, video_duration, @@ -9087,7 +9089,7 @@ td::Result> Client::get_input_me TRY_RESULT(type, object.get_required_string_field("type")); if (type == "photo") { return make_object(std::move(input_file), nullptr, td::vector(), 0, 0, - std::move(caption), nullptr, has_spoiler); + std::move(caption), false, nullptr, has_spoiler); } if (type == "video") { TRY_RESULT(width, object.get_optional_int_field("width")); @@ -9100,7 +9102,7 @@ td::Result> Client::get_input_me return make_object(std::move(input_file), std::move(input_thumbnail), td::vector(), duration, width, height, supports_streaming, - std::move(caption), nullptr, has_spoiler); + std::move(caption), false, nullptr, has_spoiler); } if (for_album && type == "animation") { return td::Status::Error(PSLICE() << "type \"" << type << "\" can't be used in sendMediaGroup"); @@ -9114,7 +9116,7 @@ td::Result> Client::get_input_me duration = td::clamp(duration, 0, MAX_DURATION); return make_object(std::move(input_file), std::move(input_thumbnail), td::vector(), duration, width, height, std::move(caption), - has_spoiler); + false, has_spoiler); } if (type == "audio") { TRY_RESULT(duration, object.get_optional_int_field("duration")); @@ -9767,7 +9769,7 @@ td::Status Client::process_send_animation_query(PromisedQueryPtr &query) { auto has_spoiler = to_bool(query->arg("has_spoiler")); do_send_message( make_object(std::move(animation), std::move(thumbnail), td::vector(), - duration, width, height, std::move(caption), has_spoiler), + duration, width, height, std::move(caption), false, has_spoiler), std::move(query)); return td::Status::OK(); } @@ -9816,7 +9818,7 @@ td::Status Client::process_send_photo_query(PromisedQueryPtr &query) { TRY_RESULT(caption, get_caption(query.get())); auto has_spoiler = to_bool(query->arg("has_spoiler")); do_send_message(make_object(std::move(photo), nullptr, td::vector(), 0, 0, - std::move(caption), nullptr, has_spoiler), + std::move(caption), false, nullptr, has_spoiler), std::move(query)); return td::Status::OK(); } @@ -9846,7 +9848,7 @@ td::Status Client::process_send_video_query(PromisedQueryPtr &query) { auto has_spoiler = to_bool(query->arg("has_spoiler")); do_send_message(make_object(std::move(video), std::move(thumbnail), td::vector(), duration, width, height, supports_streaming, - std::move(caption), nullptr, has_spoiler), + std::move(caption), false, nullptr, has_spoiler), std::move(query)); return td::Status::OK(); } @@ -10003,7 +10005,7 @@ td::Status Client::process_copy_message_query(PromisedQueryPtr &query) { if (replace_caption) { TRY_RESULT_ASSIGN(caption, get_caption(query.get())); } - auto options = make_object(true, replace_caption, std::move(caption)); + auto options = make_object(true, replace_caption, std::move(caption), false); check_message( from_chat_id, message_id, false, AccessRights::Read, "message to copy", std::move(query), @@ -10143,7 +10145,7 @@ td::Status Client::process_send_media_group_query(PromisedQueryPtr &query) { send_request( make_object( business_connection->id_, chat_id, get_input_message_reply_to(std::move(reply_parameters)), - disable_notification, protect_content, std::move(input_message_contents)), + disable_notification, protect_content, 0, std::move(input_message_contents)), td::make_unique(this, business_connection->id_, std::move(query))); }); @@ -10341,7 +10343,7 @@ td::Status Client::process_edit_message_caption_query(PromisedQueryPtr &query) { [this, inline_message_id = inline_message_id.str(), caption = std::move(caption)]( object_ptr reply_markup, PromisedQueryPtr query) mutable { send_request(make_object(inline_message_id, std::move(reply_markup), - std::move(caption)), + std::move(caption), false), td::make_unique(std::move(query))); }); } else { @@ -10353,7 +10355,7 @@ td::Status Client::process_edit_message_caption_query(PromisedQueryPtr &query) { [this, reply_markup = std::move(reply_markup), caption = std::move(caption)]( int64 chat_id, int64 message_id, PromisedQueryPtr query) mutable { send_request(make_object( - chat_id, message_id, std::move(reply_markup), std::move(caption)), + chat_id, message_id, std::move(reply_markup), std::move(caption), false), td::make_unique(this, std::move(query))); }); }); @@ -11989,7 +11991,7 @@ void Client::do_send_message(object_ptr input_messa send_request( make_object(business_connection->id_, chat_id, get_input_message_reply_to(std::move(reply_parameters)), - disable_notification, protect_content, + disable_notification, protect_content, 0, std::move(reply_markup), std::move(input_message_content)), td::make_unique(this, business_connection->id_, std::move(query))); }); From 278e1e254afee3fe9e44531d4795d2b2f5fe4fe1 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 20 May 2024 14:20:55 +0300 Subject: [PATCH 03/37] Add Message.effect_id. --- telegram-bot-api/Client.cpp | 4 ++++ telegram-bot-api/Client.h | 1 + 2 files changed, 5 insertions(+) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index fe04e63..5606809 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -3186,6 +3186,9 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const { 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 { @@ -13676,6 +13679,7 @@ void Client::init_message(MessageInfo *message_info, object_ptr message_info->is_topic_message = message->is_topic_message_; message_info->author_signature = std::move(message->author_signature_); message_info->sender_boost_count = message->sender_boost_count_; + message_info->effect_id = message->effect_id_; drop_internal_reply_to_message_in_another_chat(message); diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index 679e077..f37d537 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -921,6 +921,7 @@ class Client final : public WebhookActor::Callback { object_ptr reply_markup; td::string business_connection_id; int64 sender_business_bot_user_id = 0; + int64 effect_id = 0; bool can_be_saved = false; bool is_automatic_forward = false; From 7eee0eed846e5fda0072c916481328bf0f95a404 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 20 May 2024 14:27:04 +0300 Subject: [PATCH 04/37] Add message.show_caption_above_media. --- telegram-bot-api/Client.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 5606809..025f847 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -901,7 +901,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_); @@ -909,6 +910,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()); + } } } @@ -2814,27 +2819,27 @@ 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::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; } @@ -2846,7 +2851,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; } @@ -2858,7 +2863,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: { From 7d7b4049a4de53dba66a24615ecd8921895e6ea1 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 20 May 2024 14:41:19 +0300 Subject: [PATCH 05/37] Allow adding effects to sent messages. --- telegram-bot-api/Client.cpp | 52 ++++++++++++++++++++----------------- telegram-bot-api/Client.h | 2 +- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 025f847..20b98b1 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -7725,9 +7725,9 @@ td::Result> Client::get_input_me } td_api::object_ptr Client::get_message_send_options(bool disable_notification, - bool protect_content) { - return make_object(disable_notification, false, protect_content, false, nullptr, 0, 0, - false); + bool protect_content, int64 effect_id) { + return make_object(disable_notification, false, protect_content, false, nullptr, + effect_id, 0, false); } td::Result> Client::get_inline_query_results_button( @@ -10059,7 +10059,7 @@ td::Status Client::process_copy_messages_query(PromisedQueryPtr &query) { send_request(make_object( chat_id, message_thread_id, from_chat_id, std::move(message_ids), - get_message_send_options(disable_notification, protect_content), true, remove_caption), + get_message_send_options(disable_notification, protect_content, 0), true, remove_caption), td::make_unique(this, chat_id, message_count, std::move(query))); }); }; @@ -10113,7 +10113,7 @@ td::Status Client::process_forward_messages_query(PromisedQueryPtr &query) { send_request(make_object( chat_id, message_thread_id, from_chat_id, std::move(message_ids), - get_message_send_options(disable_notification, protect_content), false, false), + get_message_send_options(disable_notification, protect_content, 0), false, false), td::make_unique(this, chat_id, message_count, std::move(query))); }); }; @@ -10129,6 +10129,7 @@ td::Status Client::process_send_media_group_query(PromisedQueryPtr &query) { auto business_connection_id = query->arg("business_connection_id"); auto disable_notification = to_bool(query->arg("disable_notification")); auto protect_content = to_bool(query->arg("protect_content")); + auto effect_id = td::to_integer(query->arg("message_effect_id")); // TRY_RESULT(reply_markup, get_reply_markup(query.get(), bot_user_ids_)); auto reply_markup = nullptr; TRY_RESULT(input_message_contents, get_input_message_contents(query.get(), "media")); @@ -10136,7 +10137,7 @@ td::Status Client::process_send_media_group_query(PromisedQueryPtr &query) { resolve_reply_markup_bot_usernames( std::move(reply_markup), std::move(query), [this, chat_id_str = chat_id.str(), message_thread_id, business_connection_id = business_connection_id.str(), - reply_parameters = std::move(reply_parameters), disable_notification, protect_content, + reply_parameters = std::move(reply_parameters), disable_notification, protect_content, effect_id, input_message_contents = std::move(input_message_contents)](object_ptr reply_markup, PromisedQueryPtr query) mutable { if (!business_connection_id.empty()) { @@ -10148,18 +10149,19 @@ td::Status Client::process_send_media_group_query(PromisedQueryPtr &query) { return check_business_connection( business_connection_id, std::move(query), [this, chat_id, reply_parameters = std::move(reply_parameters), disable_notification, protect_content, - input_message_contents = std::move(input_message_contents), reply_markup = std::move(reply_markup)]( - const BusinessConnection *business_connection, PromisedQueryPtr query) mutable { + effect_id, input_message_contents = std::move(input_message_contents), + reply_markup = std::move(reply_markup)](const BusinessConnection *business_connection, + PromisedQueryPtr query) mutable { send_request( make_object( business_connection->id_, chat_id, get_input_message_reply_to(std::move(reply_parameters)), - disable_notification, protect_content, 0, std::move(input_message_contents)), + disable_notification, protect_content, effect_id, std::move(input_message_contents)), td::make_unique(this, business_connection->id_, std::move(query))); }); } - auto on_success = [this, disable_notification, protect_content, + auto on_success = [this, disable_notification, protect_content, effect_id, input_message_contents = std::move(input_message_contents), reply_markup = std::move(reply_markup)](int64 chat_id, int64 message_thread_id, CheckedReplyParameters reply_parameters, @@ -10171,11 +10173,11 @@ td::Status Client::process_send_media_group_query(PromisedQueryPtr &query) { auto message_count = input_message_contents.size(); count += static_cast(message_count); - send_request( - make_object( - chat_id, message_thread_id, get_input_message_reply_to(std::move(reply_parameters)), - get_message_send_options(disable_notification, protect_content), std::move(input_message_contents)), - td::make_unique(this, chat_id, message_count, std::move(query))); + send_request(make_object( + chat_id, message_thread_id, get_input_message_reply_to(std::move(reply_parameters)), + get_message_send_options(disable_notification, protect_content, effect_id), + std::move(input_message_contents)), + td::make_unique(this, chat_id, message_count, std::move(query))); }; check_reply_parameters(chat_id_str, std::move(reply_parameters), message_thread_id, std::move(query), std::move(on_success)); @@ -11973,6 +11975,7 @@ void Client::do_send_message(object_ptr input_messa auto reply_parameters = r_reply_parameters.move_as_ok(); auto disable_notification = to_bool(query->arg("disable_notification")); auto protect_content = to_bool(query->arg("protect_content")); + auto effect_id = td::to_integer(query->arg("message_effect_id")); auto r_reply_markup = get_reply_markup(query.get(), bot_user_ids_); if (r_reply_markup.is_error()) { return fail_query_with_error(std::move(query), 400, r_reply_markup.error().message()); @@ -11982,7 +11985,7 @@ void Client::do_send_message(object_ptr input_messa resolve_reply_markup_bot_usernames( std::move(reply_markup), std::move(query), [this, chat_id_str = chat_id.str(), message_thread_id, business_connection_id = business_connection_id.str(), - reply_parameters = std::move(reply_parameters), disable_notification, protect_content, + reply_parameters = std::move(reply_parameters), disable_notification, protect_content, effect_id, input_message_content = std::move(input_message_content)](object_ptr reply_markup, PromisedQueryPtr query) mutable { if (!business_connection_id.empty()) { @@ -11994,18 +11997,19 @@ void Client::do_send_message(object_ptr input_messa return check_business_connection( business_connection_id, std::move(query), [this, chat_id, reply_parameters = std::move(reply_parameters), disable_notification, protect_content, - reply_markup = std::move(reply_markup), input_message_content = std::move(input_message_content)]( - const BusinessConnection *business_connection, PromisedQueryPtr query) mutable { + effect_id, reply_markup = std::move(reply_markup), + input_message_content = std::move(input_message_content)](const BusinessConnection *business_connection, + PromisedQueryPtr query) mutable { send_request( make_object(business_connection->id_, chat_id, get_input_message_reply_to(std::move(reply_parameters)), - disable_notification, protect_content, 0, + disable_notification, protect_content, effect_id, std::move(reply_markup), std::move(input_message_content)), td::make_unique(this, business_connection->id_, std::move(query))); }); } - auto on_success = [this, disable_notification, protect_content, + auto on_success = [this, disable_notification, protect_content, effect_id, input_message_content = std::move(input_message_content), reply_markup = std::move(reply_markup)](int64 chat_id, int64 message_thread_id, CheckedReplyParameters reply_parameters, @@ -12016,10 +12020,10 @@ void Client::do_send_message(object_ptr input_messa } count++; - send_request(make_object(chat_id, message_thread_id, - get_input_message_reply_to(std::move(reply_parameters)), - get_message_send_options(disable_notification, protect_content), - std::move(reply_markup), std::move(input_message_content)), + send_request(make_object( + chat_id, message_thread_id, get_input_message_reply_to(std::move(reply_parameters)), + get_message_send_options(disable_notification, protect_content, effect_id), + std::move(reply_markup), std::move(input_message_content)), td::make_unique(this, chat_id, std::move(query))); }; check_reply_parameters(chat_id_str, std::move(reply_parameters), message_thread_id, std::move(query), diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index f37d537..7bcffe9 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -561,7 +561,7 @@ class Client final : public WebhookActor::Callback { td::Result> get_input_message_invoice(const Query *query) const; static object_ptr get_message_send_options(bool disable_notification, - bool protect_content); + bool protect_content, int64 effect_id); static td::Result>> get_poll_options(const Query *query); From 5f3e2202b7777711d9277a861d902306f0ed77cc Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 20 May 2024 14:48:41 +0300 Subject: [PATCH 06/37] Allow to send messages with caption above media. --- telegram-bot-api/Client.cpp | 49 +++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 20b98b1..8963645 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -7879,6 +7879,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; @@ -7979,8 +7980,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, 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, @@ -8022,7 +8024,7 @@ 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, false); + mpeg4_height, std::move(caption), show_caption_above_media, false); } return make_object( id, title, thumbnail_url, thumbnail_mime_type, mpeg4_url, "video/mp4", mpeg4_duration, mpeg4_width, @@ -8039,8 +8041,8 @@ td::Result> Client::get_inlin } if (input_message_content == nullptr) { - input_message_content = make_object(nullptr, nullptr, td::vector(), 0, 0, - std::move(caption), false, nullptr, false); + input_message_content = make_object( + nullptr, nullptr, td::vector(), 0, 0, std::move(caption), show_caption_above_media, nullptr, false); } return make_object(id, title, description, thumbnail_url, photo_url, photo_width, photo_height, std::move(reply_markup), @@ -8105,9 +8107,9 @@ td::Result> Client::get_inlin } if (input_message_content == nullptr) { - input_message_content = - make_object(nullptr, nullptr, td::vector(), video_duration, video_width, - video_height, false, std::move(caption), false, nullptr, false); + input_message_content = make_object( + nullptr, nullptr, td::vector(), video_duration, video_width, video_height, false, std::move(caption), + show_caption_above_media, nullptr, false); } return make_object(id, title, description, thumbnail_url, video_url, mime_type, video_width, video_height, video_duration, @@ -9070,6 +9072,7 @@ td::Result> Client::get_input_me 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(has_spoiler, object.get_optional_bool_field("has_spoiler")); TRY_RESULT(media, object.get_optional_string_field("media")); @@ -9097,7 +9100,7 @@ td::Result> Client::get_input_me TRY_RESULT(type, object.get_required_string_field("type")); if (type == "photo") { return make_object(std::move(input_file), nullptr, td::vector(), 0, 0, - std::move(caption), false, nullptr, has_spoiler); + std::move(caption), show_caption_above_media, nullptr, has_spoiler); } if (type == "video") { TRY_RESULT(width, object.get_optional_int_field("width")); @@ -9110,7 +9113,7 @@ td::Result> Client::get_input_me return make_object(std::move(input_file), std::move(input_thumbnail), td::vector(), duration, width, height, supports_streaming, - std::move(caption), false, nullptr, has_spoiler); + std::move(caption), show_caption_above_media, nullptr, has_spoiler); } if (for_album && type == "animation") { return td::Status::Error(PSLICE() << "type \"" << type << "\" can't be used in sendMediaGroup"); @@ -9124,7 +9127,7 @@ td::Result> Client::get_input_me duration = td::clamp(duration, 0, MAX_DURATION); return make_object(std::move(input_file), std::move(input_thumbnail), td::vector(), duration, width, height, std::move(caption), - false, has_spoiler); + show_caption_above_media, has_spoiler); } if (type == "audio") { TRY_RESULT(duration, object.get_optional_int_field("duration")); @@ -9774,11 +9777,12 @@ td::Status Client::process_send_animation_query(PromisedQueryPtr &query) { int32 width = get_integer_arg(query.get(), "width", 0, 0, MAX_LENGTH); int32 height = get_integer_arg(query.get(), "height", 0, 0, MAX_LENGTH); TRY_RESULT(caption, get_caption(query.get())); + auto show_caption_above_media = to_bool(query->arg("show_caption_above_media")); auto has_spoiler = to_bool(query->arg("has_spoiler")); - do_send_message( - make_object(std::move(animation), std::move(thumbnail), td::vector(), - duration, width, height, std::move(caption), false, has_spoiler), - std::move(query)); + do_send_message(make_object(std::move(animation), std::move(thumbnail), + td::vector(), duration, width, height, + std::move(caption), show_caption_above_media, has_spoiler), + std::move(query)); return td::Status::OK(); } @@ -9824,10 +9828,12 @@ td::Status Client::process_send_photo_query(PromisedQueryPtr &query) { return td::Status::Error(400, "There is no photo in the request"); } TRY_RESULT(caption, get_caption(query.get())); + auto show_caption_above_media = to_bool(query->arg("show_caption_above_media")); auto has_spoiler = to_bool(query->arg("has_spoiler")); - do_send_message(make_object(std::move(photo), nullptr, td::vector(), 0, 0, - std::move(caption), false, nullptr, has_spoiler), - std::move(query)); + do_send_message( + make_object(std::move(photo), nullptr, td::vector(), 0, 0, std::move(caption), + show_caption_above_media, nullptr, has_spoiler), + std::move(query)); return td::Status::OK(); } @@ -9853,10 +9859,11 @@ td::Status Client::process_send_video_query(PromisedQueryPtr &query) { int32 height = get_integer_arg(query.get(), "height", 0, 0, MAX_LENGTH); bool supports_streaming = to_bool(query->arg("supports_streaming")); TRY_RESULT(caption, get_caption(query.get())); + auto show_caption_above_media = to_bool(query->arg("show_caption_above_media")); auto has_spoiler = to_bool(query->arg("has_spoiler")); - do_send_message(make_object(std::move(video), std::move(thumbnail), td::vector(), - duration, width, height, supports_streaming, - std::move(caption), false, nullptr, has_spoiler), + do_send_message(make_object( + std::move(video), std::move(thumbnail), td::vector(), duration, width, height, + supports_streaming, std::move(caption), show_caption_above_media, nullptr, has_spoiler), std::move(query)); return td::Status::OK(); } From f32756cd0d1b4c50ed124199f339d7eb7c776f42 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 20 May 2024 14:54:17 +0300 Subject: [PATCH 07/37] Allow to edit show_caption_above_media. --- telegram-bot-api/Client.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 8963645..721e8a1 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -10352,28 +10352,30 @@ td::Status Client::process_edit_message_caption_query(PromisedQueryPtr &query) { auto message_id = get_message_id(query.get()); TRY_RESULT(reply_markup, get_reply_markup(query.get(), bot_user_ids_)); TRY_RESULT(caption, get_caption(query.get())); + auto show_caption_above_media = to_bool(query->arg("show_caption_above_media")); if (chat_id.empty() && message_id == 0) { TRY_RESULT(inline_message_id, get_inline_message_id(query.get())); resolve_reply_markup_bot_usernames( std::move(reply_markup), std::move(query), - [this, inline_message_id = inline_message_id.str(), caption = std::move(caption)]( + [this, inline_message_id = inline_message_id.str(), caption = std::move(caption), show_caption_above_media]( object_ptr reply_markup, PromisedQueryPtr query) mutable { send_request(make_object(inline_message_id, std::move(reply_markup), - std::move(caption), false), + std::move(caption), show_caption_above_media), td::make_unique(std::move(query))); }); } else { resolve_reply_markup_bot_usernames( std::move(reply_markup), std::move(query), - [this, chat_id = chat_id.str(), message_id, caption = std::move(caption)]( + [this, chat_id = chat_id.str(), message_id, caption = std::move(caption), show_caption_above_media]( object_ptr reply_markup, PromisedQueryPtr query) mutable { check_message(chat_id, message_id, false, AccessRights::Edit, "message to edit", std::move(query), - [this, reply_markup = std::move(reply_markup), caption = std::move(caption)]( - int64 chat_id, int64 message_id, PromisedQueryPtr query) mutable { - send_request(make_object( - chat_id, message_id, std::move(reply_markup), std::move(caption), false), - td::make_unique(this, std::move(query))); + [this, reply_markup = std::move(reply_markup), caption = std::move(caption), + show_caption_above_media](int64 chat_id, int64 message_id, PromisedQueryPtr query) mutable { + send_request( + make_object(chat_id, message_id, std::move(reply_markup), + std::move(caption), show_caption_above_media), + td::make_unique(this, std::move(query))); }); }); } From 34a52855ee17a7f010698a86ee8a4d48dc1139dc Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 20 May 2024 14:54:53 +0300 Subject: [PATCH 08/37] Allow to change show_caption_above_media when replacing caption of a copied message. --- telegram-bot-api/Client.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 721e8a1..a51594b 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -10020,7 +10020,9 @@ td::Status Client::process_copy_message_query(PromisedQueryPtr &query) { if (replace_caption) { TRY_RESULT_ASSIGN(caption, get_caption(query.get())); } - auto options = make_object(true, replace_caption, std::move(caption), false); + auto show_caption_above_media = to_bool(query->arg("show_caption_above_media")); + auto options = + make_object(true, replace_caption, std::move(caption), show_caption_above_media); check_message( from_chat_id, message_id, false, AccessRights::Read, "message to copy", std::move(query), From 70b9d04b5878d79af756782421f7180a204c26fe Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 20 May 2024 15:05:46 +0300 Subject: [PATCH 09/37] Make provider_token optional for invoices in Telegram Stars. --- telegram-bot-api/Client.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index a51594b..81fe4f0 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -7685,7 +7685,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)); @@ -9204,7 +9204,7 @@ td::Result> Client::get_input_me if (!td::check_utf8(payload.str())) { return td::Status::Error(400, "The payload must be encoded in UTF-8"); } - TRY_RESULT(provider_token, get_required_string_arg(query, "provider_token")); + auto provider_token = query->arg("provider_token"); auto provider_data = query->arg("provider_data"); auto start_parameter = query->arg("start_parameter"); TRY_RESULT(currency, get_required_string_arg(query, "currency")); From 325dc5d2934920328f6cf8a3af8c05ed627f7cdd Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 21 May 2024 12:39:13 +0300 Subject: [PATCH 10/37] Support expandable_blockquote entities. --- telegram-bot-api/Client.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 81fe4f0..83a7f16 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -523,6 +523,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(); } @@ -542,8 +545,7 @@ class Client::JsonVectorEntities final : public td::Jsonable { auto array = scope->enter_array(); for (auto &entity : entities_) { auto entity_type = entity->type_->get_id(); - if (entity_type != td_api::textEntityTypeExpandableBlockQuote::ID && - entity_type != td_api::textEntityTypeBankCardNumber::ID && + if (entity_type != td_api::textEntityTypeBankCardNumber::ID && entity_type != td_api::textEntityTypeMediaTimestamp::ID) { array << JsonEntity(entity.get(), client_); } @@ -8792,6 +8794,9 @@ td::Result> Client::get_text_entity_t if (type == "blockquote") { return make_object(); } + if (type == "expandable_blockquote") { + return make_object(); + } if (type == "mention" || type == "hashtag" || type == "cashtag" || type == "bot_command" || type == "url" || type == "email" || type == "phone_number" || type == "bank_card_number") { return nullptr; From 486539c51471997d704e5db7297682beae1b6696 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 24 May 2024 15:44:38 +0300 Subject: [PATCH 11/37] Add refundStarPayment method. --- telegram-bot-api/Client.cpp | 13 +++++++++++++ telegram-bot-api/Client.h | 1 + 2 files changed, 14 insertions(+) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 83a7f16..142dc26 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -246,6 +246,7 @@ 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("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); @@ -10461,6 +10462,18 @@ td::Status Client::process_create_invoice_link_query(PromisedQueryPtr &query) { return td::Status::OK(); } +td::Status Client::process_refund_star_payment_query(PromisedQueryPtr &query) { + TRY_RESULT(user_id, get_user_id(query.get())); + TRY_RESULT(telegram_payment_charge_id, get_required_string_arg(query.get(), "telegram_payment_charge_id")); + check_user_no_fail( + user_id, std::move(query), + [this, telegram_payment_charge_id = telegram_payment_charge_id.str(), user_id](PromisedQueryPtr query) { + send_request(make_object(user_id, telegram_payment_charge_id), + td::make_unique(std::move(query))); + }); + return td::Status::OK(); +} + td::Status Client::process_set_game_score_query(PromisedQueryPtr &query) { auto chat_id = query->arg("chat_id"); auto message_id = get_message_id(query.get()); diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index 7bcffe9..4e0bc74 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -647,6 +647,7 @@ class Client final : public WebhookActor::Callback { td::Status process_delete_message_query(PromisedQueryPtr &query); td::Status process_delete_messages_query(PromisedQueryPtr &query); td::Status process_create_invoice_link_query(PromisedQueryPtr &query); + td::Status process_refund_star_payment_query(PromisedQueryPtr &query); td::Status process_set_game_score_query(PromisedQueryPtr &query); td::Status process_get_game_high_scores_query(PromisedQueryPtr &query); td::Status process_answer_web_app_query_query(PromisedQueryPtr &query); From 831968def2449efd9bbf630d8bd0296fa456db2d Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 28 May 2024 00:11:50 +0300 Subject: [PATCH 12/37] Update version to 7.4. --- CMakeLists.txt | 2 +- telegram-bot-api/telegram-bot-api.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 276606d..b7b9380 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ if (POLICY CMP0065) cmake_policy(SET CMP0065 NEW) endif() -project(TelegramBotApi VERSION 7.3 LANGUAGES CXX) +project(TelegramBotApi VERSION 7.4 LANGUAGES CXX) if (POLICY CMP0069) option(TELEGRAM_BOT_API_ENABLE_LTO "Use \"ON\" to enable Link Time Optimization.") diff --git a/telegram-bot-api/telegram-bot-api.cpp b/telegram-bot-api/telegram-bot-api.cpp index f66a522..0538d9c 100644 --- a/telegram-bot-api/telegram-bot-api.cpp +++ b/telegram-bot-api/telegram-bot-api.cpp @@ -165,7 +165,7 @@ int main(int argc, char *argv[]) { auto start_time = td::Time::now(); auto shared_data = std::make_shared(); auto parameters = std::make_unique(); - parameters->version_ = "7.3"; + parameters->version_ = "7.4"; parameters->shared_data_ = shared_data; parameters->start_time_ = start_time; auto net_query_stats = td::create_net_query_stats(); From a94b95eac5d81c93e44a659dbc5d315b07729317 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 30 May 2024 19:40:54 +0300 Subject: [PATCH 13/37] Update copyright year. --- telegram-bot-api/Client.cpp | 2 +- telegram-bot-api/Client.h | 2 +- telegram-bot-api/ClientManager.cpp | 2 +- telegram-bot-api/ClientManager.h | 2 +- telegram-bot-api/ClientParameters.h | 2 +- telegram-bot-api/HttpConnection.cpp | 2 +- telegram-bot-api/HttpConnection.h | 2 +- telegram-bot-api/HttpServer.h | 2 +- telegram-bot-api/HttpStatConnection.cpp | 2 +- telegram-bot-api/HttpStatConnection.h | 2 +- telegram-bot-api/Query.cpp | 2 +- telegram-bot-api/Query.h | 2 +- telegram-bot-api/Stats.cpp | 2 +- telegram-bot-api/Stats.h | 2 +- telegram-bot-api/Watchdog.cpp | 2 +- telegram-bot-api/Watchdog.h | 2 +- telegram-bot-api/WebhookActor.cpp | 2 +- telegram-bot-api/WebhookActor.h | 2 +- telegram-bot-api/telegram-bot-api.cpp | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 142dc26..bd5874e 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) diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index 4e0bc74..58b234e 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -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) diff --git a/telegram-bot-api/ClientManager.cpp b/telegram-bot-api/ClientManager.cpp index 68338fd..5b6f454 100644 --- a/telegram-bot-api/ClientManager.cpp +++ b/telegram-bot-api/ClientManager.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) diff --git a/telegram-bot-api/ClientManager.h b/telegram-bot-api/ClientManager.h index ef91214..8d4e2d6 100644 --- a/telegram-bot-api/ClientManager.h +++ b/telegram-bot-api/ClientManager.h @@ -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) diff --git a/telegram-bot-api/ClientParameters.h b/telegram-bot-api/ClientParameters.h index b8558f9..fac9b77 100644 --- a/telegram-bot-api/ClientParameters.h +++ b/telegram-bot-api/ClientParameters.h @@ -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) diff --git a/telegram-bot-api/HttpConnection.cpp b/telegram-bot-api/HttpConnection.cpp index ade03d3..52a9823 100644 --- a/telegram-bot-api/HttpConnection.cpp +++ b/telegram-bot-api/HttpConnection.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) diff --git a/telegram-bot-api/HttpConnection.h b/telegram-bot-api/HttpConnection.h index 0e3b39c..b66b062 100644 --- a/telegram-bot-api/HttpConnection.h +++ b/telegram-bot-api/HttpConnection.h @@ -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) diff --git a/telegram-bot-api/HttpServer.h b/telegram-bot-api/HttpServer.h index c2398ee..21c26a8 100644 --- a/telegram-bot-api/HttpServer.h +++ b/telegram-bot-api/HttpServer.h @@ -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) diff --git a/telegram-bot-api/HttpStatConnection.cpp b/telegram-bot-api/HttpStatConnection.cpp index d01af06..574b8bd 100644 --- a/telegram-bot-api/HttpStatConnection.cpp +++ b/telegram-bot-api/HttpStatConnection.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) diff --git a/telegram-bot-api/HttpStatConnection.h b/telegram-bot-api/HttpStatConnection.h index b653326..b699ba7 100644 --- a/telegram-bot-api/HttpStatConnection.h +++ b/telegram-bot-api/HttpStatConnection.h @@ -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) diff --git a/telegram-bot-api/Query.cpp b/telegram-bot-api/Query.cpp index 39a59da..66d2b5a 100644 --- a/telegram-bot-api/Query.cpp +++ b/telegram-bot-api/Query.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) diff --git a/telegram-bot-api/Query.h b/telegram-bot-api/Query.h index 5044ce0..bcf5ef7 100644 --- a/telegram-bot-api/Query.h +++ b/telegram-bot-api/Query.h @@ -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) diff --git a/telegram-bot-api/Stats.cpp b/telegram-bot-api/Stats.cpp index d682610..2190644 100644 --- a/telegram-bot-api/Stats.cpp +++ b/telegram-bot-api/Stats.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) diff --git a/telegram-bot-api/Stats.h b/telegram-bot-api/Stats.h index 3871053..dedd3df 100644 --- a/telegram-bot-api/Stats.h +++ b/telegram-bot-api/Stats.h @@ -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) diff --git a/telegram-bot-api/Watchdog.cpp b/telegram-bot-api/Watchdog.cpp index 9b5c88d..98c7ff2 100644 --- a/telegram-bot-api/Watchdog.cpp +++ b/telegram-bot-api/Watchdog.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) diff --git a/telegram-bot-api/Watchdog.h b/telegram-bot-api/Watchdog.h index 89ac3c6..c34eb2d 100644 --- a/telegram-bot-api/Watchdog.h +++ b/telegram-bot-api/Watchdog.h @@ -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) diff --git a/telegram-bot-api/WebhookActor.cpp b/telegram-bot-api/WebhookActor.cpp index 3e0caa0..6968bc2 100644 --- a/telegram-bot-api/WebhookActor.cpp +++ b/telegram-bot-api/WebhookActor.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) diff --git a/telegram-bot-api/WebhookActor.h b/telegram-bot-api/WebhookActor.h index 4c101a3..610a30b 100644 --- a/telegram-bot-api/WebhookActor.h +++ b/telegram-bot-api/WebhookActor.h @@ -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) diff --git a/telegram-bot-api/telegram-bot-api.cpp b/telegram-bot-api/telegram-bot-api.cpp index 0538d9c..6bc71fb 100644 --- a/telegram-bot-api/telegram-bot-api.cpp +++ b/telegram-bot-api/telegram-bot-api.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) From 221db0fa1f5c695cd020f9ec388f03ce85c855ef Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 30 May 2024 19:47:21 +0300 Subject: [PATCH 14/37] Improve getUpdates warnings. --- telegram-bot-api/Client.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index bd5874e..b9cebed 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -12225,7 +12225,7 @@ void Client::do_get_updates(int32 offset, int32 limit, int32 timeout, PromisedQu CHECK(total_size >= updates.size()); total_size -= updates.size(); - bool need_warning = total_size > 0 && (query->start_timestamp() - previous_get_updates_finish_time_ > 10.0); + bool need_warning = total_size > 0 && (query->start_timestamp() - previous_get_updates_finish_time_ > 5.0); if (total_size <= MIN_PENDING_UPDATES_WARNING / 2) { if (last_pending_update_count_ > MIN_PENDING_UPDATES_WARNING) { need_warning = true; @@ -12237,7 +12237,8 @@ void Client::do_get_updates(int32 offset, int32 limit, int32 timeout, PromisedQu last_pending_update_count_ *= 2; } } - if (need_warning && previous_get_updates_finish_time_ > 0) { + if (need_warning && previous_get_updates_finish_time_ > 0 && + query->start_timestamp() > previous_get_updates_finish_time_) { LOG(WARNING) << "Found " << updates.size() << " updates out of " << (total_size + updates.size()) << " after last getUpdates call " << (query->start_timestamp() - previous_get_updates_finish_time_) << " seconds ago in " << (td::Time::now() - query->start_timestamp()) << " seconds from " From 2b0bb9207c55d440bb01bde157b41009330319f7 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 6 Jun 2024 13:57:02 +0300 Subject: [PATCH 15/37] Split "chat_member" and "chat_join_request" updates by a user. --- telegram-bot-api/Client.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index b9cebed..aec8ce0 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -12963,7 +12963,7 @@ void Client::add_update_chat_member(object_ptr &&updat } auto user_id = static_cast(update->old_chat_member_->member_id_.get())->user_id_; bool is_my = (user_id == my_id_); - auto webhook_queue_id = update->chat_id_ + (static_cast(is_my ? 5 : 6) << 33); + auto webhook_queue_id = (is_my ? update->chat_id_ : user_id) + (static_cast(is_my ? 5 : 6) << 33); auto update_type = is_my ? UpdateType::MyChatMember : UpdateType::ChatMember; add_update(update_type, JsonChatMemberUpdated(update.get(), this), left_time, webhook_queue_id); } else { @@ -12977,7 +12977,7 @@ void Client::add_update_chat_join_request(object_ptrrequest_ != nullptr); auto left_time = update->request_->date_ + 86400 - get_unix_time(); if (left_time > 0) { - auto webhook_queue_id = update->chat_id_ + (static_cast(6) << 33); + auto webhook_queue_id = update->request_->user_id_ + (static_cast(6) << 33); add_update(UpdateType::ChatJoinRequest, JsonChatJoinRequest(update.get(), this), left_time, webhook_queue_id); } else { LOG(DEBUG) << "Skip updateNewChatJoinRequest with date " << update->request_->date_ << ", because current date is " From d982389d773059d917dedb623e23cd82ffc2ef8d Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 11 Jun 2024 21:42:50 +0300 Subject: [PATCH 16/37] Update TDLib to 1.8.31. --- td | 2 +- telegram-bot-api/Client.cpp | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/td b/td index fab354a..8f19c75 160000 --- a/td +++ b/td @@ -1 +1 @@ -Subproject commit fab354add5a257a8121a4a7f1ff6b1b9fa9a9073 +Subproject commit 8f19c751dc296cedb9a921badb7a02a8c0cb1aeb diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index aec8ce0..a1a5440 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -7011,8 +7011,12 @@ 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; } @@ -7020,7 +7024,7 @@ td_api::object_ptr Client::get_input_message_reply_ 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(0, reply_parameters.reply_to_message_id, + return make_object(reply_parameters.reply_to_message_id, std::move(reply_parameters.quote)); } return nullptr; From e2af6c8e021d7a85509fab4ddd2990db312ff5d3 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 11 Jun 2024 22:07:13 +0300 Subject: [PATCH 17/37] Add callback query updates from business messages. --- telegram-bot-api/Client.cpp | 99 ++++++++++++++++++++++++++++++++----- telegram-bot-api/Client.h | 12 ++++- 2 files changed, 98 insertions(+), 13 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index a1a5440..fd1a290 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -4839,12 +4839,14 @@ 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, - const td::string &new_message_business_connection_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_business_connection_id_(new_message_business_connection_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 { @@ -4856,12 +4858,14 @@ class Client::TdOnGetStickerSetCallback final : public TdQueryCallback { << td::oneline(to_string(error)); } return client_->on_get_sticker_set(set_id_, new_callback_query_user_id_, new_message_chat_id_, - new_message_business_connection_id_, nullptr); + new_message_business_connection_id_, new_business_callback_query_user_id_, + nullptr); } CHECK(result->get_id() == td_api::stickerSet::ID); client_->on_get_sticker_set(set_id_, new_callback_query_user_id_, new_message_chat_id_, - new_message_business_connection_id_, move_object_as(result)); + new_message_business_connection_id_, new_business_callback_query_user_id_, + move_object_as(result)); } private: @@ -4870,6 +4874,7 @@ class Client::TdOnGetStickerSetCallback final : public TdQueryCallback { 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::TdOnGetChatCustomEmojiStickerSetCallback final : public TdQueryCallback { @@ -5800,7 +5805,7 @@ 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, const td::string &new_message_business_connection_id, - object_ptr sticker_set) { + int64 new_business_callback_query_user_id, object_ptr sticker_set) { if (new_callback_query_user_id != 0) { auto &queue = new_callback_query_queues_[new_callback_query_user_id]; CHECK(queue.has_active_request_); @@ -5822,6 +5827,13 @@ void Client::on_get_sticker_set(int64 set_id, int64 new_callback_query_user_id, 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) { @@ -5840,6 +5852,9 @@ void Client::on_get_sticker_set(int64 set_id, int64 new_callback_query_user_id, 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) { @@ -6822,6 +6837,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; @@ -12896,7 +12914,7 @@ void Client::process_new_callback_query_queue(int64 user_id, int state) { queue.has_active_request_ = true; return send_request( make_object(message_sticker_set_id), - td::make_unique(this, message_sticker_set_id, user_id, 0, td::string())); + td::make_unique(this, message_sticker_set_id, user_id, 0, td::string(), 0)); } auto reply_to_message_id = get_same_chat_reply_to_message_id(message_info); if (reply_to_message_id > 0) { @@ -12907,7 +12925,7 @@ void Client::process_new_callback_query_queue(int64 user_id, int state) { queue.has_active_request_ = true; return send_request( make_object(reply_sticker_set_id), - td::make_unique(this, reply_sticker_set_id, user_id, 0, td::string())); + td::make_unique(this, reply_sticker_set_id, user_id, 0, td::string(), 0)); } } } @@ -12925,6 +12943,63 @@ void Client::process_new_callback_query_queue(int64 user_id, int state) { new_callback_query_queues_.erase(user_id); } +void Client::add_new_business_callback_query(object_ptr &&query) { + CHECK(query != nullptr); + auto user_id = query->sender_user_id_; + CHECK(user_id != 0); + new_business_callback_query_queues_[user_id].queue_.push(std::move(query)); + process_new_business_callback_query_queue(user_id); +} + +void Client::process_new_business_callback_query_queue(int64 user_id) { + auto &queue = new_business_callback_query_queues_[user_id]; + if (queue.has_active_request_) { + CHECK(!queue.queue_.empty()); + LOG(INFO) << "Have an active request in business callback query queue of size " << queue.queue_.size() + << " for user " << user_id; + return; + } + if (logging_out_ || closing_) { + LOG(INFO) << "Ignore business callback query while closing for user " << user_id; + new_business_callback_query_queues_.erase(user_id); + return; + } + while (!queue.queue_.empty()) { + auto &query = queue.queue_.front(); + auto &message_ref = query->message_; + LOG(INFO) << "Process business callback query from user " << user_id; + + drop_internal_reply_to_message_in_another_chat(message_ref->message_); + + auto message_sticker_set_id = get_sticker_set_id(message_ref->message_->content_); + if (!have_sticker_set_name(message_sticker_set_id)) { + queue.has_active_request_ = true; + return send_request( + make_object(message_sticker_set_id), + td::make_unique(this, message_sticker_set_id, 0, 0, td::string(), user_id)); + } + if (message_ref->reply_to_message_ != nullptr) { + drop_internal_reply_to_message_in_another_chat(message_ref->reply_to_message_); + auto reply_sticker_set_id = get_sticker_set_id(message_ref->reply_to_message_->content_); + if (!have_sticker_set_name(reply_sticker_set_id)) { + queue.has_active_request_ = true; + return send_request( + make_object(reply_sticker_set_id), + td::make_unique(this, reply_sticker_set_id, 0, 0, td::string(), user_id)); + } + } + + CHECK(user_id == query->sender_user_id_); + auto message_info = create_business_message(query->connection_id_, std::move(message_ref)); + add_update(UpdateType::CallbackQuery, + JsonCallbackQuery(query->id_, user_id, 0, 0, message_info.get(), query->chat_instance_, + query->payload_.get(), this), + 150, user_id + (static_cast(3) << 33)); + queue.queue_.pop(); + } + new_callback_query_queues_.erase(user_id); +} + void Client::add_new_inline_callback_query(object_ptr &&query) { CHECK(query != nullptr); add_update(UpdateType::CallbackQuery, @@ -13481,7 +13556,7 @@ void Client::process_new_message_queue(int64 chat_id, int state) { queue.has_active_request_ = true; return send_request( make_object(message_sticker_set_id), - td::make_unique(this, message_sticker_set_id, 0, chat_id, td::string())); + td::make_unique(this, message_sticker_set_id, 0, chat_id, td::string(), 0)); } if (reply_to_message_id > 0) { auto reply_to_message_info = get_message(chat_id, reply_to_message_id, true); @@ -13491,7 +13566,7 @@ void Client::process_new_message_queue(int64 chat_id, int state) { queue.has_active_request_ = true; return send_request( make_object(reply_sticker_set_id), - td::make_unique(this, reply_sticker_set_id, 0, chat_id, td::string())); + td::make_unique(this, reply_sticker_set_id, 0, chat_id, td::string(), 0)); } } } @@ -13581,7 +13656,7 @@ void Client::process_new_business_message_queue(const td::string &connection_id) queue.has_active_request_ = true; return send_request( make_object(message_sticker_set_id), - td::make_unique(this, message_sticker_set_id, 0, 0, connection_id)); + td::make_unique(this, message_sticker_set_id, 0, 0, connection_id, 0)); } if (message_ref->reply_to_message_ != nullptr) { drop_internal_reply_to_message_in_another_chat(message_ref->reply_to_message_); @@ -13590,7 +13665,7 @@ void Client::process_new_business_message_queue(const td::string &connection_id) queue.has_active_request_ = true; return send_request( make_object(reply_sticker_set_id), - td::make_unique(this, reply_sticker_set_id, 0, 0, connection_id)); + td::make_unique(this, reply_sticker_set_id, 0, 0, connection_id, 0)); } } @@ -13744,7 +13819,7 @@ void Client::init_message(MessageInfo *message_info, object_ptr auto sticker_set_id = get_sticker_set_id(message_info->content); if (!have_sticker_set_name(sticker_set_id)) { send_request(make_object(sticker_set_id), - td::make_unique(this, sticker_set_id, 0, 0, td::string())); + td::make_unique(this, sticker_set_id, 0, 0, td::string(), 0)); } } else if (message->content_->get_id() == td_api::messagePoll::ID) { message_info->content = std::move(message->content_); diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index 58b234e..d264203 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -257,7 +257,7 @@ class Client final : public WebhookActor::Callback { void on_get_sticker_set(int64 set_id, int64 new_callback_query_user_id, int64 new_message_chat_id, const td::string &new_message_business_connection_id, - object_ptr sticker_set); + int64 new_business_callback_query_user_id, object_ptr sticker_set); void on_get_sticker_set_name(int64 set_id, const td::string &name); @@ -1063,6 +1063,10 @@ class Client final : public WebhookActor::Callback { void process_new_callback_query_queue(int64 user_id, int state); + void add_new_business_callback_query(object_ptr &&query); + + void process_new_business_callback_query_queue(int64 user_id); + void add_new_inline_callback_query(object_ptr &&query); void add_new_shipping_query(object_ptr &&query); @@ -1240,6 +1244,12 @@ class Client final : public WebhookActor::Callback { }; td::FlatHashMap new_callback_query_queues_; // sender_user_id -> queue + struct NewBusinessCallbackQueryQueue { + std::queue> queue_; + bool has_active_request_ = false; + }; + td::FlatHashMap new_business_callback_query_queues_; // sender_user_id -> queue + td::WaitFreeHashMap sticker_set_names_; td::WaitFreeHashMap last_send_message_time_; From 7ee51f8c6de1038b5d6c53a698dd94ebbd697090 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 11 Jun 2024 22:27:25 +0300 Subject: [PATCH 18/37] Support editMessageText for business messages. --- telegram-bot-api/Client.cpp | 45 +++++++++++++++++++++++++++---------- telegram-bot-api/Client.h | 2 +- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index fd1a290..bd94386 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -4129,9 +4129,9 @@ class Client::TdOnSendMessageCallback final : public TdQueryCallback { PromisedQueryPtr query_; }; -class Client::TdOnSendBusinessMessageCallback final : public TdQueryCallback { +class Client::TdOnReturnBusinessMessageCallback final : public TdQueryCallback { public: - TdOnSendBusinessMessageCallback(Client *client, td::string business_connection_id, PromisedQueryPtr query) + TdOnReturnBusinessMessageCallback(Client *client, td::string business_connection_id, PromisedQueryPtr query) : client_(client), business_connection_id_(std::move(business_connection_id)), query_(std::move(query)) { } @@ -4143,7 +4143,7 @@ class Client::TdOnSendBusinessMessageCallback final : public TdQueryCallback { 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, "sent business message", client_), std::move(query_)); + answer_query(JsonMessage(message.get(), true, "business message", client_), std::move(query_)); } private: @@ -10269,6 +10269,7 @@ td::Status Client::process_set_message_reaction_query(PromisedQueryPtr &query) { td::Status Client::process_edit_message_text_query(PromisedQueryPtr &query) { TRY_RESULT(input_message_text, get_input_message_text(query.get())); + auto business_connection_id = query->arg("business_connection_id"); auto chat_id = query->arg("chat_id"); auto message_id = get_message_id(query.get()); TRY_RESULT(reply_markup, get_reply_markup(query.get(), bot_user_ids_)); @@ -10286,10 +10287,30 @@ td::Status Client::process_edit_message_text_query(PromisedQueryPtr &query) { } else { resolve_reply_markup_bot_usernames( std::move(reply_markup), std::move(query), - [this, chat_id = chat_id.str(), message_id, input_message_text = std::move(input_message_text)]( - object_ptr reply_markup, PromisedQueryPtr query) mutable { + [this, business_connection_id = business_connection_id.str(), chat_id_str = chat_id.str(), message_id, + input_message_text = std::move(input_message_text)](object_ptr reply_markup, + PromisedQueryPtr query) mutable { + if (!business_connection_id.empty()) { + 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(); + return check_business_connection( + business_connection_id, std::move(query), + [this, business_connection_id, chat_id, message_id, input_message_text = std::move(input_message_text), + reply_markup = std::move(reply_markup)](const BusinessConnection *business_connection, + PromisedQueryPtr query) mutable { + send_request(make_object(business_connection_id, chat_id, message_id, + std::move(reply_markup), + std::move(input_message_text)), + td::make_unique(this, business_connection_id, + std::move(query))); + }); + } + check_message( - chat_id, message_id, false, AccessRights::Edit, "message to edit", std::move(query), + chat_id_str, message_id, false, AccessRights::Edit, "message to edit", std::move(query), [this, input_message_text = std::move(input_message_text), reply_markup = std::move(reply_markup)]( int64 chat_id, int64 message_id, PromisedQueryPtr query) mutable { send_request(make_object(chat_id, message_id, std::move(reply_markup), @@ -12051,12 +12072,12 @@ void Client::do_send_message(object_ptr input_messa effect_id, reply_markup = std::move(reply_markup), input_message_content = std::move(input_message_content)](const BusinessConnection *business_connection, PromisedQueryPtr query) mutable { - send_request( - make_object(business_connection->id_, chat_id, - get_input_message_reply_to(std::move(reply_parameters)), - disable_notification, protect_content, effect_id, - std::move(reply_markup), std::move(input_message_content)), - td::make_unique(this, business_connection->id_, std::move(query))); + send_request(make_object( + business_connection->id_, chat_id, + get_input_message_reply_to(std::move(reply_parameters)), disable_notification, + protect_content, effect_id, std::move(reply_markup), std::move(input_message_content)), + td::make_unique(this, business_connection->id_, + std::move(query))); }); } diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index d264203..4a47f77 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -206,7 +206,7 @@ class Client final : public WebhookActor::Callback { class TdOnInitCallback; class TdOnGetUserProfilePhotosCallback; class TdOnSendMessageCallback; - class TdOnSendBusinessMessageCallback; + class TdOnReturnBusinessMessageCallback; class TdOnSendMessageAlbumCallback; class TdOnSendBusinessMessageAlbumCallback; class TdOnForwardMessagesCallback; From c8079841edd361f40d6bbe86f91739157a284299 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 11 Jun 2024 22:41:59 +0300 Subject: [PATCH 19/37] Support editMessageLiveLocation for business messages. --- telegram-bot-api/Client.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index bd94386..2bc4cc4 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -10330,6 +10330,7 @@ td::Status Client::process_edit_message_live_location_query(PromisedQueryPtr &qu if (query->method() == "editmessagelivelocation") { TRY_RESULT_ASSIGN(location, get_location(query.get())); } + auto business_connection_id = query->arg("business_connection_id"); auto chat_id = query->arg("chat_id"); auto message_id = get_message_id(query.get()); TRY_RESULT(reply_markup, get_reply_markup(query.get(), bot_user_ids_)); @@ -10348,9 +10349,29 @@ td::Status Client::process_edit_message_live_location_query(PromisedQueryPtr &qu } else { resolve_reply_markup_bot_usernames( std::move(reply_markup), std::move(query), - [this, chat_id = chat_id.str(), message_id, location = std::move(location), live_period, heading, + [this, business_connection_id = business_connection_id.str(), chat_id_str = chat_id.str(), message_id, + location = std::move(location), live_period, heading, proximity_alert_radius](object_ptr reply_markup, PromisedQueryPtr query) mutable { - check_message(chat_id, message_id, false, AccessRights::Edit, "message to edit", std::move(query), + if (!business_connection_id.empty()) { + 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(); + return check_business_connection( + business_connection_id, std::move(query), + [this, business_connection_id, chat_id, message_id, location = std::move(location), live_period, + heading, proximity_alert_radius, reply_markup = std::move(reply_markup)]( + const BusinessConnection *business_connection, PromisedQueryPtr query) mutable { + send_request(make_object( + business_connection_id, chat_id, message_id, std::move(reply_markup), + std::move(location), live_period, heading, proximity_alert_radius), + td::make_unique(this, business_connection_id, + std::move(query))); + }); + } + + check_message(chat_id_str, message_id, false, AccessRights::Edit, "message to edit", std::move(query), [this, location = std::move(location), live_period, heading, proximity_alert_radius, reply_markup = std::move(reply_markup)](int64 chat_id, int64 message_id, PromisedQueryPtr query) mutable { From 6c01c85d27655784991d0f9788a9a2c8ee39d0d1 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 11 Jun 2024 22:44:26 +0300 Subject: [PATCH 20/37] Support editMessageMedia for business messages. --- telegram-bot-api/Client.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 2bc4cc4..eebc7ba 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -10386,6 +10386,7 @@ td::Status Client::process_edit_message_live_location_query(PromisedQueryPtr &qu } td::Status Client::process_edit_message_media_query(PromisedQueryPtr &query) { + auto business_connection_id = query->arg("business_connection_id"); auto chat_id = query->arg("chat_id"); auto message_id = get_message_id(query.get()); TRY_RESULT(reply_markup, get_reply_markup(query.get(), bot_user_ids_)); @@ -10404,10 +10405,30 @@ td::Status Client::process_edit_message_media_query(PromisedQueryPtr &query) { } else { resolve_reply_markup_bot_usernames( std::move(reply_markup), std::move(query), - [this, chat_id = chat_id.str(), message_id, input_message_content = std::move(input_media)]( - object_ptr reply_markup, PromisedQueryPtr query) mutable { + [this, business_connection_id = business_connection_id.str(), chat_id_str = chat_id.str(), message_id, + input_message_content = std::move(input_media)](object_ptr reply_markup, + PromisedQueryPtr query) mutable { + if (!business_connection_id.empty()) { + 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(); + return check_business_connection( + business_connection_id, std::move(query), + [this, business_connection_id, chat_id, message_id, + input_message_content = std::move(input_message_content), reply_markup = std::move(reply_markup)]( + const BusinessConnection *business_connection, PromisedQueryPtr query) mutable { + send_request(make_object(business_connection_id, chat_id, + message_id, std::move(reply_markup), + std::move(input_message_content)), + td::make_unique(this, business_connection_id, + std::move(query))); + }); + } + check_message( - chat_id, message_id, false, AccessRights::Edit, "message to edit", std::move(query), + chat_id_str, message_id, false, AccessRights::Edit, "message to edit", std::move(query), [this, reply_markup = std::move(reply_markup), input_message_content = std::move(input_message_content)]( int64 chat_id, int64 message_id, PromisedQueryPtr query) mutable { send_request(make_object(chat_id, message_id, std::move(reply_markup), From f75e2155c175ce7807a317f455b5efd6531f5503 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 11 Jun 2024 22:50:39 +0300 Subject: [PATCH 21/37] Support editMessageCaption for business messages. --- telegram-bot-api/Client.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index eebc7ba..23414cb 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -10441,6 +10441,7 @@ td::Status Client::process_edit_message_media_query(PromisedQueryPtr &query) { } td::Status Client::process_edit_message_caption_query(PromisedQueryPtr &query) { + auto business_connection_id = query->arg("business_connection_id"); auto chat_id = query->arg("chat_id"); auto message_id = get_message_id(query.get()); TRY_RESULT(reply_markup, get_reply_markup(query.get(), bot_user_ids_)); @@ -10460,9 +10461,29 @@ td::Status Client::process_edit_message_caption_query(PromisedQueryPtr &query) { } else { resolve_reply_markup_bot_usernames( std::move(reply_markup), std::move(query), - [this, chat_id = chat_id.str(), message_id, caption = std::move(caption), show_caption_above_media]( - object_ptr reply_markup, PromisedQueryPtr query) mutable { - check_message(chat_id, message_id, false, AccessRights::Edit, "message to edit", std::move(query), + [this, business_connection_id = business_connection_id.str(), chat_id_str = chat_id.str(), message_id, + caption = std::move(caption), + show_caption_above_media](object_ptr reply_markup, PromisedQueryPtr query) mutable { + if (!business_connection_id.empty()) { + 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(); + return check_business_connection( + business_connection_id, std::move(query), + [this, business_connection_id, chat_id, message_id, reply_markup = std::move(reply_markup), + caption = std::move(caption), show_caption_above_media](const BusinessConnection *business_connection, + PromisedQueryPtr query) mutable { + send_request(make_object( + business_connection_id, chat_id, message_id, std::move(reply_markup), + std::move(caption), show_caption_above_media), + td::make_unique(this, business_connection_id, + std::move(query))); + }); + } + + check_message(chat_id_str, message_id, false, AccessRights::Edit, "message to edit", std::move(query), [this, reply_markup = std::move(reply_markup), caption = std::move(caption), show_caption_above_media](int64 chat_id, int64 message_id, PromisedQueryPtr query) mutable { send_request( From 86fb9bc8b8fdda6758a1d0ee1114da938ee79a52 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 11 Jun 2024 22:53:41 +0300 Subject: [PATCH 22/37] Support editMessageReplyMarkup for business messages. --- telegram-bot-api/Client.cpp | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 23414cb..b77592c 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -10497,6 +10497,7 @@ td::Status Client::process_edit_message_caption_query(PromisedQueryPtr &query) { } td::Status Client::process_edit_message_reply_markup_query(PromisedQueryPtr &query) { + auto business_connection_id = query->arg("business_connection_id"); auto chat_id = query->arg("chat_id"); auto message_id = get_message_id(query.get()); TRY_RESULT(reply_markup, get_reply_markup(query.get(), bot_user_ids_)); @@ -10513,9 +10514,26 @@ td::Status Client::process_edit_message_reply_markup_query(PromisedQueryPtr &que } else { resolve_reply_markup_bot_usernames( std::move(reply_markup), std::move(query), - [this, chat_id = chat_id.str(), message_id](object_ptr reply_markup, - PromisedQueryPtr query) { - check_message(chat_id, message_id, false, AccessRights::Edit, "message to edit", std::move(query), + [this, business_connection_id = business_connection_id.str(), chat_id_str = chat_id.str(), message_id]( + object_ptr reply_markup, PromisedQueryPtr query) { + if (!business_connection_id.empty()) { + 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(); + return check_business_connection( + business_connection_id, std::move(query), + [this, business_connection_id, chat_id, message_id, reply_markup = std::move(reply_markup)]( + const BusinessConnection *business_connection, PromisedQueryPtr query) mutable { + send_request(make_object(business_connection_id, chat_id, + message_id, std::move(reply_markup)), + td::make_unique(this, business_connection_id, + std::move(query))); + }); + } + + check_message(chat_id_str, message_id, false, AccessRights::Edit, "message to edit", std::move(query), [this, reply_markup = std::move(reply_markup)](int64 chat_id, int64 message_id, PromisedQueryPtr query) mutable { send_request( From bd31c2a9ce5154523d7afc89bce2c943592cc448 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 11 Jun 2024 23:02:03 +0300 Subject: [PATCH 23/37] Support stopPoll for business messages. --- telegram-bot-api/Client.cpp | 52 ++++++++++++++++++++++++++++++++++--- telegram-bot-api/Client.h | 1 + 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index b77592c..41562d4 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -4359,6 +4359,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)) { @@ -10021,15 +10049,33 @@ td::Status Client::process_send_poll_query(PromisedQueryPtr &query) { } td::Status Client::process_stop_poll_query(PromisedQueryPtr &query) { + auto business_connection_id = query->arg("business_connection_id"); auto chat_id = query->arg("chat_id"); auto message_id = get_message_id(query.get()); TRY_RESULT(reply_markup, get_reply_markup(query.get(), bot_user_ids_)); resolve_reply_markup_bot_usernames( std::move(reply_markup), std::move(query), - [this, chat_id = chat_id.str(), message_id](object_ptr reply_markup, - PromisedQueryPtr query) { - check_message(chat_id, message_id, false, AccessRights::Edit, "message with poll to stop", std::move(query), + [this, business_connection_id = business_connection_id.str(), chat_id_str = chat_id.str(), message_id]( + object_ptr reply_markup, PromisedQueryPtr query) { + if (!business_connection_id.empty()) { + 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(); + return check_business_connection( + business_connection_id, std::move(query), + [this, business_connection_id, chat_id, message_id, reply_markup = std::move(reply_markup)]( + const BusinessConnection *business_connection, PromisedQueryPtr query) mutable { + send_request( + make_object(business_connection_id, chat_id, message_id, + std::move(reply_markup)), + td::make_unique(this, business_connection_id, std::move(query))); + }); + } + + check_message(chat_id_str, message_id, false, AccessRights::Edit, "message with poll to stop", std::move(query), [this, reply_markup = std::move(reply_markup)](int64 chat_id, int64 message_id, PromisedQueryPtr query) mutable { send_request( diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index 4a47f77..3d53307 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -214,6 +214,7 @@ class Client final : public WebhookActor::Callback { class TdOnEditMessageCallback; class TdOnEditInlineMessageCallback; class TdOnStopPollCallback; + class TdOnStopBusinessPollCallback; class TdOnOkQueryCallback; class TdOnGetReplyMessageCallback; class TdOnGetEditedMessageCallback; From a879acc49df6bbd61c5a06d09f0c488031e540a5 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 11 Jun 2024 23:12:04 +0300 Subject: [PATCH 24/37] Add check_business_connection_chat_id. --- telegram-bot-api/Client.cpp | 140 +++++++++++++++--------------------- telegram-bot-api/Client.h | 4 ++ 2 files changed, 60 insertions(+), 84 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 41562d4..b39f3e6 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -6074,6 +6074,21 @@ void Client::check_business_connection(const td::string &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); @@ -10059,15 +10074,10 @@ td::Status Client::process_stop_poll_query(PromisedQueryPtr &query) { [this, business_connection_id = business_connection_id.str(), chat_id_str = chat_id.str(), message_id]( object_ptr reply_markup, PromisedQueryPtr query) { if (!business_connection_id.empty()) { - 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(); - return check_business_connection( - business_connection_id, std::move(query), - [this, business_connection_id, chat_id, message_id, reply_markup = std::move(reply_markup)]( - const BusinessConnection *business_connection, PromisedQueryPtr query) mutable { + return check_business_connection_chat_id( + business_connection_id, chat_id_str, std::move(query), + [this, business_connection_id, message_id, reply_markup = std::move(reply_markup)]( + const BusinessConnection *business_connection, int64 chat_id, PromisedQueryPtr query) mutable { send_request( make_object(business_connection_id, chat_id, message_id, std::move(reply_markup)), @@ -10224,17 +10234,11 @@ td::Status Client::process_send_media_group_query(PromisedQueryPtr &query) { input_message_contents = std::move(input_message_contents)](object_ptr reply_markup, PromisedQueryPtr query) mutable { if (!business_connection_id.empty()) { - 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(); - return check_business_connection( - business_connection_id, std::move(query), - [this, chat_id, reply_parameters = std::move(reply_parameters), disable_notification, protect_content, - effect_id, input_message_contents = std::move(input_message_contents), - reply_markup = std::move(reply_markup)](const BusinessConnection *business_connection, - PromisedQueryPtr query) mutable { + return check_business_connection_chat_id( + business_connection_id, chat_id_str, std::move(query), + [this, reply_parameters = std::move(reply_parameters), disable_notification, protect_content, effect_id, + input_message_contents = std::move(input_message_contents), reply_markup = std::move(reply_markup)]( + const BusinessConnection *business_connection, int64 chat_id, PromisedQueryPtr query) mutable { send_request( make_object( business_connection->id_, chat_id, get_input_message_reply_to(std::move(reply_parameters)), @@ -10277,11 +10281,10 @@ td::Status Client::process_send_chat_action_query(PromisedQueryPtr &query) { return td::Status::Error(400, "Wrong parameter action in request"); } if (!business_connection_id.empty()) { - TRY_RESULT(chat_id, get_business_connection_chat_id(chat_id_str)); - check_business_connection( - business_connection_id, std::move(query), - [this, chat_id, action = std::move(action)](const BusinessConnection *business_connection, - PromisedQueryPtr query) mutable { + check_business_connection_chat_id( + business_connection_id, chat_id_str.str(), std::move(query), + [this, action = std::move(action)](const BusinessConnection *business_connection, int64 chat_id, + PromisedQueryPtr query) mutable { send_request(make_object(chat_id, 0, business_connection->id_, std::move(action)), td::make_unique(std::move(query))); }); @@ -10337,15 +10340,10 @@ td::Status Client::process_edit_message_text_query(PromisedQueryPtr &query) { input_message_text = std::move(input_message_text)](object_ptr reply_markup, PromisedQueryPtr query) mutable { if (!business_connection_id.empty()) { - 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(); - return check_business_connection( - business_connection_id, std::move(query), - [this, business_connection_id, chat_id, message_id, input_message_text = std::move(input_message_text), - reply_markup = std::move(reply_markup)](const BusinessConnection *business_connection, + return check_business_connection_chat_id( + business_connection_id, chat_id_str, std::move(query), + [this, business_connection_id, message_id, input_message_text = std::move(input_message_text), + reply_markup = std::move(reply_markup)](const BusinessConnection *business_connection, int64 chat_id, PromisedQueryPtr query) mutable { send_request(make_object(business_connection_id, chat_id, message_id, std::move(reply_markup), @@ -10399,16 +10397,11 @@ td::Status Client::process_edit_message_live_location_query(PromisedQueryPtr &qu location = std::move(location), live_period, heading, proximity_alert_radius](object_ptr reply_markup, PromisedQueryPtr query) mutable { if (!business_connection_id.empty()) { - 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(); - return check_business_connection( - business_connection_id, std::move(query), - [this, business_connection_id, chat_id, message_id, location = std::move(location), live_period, - heading, proximity_alert_radius, reply_markup = std::move(reply_markup)]( - const BusinessConnection *business_connection, PromisedQueryPtr query) mutable { + return check_business_connection_chat_id( + business_connection_id, chat_id_str, std::move(query), + [this, business_connection_id, message_id, location = std::move(location), live_period, heading, + proximity_alert_radius, reply_markup = std::move(reply_markup)]( + const BusinessConnection *business_connection, int64 chat_id, PromisedQueryPtr query) mutable { send_request(make_object( business_connection_id, chat_id, message_id, std::move(reply_markup), std::move(location), live_period, heading, proximity_alert_radius), @@ -10455,16 +10448,11 @@ td::Status Client::process_edit_message_media_query(PromisedQueryPtr &query) { input_message_content = std::move(input_media)](object_ptr reply_markup, PromisedQueryPtr query) mutable { if (!business_connection_id.empty()) { - 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(); - return check_business_connection( - business_connection_id, std::move(query), - [this, business_connection_id, chat_id, message_id, - input_message_content = std::move(input_message_content), reply_markup = std::move(reply_markup)]( - const BusinessConnection *business_connection, PromisedQueryPtr query) mutable { + return check_business_connection_chat_id( + business_connection_id, chat_id_str, std::move(query), + [this, business_connection_id, message_id, input_message_content = std::move(input_message_content), + reply_markup = std::move(reply_markup)](const BusinessConnection *business_connection, int64 chat_id, + PromisedQueryPtr query) mutable { send_request(make_object(business_connection_id, chat_id, message_id, std::move(reply_markup), std::move(input_message_content)), @@ -10511,16 +10499,11 @@ td::Status Client::process_edit_message_caption_query(PromisedQueryPtr &query) { caption = std::move(caption), show_caption_above_media](object_ptr reply_markup, PromisedQueryPtr query) mutable { if (!business_connection_id.empty()) { - 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(); - return check_business_connection( - business_connection_id, std::move(query), - [this, business_connection_id, chat_id, message_id, reply_markup = std::move(reply_markup), - caption = std::move(caption), show_caption_above_media](const BusinessConnection *business_connection, - PromisedQueryPtr query) mutable { + return check_business_connection_chat_id( + business_connection_id, chat_id_str, std::move(query), + [this, business_connection_id, message_id, reply_markup = std::move(reply_markup), + caption = std::move(caption), show_caption_above_media]( + const BusinessConnection *business_connection, int64 chat_id, PromisedQueryPtr query) mutable { send_request(make_object( business_connection_id, chat_id, message_id, std::move(reply_markup), std::move(caption), show_caption_above_media), @@ -10563,15 +10546,10 @@ td::Status Client::process_edit_message_reply_markup_query(PromisedQueryPtr &que [this, business_connection_id = business_connection_id.str(), chat_id_str = chat_id.str(), message_id]( object_ptr reply_markup, PromisedQueryPtr query) { if (!business_connection_id.empty()) { - 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(); - return check_business_connection( - business_connection_id, std::move(query), - [this, business_connection_id, chat_id, message_id, reply_markup = std::move(reply_markup)]( - const BusinessConnection *business_connection, PromisedQueryPtr query) mutable { + return check_business_connection_chat_id( + business_connection_id, chat_id_str, std::move(query), + [this, business_connection_id, message_id, reply_markup = std::move(reply_markup)]( + const BusinessConnection *business_connection, int64 chat_id, PromisedQueryPtr query) mutable { send_request(make_object(business_connection_id, chat_id, message_id, std::move(reply_markup)), td::make_unique(this, business_connection_id, @@ -12188,17 +12166,11 @@ void Client::do_send_message(object_ptr input_messa input_message_content = std::move(input_message_content)](object_ptr reply_markup, PromisedQueryPtr query) mutable { if (!business_connection_id.empty()) { - 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(); - return check_business_connection( - business_connection_id, std::move(query), - [this, chat_id, reply_parameters = std::move(reply_parameters), disable_notification, protect_content, - effect_id, reply_markup = std::move(reply_markup), - input_message_content = std::move(input_message_content)](const BusinessConnection *business_connection, - PromisedQueryPtr query) mutable { + return check_business_connection_chat_id( + business_connection_id, chat_id_str, std::move(query), + [this, reply_parameters = std::move(reply_parameters), disable_notification, protect_content, effect_id, + reply_markup = std::move(reply_markup), input_message_content = std::move(input_message_content)]( + const BusinessConnection *business_connection, int64 chat_id, PromisedQueryPtr query) mutable { send_request(make_object( business_connection->id_, chat_id, get_input_message_reply_to(std::move(reply_parameters)), disable_notification, diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index 3d53307..669a395 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -344,6 +344,10 @@ class Client final : public WebhookActor::Callback { void check_business_connection(const td::string &business_connection_id, PromisedQueryPtr query, OnSuccess on_success); + template + void check_business_connection_chat_id(const td::string &business_connection_id, const td::string &chat_id_str, + PromisedQueryPtr query, OnSuccess on_success); + template void check_bot_command_scope(BotCommandScope &&scope, PromisedQueryPtr query, OnSuccess on_success); From 025884aeca08f09486763afcb37b52a99ca1cda7 Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 15 Jun 2024 00:57:27 +0300 Subject: [PATCH 25/37] Add getStarTransactions. --- telegram-bot-api/Client.cpp | 146 +++++++++++++++++++++++++++++++++++- telegram-bot-api/Client.h | 6 ++ 2 files changed, 150 insertions(+), 2 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index b39f3e6..3444998 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -246,6 +246,7 @@ 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); @@ -3928,6 +3929,117 @@ class Client::JsonBusinessMessagesDeleted final : public td::Jsonable { 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::starTransactionPartnerUser::ID: { + auto source_user = static_cast(source_); + object("type", "user"); + object("user", JsonUser(source_user->user_id_, client_)); + break; + } + case td_api::starTransactionPartnerTelegram::ID: + case td_api::starTransactionPartnerAppStore::ID: + case td_api::starTransactionPartnerGooglePlay::ID: + case td_api::starTransactionPartnerChannel::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) { @@ -5388,12 +5500,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_)); } } @@ -5402,6 +5514,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) @@ -10610,6 +10743,15 @@ td::Status Client::process_create_invoice_link_query(PromisedQueryPtr &query) { return td::Status::OK(); } +td::Status Client::process_get_star_transactions_query(PromisedQueryPtr &query) { + auto offset = get_integer_arg(query.get(), "offset", 0, 0); + auto limit = get_integer_arg(query.get(), "limit", 100, 1, 100); + send_request(make_object(make_object(my_id_), nullptr, + td::to_string(offset), limit), + td::make_unique(this, std::move(query))); + return td::Status::OK(); +} + td::Status Client::process_refund_star_payment_query(PromisedQueryPtr &query) { TRY_RESULT(user_id, get_user_id(query.get())); TRY_RESULT(telegram_payment_charge_id, get_required_string_arg(query.get(), "telegram_payment_charge_id")); diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index 669a395..87964a7 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -195,6 +195,10 @@ class Client final : public WebhookActor::Callback { class JsonGiveawayWinners; class JsonGiveawayCompleted; class JsonChatBoostAdded; + class JsonRevenueWithdrawalState; + class JsonStarTransactionPartner; + class JsonStarTransaction; + class JsonStarTransactions; class JsonUpdateTypes; class JsonWebhookInfo; class JsonStickerSet; @@ -238,6 +242,7 @@ class Client final : public WebhookActor::Callback { class TdOnGetSupergroupMemberCountCallback; class TdOnGetUserChatBoostsCallback; class TdOnCreateInvoiceLinkCallback; + class TdOnGetStarTransactionsQueryCallback; class TdOnReplacePrimaryChatInviteLinkCallback; class TdOnGetChatInviteLinkCallback; class TdOnGetGameHighScoresCallback; @@ -652,6 +657,7 @@ class Client final : public WebhookActor::Callback { td::Status process_delete_message_query(PromisedQueryPtr &query); td::Status process_delete_messages_query(PromisedQueryPtr &query); td::Status process_create_invoice_link_query(PromisedQueryPtr &query); + td::Status process_get_star_transactions_query(PromisedQueryPtr &query); td::Status process_refund_star_payment_query(PromisedQueryPtr &query); td::Status process_set_game_score_query(PromisedQueryPtr &query); td::Status process_get_game_high_scores_query(PromisedQueryPtr &query); From ecfce9042b61bc3719f51014aff238b5ac14a5ad Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 18 Jun 2024 01:01:31 +0300 Subject: [PATCH 26/37] Update version to 7.5. --- CMakeLists.txt | 2 +- telegram-bot-api/telegram-bot-api.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b7b9380..8d38880 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ if (POLICY CMP0065) cmake_policy(SET CMP0065 NEW) endif() -project(TelegramBotApi VERSION 7.4 LANGUAGES CXX) +project(TelegramBotApi VERSION 7.5 LANGUAGES CXX) if (POLICY CMP0069) option(TELEGRAM_BOT_API_ENABLE_LTO "Use \"ON\" to enable Link Time Optimization.") diff --git a/telegram-bot-api/telegram-bot-api.cpp b/telegram-bot-api/telegram-bot-api.cpp index 6bc71fb..a5af3f6 100644 --- a/telegram-bot-api/telegram-bot-api.cpp +++ b/telegram-bot-api/telegram-bot-api.cpp @@ -165,7 +165,7 @@ int main(int argc, char *argv[]) { auto start_time = td::Time::now(); auto shared_data = std::make_shared(); auto parameters = std::make_unique(); - parameters->version_ = "7.4"; + parameters->version_ = "7.5"; parameters->shared_data_ = shared_data; parameters->start_time_ = start_time; auto net_query_stats = td::create_net_query_stats(); From 1873bf58f3aa8eabdf09ab2f664a55e22bf495f6 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 26 Jun 2024 00:46:00 +0300 Subject: [PATCH 27/37] Simplify some calls to fail_query_with_error. --- telegram-bot-api/Client.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 3444998..4ed5580 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -4865,7 +4865,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); @@ -5197,7 +5197,7 @@ class Client::TdOnGetChatPinnedMessageToUnpinCallback final : public TdQueryCall if (error->code_ == 429) { 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"); } } @@ -5252,8 +5252,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() From f47e0a9fde27343dea9e1a80e87f898acaa803ff Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 30 Jun 2024 12:43:03 +0300 Subject: [PATCH 28/37] Update TDLib to 1.8.32. --- td | 2 +- telegram-bot-api/Client.cpp | 94 ++++++++++++++++++++++++++++++++----- telegram-bot-api/Client.h | 5 ++ 3 files changed, 89 insertions(+), 12 deletions(-) diff --git a/td b/td index 8f19c75..35cfcf5 160000 --- a/td +++ b/td @@ -1 +1 @@ -Subproject commit 8f19c751dc296cedb9a921badb7a02a8c0cb1aeb +Subproject commit 35cfcf5d15981b99e8f31a2195641f035dd516c3 diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 4ed5580..c26a74d 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -3177,6 +3177,8 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const { object("boost_added", JsonChatBoostAdded(content)); break; } + case td_api::messagePaidMedia::ID: + break; default: UNREACHABLE(); } @@ -3974,10 +3976,10 @@ class Client::JsonStarTransactionPartner final : public td::Jsonable { } break; } - case td_api::starTransactionPartnerUser::ID: { - auto source_user = static_cast(source_); + case td_api::starTransactionPartnerBot::ID: { + auto source_user = static_cast(source_); object("type", "user"); - object("user", JsonUser(source_user->user_id_, client_)); + object("user", JsonUser(source_user->bot_user_id_, client_)); break; } case td_api::starTransactionPartnerTelegram::ID: @@ -3987,6 +3989,7 @@ class Client::JsonStarTransactionPartner final : public td::Jsonable { LOG(ERROR) << "Receive " << to_string(*source_); object("type", "other"); break; + case td_api::starTransactionPartnerTelegramAds::ID: case td_api::starTransactionPartnerUnsupported::ID: object("type", "other"); break; @@ -7915,7 +7918,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) { @@ -9318,10 +9321,10 @@ td::Result> Client::get_input_me td::vector(), duration, width, height, supports_streaming, std::move(caption), show_caption_above_media, nullptr, has_spoiler); } - if (for_album && type == "animation") { - return td::Status::Error(PSLICE() << "type \"" << type << "\" can't be used in sendMediaGroup"); - } if (type == "animation") { + if (for_album) { + return td::Status::Error(PSLICE() << "type \"" << type << "\" can't be used in sendMediaGroup"); + } TRY_RESULT(width, object.get_optional_int_field("width")); TRY_RESULT(height, object.get_optional_int_field("height")); TRY_RESULT(duration, object.get_optional_int_field("duration")); @@ -9399,6 +9402,67 @@ td::Result>> Client:: return std::move(contents); } +td::Result> Client::get_input_paid_media(const Query *query, + td::JsonValue &&input_media) const { + if (input_media.type() != td::JsonValue::Type::Object) { + return td::Status::Error("expected an Object"); + } + + auto &object = input_media.get_object(); + TRY_RESULT(media, object.get_optional_string_field("media")); + + auto input_file = get_input_file(query, td::Slice(), media, false); + if (input_file == nullptr) { + return td::Status::Error("media not found"); + } + + object_ptr input_thumbnail; + TRY_RESULT(thumbnail, object.get_optional_string_field("thumbnail")); + auto thumbnail_input_file = get_input_file(query, "thumbnail", thumbnail, true); + if (thumbnail_input_file != nullptr) { + input_thumbnail = make_object(std::move(thumbnail_input_file), 0, 0); + } + + TRY_RESULT(width, object.get_optional_int_field("width")); + TRY_RESULT(height, object.get_optional_int_field("height")); + width = td::clamp(width, 0, MAX_LENGTH); + height = td::clamp(height, 0, MAX_LENGTH); + + object_ptr media_type; + TRY_RESULT(type, object.get_required_string_field("type")); + if (type == "photo") { + media_type = make_object(); + } else if (type == "video") { + TRY_RESULT(duration, object.get_optional_int_field("duration")); + TRY_RESULT(supports_streaming, object.get_optional_bool_field("supports_streaming")); + duration = td::clamp(duration, 0, MAX_DURATION); + media_type = make_object(duration, supports_streaming); + } else { + return td::Status::Error(PSLICE() << "type \"" << type << "\" is unsupported"); + } + + return make_object(std::move(media_type), std::move(input_file), std::move(input_thumbnail), + td::vector(), width, height); +} + +td::Result> Client::get_input_paid_media(const Query *query, + td::Slice field_name) const { + TRY_RESULT(media, get_required_string_arg(query, field_name)); + + LOG(INFO) << "Parsing JSON object: " << media; + auto r_value = json_decode(media); + if (r_value.is_error()) { + LOG(INFO) << "Can't parse JSON object: " << r_value.error(); + return td::Status::Error(400, "Can't parse input paid media JSON object"); + } + + auto r_input_paid_media = get_input_paid_media(query, r_value.move_as_ok()); + if (r_input_paid_media.is_error()) { + return td::Status::Error(400, PSLICE() << "Can't parse InputPaidMedia: " << r_input_paid_media.error().message()); + } + return r_input_paid_media.move_as_ok(); +} + td::Result> Client::get_input_message_invoice( const Query *query) const { TRY_RESULT(title, get_required_string_arg(query, "title")); @@ -9456,10 +9520,15 @@ td::Result> Client::get_input_me auto send_email_address_to_provider = to_bool(query->arg("send_email_to_provider")); auto is_flexible = to_bool(query->arg("is_flexible")); - object_ptr extended_media; - if (!query->arg("extended_media").empty()) { - TRY_RESULT_ASSIGN(extended_media, get_input_media(query, "extended_media")); + object_ptr paid_media; + if (!query->arg("paid_media").empty()) { + TRY_RESULT_ASSIGN(paid_media, get_input_paid_media(query, "paid_media")); + } else if (!query->arg("extended_media").empty()) { + TRY_RESULT_ASSIGN(paid_media, get_input_paid_media(query, "extended_media")); } + TRY_RESULT(paid_media_caption, get_formatted_text(query->arg("paid_media_caption").str(), + query->arg("paid_media_caption_parse_mode").str(), + get_input_entities(query, "paid_media_caption_entities"))); return make_object( make_object(currency.str(), std::move(prices), max_tip_amount, std::move(suggested_tip_amounts), @@ -9467,7 +9536,8 @@ td::Result> Client::get_input_me need_shipping_address, send_phone_number_to_provider, send_email_address_to_provider, is_flexible), title.str(), description.str(), photo_url.str(), photo_size, photo_width, photo_height, payload.str(), - provider_token.str(), provider_data.str(), start_parameter.str(), std::move(extended_media)); + provider_token.str(), provider_data.str(), start_parameter.str(), std::move(paid_media), + std::move(paid_media_caption)); } td::Result>> Client::get_poll_options(const Query *query) { @@ -13548,6 +13618,8 @@ bool Client::need_skip_update_message(int64 chat_id, const object_ptr>> get_input_message_contents( const Query *query, td::JsonValue &&value) const; + td::Result> get_input_paid_media(const Query *query, + td::JsonValue &&input_media) const; + + td::Result> get_input_paid_media(const Query *query, td::Slice field_name) const; + td::Result> get_input_message_invoice(const Query *query) const; static object_ptr get_message_send_options(bool disable_notification, From 76006f4a2e0a8afb58c0747a28d2849e4ce714ac Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 30 Jun 2024 13:26:14 +0300 Subject: [PATCH 29/37] Add "telegram_ads" transaction partner. --- telegram-bot-api/Client.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index c26a74d..b48311a 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -3982,6 +3982,9 @@ class Client::JsonStarTransactionPartner final : public td::Jsonable { object("user", JsonUser(source_user->bot_user_id_, client_)); 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: @@ -3989,7 +3992,6 @@ class Client::JsonStarTransactionPartner final : public td::Jsonable { LOG(ERROR) << "Receive " << to_string(*source_); object("type", "other"); break; - case td_api::starTransactionPartnerTelegramAds::ID: case td_api::starTransactionPartnerUnsupported::ID: object("type", "other"); break; From 546777ab24414e9cc419b452795b3a465431ddfb Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 30 Jun 2024 13:27:55 +0300 Subject: [PATCH 30/37] Add invoice_payload to "user" transaction partner. --- telegram-bot-api/Client.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index b48311a..5d71fef 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -3980,6 +3980,14 @@ class Client::JsonStarTransactionPartner final : public td::Jsonable { auto source_user = static_cast(source_); object("type", "user"); object("user", JsonUser(source_user->bot_user_id_, client_)); + if (!source_user->invoice_payload_.empty()) { + if (!td::check_utf8(source_user->invoice_payload_)) { + LOG(WARNING) << "Receive non-UTF-8 invoice payload"; + object("invoice_payload", td::JsonRawString(source_user->invoice_payload_)); + } else { + object("invoice_payload", source_user->invoice_payload_); + } + } break; } case td_api::starTransactionPartnerTelegramAds::ID: From 3e1fee6d7a3dad669f2c38d764b9c8e2bc6a3de1 Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 30 Jun 2024 13:33:06 +0300 Subject: [PATCH 31/37] Add ChatFullInfo.can_send_paid_media for channels. --- telegram-bot-api/Client.cpp | 4 ++++ telegram-bot-api/Client.h | 1 + 2 files changed, 5 insertions(+) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 5d71fef..45d9eb9 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -1091,6 +1091,9 @@ class Client::JsonChat final : public td::Jsonable { 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; @@ -6952,6 +6955,7 @@ void Client::on_update(object_ptr result) { 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: { diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index 2e25de3..7805588 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -878,6 +878,7 @@ class Client final : public WebhookActor::Callback { bool join_by_request = false; bool has_hidden_members = false; bool has_aggressive_anti_spam_enabled = false; + bool has_paid_media_allowed = false; }; static void add_supergroup(SupergroupInfo *supergroup_info, object_ptr &&supergroup); SupergroupInfo *add_supergroup_info(int64 supergroup_id); From 4fe3ba9c99df29884067906c714291f46416200f Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 30 Jun 2024 14:05:09 +0300 Subject: [PATCH 32/37] Add Message.paid_media and ExternalReplyInfo.paid_media. --- telegram-bot-api/Client.cpp | 79 +++++++++++++++++++++++++++++++++++-- telegram-bot-api/Client.h | 2 + 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 45d9eb9..04c6af8 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -1526,6 +1526,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) { @@ -2593,6 +2657,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); @@ -2842,6 +2911,12 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const { 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); @@ -3180,8 +3255,6 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const { object("boost_added", JsonChatBoostAdded(content)); break; } - case td_api::messagePaidMedia::ID: - break; default: UNREACHABLE(); } @@ -13632,8 +13705,6 @@ bool Client::need_skip_update_message(int64 chat_id, const object_ptr Date: Sun, 30 Jun 2024 14:16:49 +0300 Subject: [PATCH 33/37] Add sendPaidMedia. --- telegram-bot-api/Client.cpp | 43 +++++++++++++++++++++++++++++++++++++ telegram-bot-api/Client.h | 7 ++++++ 2 files changed, 50 insertions(+) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 04c6af8..f4258f6 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -223,6 +223,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); @@ -9550,6 +9551,37 @@ td::Result> Client::get_input_paid_me return r_input_paid_media.move_as_ok(); } +td::Result>> Client::get_paid_media(const Query *query, + td::Slice field_name) const { + TRY_RESULT(media, get_required_string_arg(query, field_name)); + + LOG(INFO) << "Parsing JSON object: " << media; + auto r_value = json_decode(media); + if (r_value.is_error()) { + LOG(INFO) << "Can't parse JSON object: " << r_value.error(); + return td::Status::Error(400, "Can't parse paid media JSON object"); + } + + return get_paid_media(query, r_value.move_as_ok()); +} + +td::Result>> Client::get_paid_media(const Query *query, + td::JsonValue &&value) const { + if (value.type() != td::JsonValue::Type::Array) { + return td::Status::Error(400, "Expected an Array of InputPaidMedia"); + } + + td::vector> paid_media; + for (auto &input_media : value.get_array()) { + auto r_paid_media = get_input_paid_media(query, std::move(input_media)); + if (r_paid_media.is_error()) { + return td::Status::Error(400, PSLICE() << "Can't parse InputPaidMedia: " << r_paid_media.error().message()); + } + paid_media.push_back(r_paid_media.move_as_ok()); + } + return std::move(paid_media); +} + td::Result> Client::get_input_message_invoice( const Query *query) const { TRY_RESULT(title, get_required_string_arg(query, "title")); @@ -10255,6 +10287,17 @@ td::Status Client::process_send_voice_query(PromisedQueryPtr &query) { return td::Status::OK(); } +td::Status Client::process_send_paid_media_query(PromisedQueryPtr &query) { + int32 star_count = get_integer_arg(query.get(), "star_count", 0, 0, 1000000000); + TRY_RESULT(paid_media, get_paid_media(query.get(), "media")); + TRY_RESULT(caption, get_caption(query.get())); + auto show_caption_above_media = to_bool(query->arg("show_caption_above_media")); + do_send_message(make_object(star_count, std::move(paid_media), std::move(caption), + show_caption_above_media), + std::move(query)); + return td::Status::OK(); +} + td::Status Client::process_send_game_query(PromisedQueryPtr &query) { TRY_RESULT(game_short_name, get_required_string_arg(query.get(), "game_short_name")); do_send_message(make_object(my_id_, game_short_name.str()), std::move(query)); diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index 030e77d..92396ba 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -575,6 +575,12 @@ class Client final : public WebhookActor::Callback { td::Result> get_input_paid_media(const Query *query, td::Slice field_name) const; + td::Result>> get_paid_media(const Query *query, + td::Slice field_name) const; + + td::Result>> get_paid_media(const Query *query, + td::JsonValue &&value) const; + td::Result> get_input_message_invoice(const Query *query) const; static object_ptr get_message_send_options(bool disable_notification, @@ -642,6 +648,7 @@ class Client final : public WebhookActor::Callback { td::Status process_send_video_query(PromisedQueryPtr &query); td::Status process_send_video_note_query(PromisedQueryPtr &query); td::Status process_send_voice_query(PromisedQueryPtr &query); + td::Status process_send_paid_media_query(PromisedQueryPtr &query); td::Status process_send_game_query(PromisedQueryPtr &query); td::Status process_send_invoice_query(PromisedQueryPtr &query); td::Status process_send_location_query(PromisedQueryPtr &query); From cfa7313aedc3ae8b9de530510705bdc85bd44372 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Jul 2024 01:32:50 +0300 Subject: [PATCH 34/37] Update version to 7.6. --- CMakeLists.txt | 2 +- telegram-bot-api/telegram-bot-api.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d38880..e16bbd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ if (POLICY CMP0065) cmake_policy(SET CMP0065 NEW) endif() -project(TelegramBotApi VERSION 7.5 LANGUAGES CXX) +project(TelegramBotApi VERSION 7.6 LANGUAGES CXX) if (POLICY CMP0069) option(TELEGRAM_BOT_API_ENABLE_LTO "Use \"ON\" to enable Link Time Optimization.") diff --git a/telegram-bot-api/telegram-bot-api.cpp b/telegram-bot-api/telegram-bot-api.cpp index a5af3f6..02fdb54 100644 --- a/telegram-bot-api/telegram-bot-api.cpp +++ b/telegram-bot-api/telegram-bot-api.cpp @@ -165,7 +165,7 @@ int main(int argc, char *argv[]) { auto start_time = td::Time::now(); auto shared_data = std::make_shared(); auto parameters = std::make_unique(); - parameters->version_ = "7.5"; + parameters->version_ = "7.6"; parameters->shared_data_ = shared_data; parameters->start_time_ = start_time; auto net_query_stats = td::create_net_query_stats(); From d4bb6785afe74c1a175a4ea66874bde19d6d5879 Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 7 Jul 2024 00:12:40 +0300 Subject: [PATCH 35/37] Update TDLib to 1.8.33. --- td | 2 +- telegram-bot-api/Client.cpp | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/td b/td index 35cfcf5..cb16492 160000 --- a/td +++ b/td @@ -1 +1 @@ -Subproject commit 35cfcf5d15981b99e8f31a2195641f035dd516c3 +Subproject commit cb164927417f22811c74cd8678ed4a5ab7cb80ba diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index f4258f6..542745e 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -1009,7 +1009,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(); @@ -3256,6 +3256,8 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const { object("boost_added", JsonChatBoostAdded(content)); break; } + case td_api::messagePaymentRefunded::ID: + break; default: UNREACHABLE(); } @@ -13101,7 +13103,7 @@ void Client::json_store_permissions(td::JsonObjectScope &object, const td_api::c object("can_send_voice_notes", td::JsonBool(permissions->can_send_voice_notes_)); object("can_send_polls", td::JsonBool(permissions->can_send_polls_)); object("can_send_other_messages", td::JsonBool(permissions->can_send_other_messages_)); - object("can_add_web_page_previews", td::JsonBool(permissions->can_add_web_page_previews_)); + object("can_add_web_page_previews", td::JsonBool(permissions->can_add_link_previews_)); object("can_change_info", td::JsonBool(permissions->can_change_info_)); object("can_invite_users", td::JsonBool(permissions->can_invite_users_)); object("can_pin_messages", td::JsonBool(permissions->can_pin_messages_)); @@ -13748,6 +13750,8 @@ bool Client::need_skip_update_message(int64 chat_id, const object_ptr Date: Sun, 7 Jul 2024 00:16:25 +0300 Subject: [PATCH 36/37] Add Message.refunded_payment. --- telegram-bot-api/Client.cpp | 34 ++++++++++++++++++++++++++++++---- telegram-bot-api/Client.h | 1 + 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 542745e..212524c 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -2068,7 +2068,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_); } @@ -2077,6 +2076,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) @@ -3256,8 +3280,11 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const { object("boost_added", JsonChatBoostAdded(content)); break; } - case td_api::messagePaymentRefunded::ID: + case td_api::messagePaymentRefunded::ID: { + auto content = static_cast(message_->content.get()); + object("refunded_payment", JsonRefundedPayment(content)); break; + } default: UNREACHABLE(); } @@ -13642,6 +13669,7 @@ bool Client::need_skip_update_message(int64 chat_id, const object_ptr Date: Sun, 7 Jul 2024 00:17:06 +0300 Subject: [PATCH 37/37] Update version to 7.7. --- CMakeLists.txt | 2 +- telegram-bot-api/telegram-bot-api.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e16bbd8..628b0bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ if (POLICY CMP0065) cmake_policy(SET CMP0065 NEW) endif() -project(TelegramBotApi VERSION 7.6 LANGUAGES CXX) +project(TelegramBotApi VERSION 7.7 LANGUAGES CXX) if (POLICY CMP0069) option(TELEGRAM_BOT_API_ENABLE_LTO "Use \"ON\" to enable Link Time Optimization.") diff --git a/telegram-bot-api/telegram-bot-api.cpp b/telegram-bot-api/telegram-bot-api.cpp index 02fdb54..82278b1 100644 --- a/telegram-bot-api/telegram-bot-api.cpp +++ b/telegram-bot-api/telegram-bot-api.cpp @@ -165,7 +165,7 @@ int main(int argc, char *argv[]) { auto start_time = td::Time::now(); auto shared_data = std::make_shared(); auto parameters = std::make_unique(); - parameters->version_ = "7.6"; + parameters->version_ = "7.7"; parameters->shared_data_ = shared_data; parameters->start_time_ = start_time; auto net_query_stats = td::create_net_query_stats();