Merge branch 'tdlib:master' into master

This commit is contained in:
omg-xtao 2024-07-03 17:33:02 +08:00 committed by GitHub
commit c163b83295
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 232 additions and 18 deletions

View File

@ -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.")

2
td

@ -1 +1 @@
Subproject commit 8f19c751dc296cedb9a921badb7a02a8c0cb1aeb
Subproject commit 35cfcf5d15981b99e8f31a2195641f035dd516c3

View File

@ -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);
@ -1092,6 +1093,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;
@ -1524,6 +1528,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<const td_api::paidMediaPreview *>(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<const td_api::paidMediaPhoto *>(paid_media_);
object("type", "photo");
object("photo", JsonPhoto(media->photo_.get(), client_));
break;
}
case td_api::paidMediaVideo::ID: {
auto media = static_cast<const td_api::paidMediaVideo *>(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) {
@ -2591,6 +2659,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<const td_api::messagePaidMedia *>(reply_->content_.get());
object("paid_media", JsonPaidMediaInfo(content, client_));
break;
}
case td_api::messagePhoto::ID: {
auto content = static_cast<const td_api::messagePhoto *>(reply_->content_.get());
CHECK(content->photo_ != nullptr);
@ -2840,6 +2913,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<const td_api::messagePaidMedia *>(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<const td_api::messagePhoto *>(message_->content.get());
CHECK(content->photo_ != nullptr);
@ -3975,12 +4054,23 @@ class Client::JsonStarTransactionPartner final : public td::Jsonable {
}
break;
}
case td_api::starTransactionPartnerUser::ID: {
auto source_user = static_cast<const td_api::starTransactionPartnerUser *>(source_);
case td_api::starTransactionPartnerBot::ID: {
auto source_user = static_cast<const td_api::starTransactionPartnerBot *>(source_);
object("type", "user");
object("user", JsonUser(source_user->user_id_, client_));
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:
object("type", "telegram_ads");
break;
case td_api::starTransactionPartnerTelegram::ID:
case td_api::starTransactionPartnerAppStore::ID:
case td_api::starTransactionPartnerGooglePlay::ID:
@ -4866,7 +4956,7 @@ class Client::TdOnGetChatMemberCallback final : public TdQueryCallback {
void on_result(object_ptr<td_api::Object> result) final {
if (result->get_id() == td_api::error::ID) {
return fail_query_with_error(std::move(query_), move_object_as<td_api::error>(result), "user not found");
return fail_query_with_error(std::move(query_), move_object_as<td_api::error>(result));
}
CHECK(result->get_id() == td_api::chatMember::ID);
@ -5198,7 +5288,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<td_api::error>(400, "Message to unpin not found"));
return fail_query_with_error(std::move(query_), 400, "Message to unpin not found");
}
}
@ -5253,8 +5343,7 @@ class Client::TdOnGetMyDefaultAdministratorRightsCallback final : public TdQuery
auto full_info = move_object_as<td_api::userFullInfo>(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<td_api::error>(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()
@ -6941,6 +7030,7 @@ void Client::on_update(object_ptr<td_api::Object> 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: {
@ -7917,7 +8007,7 @@ td::Result<td_api::object_ptr<td_api::InputMessageContent>> 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) {
@ -9320,10 +9410,10 @@ td::Result<td_api::object_ptr<td_api::InputMessageContent>> Client::get_input_me
td::vector<int32>(), duration, width, height, supports_streaming,
std::move(caption), show_caption_above_media, nullptr, has_spoiler);
}
if (for_album && type == "animation") {
if (type == "animation") {
if (for_album) {
return td::Status::Error(PSLICE() << "type \"" << type << "\" can't be used in sendMediaGroup");
}
if (type == "animation") {
TRY_RESULT(width, object.get_optional_int_field("width"));
TRY_RESULT(height, object.get_optional_int_field("height"));
TRY_RESULT(duration, object.get_optional_int_field("duration"));
@ -9401,6 +9491,98 @@ td::Result<td::vector<td_api::object_ptr<td_api::InputMessageContent>>> Client::
return std::move(contents);
}
td::Result<td_api::object_ptr<td_api::inputPaidMedia>> 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<td_api::inputThumbnail> 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<td_api::inputThumbnail>(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<td_api::InputPaidMediaType> media_type;
TRY_RESULT(type, object.get_required_string_field("type"));
if (type == "photo") {
media_type = make_object<td_api::inputPaidMediaTypePhoto>();
} 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<td_api::inputPaidMediaTypeVideo>(duration, supports_streaming);
} else {
return td::Status::Error(PSLICE() << "type \"" << type << "\" is unsupported");
}
return make_object<td_api::inputPaidMedia>(std::move(media_type), std::move(input_file), std::move(input_thumbnail),
td::vector<int32>(), width, height);
}
td::Result<td_api::object_ptr<td_api::inputPaidMedia>> 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<td::vector<td_api::object_ptr<td_api::inputPaidMedia>>> 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<td::vector<td_api::object_ptr<td_api::inputPaidMedia>>> Client::get_paid_media(const Query *query,
td::JsonValue &&value) const {
if (value.type() != td::JsonValue::Type::Array) {
return td::Status::Error(400, "Expected an Array of InputPaidMedia");
}
td::vector<object_ptr<td_api::inputPaidMedia>> paid_media;
for (auto &input_media : value.get_array()) {
auto r_paid_media = get_input_paid_media(query, std::move(input_media));
if (r_paid_media.is_error()) {
return td::Status::Error(400, PSLICE() << "Can't parse InputPaidMedia: " << r_paid_media.error().message());
}
paid_media.push_back(r_paid_media.move_as_ok());
}
return std::move(paid_media);
}
td::Result<td_api::object_ptr<td_api::inputMessageInvoice>> Client::get_input_message_invoice(
const Query *query) const {
TRY_RESULT(title, get_required_string_arg(query, "title"));
@ -9458,10 +9640,15 @@ td::Result<td_api::object_ptr<td_api::inputMessageInvoice>> 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<td_api::InputMessageContent> extended_media;
if (!query->arg("extended_media").empty()) {
TRY_RESULT_ASSIGN(extended_media, get_input_media(query, "extended_media"));
object_ptr<td_api::inputPaidMedia> 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<td_api::inputMessageInvoice>(
make_object<td_api::invoice>(currency.str(), std::move(prices), max_tip_amount, std::move(suggested_tip_amounts),
@ -9469,7 +9656,8 @@ td::Result<td_api::object_ptr<td_api::inputMessageInvoice>> 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<td::vector<td_api::object_ptr<td_api::formattedText>>> Client::get_poll_options(const Query *query) {
@ -10100,6 +10288,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<td_api::inputMessagePaidMedia>(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<td_api::inputMessageGame>(my_id_, game_short_name.str()), std::move(query));

View File

@ -121,6 +121,8 @@ class Client final : public WebhookActor::Callback {
class JsonVideo;
class JsonVideoNote;
class JsonVoiceNote;
class JsonPaidMedia;
class JsonPaidMediaInfo;
class JsonContact;
class JsonDice;
class JsonGame;
@ -568,6 +570,17 @@ class Client final : public WebhookActor::Callback {
td::Result<td::vector<object_ptr<td_api::InputMessageContent>>> get_input_message_contents(
const Query *query, td::JsonValue &&value) const;
td::Result<object_ptr<td_api::inputPaidMedia>> get_input_paid_media(const Query *query,
td::JsonValue &&input_media) const;
td::Result<object_ptr<td_api::inputPaidMedia>> get_input_paid_media(const Query *query, td::Slice field_name) const;
td::Result<td::vector<object_ptr<td_api::inputPaidMedia>>> get_paid_media(const Query *query,
td::Slice field_name) const;
td::Result<td::vector<object_ptr<td_api::inputPaidMedia>>> get_paid_media(const Query *query,
td::JsonValue &&value) const;
td::Result<object_ptr<td_api::inputMessageInvoice>> get_input_message_invoice(const Query *query) const;
static object_ptr<td_api::messageSendOptions> get_message_send_options(bool disable_notification,
@ -635,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);
@ -874,6 +888,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<td_api::supergroup> &&supergroup);
SupergroupInfo *add_supergroup_info(int64 supergroup_id);

View File

@ -165,7 +165,7 @@ int main(int argc, char *argv[]) {
auto start_time = td::Time::now();
auto shared_data = std::make_shared<SharedData>();
auto parameters = std::make_unique<ClientParameters>();
parameters->version_ = "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();