Merge version 6.1

This commit is contained in:
Giuseppe Marino 2022-06-30 15:51:45 +02:00
commit 58168e2df3
No known key found for this signature in database
GPG Key ID: C26F7A532ADEC25E
8 changed files with 206 additions and 109 deletions

View File

@ -6,7 +6,7 @@ if (POLICY CMP0065)
cmake_policy(SET CMP0065 NEW)
endif()
project(TelegramBotApi VERSION 6.0.1 LANGUAGES CXX)
project(TelegramBotApi VERSION 6.1 LANGUAGES CXX)
if (POLICY CMP0069)
option(TELEGRAM_BOT_API_ENABLE_LTO "Use \"ON\" to enable Link Time Optimization.")

2
td

@ -1 +1 @@
Subproject commit 782670c7dbf278e0ba07fc7e168f39ac154c7238
Subproject commit b393215d6671863b6baf2a589d343cff9474f6ba

View File

@ -245,6 +245,7 @@ bool Client::init_methods() {
methods_.emplace("editmessagecaption", &Client::process_edit_message_caption_query);
methods_.emplace("editmessagereplymarkup", &Client::process_edit_message_reply_markup_query);
methods_.emplace("deletemessage", &Client::process_delete_message_query);
methods_.emplace("createinvoicelink", &Client::process_create_invoice_link_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);
@ -336,16 +337,18 @@ bool Client::init_methods() {
class Client::JsonFile final : public Jsonable {
public:
JsonFile(const td_api::file *file, const Client *client) : file_(file), client_(client) {
JsonFile(const td_api::file *file, const Client *client, bool with_path)
: file_(file), client_(client), with_path_(with_path) {
}
void store(JsonValueScope *scope) const {
auto object = scope->enter_object();
client_->json_store_file(object, file_, true);
client_->json_store_file(object, file_, with_path_);
}
private:
const td_api::file *file_;
const Client *client_;
bool with_path_;
};
class Client::JsonDatedFile final : public Jsonable {
@ -403,6 +406,12 @@ class Client::JsonUser final : public Jsonable {
if (user_info != nullptr && !user_info->language_code.empty()) {
object("language_code", user_info->language_code);
}
if (user_info != nullptr && user_info->is_premium) {
object("is_premium", td::JsonTrue());
}
if (user_info != nullptr && user_info->added_to_attachment_menu) {
object("added_to_attachment_menu", td::JsonTrue());
}
// start custom properties impl
if (user_info != nullptr && user_info->is_verified) {
@ -803,6 +812,12 @@ class Client::JsonChat final : public Jsonable {
if (supergroup_info->is_supergroup) {
object("permissions", JsonChatPermissions(chat_info->permissions.get()));
}
if (supergroup_info->is_supergroup && supergroup_info->join_to_send_messages) {
object("join_to_send_messages", td::JsonTrue());
}
if (supergroup_info->is_supergroup && supergroup_info->join_by_request) {
object("join_by_request", td::JsonTrue());
}
if (supergroup_info->slow_mode_delay != 0) {
object("slow_mode_delay", supergroup_info->slow_mode_delay);
}
@ -1111,6 +1126,9 @@ class Client::JsonSticker final : public Jsonable {
object("mask_position", JsonMaskPosition(mask_position.get()));
}
}
if (sticker_->premium_animation_ != nullptr) {
object("premium_animation", JsonFile(sticker_->premium_animation_.get(), client_, false));
}
client_->json_store_thumbnail(object, sticker_->thumbnail_.get());
client_->json_store_file(object, sticker_->sticker_.get());
}
@ -1298,7 +1316,7 @@ class Client::JsonInvoice final : public Jsonable {
void store(JsonValueScope *scope) const {
auto object = scope->enter_object();
object("title", invoice_->title_);
object("description", invoice_->description_);
object("description", invoice_->description_->text_);
object("start_parameter", invoice_->start_parameter_);
object("currency", invoice_->currency_);
object("total_amount", invoice_->total_amount_);
@ -1982,10 +2000,7 @@ void Client::JsonMessage::store(JsonValueScope *scope) const {
}
case td_api::messageChatChangePhoto::ID: {
auto content = static_cast<const td_api::messageChatChangePhoto *>(message_->content.get());
if (content->photo_ == nullptr) {
LOG(ERROR) << "Got empty messageChatChangePhoto";
break;
}
CHECK(content->photo_ != nullptr);
object("new_chat_photo", JsonChatPhoto(content->photo_.get(), client_));
break;
}
@ -3906,6 +3921,25 @@ class Client::TdOnGetSupergroupMembersCountCallback final : public TdQueryCallba
PromisedQueryPtr query_;
};
class Client::TdOnCreateInvoiceLinkCallback final : public TdQueryCallback {
public:
explicit TdOnCreateInvoiceLinkCallback(PromisedQueryPtr query) : query_(std::move(query)) {
}
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));
}
CHECK(result->get_id() == td_api::httpUrl::ID);
auto http_url = move_object_as<td_api::httpUrl>(result);
return answer_query(td::VirtuallyJsonableString(http_url->url_), std::move(query_));
}
private:
PromisedQueryPtr query_;
};
class Client::TdOnReplacePrimaryChatInviteLinkCallback final : public TdQueryCallback {
public:
explicit TdOnReplacePrimaryChatInviteLinkCallback(PromisedQueryPtr query) : query_(std::move(query)) {
@ -4006,7 +4040,7 @@ class Client::TdOnReturnFileCallback final : public TdQueryCallback {
CHECK(result->get_id() == td_api::file::ID);
auto file = move_object_as<td_api::file>(result);
answer_query(JsonFile(file.get(), client_), std::move(query_));
answer_query(JsonFile(file.get(), client_, false), std::move(query_));
}
private:
@ -5270,7 +5304,9 @@ void Client::on_update(object_ptr<td_api::Object> result) {
auto user_id = update->user_id_;
auto full_info = update->user_full_info_.get();
set_user_photo(user_id, std::move(full_info->photo_));
set_user_bio(user_id, std::move(full_info->bio_));
if (full_info->bio_ != nullptr) {
set_user_bio(user_id, std::move(full_info->bio_->text_));
}
set_user_has_private_forwards(user_id, full_info->has_private_forwards_);
break;
}
@ -6152,8 +6188,9 @@ td::Result<td_api::object_ptr<td_api::InputMessageContent>> Client::get_input_me
return make_object<td_api::inputMessageInvoice>(
make_object<td_api::invoice>(currency, std::move(prices), max_tip_amount, std::move(suggested_tip_amounts),
false, need_name, need_phone_number, need_email_address, need_shipping_address,
send_phone_number_to_provider, send_email_address_to_provider, is_flexible),
td::string(), false, need_name, need_phone_number, 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());
}
@ -7284,6 +7321,71 @@ td::Result<td::vector<td_api::object_ptr<td_api::InputMessageContent>>> Client::
return std::move(contents);
}
td::Result<td_api::object_ptr<td_api::inputMessageInvoice>> Client::get_input_message_invoice(const Query *query) {
TRY_RESULT(title, get_required_string_arg(query, "title"));
TRY_RESULT(description, get_required_string_arg(query, "description"));
TRY_RESULT(payload, get_required_string_arg(query, "payload"));
if (!td::check_utf8(payload.str())) {
return Status::Error(400, "The payload must be encoded in UTF-8");
}
TRY_RESULT(provider_token, get_required_string_arg(query, "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"));
TRY_RESULT(labeled_price_parts, get_required_string_arg(query, "prices"));
auto r_labeled_price_parts_value = json_decode(labeled_price_parts);
if (r_labeled_price_parts_value.is_error()) {
return Status::Error(400, "Can't parse prices JSON object");
}
TRY_RESULT(prices, get_labeled_price_parts(r_labeled_price_parts_value.ok_ref()));
int64 max_tip_amount = 0;
td::vector<int64> suggested_tip_amounts;
{
auto max_tip_amount_str = query->arg("max_tip_amount");
if (!max_tip_amount_str.empty()) {
auto r_max_tip_amount = td::to_integer_safe<int64>(max_tip_amount_str);
if (r_max_tip_amount.is_error()) {
return Status::Error(400, "Can't parse \"max_tip_amount\" as Number");
}
max_tip_amount = r_max_tip_amount.ok();
}
auto suggested_tip_amounts_str = query->arg("suggested_tip_amounts");
if (!suggested_tip_amounts_str.empty()) {
auto r_suggested_tip_amounts_value = json_decode(suggested_tip_amounts_str);
if (r_suggested_tip_amounts_value.is_error()) {
return Status::Error(400, "Can't parse suggested_tip_amounts JSON object");
}
TRY_RESULT_ASSIGN(suggested_tip_amounts, get_suggested_tip_amounts(r_suggested_tip_amounts_value.ok_ref()));
}
}
auto photo_url = query->arg("photo_url");
int32 photo_size = get_integer_arg(query, "photo_size", 0, 0, 1000000000);
int32 photo_width = get_integer_arg(query, "photo_width", 0, 0, MAX_LENGTH);
int32 photo_height = get_integer_arg(query, "photo_height", 0, 0, MAX_LENGTH);
auto need_name = to_bool(query->arg("need_name"));
auto need_phone_number = to_bool(query->arg("need_phone_number"));
auto need_email_address = to_bool(query->arg("need_email"));
auto need_shipping_address = to_bool(query->arg("need_shipping_address"));
auto send_phone_number_to_provider = to_bool(query->arg("send_phone_number_to_provider"));
auto send_email_address_to_provider = to_bool(query->arg("send_email_to_provider"));
auto is_flexible = to_bool(query->arg("is_flexible"));
return make_object<td_api::inputMessageInvoice>(
make_object<td_api::invoice>(currency.str(), std::move(prices), max_tip_amount, std::move(suggested_tip_amounts),
td::string(), false, need_name, need_phone_number, need_email_address,
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());
}
td::Result<td::vector<td::string>> Client::get_poll_options(const Query *query) {
auto input_options = query->arg("options");
LOG(INFO) << "Parsing JSON object: " << input_options;
@ -7555,8 +7657,15 @@ void Client::on_message_send_failed(int64 chat_id, int64 old_message_id, int64 n
auto query_id = extract_yet_unsent_message_query_id(chat_id, old_message_id, nullptr);
auto &query = *pending_send_message_queries_[query_id];
if (query.is_multisend) {
if (query.error == nullptr) {
query.error = std::move(error);
if (query.error == nullptr || query.error->message_ == "Group send failed") {
if (error->code_ == 429 || error->message_ == "Group send failed") {
query.error = std::move(error);
} else {
auto pos = (query.total_message_count - query.awaited_message_count + 1);
query.error = make_object<td_api::error>(error->code_, PSTRING() << "Failed to send message #" << pos
<< " with the error message \""
<< error->message_ << '"');
}
}
query.awaited_message_count--;
@ -7870,69 +7979,8 @@ td::Status Client::process_send_game_query(PromisedQueryPtr &query) {
td::Status Client::process_send_invoice_query(PromisedQueryPtr &query) {
CHECK_IS_BOT();
TRY_RESULT(title, get_required_string_arg(query.get(), "title"));
TRY_RESULT(description, get_required_string_arg(query.get(), "description"));
TRY_RESULT(payload, get_required_string_arg(query.get(), "payload"));
if (!td::check_utf8(payload.str())) {
return Status::Error(400, "The payload must be encoded in UTF-8");
}
TRY_RESULT(provider_token, get_required_string_arg(query.get(), "provider_token"));
auto provider_data = query->arg("provider_data");
auto start_parameter = query->arg("start_parameter");
TRY_RESULT(currency, get_required_string_arg(query.get(), "currency"));
TRY_RESULT(labeled_price_parts, get_required_string_arg(query.get(), "prices"));
auto r_labeled_price_parts_value = json_decode(labeled_price_parts);
if (r_labeled_price_parts_value.is_error()) {
return Status::Error(400, "Can't parse prices JSON object");
}
TRY_RESULT(prices, get_labeled_price_parts(r_labeled_price_parts_value.ok_ref()));
int64 max_tip_amount = 0;
td::vector<int64> suggested_tip_amounts;
{
auto max_tip_amount_str = query->arg("max_tip_amount");
if (!max_tip_amount_str.empty()) {
auto r_max_tip_amount = td::to_integer_safe<int64>(max_tip_amount_str);
if (r_max_tip_amount.is_error()) {
return Status::Error(400, "Can't parse \"max_tip_amount\" as Number");
}
max_tip_amount = r_max_tip_amount.ok();
}
auto suggested_tip_amounts_str = query->arg("suggested_tip_amounts");
if (!suggested_tip_amounts_str.empty()) {
auto r_suggested_tip_amounts_value = json_decode(suggested_tip_amounts_str);
if (r_suggested_tip_amounts_value.is_error()) {
return Status::Error(400, "Can't parse suggested_tip_amounts JSON object");
}
TRY_RESULT_ASSIGN(suggested_tip_amounts, get_suggested_tip_amounts(r_suggested_tip_amounts_value.ok_ref()));
}
}
auto photo_url = query->arg("photo_url");
int32 photo_size = get_integer_arg(query.get(), "photo_size", 0, 0, 1000000000);
int32 photo_width = get_integer_arg(query.get(), "photo_width", 0, 0, MAX_LENGTH);
int32 photo_height = get_integer_arg(query.get(), "photo_height", 0, 0, MAX_LENGTH);
auto need_name = to_bool(query->arg("need_name"));
auto need_phone_number = to_bool(query->arg("need_phone_number"));
auto need_email_address = to_bool(query->arg("need_email"));
auto need_shipping_address = to_bool(query->arg("need_shipping_address"));
auto send_phone_number_to_provider = to_bool(query->arg("send_phone_number_to_provider"));
auto send_email_address_to_provider = to_bool(query->arg("send_email_to_provider"));
auto is_flexible = to_bool(query->arg("is_flexible"));
do_send_message(make_object<td_api::inputMessageInvoice>(
make_object<td_api::invoice>(
currency.str(), std::move(prices), max_tip_amount, std::move(suggested_tip_amounts), false,
need_name, need_phone_number, need_email_address, 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(query));
TRY_RESULT(input_message_invoice, get_input_message_invoice(query.get()));
do_send_message(std::move(input_message_invoice), std::move(query));
return Status::OK();
}
@ -8324,6 +8372,13 @@ td::Status Client::process_delete_message_query(PromisedQueryPtr &query) {
return Status::OK();
}
td::Status Client::process_create_invoice_link_query(PromisedQueryPtr &query) {
TRY_RESULT(input_message_invoice, get_input_message_invoice(query.get()));
send_request(make_object<td_api::createInvoiceLink>(std::move(input_message_invoice)),
td::make_unique<TdOnCreateInvoiceLinkCallback>(std::move(query)));
return Status::OK();
}
td::Status Client::process_set_game_score_query(PromisedQueryPtr &query) {
CHECK_IS_BOT();
auto chat_id = query->arg("chat_id");
@ -9212,16 +9267,20 @@ td::Status Client::process_set_webhook_query(PromisedQueryPtr &query) {
// do not send warning just after webhook was deleted or set
next_bot_updates_warning_time_ = td::max(next_bot_updates_warning_time_, now + BOT_UPDATES_WARNING_DELAY);
bool new_has_certificate = new_url.empty() ? false
: (get_webhook_certificate(query.get()) != nullptr ||
(query->is_internal() && query->arg("certificate") == "previous"));
int32 new_max_connections = new_url.empty() ? 0 : get_webhook_max_connections(query.get());
Slice new_ip_address = new_url.empty() ? Slice() : query->arg("ip_address");
bool new_fix_ip_address = new_url.empty() ? false : get_webhook_fix_ip_address(query.get());
Slice new_secret_token = new_url.empty() ? Slice() : query->arg("secret_token");
bool drop_pending_updates = to_bool(query->arg("drop_pending_updates"));
if (webhook_set_query_) {
// already updating webhook. Cancel previous request
fail_query_conflict("Conflict: terminated by other setWebhook", std::move(webhook_set_query_));
} else if (webhook_url_ == new_url && !has_webhook_certificate_ && query->file("certificate") == nullptr &&
query->arg("certificate").empty() && new_max_connections == webhook_max_connections_ &&
new_fix_ip_address == webhook_fix_ip_address_ &&
} else if (webhook_url_ == new_url && !has_webhook_certificate_ && !new_has_certificate &&
new_max_connections == webhook_max_connections_ && new_fix_ip_address == webhook_fix_ip_address_ &&
new_secret_token == webhook_secret_token_ &&
(!new_fix_ip_address || new_ip_address == webhook_ip_address_) && !drop_pending_updates) {
if (update_allowed_update_types(query.get())) {
save_webhook();
@ -9790,7 +9849,7 @@ void Client::on_file_download(int32 file_id, td::Result<object_ptr<td_api::file>
const auto &error = r_file.error();
fail_query_with_error(std::move(query), error.code(), error.public_message());
} else {
answer_query(JsonFile(r_file.ok().get(), this), std::move(query));
answer_query(JsonFile(r_file.ok().get(), this, true), std::move(query));
}
}
}
@ -9822,6 +9881,9 @@ void Client::save_webhook() const {
if (webhook_fix_ip_address_) {
value += "#fix_ip/";
}
if (!webhook_secret_token_.empty()) {
value += PSTRING() << "#secret" << webhook_secret_token_ << '/';
}
if (allowed_update_types_ != DEFAULT_ALLOWED_UPDATE_TYPES) {
value += PSTRING() << "#allow" << allowed_update_types_ << '/';
}
@ -9865,6 +9927,7 @@ void Client::webhook_closed(Status status) {
webhook_max_connections_ = 0;
webhook_ip_address_ = td::string();
webhook_fix_ip_address_ = false;
webhook_secret_token_ = td::string();
webhook_set_time_ = td::Time::now();
last_webhook_error_date_ = 0;
last_webhook_error_ = Status::OK();
@ -9887,6 +9950,18 @@ td::string Client::get_webhook_certificate_path() const {
return dir_ + "cert.pem";
}
const td::HttpFile *Client::get_webhook_certificate(const Query *query) const {
auto file = query->file("certificate");
if (file == nullptr) {
auto attach_name = query->arg("certificate");
Slice attach_protocol{"attach://"};
if (td::begins_with(attach_name, attach_protocol)) {
file = query->file(attach_name.substr(attach_protocol.size()));
}
}
return file;
}
td::int32 Client::get_webhook_max_connections(const Query *query) const {
auto default_value = parameters_->default_max_webhook_connections_;
auto max_value = parameters_->local_mode_ ? 100000 : 100;
@ -9914,8 +9989,16 @@ void Client::do_set_webhook(PromisedQueryPtr query, bool was_deleted) {
if (url.is_error()) {
return fail_query(400, "Bad Request: invalid webhook URL specified", std::move(query));
}
auto *cert_file_ptr = query->file("certificate");
auto secret_token = query->arg("secret_token");
if (secret_token.size() > 256) {
return fail_query(400, "Bad Request: secret token is too long", std::move(query));
}
if (!td::is_base64url_characters(secret_token)) {
return fail_query(400, "Bad Request: secret token contains unallowed characters", std::move(query));
}
has_webhook_certificate_ = false;
auto *cert_file_ptr = get_webhook_certificate(query.get());
if (cert_file_ptr != nullptr) {
auto size = cert_file_ptr->size;
if (size > MAX_CERTIFICATE_FILE_SIZE) {
@ -9929,14 +10012,14 @@ void Client::do_set_webhook(PromisedQueryPtr query, bool was_deleted) {
return fail_query(500, "Internal Server Error: failed to save certificate", std::move(query));
}
has_webhook_certificate_ = true;
}
if (query->is_internal() && query->arg("certificate") == "previous") {
} else if (query->is_internal() && query->arg("certificate") == "previous") {
has_webhook_certificate_ = true;
}
webhook_url_ = new_url.str();
webhook_set_time_ = td::Time::now();
webhook_max_connections_ = get_webhook_max_connections(query.get());
webhook_secret_token_ = secret_token.str();
webhook_ip_address_ = query->arg("ip_address").str();
webhook_fix_ip_address_ = get_webhook_fix_ip_address(query.get());
last_webhook_error_date_ = 0;
@ -9949,7 +10032,7 @@ void Client::do_set_webhook(PromisedQueryPtr query, bool was_deleted) {
webhook_id_ = td::create_actor<WebhookActor>(
webhook_actor_name, actor_shared(this, webhook_generation_), tqueue_id_, url.move_as_ok(),
has_webhook_certificate_ ? get_webhook_certificate_path() : "", webhook_max_connections_, query->is_internal(),
webhook_ip_address_, webhook_fix_ip_address_, parameters_);
webhook_ip_address_, webhook_fix_ip_address_, webhook_secret_token_, parameters_);
// wait for webhook verified or webhook callback
webhook_query_type_ = WebhookQueryType::Verify;
webhook_set_query_ = std::move(query);
@ -10031,7 +10114,10 @@ void Client::on_sent_message(object_ptr<td_api::message> &&message, int64 query_
auto emplace_result = yet_unsent_messages_.emplace(yet_unsent_message_id, yet_unsent_message);
CHECK(emplace_result.second);
yet_unsent_message_count_[chat_id]++;
pending_send_message_queries_[query_id]->awaited_message_count++;
auto &query = *pending_send_message_queries_[query_id];
query.awaited_message_count++;
query.total_message_count++;
}
void Client::abort_long_poll(bool from_set_webhook) {
@ -10210,6 +10296,8 @@ void Client::add_user(UserInfo *user_info, object_ptr<td_api::user> &&user) {
//end custom properties
user_info->have_access = user->have_access_;
user_info->is_premium = user->is_premium_;
user_info->added_to_attachment_menu = user->added_to_attachment_menu_;
switch (user->type_->get_id()) {
case td_api::userTypeRegular::ID:
@ -10312,6 +10400,8 @@ void Client::add_supergroup(SupergroupInfo *supergroup_info, object_ptr<td_api::
supergroup_info->status = std::move(supergroup->status_);
supergroup_info->is_supergroup = !supergroup->is_channel_;
supergroup_info->has_location = supergroup->has_location_;
supergroup_info->join_to_send_messages = supergroup->join_to_send_messages_;
supergroup_info->join_by_request = supergroup->join_by_request_;
// start custom properties
supergroup_info->is_verified = supergroup->is_verified_;
@ -10968,14 +11058,6 @@ bool Client::need_skip_update_message(int64 chat_id, const object_ptr<td_api::me
}
switch (message->content_->get_id()) {
case td_api::messagePhoto::ID: {
auto content = static_cast<const td_api::messagePhoto *>(message->content_.get());
if (content->photo_ == nullptr) {
LOG(ERROR) << "Got empty messagePhoto";
return true;
}
break;
}
case td_api::messageChatAddMembers::ID: {
auto content = static_cast<const td_api::messageChatAddMembers *>(message->content_.get());
if (content->member_user_ids_.empty()) {
@ -10984,14 +11066,6 @@ bool Client::need_skip_update_message(int64 chat_id, const object_ptr<td_api::me
}
break;
}
case td_api::messageChatChangePhoto::ID: {
auto content = static_cast<const td_api::messageChatChangePhoto *>(message->content_.get());
if (content->photo_ == nullptr) {
LOG(ERROR) << "Got empty messageChatChangePhoto";
return true;
}
break;
}
case td_api::messageSupergroupChatCreate::ID: {
if (chat->type != ChatInfo::Type::Supergroup) {
LOG(ERROR) << "Receive messageSupergroupChatCreate in the non-supergroup chat " << chat_id;
@ -11007,7 +11081,7 @@ bool Client::need_skip_update_message(int64 chat_id, const object_ptr<td_api::me
}
const MessageInfo *pinned_message = get_message(chat_id, pinned_message_id);
if (pinned_message == nullptr) {
LOG(WARNING) << "Pinned unknown, inaccessible or deleted message " << pinned_message_id;
LOG(WARNING) << "Pinned unknown, inaccessible or deleted message " << pinned_message_id << " in " << chat_id;
return true;
}
break;

View File

@ -13,6 +13,8 @@
#include "td/telegram/ClientActor.h"
#include "td/telegram/td_api.h"
#include "td/net/HttpFile.h"
#include "td/actor/actor.h"
#include "td/actor/PromiseFuture.h"
#include "td/actor/SignalSlot.h"
@ -203,6 +205,7 @@ class Client final : public WebhookActor::Callback {
class TdOnGetGroupMembersCallback;
class TdOnGetSupergroupMembersCallback;
class TdOnGetSupergroupMembersCountCallback;
class TdOnCreateInvoiceLinkCallback;
class TdOnReplacePrimaryChatInviteLinkCallback;
class TdOnGetChatInviteLinkCallback;
class TdOnGetGameHighScoresCallback;
@ -475,6 +478,8 @@ 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;
static td::Result<object_ptr<td_api::inputMessageInvoice>> get_input_message_invoice(const Query *query);
static object_ptr<td_api::messageSendOptions> get_message_send_options(bool disable_notification,
bool protect_content,
object_ptr<td_api::MessageSchedulingState> &&scheduling_state);
@ -556,6 +561,7 @@ class Client final : public WebhookActor::Callback {
Status process_edit_message_caption_query(PromisedQueryPtr &query);
Status process_edit_message_reply_markup_query(PromisedQueryPtr &query);
Status process_delete_message_query(PromisedQueryPtr &query);
Status process_create_invoice_link_query(PromisedQueryPtr &query);
Status process_set_game_score_query(PromisedQueryPtr &query);
Status process_get_game_high_scores_query(PromisedQueryPtr &query);
Status process_answer_web_app_query_query(PromisedQueryPtr &query);
@ -650,6 +656,7 @@ class Client final : public WebhookActor::Callback {
void webhook_error(Status status) final;
void webhook_closed(Status status) final;
void hangup_shared() final;
const td::HttpFile *get_webhook_certificate(const Query *query) const;
int32 get_webhook_max_connections(const Query *query) const;
static bool get_webhook_fix_ip_address(const Query *query);
void do_set_webhook(PromisedQueryPtr query, bool was_deleted);
@ -719,6 +726,8 @@ class Client final : public WebhookActor::Callback {
bool can_read_all_group_messages = false;
bool is_inline_bot = false;
bool has_private_forwards = false;
bool is_premium = false;
bool added_to_attachment_menu = false;
};
static void add_user(UserInfo *user_info, object_ptr<td_api::user> &&user);
void set_user_photo(int64 user_id, object_ptr<td_api::chatPhoto> &&photo);
@ -759,6 +768,8 @@ class Client final : public WebhookActor::Callback {
bool is_supergroup = false;
bool can_set_sticker_set = false;
bool has_location = false;
bool join_to_send_messages = false;
bool join_by_request = false;
// start custom properties
bool is_verified = false;
@ -1054,6 +1065,7 @@ class Client final : public WebhookActor::Callback {
struct PendingSendMessageQuery {
PromisedQueryPtr query;
bool is_multisend = false;
int32 total_message_count = 0;
int32 awaited_message_count = 0;
td::vector<td::string> messages;
object_ptr<td_api::error> error;
@ -1131,6 +1143,7 @@ class Client final : public WebhookActor::Callback {
int32 webhook_max_connections_ = 0;
td::string webhook_ip_address_;
bool webhook_fix_ip_address_ = false;
td::string webhook_secret_token_;
int32 last_webhook_error_date_ = 0;
Status last_webhook_error_;
double next_allowed_set_webhook_time_ = 0;

View File

@ -528,6 +528,11 @@ PromisedQueryPtr ClientManager::get_webhook_restore_query(td::Slice token, bool
parser.skip('/');
}
if (parser.try_skip("#secret")) {
args.emplace_back(add_string("secret_token"), add_string(parser.read_till('/')));
parser.skip('/');
}
if (parser.try_skip("#allow")) {
args.emplace_back(add_string("allowed_updates"), add_string(parser.read_till('/')));
parser.skip('/');

View File

@ -42,7 +42,7 @@ std::atomic<td::uint64> WebhookActor::total_connections_count_{0};
WebhookActor::WebhookActor(td::ActorShared<Callback> callback, td::int64 tqueue_id, td::HttpUrl url,
td::string cert_path, td::int32 max_connections, bool from_db_flag,
td::string cached_ip_address, bool fix_ip_address,
td::string cached_ip_address, bool fix_ip_address, td::string secret_token,
std::shared_ptr<const ClientParameters> parameters)
: callback_(std::move(callback))
, tqueue_id_(tqueue_id)
@ -51,7 +51,8 @@ WebhookActor::WebhookActor(td::ActorShared<Callback> callback, td::int64 tqueue_
, parameters_(std::move(parameters))
, fix_ip_address_(fix_ip_address)
, from_db_flag_(from_db_flag)
, max_connections_(max_connections) {
, max_connections_(max_connections)
, secret_token_(std::move(secret_token)) {
CHECK(max_connections_ > 0);
if (!cached_ip_address.empty()) {
@ -539,6 +540,9 @@ td::Status WebhookActor::send_update() {
if (!url_.userinfo_.empty()) {
hc.add_header("Authorization", PSLICE() << "Basic " << td::base64_encode(url_.userinfo_));
}
if (!secret_token_.empty()) {
hc.add_header("X-Telegram-Bot-Api-Secret-Token", secret_token_);
}
hc.set_content_type("application/json");
hc.set_content_size(body.size());
hc.set_keep_alive();

View File

@ -54,7 +54,7 @@ class WebhookActor final : public td::HttpOutboundConnection::Callback {
WebhookActor(td::ActorShared<Callback> callback, td::int64 tqueue_id, td::HttpUrl url, td::string cert_path,
td::int32 max_connections, bool from_db_flag, td::string cached_ip_address, bool fix_ip_address,
std::shared_ptr<const ClientParameters> parameters);
td::string secret_token, std::shared_ptr<const ClientParameters> parameters);
void update();
@ -163,6 +163,7 @@ class WebhookActor final : public td::HttpOutboundConnection::Callback {
td::vector<td::BufferedFd<td::SocketFd>> ready_sockets_;
td::int32 max_connections_ = 0;
td::string secret_token_;
td::Container<Connection> connections_;
td::ListNode ready_connections_;
td::FloodControlFast active_new_connection_flood_;

View File

@ -200,7 +200,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_ = "6.0.1";
parameters->version_ = "6.1";
parameters->shared_data_ = shared_data;
parameters->start_time_ = start_time;
auto net_query_stats = td::create_net_query_stats();