From e184e6c117ef18bb7114429cce11afc87914c362 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 8 Dec 2020 03:29:19 +0300 Subject: [PATCH 01/39] Update TDLib. Support can_manage_voice_chats administrator right. --- td | 2 +- telegram-bot-api/Client.cpp | 22 +++++++++++++++++++--- telegram-bot-api/telegram-bot-api.cpp | 1 + 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/td b/td index eb80924..db38757 160000 --- a/td +++ b/td @@ -1 +1 @@ -Subproject commit eb80924dad30af4e6d8385d058bb7e847174df5e +Subproject commit db3875710bcf9f29baa360d91d7b11b0199229a9 diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index e45d86b..cc46212 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -13,6 +13,7 @@ #include "td/db/TQueue.h" +#include "td/utils/algorithm.h" #include "td/utils/base64.h" #include "td/utils/filesystem.h" #include "td/utils/HttpUrl.h" @@ -1746,6 +1747,12 @@ void Client::JsonMessage::store(JsonValueScope *scope) const { object("proximity_alert_triggered", JsonProximityAlertTriggered(content, client_)); break; } + case td_api::messageVoiceChatStarted::ID: + break; + case td_api::messageVoiceChatEnded::ID: + break; + case td_api::messageInviteVoiceChatParticipants::ID: + break; default: UNREACHABLE(); } @@ -2056,6 +2063,7 @@ class Client::JsonChatMember : public Jsonable { object("can_pin_messages", td::JsonBool(administrator->can_pin_messages_)); } object("can_promote_members", td::JsonBool(administrator->can_promote_members_)); + object("can_manage_voice_chats", td::JsonBool(administrator->can_manage_voice_chats_)); if (!administrator->custom_title_.empty()) { object("custom_title", administrator->custom_title_); } @@ -5021,7 +5029,7 @@ td::Result> Client::get_inlin TRY_RESULT(sticker_file_id, get_json_object_string_field(object, "sticker_file_id", false)); if (input_message_content == nullptr) { - input_message_content = make_object(nullptr, nullptr, 0, 0); + input_message_content = make_object(nullptr, nullptr, 0, 0, td::string()); } return make_object(id, "", sticker_file_id, 0, 0, std::move(reply_markup), std::move(input_message_content)); @@ -6021,7 +6029,8 @@ td::Status Client::process_send_sticker_query(PromisedQueryPtr &query) { if (sticker == nullptr) { return Status::Error(400, "There is no sticker in the request"); } - do_send_message(make_object(std::move(sticker), nullptr, 0, 0), std::move(query)); + do_send_message(make_object(std::move(sticker), nullptr, 0, 0, td::string()), + std::move(query)); return Status::OK(); } @@ -6897,10 +6906,11 @@ td::Status Client::process_promote_chat_member_query(PromisedQueryPtr &query) { auto can_restrict_members = to_bool(query->arg("can_restrict_members")); auto can_pin_messages = to_bool(query->arg("can_pin_messages")); auto can_promote_members = to_bool(query->arg("can_promote_members")); + auto can_manage_voice_chats = to_bool(query->arg("can_manage_voice_chats")); auto is_anonymous = to_bool(query->arg("is_anonymous")); auto status = make_object( td::string(), true, can_change_info, can_post_messages, can_edit_messages, can_delete_messages, can_invite_users, - can_restrict_members, can_pin_messages, can_promote_members, is_anonymous); + can_restrict_members, can_pin_messages, can_promote_members, can_manage_voice_chats, is_anonymous); check_chat(chat_id, AccessRights::Write, std::move(query), [this, user_id, status = std::move(status)](int64 chat_id, PromisedQueryPtr query) mutable { auto chat_info = get_chat(chat_id); @@ -8391,6 +8401,12 @@ bool Client::need_skip_update_message(int64 chat_id, const object_ptr Date: Tue, 8 Dec 2020 03:57:25 +0300 Subject: [PATCH 02/39] Add the field InlineQuery.chat_type, which can be sent by the server in the distant future. --- telegram-bot-api/Client.cpp | 58 ++++++++++++++++++++++++++++--------- telegram-bot-api/Client.h | 2 +- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index cc46212..dd507a2 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -1798,10 +1798,12 @@ class Client::JsonMessageId : public Jsonable { class Client::JsonInlineQuery : public Jsonable { public: JsonInlineQuery(int64 inline_query_id, int32 sender_user_id, const td_api::location *user_location, - const td::string &query, const td::string &offset, const Client *client) + const td_api::ChatType *chat_type, const td::string &query, const td::string &offset, + const Client *client) : inline_query_id_(inline_query_id) , sender_user_id_(sender_user_id) , user_location_(user_location) + , chat_type_(chat_type) , query_(query) , offset_(offset) , client_(client) { @@ -1814,6 +1816,35 @@ class Client::JsonInlineQuery : public Jsonable { if (user_location_ != nullptr) { object("location", JsonLocation(user_location_)); } + if (chat_type_ != nullptr) { + auto chat_type = [&] { + switch (chat_type_->get_id()) { + case td_api::chatTypePrivate::ID: { + auto type = static_cast(chat_type_); + if (type->user_id_ == sender_user_id_) { + return "sender"; + } + return "private"; + } + case td_api::chatTypeBasicGroup::ID: + return "group"; + case td_api::chatTypeSupergroup::ID: { + auto type = static_cast(chat_type_); + if (type->is_channel_) { + return "channel"; + } else { + return "supergroup"; + } + } + case td_api::chatTypeSecret::ID: + return ""; + default: + UNREACHABLE(); + return ""; + } + }(); + object("chat_type", chat_type); + } object("query", query_); object("offset", offset_); } @@ -1822,6 +1853,7 @@ class Client::JsonInlineQuery : public Jsonable { int64 inline_query_id_; int32 sender_user_id_; const td_api::location *user_location_; + const td_api::ChatType *chat_type_; const td::string &query_; const td::string &offset_; const Client *client_; @@ -3952,33 +3984,32 @@ void Client::on_update(object_ptr result) { bool need_warning = false; switch (chat->type_->get_id()) { case td_api::chatTypePrivate::ID: { - auto info = move_object_as(chat->type_); + auto type = move_object_as(chat->type_); chat_info->type = ChatInfo::Type::Private; - auto user_id = info->user_id_; + auto user_id = type->user_id_; chat_info->user_id = user_id; need_warning = get_user_info(user_id) == nullptr; break; } case td_api::chatTypeBasicGroup::ID: { - auto info = move_object_as(chat->type_); + auto type = move_object_as(chat->type_); chat_info->type = ChatInfo::Type::Group; - auto group_id = info->basic_group_id_; + auto group_id = type->basic_group_id_; chat_info->group_id = group_id; need_warning = get_group_info(group_id) == nullptr; break; } case td_api::chatTypeSupergroup::ID: { - auto info = move_object_as(chat->type_); + auto type = move_object_as(chat->type_); chat_info->type = ChatInfo::Type::Supergroup; - auto supergroup_id = info->supergroup_id_; + auto supergroup_id = type->supergroup_id_; chat_info->supergroup_id = supergroup_id; need_warning = get_supergroup_info(supergroup_id) == nullptr; break; } - case td_api::chatTypeSecret::ID: { + case td_api::chatTypeSecret::ID: // unsupported break; - } default: UNREACHABLE(); } @@ -4108,8 +4139,8 @@ void Client::on_update(object_ptr result) { break; case td_api::updateNewInlineQuery::ID: { auto update = move_object_as(result); - add_new_inline_query(update->id_, update->sender_user_id_, std::move(update->user_location_), update->query_, - update->offset_); + add_new_inline_query(update->id_, update->sender_user_id_, std::move(update->user_location_), + std::move(update->chat_type_), update->query_, update->offset_); break; } case td_api::updateNewChosenInlineResult::ID: { @@ -8149,9 +8180,10 @@ void Client::add_update_poll_answer(object_ptr &&updat } void Client::add_new_inline_query(int64 inline_query_id, int32 sender_user_id, object_ptr location, - const td::string &query, const td::string &offset) { + object_ptr chat_type, const td::string &query, + const td::string &offset) { add_update(UpdateType::InlineQuery, - JsonInlineQuery(inline_query_id, sender_user_id, location.get(), query, offset, this), 30, + JsonInlineQuery(inline_query_id, sender_user_id, location.get(), chat_type.get(), query, offset, this), 30, sender_user_id + (static_cast(1) << 33)); } diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index 9273b96..7ed3737 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -719,7 +719,7 @@ class Client : public WebhookActor::Callback { void add_update_poll_answer(object_ptr &&update); void add_new_inline_query(int64 inline_query_id, int32 sender_user_id, object_ptr location, - const td::string &query, const td::string &offset); + object_ptr chat_type, const td::string &query, const td::string &offset); void add_new_chosen_inline_result(int32 sender_user_id, object_ptr location, const td::string &query, const td::string &result_id, From 95acc573f596cd99f80e417752aa2f979ac1cf72 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 23 Dec 2020 10:39:52 +0300 Subject: [PATCH 03/39] Update .clang-format. --- .clang-format | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-format b/.clang-format index 78d519b..6ce3c0d 100644 --- a/.clang-format +++ b/.clang-format @@ -92,7 +92,7 @@ PenaltyBreakString: 1000 PenaltyBreakTemplateDeclaration: 10 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 200 -PointerAlignment: Left +PointerAlignment: Right ReflowComments: false # true SortIncludes: false # disabled, because we need case insensitive sort SortUsingDeclarations: false # true From 874474ddab404ba5d1bb68133553a49efc9c558d Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 30 Dec 2020 17:28:44 +0300 Subject: [PATCH 04/39] Improve verbosity level change. --- telegram-bot-api/telegram-bot-api.cpp | 38 +++++++++++++++++---------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/telegram-bot-api/telegram-bot-api.cpp b/telegram-bot-api/telegram-bot-api.cpp index 4b58675..0b79143 100644 --- a/telegram-bot-api/telegram-bot-api.cpp +++ b/telegram-bot-api/telegram-bot-api.cpp @@ -297,6 +297,14 @@ int main(int argc, char *argv[]) { second_verbosity_level_ = verbosity_level; } + int get_first_verbosity_level() const { + return first_verbosity_level_; + } + + int get_second_verbosity_level() const { + return second_verbosity_level_; + } + void rotate() override { if (first_) { first_->rotate(); @@ -368,10 +376,14 @@ int main(int argc, char *argv[]) { ::td::VERBOSITY_NAME(dns_resolver) = VERBOSITY_NAME(WARNING); - int memory_verbosity_level = td::max(VERBOSITY_NAME(INFO), verbosity_level); - SET_VERBOSITY_LEVEL(memory_verbosity_level); - log.set_first_verbosity_level(verbosity_level); - log.set_second_verbosity_level(memory_verbosity_level); + auto set_verbosity_level = [&log](int new_verbosity_level) { + int memory_verbosity_level = td::max(VERBOSITY_NAME(INFO), new_verbosity_level); + SET_VERBOSITY_LEVEL(memory_verbosity_level); + + log.set_first_verbosity_level(new_verbosity_level); + log.set_second_verbosity_level(memory_verbosity_level); + }; + set_verbosity_level(verbosity_level); // LOG(WARNING) << "Bot API server with commit " << td::GitInfo::commit() << ' ' // << (td::GitInfo::is_dirty() ? "(dirty)" : "") << " started"; @@ -443,20 +455,18 @@ int main(int argc, char *argv[]) { } if (!need_change_verbosity_level.test_and_set()) { - auto current_global_verbosity_level = GET_VERBOSITY_LEVEL(); - SET_VERBOSITY_LEVEL(256 - current_global_verbosity_level); - verbosity_level = 256 - verbosity_level; - log.set_first_verbosity_level(verbosity_level); + if (log.get_first_verbosity_level() == verbosity_level) { + // increase default log verbosity level + set_verbosity_level(100); + } else { + // return back verbosity level + set_verbosity_level(verbosity_level); + } } auto next_verbosity_level = shared_data->next_verbosity_level_.exchange(-1); if (next_verbosity_level != -1) { - verbosity_level = next_verbosity_level; - memory_verbosity_level = td::max(VERBOSITY_NAME(INFO), verbosity_level); - SET_VERBOSITY_LEVEL(memory_verbosity_level); - - log.set_first_verbosity_level(verbosity_level); - log.set_second_verbosity_level(memory_verbosity_level); + set_verbosity_level(next_verbosity_level); } if (!need_dump_log.test_and_set()) { From 81b25986e1e395c951a34ff240f99f0af1420ebf Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 30 Dec 2020 21:50:52 +0300 Subject: [PATCH 05/39] Output fatal errors to both logs. --- telegram-bot-api/telegram-bot-api.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/telegram-bot-api/telegram-bot-api.cpp b/telegram-bot-api/telegram-bot-api.cpp index 0b79143..4536919 100644 --- a/telegram-bot-api/telegram-bot-api.cpp +++ b/telegram-bot-api/telegram-bot-api.cpp @@ -274,6 +274,9 @@ int main(int argc, char *argv[]) { public: void append(td::CSlice slice, int log_level) override { if (first_ && log_level <= first_verbosity_level_) { + if (log_level == VERBOSITY_NAME(FATAL) && second_ && VERBOSITY_NAME(FATAL) <= second_verbosity_level_) { + second_->append(slice, VERBOSITY_NAME(ERROR)); + } first_->append(slice, log_level); } if (second_ && log_level <= second_verbosity_level_) { From 525b8ff2f969918e79d4dbf742b6f7a9f0f87594 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 1 Jan 2021 16:27:36 +0300 Subject: [PATCH 06/39] Start webhook connection creation in inactive mode. --- telegram-bot-api/WebhookActor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telegram-bot-api/WebhookActor.cpp b/telegram-bot-api/WebhookActor.cpp index 75ade49..e04887d 100644 --- a/telegram-bot-api/WebhookActor.cpp +++ b/telegram-bot-api/WebhookActor.cpp @@ -653,7 +653,7 @@ void WebhookActor::handle(td::unique_ptr response) { void WebhookActor::start_up() { max_loaded_updates_ = max_connections_ * 2; - next_ip_address_resolve_time_ = last_success_time_ = td::Time::now(); + next_ip_address_resolve_time_ = last_success_time_ = td::Time::now() - 3600; active_new_connection_flood_.add_limit(1, 10 * max_connections_); active_new_connection_flood_.add_limit(5, 20 * max_connections_); From a1e72497507b33c1d4972adaaef033618f10aae7 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 6 Jan 2021 17:24:16 +0300 Subject: [PATCH 07/39] 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/WebhookActor.cpp | 2 +- telegram-bot-api/WebhookActor.h | 2 +- telegram-bot-api/telegram-bot-api.cpp | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index dd507a2..96b19df 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-2020 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 // // 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 7ed3737..42d1079 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-2020 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 // // 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 f275535..859d8f5 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-2020 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 // // 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 c76dc7a..8d0c375 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-2020 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 // // 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 ee7583a..c04938b 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-2020 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 // // 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 2b87707..ae4bda4 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-2020 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 // // 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 8d583db..a4b1160 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-2020 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 // // 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 18a5b06..35bf747 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-2020 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 // // 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 5d666b2..9d66aba 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-2020 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 // // 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 0574309..5ef7db9 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-2020 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 // // 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 41cb1ec..5deed1d 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-2020 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 // // 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 24bdac3..33bedc4 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-2020 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 // // 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 b32d0de..ba81026 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-2020 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 // // 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 d2438d7..06e6606 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-2020 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 // // 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 e04887d..d8cbb7e 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-2020 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 // // 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 f588b3f..03e37a1 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-2020 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 // // 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 4536919..833a513 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-2020 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 // // 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 baa16f5e874440ddbe47035331becf60a5d1d2b9 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 15 Jan 2021 15:33:57 +0300 Subject: [PATCH 08/39] Improve HTTP error code for requests with unacceptable bot token. --- telegram-bot-api/ClientManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telegram-bot-api/ClientManager.cpp b/telegram-bot-api/ClientManager.cpp index 859d8f5..60c2e9b 100644 --- a/telegram-bot-api/ClientManager.cpp +++ b/telegram-bot-api/ClientManager.cpp @@ -70,7 +70,7 @@ void ClientManager::send(PromisedQueryPtr query) { } auto r_user_id = td::to_integer_safe(query->token().substr(0, token.find(':'))); if (r_user_id.is_error() || r_user_id.ok() < 0 || !token_range_(r_user_id.ok())) { - return fail_query(401, "Unauthorized: unallowed token specified", std::move(query)); + return fail_query(421, "Misdirected Request: unallowed token specified", std::move(query)); } if (query->is_test_dc()) { From 789d5bb610f07bd87513bad0efe9f6781da4ce95 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 15 Jan 2021 15:41:55 +0300 Subject: [PATCH 09/39] Remove unused field and improve pending_update_count_ field name. --- telegram-bot-api/WebhookActor.cpp | 15 ++++++--------- telegram-bot-api/WebhookActor.h | 3 +-- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/telegram-bot-api/WebhookActor.cpp b/telegram-bot-api/WebhookActor.cpp index d8cbb7e..f55d9bf 100644 --- a/telegram-bot-api/WebhookActor.cpp +++ b/telegram-bot-api/WebhookActor.cpp @@ -382,20 +382,19 @@ void WebhookActor::load_updates() { for (auto &update : updates) { VLOG(webhook) << "Load update " << update.id; if (update_map_.find(update.id) != update_map_.end()) { - LOG(ERROR) << "Receive duplicated event from tqueue " << update.id; + LOG(ERROR) << "Receive duplicated event " << update.id << " from tqueue"; continue; } auto &dest = update_map_[update.id]; dest.id_ = update.id; dest.json_ = update.data.str(); - dest.state_ = Update::State::Begin; dest.delay_ = 1; dest.wakeup_at_ = now; CHECK(update.expires_at >= unix_time_now); dest.expires_at_ = update.expires_at; dest.queue_id_ = update.extra; tqueue_offset_ = update.id.next().move_as_ok(); - begin_updates_n_++; + pending_update_count_++; if (dest.queue_id_ == 0) { dest.queue_id_ = unique_queue_id_++; @@ -485,14 +484,13 @@ void WebhookActor::on_update_error(td::TQueue::EventId event_id, td::Slice error return; } auto &update = it->second; - update.state_ = Update::State::Begin; update.delay_ = next_delay; update.wakeup_at_ = now + next_effective_delay; update.fail_count_++; queues_.emplace(update.wakeup_at_, update.queue_id_); VLOG(webhook) << "Delay update " << event_id << " for " << (update.wakeup_at_ - now) << " seconds because of " << error << " after " << update.fail_count_ << " fails"; - begin_updates_n_++; + pending_update_count_++; } td::Status WebhookActor::send_update() { @@ -533,8 +531,7 @@ td::Status WebhookActor::send_update() { } auto &connection = *Connection::from_list_node(ready_connections_.get()); - begin_updates_n_--; - update.state_ = Update::State::Send; + pending_update_count_--; connection.event_id_ = update.id_; VLOG(webhook) << "Send update " << update.id_ << " from queue " << queue_id << " into connection " << connection.id_ @@ -548,8 +545,8 @@ td::Status WebhookActor::send_update() { } void WebhookActor::send_updates() { - VLOG(webhook) << "Have " << begin_updates_n_ << " pending updates to send"; - while (begin_updates_n_ > 0) { + VLOG(webhook) << "Have " << pending_update_count_ << " pending updates to send"; + while (pending_update_count_ > 0) { if (send_update().is_error()) { return; } diff --git a/telegram-bot-api/WebhookActor.h b/telegram-bot-api/WebhookActor.h index 03e37a1..4ab3060 100644 --- a/telegram-bot-api/WebhookActor.h +++ b/telegram-bot-api/WebhookActor.h @@ -97,7 +97,6 @@ class WebhookActor : public td::HttpOutboundConnection::Callback { double wakeup_at_ = 0; int delay_ = 0; int fail_count_ = 0; - enum State { Begin, Send } state_ = State::Begin; td::int64 queue_id_{0}; }; @@ -119,7 +118,7 @@ class WebhookActor : public td::HttpOutboundConnection::Callback { } }; - td::int32 begin_updates_n_ = 0; + td::int32 pending_update_count_ = 0; td::TQueue::EventId tqueue_offset_; std::size_t max_loaded_updates_ = 0; From fcdb824f867a19551d067c889ff648ba76c5ce62 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 15 Jan 2021 16:40:20 +0300 Subject: [PATCH 10/39] Remove pending_update_count_ field. --- telegram-bot-api/WebhookActor.cpp | 15 +++++---------- telegram-bot-api/WebhookActor.h | 2 -- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/telegram-bot-api/WebhookActor.cpp b/telegram-bot-api/WebhookActor.cpp index f55d9bf..5715fc0 100644 --- a/telegram-bot-api/WebhookActor.cpp +++ b/telegram-bot-api/WebhookActor.cpp @@ -253,7 +253,7 @@ void WebhookActor::on_socket_ready_async(td::Result r_fd, td::int6 } void WebhookActor::create_new_connections() { - size_t need_connections = queues_.size(); + size_t need_connections = queue_updates_.size(); if (need_connections > static_cast(max_connections_)) { need_connections = max_connections_; } @@ -394,7 +394,6 @@ void WebhookActor::load_updates() { dest.expires_at_ = update.expires_at; dest.queue_id_ = update.extra; tqueue_offset_ = update.id.next().move_as_ok(); - pending_update_count_++; if (dest.queue_id_ == 0) { dest.queue_id_ = unique_queue_id_++; @@ -490,7 +489,6 @@ void WebhookActor::on_update_error(td::TQueue::EventId event_id, td::Slice error queues_.emplace(update.wakeup_at_, update.queue_id_); VLOG(webhook) << "Delay update " << event_id << " for " << (update.wakeup_at_ - now) << " seconds because of " << error << " after " << update.fail_count_ << " fails"; - pending_update_count_++; } td::Status WebhookActor::send_update() { @@ -499,7 +497,7 @@ td::Status WebhookActor::send_update() { } if (queues_.empty()) { - return td::Status::Error("No updates"); + return td::Status::Error("No pending updates"); } auto it = queues_.begin(); if (it->wakeup_at > td::Time::now()) { @@ -531,7 +529,6 @@ td::Status WebhookActor::send_update() { } auto &connection = *Connection::from_list_node(ready_connections_.get()); - pending_update_count_--; connection.event_id_ = update.id_; VLOG(webhook) << "Send update " << update.id_ << " from queue " << queue_id << " into connection " << connection.id_ @@ -545,11 +542,9 @@ td::Status WebhookActor::send_update() { } void WebhookActor::send_updates() { - VLOG(webhook) << "Have " << pending_update_count_ << " pending updates to send"; - while (pending_update_count_ > 0) { - if (send_update().is_error()) { - return; - } + VLOG(webhook) << "Have " << (queues_.size() + update_map_.size() - queue_updates_.size()) << " pending updates in " + << queues_.size() << " queues to send"; + while (send_update().is_ok()) { } } diff --git a/telegram-bot-api/WebhookActor.h b/telegram-bot-api/WebhookActor.h index 4ab3060..60ab1bc 100644 --- a/telegram-bot-api/WebhookActor.h +++ b/telegram-bot-api/WebhookActor.h @@ -118,8 +118,6 @@ class WebhookActor : public td::HttpOutboundConnection::Callback { } }; - td::int32 pending_update_count_ = 0; - td::TQueue::EventId tqueue_offset_; std::size_t max_loaded_updates_ = 0; struct EventIdHash { From d9c247e5ed074ea31ace835c8933fe03334889bb Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 15 Jan 2021 16:54:14 +0300 Subject: [PATCH 11/39] Improve warning messages. --- telegram-bot-api/Client.cpp | 12 ++++++------ telegram-bot-api/Client.h | 2 +- telegram-bot-api/WebhookActor.cpp | 12 +++++------- telegram-bot-api/WebhookActor.h | 2 +- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 96b19df..2df448d 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -21,7 +21,6 @@ #include "td/utils/logging.h" #include "td/utils/misc.h" #include "td/utils/PathView.h" -#include "td/utils/port/Clocks.h" #include "td/utils/port/path.h" #include "td/utils/port/Stat.h" #include "td/utils/Random.h" @@ -3242,7 +3241,7 @@ void Client::start_up() { next_set_webhook_logging_time_ = start_time_; next_webhook_is_not_modified_warning_time_ = start_time_; previous_get_updates_start_time_ = start_time_ - 100; - previous_get_updates_finish_time_ = start_time_ - 100; + next_get_updates_conflict_time_ = start_time_ - 100; sticker_set_names_[GREAT_MINDS_SET_ID] = GREAT_MINDS_SET_NAME.str(); @@ -7592,9 +7591,9 @@ void Client::abort_long_poll(bool from_set_webhook) { void Client::fail_query_conflict(Slice message, PromisedQueryPtr &&query) { auto now = td::Time::now_cached(); - if (now >= previous_get_updates_finish_time_) { + if (now >= next_get_updates_conflict_time_) { fail_query(409, message, std::move(query)); - previous_get_updates_finish_time_ = now + 3.0; + next_get_updates_conflict_time_ = now + 3.0; } else { td::create_actor( "FailQueryConflictSleepActor", 3.0, @@ -7686,7 +7685,8 @@ void Client::do_get_updates(int32 offset, int32 limit, int32 timeout, PromisedQu } if (need_warning) { LOG(WARNING) << "Found " << updates.size() << " updates out of " << total_size << " + " << updates.size() - << " after last getUpdates call at " << previous_get_updates_finish_date_; + << " after last getUpdates call " << (td::Time::now() - previous_get_updates_finish_time_) + << " seconds ago"; } else { LOG(DEBUG) << "Found " << updates.size() << " updates out of " << total_size << " from " << from; } @@ -7702,7 +7702,7 @@ void Client::do_get_updates(int32 offset, int32 limit, int32 timeout, PromisedQu long_poll_slot_.set_timeout_at(long_poll_hard_timeout_); return; } - previous_get_updates_finish_date_ = td::Clocks::system(); // local time to output it to the log + previous_get_updates_finish_time_ = td::Time::now(); next_bot_updates_warning_time_ = td::Time::now() + BOT_UPDATES_WARNING_DELAY; if (total_size == updates.size() && was_bot_updates_warning_) { send_request(make_object(0, ""), std::make_unique()); diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index 42d1079..01cf068 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -922,8 +922,8 @@ class Client : public WebhookActor::Callback { int32 previous_get_updates_offset_ = -1; double previous_get_updates_start_time_ = 0; - double previous_get_updates_finish_date_ = 0; double previous_get_updates_finish_time_ = 0; + double next_get_updates_conflict_time_ = 0; td::uint64 webhook_generation_ = 1; diff --git a/telegram-bot-api/WebhookActor.cpp b/telegram-bot-api/WebhookActor.cpp index 5715fc0..77db56d 100644 --- a/telegram-bot-api/WebhookActor.cpp +++ b/telegram-bot-api/WebhookActor.cpp @@ -8,8 +8,6 @@ #include "telegram-bot-api/ClientParameters.h" -#include "td/db/TQueue.h" - #include "td/net/GetHostByNameActor.h" #include "td/net/HttpHeaderCreator.h" #include "td/net/HttpProxy.h" @@ -26,7 +24,6 @@ #include "td/utils/JsonBuilder.h" #include "td/utils/logging.h" #include "td/utils/misc.h" -#include "td/utils/port/Clocks.h" #include "td/utils/port/IPAddress.h" #include "td/utils/port/SocketFd.h" #include "td/utils/Random.h" @@ -419,9 +416,10 @@ void WebhookActor::load_updates() { } } if (need_warning) { - LOG(WARNING) << "Loaded " << updates.size() << " updates out of " << total_size << ". Have total of " - << update_map_.size() << " loaded in " << queues_.size() << " queues after last error \"" - << last_error_message_ << "\" at " << last_error_date_; + LOG(WARNING) << "Loaded " << updates.size() << " updates out of " << total_size << ". Have " << update_map_.size() + << " updates loaded in " << queue_updates_.size() << " queues after last error \"" + << last_error_message_ << "\" " << (last_error_time_ == 0 ? -1 : td::Time::now() - last_error_time_) + << " seconds ago"; } if (updates.size() == total_size && last_update_was_successful_) { @@ -741,7 +739,7 @@ void WebhookActor::on_connection_error(td::Status error) { void WebhookActor::on_webhook_error(td::Slice error) { if (was_checked_) { send_closure(callback_, &Callback::webhook_error, td::Status::Error(error)); - last_error_date_ = td::Clocks::system(); // local time to output it to the log + last_error_time_ = td::Time::now(); last_error_message_ = error.str(); } } diff --git a/telegram-bot-api/WebhookActor.h b/telegram-bot-api/WebhookActor.h index 60ab1bc..c490f8c 100644 --- a/telegram-bot-api/WebhookActor.h +++ b/telegram-bot-api/WebhookActor.h @@ -79,7 +79,7 @@ class WebhookActor : public td::HttpOutboundConnection::Callback { td::string cert_path_; std::shared_ptr parameters_; - double last_error_date_ = 0; + double last_error_time_ = 0; td::string last_error_message_ = ""; bool fix_ip_address_ = false; From 08ba28539fdd073d0b3ad3409ac1b036151be448 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 27 Jan 2021 00:57:51 +0300 Subject: [PATCH 12/39] Return error 500 if sent message was immediately deleted and can't be returned. --- telegram-bot-api/Client.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 2df448d..4847f66 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -8714,21 +8714,23 @@ void Client::delete_message(int64 chat_id, int64 message_id, bool only_from_cach auto it = messages_.find({chat_id, message_id}); if (it == messages_.end()) { if (yet_unsent_messages_.count({chat_id, message_id}) > 0) { - // yet unsent message is deleted, possible only if we are trying to write to inaccessible supergroup + // yet unsent message is deleted, possible only if we are trying to write to inaccessible supergroup or + // sent message was deleted before added to the chat auto chat_info = get_chat(chat_id); CHECK(chat_info != nullptr); - Status error; - if (chat_info->type != ChatInfo::Type::Supergroup) { - LOG(ERROR) << "Yet unsent message " << message_id << " is deleted in the chat " << chat_id; - error = Status::Error(403, "Forbidden: bot is not a member of the chat"); - } else { + Status error = + Status::Error(500, "Internal Server Error: sent message was immediately deleted and can't be returned"); + if (chat_info->type == ChatInfo::Type::Supergroup) { auto supergroup_info = get_supergroup_info(chat_info->supergroup_id); CHECK(supergroup_info != nullptr); - if (supergroup_info->is_supergroup) { - error = Status::Error(403, "Forbidden: bot is not a member of the supergroup chat"); - } else { - error = Status::Error(403, "Forbidden: bot is not a member of the channel chat"); + if (supergroup_info->status->get_id() == td_api::chatMemberStatusBanned::ID || + supergroup_info->status->get_id() == td_api::chatMemberStatusLeft::ID) { + if (supergroup_info->is_supergroup) { + error = Status::Error(403, "Forbidden: bot is not a member of the supergroup chat"); + } else { + error = Status::Error(403, "Forbidden: bot is not a member of the channel chat"); + } } } From 8b2926a92f6885ca39ef687559a3064ea7d21c66 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Feb 2021 15:44:32 +0300 Subject: [PATCH 13/39] Improve error message on wrong API ID specified. --- telegram-bot-api/Client.cpp | 23 +++++++++++++++-------- telegram-bot-api/Client.h | 5 ++++- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 4847f66..bfe557b 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -2295,7 +2295,7 @@ class Client::TdOnAuthorizationCallback : public TdQueryCallback { } LOG(WARNING) << "Logging out due to " << td::oneline(to_string(error)); - client_->log_out(); + client_->log_out(error->message_ == "API_ID_INVALID"); } else if (was_ready) { client_->on_update_authorization_state(); } @@ -3199,7 +3199,8 @@ void Client::close() { } } -void Client::log_out() { +void Client::log_out(bool is_api_id_invalid) { + is_api_id_invalid_ |= is_api_id_invalid; if (!td_client_.empty() && !logging_out_ && !closing_) { do_send_request(make_object(), std::make_unique()); } @@ -3763,7 +3764,8 @@ void Client::get_chat_member(int64 chat_id, int32 user_id, PromisedQueryPtr quer void Client::send_request(object_ptr &&f, std::unique_ptr handler) { if (logging_out_) { - return handler->on_result(make_object(LOGGING_OUT_ERROR_CODE, LOGGING_OUT_ERROR_DESCRIPTION.str())); + return handler->on_result( + make_object(LOGGING_OUT_ERROR_CODE, get_logging_out_error_description().str())); } if (closing_) { return handler->on_result(make_object(CLOSING_ERROR_CODE, CLOSING_ERROR_DESCRIPTION.str())); @@ -3801,7 +3803,7 @@ void Client::on_update_file(object_ptr file) { // also includes all 5xx and 429 errors auto error = Status::Error(400, "Bad Request: wrong file_id or the file is temporarily unavailable"); if (logging_out_) { - error = Status::Error(LOGGING_OUT_ERROR_CODE, LOGGING_OUT_ERROR_DESCRIPTION); + error = Status::Error(LOGGING_OUT_ERROR_CODE, get_logging_out_error_description()); } if (closing_) { error = Status::Error(CLOSING_ERROR_CODE, CLOSING_ERROR_DESCRIPTION); @@ -3886,7 +3888,7 @@ void Client::on_update_authorization_state() { case td_api::authorizationStateClosed::ID: return on_closed(); default: - return log_out(); // just in case + return log_out(false); // just in case } } @@ -4185,6 +4187,10 @@ void Client::on_result(td::uint64 id, object_ptr result) { handlers_.erase(id); } +td::Slice Client::get_logging_out_error_description() const { + return is_api_id_invalid_ ? API_ID_INVALID_ERROR_DESCRIPTION : LOGGING_OUT_ERROR_DESCRIPTION; +} + void Client::on_closed() { LOG(WARNING) << "Closed"; CHECK(logging_out_ || closing_); @@ -4192,7 +4198,7 @@ void Client::on_closed() { td_client_.reset(); int http_status_code = logging_out_ ? LOGGING_OUT_ERROR_CODE : CLOSING_ERROR_CODE; - Slice description = logging_out_ ? LOGGING_OUT_ERROR_DESCRIPTION : CLOSING_ERROR_DESCRIPTION; + Slice description = logging_out_ ? get_logging_out_error_description() : CLOSING_ERROR_DESCRIPTION; if (webhook_set_query_) { fail_query(http_status_code, description, std::move(webhook_set_query_)); } @@ -5932,10 +5938,10 @@ void Client::on_cmd(PromisedQueryPtr query) { } if (logging_out_) { - return fail_query(LOGGING_OUT_ERROR_CODE, LOGGING_OUT_ERROR_DESCRIPTION, std::move(query)); + return fail_query(LOGGING_OUT_ERROR_CODE, get_logging_out_error_description(), std::move(query)); } if (closing_) { - return fail_query(CLOSING_ERROR_CODE, LOGGING_OUT_ERROR_DESCRIPTION, std::move(query)); + return fail_query(CLOSING_ERROR_CODE, CLOSING_ERROR_DESCRIPTION, std::move(query)); } CHECK(was_authorized_); @@ -9085,6 +9091,7 @@ constexpr Client::Slice Client::MASK_POINTS[MASK_POINTS_SIZE]; constexpr int Client::LOGGING_OUT_ERROR_CODE; constexpr Client::Slice Client::LOGGING_OUT_ERROR_DESCRIPTION; +constexpr Client::Slice Client::API_ID_INVALID_ERROR_DESCRIPTION; constexpr int Client::CLOSING_ERROR_CODE; constexpr Client::Slice Client::CLOSING_ERROR_DESCRIPTION; diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index 01cf068..b733404 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -78,6 +78,7 @@ class Client : public WebhookActor::Callback { static constexpr int LOGGING_OUT_ERROR_CODE = 401; static constexpr Slice LOGGING_OUT_ERROR_DESCRIPTION = "Unauthorized"; + static constexpr Slice API_ID_INVALID_ERROR_DESCRIPTION = "Unauthorized: invalid api-id/api-hash"; static constexpr int CLOSING_ERROR_CODE = 500; static constexpr Slice CLOSING_ERROR_DESCRIPTION = "Internal Server Error: restart"; @@ -267,7 +268,8 @@ class Client : public WebhookActor::Callback { void on_result(td::uint64 id, object_ptr result); void on_update_authorization_state(); - void log_out(); + void log_out(bool is_api_id_invalid); + Slice get_logging_out_error_description() const; void on_closed(); void finish_closing(); @@ -787,6 +789,7 @@ class Client : public WebhookActor::Callback { bool was_authorized_ = false; bool closing_ = false; bool logging_out_ = false; + bool is_api_id_invalid_ = false; bool need_close_ = false; bool clear_tqueue_ = false; From f781aab119a52f27e1a89af28a9706d3f5293048 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 3 Feb 2021 17:32:43 +0300 Subject: [PATCH 14/39] Add webhook response time to log. --- telegram-bot-api/WebhookActor.cpp | 16 +++++++++++++--- telegram-bot-api/WebhookActor.h | 3 ++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/telegram-bot-api/WebhookActor.cpp b/telegram-bot-api/WebhookActor.cpp index 77db56d..4df3ab0 100644 --- a/telegram-bot-api/WebhookActor.cpp +++ b/telegram-bot-api/WebhookActor.cpp @@ -435,6 +435,7 @@ void WebhookActor::load_updates() { void WebhookActor::drop_event(td::TQueue::EventId event_id) { auto it = update_map_.find(event_id); + CHECK(it != update_map_.end()); auto queue_id = it->second.queue_id_; update_map_.erase(it); @@ -456,7 +457,12 @@ void WebhookActor::drop_event(td::TQueue::EventId event_id) { void WebhookActor::on_update_ok(td::TQueue::EventId event_id) { last_update_was_successful_ = true; last_success_time_ = td::Time::now(); - VLOG(webhook) << "Receive ok for update " << event_id; + + auto it = update_map_.find(event_id); + CHECK(it != update_map_.end()); + + VLOG(webhook) << "Receive ok for update " << event_id << " in " << (last_success_time_ - it->second.last_send_time_) + << " seconds"; drop_event(event_id); } @@ -466,6 +472,7 @@ void WebhookActor::on_update_error(td::TQueue::EventId event_id, td::Slice error double now = td::Time::now(); auto it = update_map_.find(event_id); + CHECK(it != update_map_.end()); const int MAX_RETRY_AFTER = 3600; retry_after = td::clamp(retry_after, 0, MAX_RETRY_AFTER); @@ -486,7 +493,8 @@ void WebhookActor::on_update_error(td::TQueue::EventId event_id, td::Slice error update.fail_count_++; queues_.emplace(update.wakeup_at_, update.queue_id_); VLOG(webhook) << "Delay update " << event_id << " for " << (update.wakeup_at_ - now) << " seconds because of " - << error << " after " << update.fail_count_ << " fails"; + << error << " after " << update.fail_count_ << " fails received in " << (now - update.last_send_time_) + << " seconds"; } td::Status WebhookActor::send_update() { @@ -498,7 +506,8 @@ td::Status WebhookActor::send_update() { return td::Status::Error("No pending updates"); } auto it = queues_.begin(); - if (it->wakeup_at > td::Time::now()) { + auto now = td::Time::now(); + if (it->wakeup_at > now) { relax_wakeup_at(it->wakeup_at, "send_update"); return td::Status::Error("No ready updates"); } @@ -508,6 +517,7 @@ td::Status WebhookActor::send_update() { auto event_id = queue_updates_[queue_id].event_ids.front(); auto &update = update_map_[event_id]; + update.last_send_time_ = now; auto body = td::json_encode(JsonUpdate(update.id_.value(), update.json_)); diff --git a/telegram-bot-api/WebhookActor.h b/telegram-bot-api/WebhookActor.h index c490f8c..49de882 100644 --- a/telegram-bot-api/WebhookActor.h +++ b/telegram-bot-api/WebhookActor.h @@ -94,10 +94,11 @@ class WebhookActor : public td::HttpOutboundConnection::Callback { td::TQueue::EventId id_; td::string json_; td::int32 expires_at_ = 0; + double last_send_time_ = 0; double wakeup_at_ = 0; int delay_ = 0; int fail_count_ = 0; - td::int64 queue_id_{0}; + td::int64 queue_id_ = 0; }; struct QueueUpdates { From a01c36ec1f61ceb4d367bcbff4593d08783dff13 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 15 Feb 2021 01:23:18 +0300 Subject: [PATCH 15/39] Allow to change memory log verbosity level. --- telegram-bot-api/telegram-bot-api.cpp | 29 ++++++++++++++++++--------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/telegram-bot-api/telegram-bot-api.cpp b/telegram-bot-api/telegram-bot-api.cpp index 833a513..8bffe3e 100644 --- a/telegram-bot-api/telegram-bot-api.cpp +++ b/telegram-bot-api/telegram-bot-api.cpp @@ -146,7 +146,8 @@ int main(int argc, char *argv[]) { td::string http_ip_address = "0.0.0.0"; td::string http_stat_ip_address = "0.0.0.0"; td::string log_file_path; - int verbosity_level = 0; + int default_verbosity_level = 0; + int memory_verbosity_level = VERBOSITY_NAME(INFO); td::int64 log_max_file_size = 2000000000; td::string working_directory; td::string temporary_directory; @@ -225,7 +226,10 @@ int main(int argc, char *argv[]) { options.add_option('l', "log", "path to the file where the log will be written", td::OptionParser::parse_string(log_file_path)); - options.add_checked_option('v', "verbosity", "log verbosity level", td::OptionParser::parse_integer(verbosity_level)); + options.add_checked_option('v', "verbosity", "log verbosity level", + td::OptionParser::parse_integer(default_verbosity_level)); + options.add_checked_option('\0', "memory-verbosity", "memory log verbosity level; defaults to 3", + td::OptionParser::parse_integer(memory_verbosity_level)); options.add_checked_option( '\0', "log-max-file-size", PSLICE() << "maximum size of the log file in bytes before it will be auto-rotated (default is " @@ -254,11 +258,17 @@ int main(int argc, char *argv[]) { return td::Status::OK(); }); options.add_check([&] { - if (verbosity_level < 0) { + if (default_verbosity_level < 0) { return td::Status::Error("Wrong verbosity level specified"); } return td::Status::OK(); }); + options.add_check([&] { + if (memory_verbosity_level < 0) { + return td::Status::Error("Wrong memory verbosity level specified"); + } + return td::Status::OK(); + }); auto r_non_options = options.run(argc, argv, 0); if (need_print_usage) { LOG(PLAIN) << options; @@ -379,14 +389,13 @@ int main(int argc, char *argv[]) { ::td::VERBOSITY_NAME(dns_resolver) = VERBOSITY_NAME(WARNING); - auto set_verbosity_level = [&log](int new_verbosity_level) { - int memory_verbosity_level = td::max(VERBOSITY_NAME(INFO), new_verbosity_level); - SET_VERBOSITY_LEVEL(memory_verbosity_level); + log.set_second_verbosity_level(memory_verbosity_level); + auto set_verbosity_level = [&log, memory_verbosity_level](int new_verbosity_level) { + SET_VERBOSITY_LEVEL(td::max(memory_verbosity_level, new_verbosity_level)); log.set_first_verbosity_level(new_verbosity_level); - log.set_second_verbosity_level(memory_verbosity_level); }; - set_verbosity_level(verbosity_level); + set_verbosity_level(default_verbosity_level); // LOG(WARNING) << "Bot API server with commit " << td::GitInfo::commit() << ' ' // << (td::GitInfo::is_dirty() ? "(dirty)" : "") << " started"; @@ -458,12 +467,12 @@ int main(int argc, char *argv[]) { } if (!need_change_verbosity_level.test_and_set()) { - if (log.get_first_verbosity_level() == verbosity_level) { + if (log.get_first_verbosity_level() == default_verbosity_level) { // increase default log verbosity level set_verbosity_level(100); } else { // return back verbosity level - set_verbosity_level(verbosity_level); + set_verbosity_level(default_verbosity_level); } } From 35aa4d30a46d11bf848a0c5e316a82db8eb5ed6b Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 17 Feb 2021 14:45:22 +0300 Subject: [PATCH 16/39] Add related to voice chat service messages. --- telegram-bot-api/Client.cpp | 67 ++++++++++++++++++++++++++++++++----- telegram-bot-api/Client.h | 3 ++ 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index bfe557b..5dd25d5 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -1369,6 +1369,49 @@ class Client::JsonProximityAlertTriggered : public Jsonable { const Client *client_; }; +class Client::JsonVoiceChatStarted : public Jsonable { + public: + explicit JsonVoiceChatStarted(const td_api::messageVoiceChatStarted *voice_chat_started) + : voice_chat_started_(voice_chat_started) { + } + void store(JsonValueScope *scope) const { + auto object = scope->enter_object(); + } + + private: + const td_api::messageVoiceChatStarted *voice_chat_started_; +}; + +class Client::JsonVoiceChatEnded : public Jsonable { + public: + explicit JsonVoiceChatEnded(const td_api::messageVoiceChatEnded *voice_chat_ended) + : voice_chat_ended_(voice_chat_ended) { + } + void store(JsonValueScope *scope) const { + auto object = scope->enter_object(); + object("duration", voice_chat_ended_->duration_); + } + + private: + const td_api::messageVoiceChatEnded *voice_chat_ended_; +}; + +class Client::JsonInviteVoiceChatParticipants : public Jsonable { + public: + JsonInviteVoiceChatParticipants(const td_api::messageInviteVoiceChatParticipants *invite_voice_chat_participants, + const Client *client) + : invite_voice_chat_participants_(invite_voice_chat_participants), client_(client) { + } + void store(JsonValueScope *scope) const { + auto object = scope->enter_object(); + object("users", JsonUsers(invite_voice_chat_participants_->user_ids_, client_)); + } + + private: + const td_api::messageInviteVoiceChatParticipants *invite_voice_chat_participants_; + const Client *client_; +}; + class Client::JsonCallbackGame : public Jsonable { public: void store(JsonValueScope *scope) const { @@ -1746,12 +1789,21 @@ void Client::JsonMessage::store(JsonValueScope *scope) const { object("proximity_alert_triggered", JsonProximityAlertTriggered(content, client_)); break; } - case td_api::messageVoiceChatStarted::ID: + case td_api::messageVoiceChatStarted::ID: { + auto content = static_cast(message_->content.get()); + object("voice_chat_started", JsonVoiceChatStarted(content)); break; - case td_api::messageVoiceChatEnded::ID: + } + case td_api::messageVoiceChatEnded::ID: { + auto content = static_cast(message_->content.get()); + object("voice_chat_ended", JsonVoiceChatEnded(content)); break; - case td_api::messageInviteVoiceChatParticipants::ID: + } + case td_api::messageInviteVoiceChatParticipants::ID: { + auto content = static_cast(message_->content.get()); + object("voice_chat_members_invited", JsonInviteVoiceChatParticipants(content, client_)); break; + } default: UNREACHABLE(); } @@ -8335,6 +8387,9 @@ bool Client::need_skip_update_message(int64 chat_id, const object_ptr Date: Wed, 17 Feb 2021 15:45:24 +0300 Subject: [PATCH 17/39] Add message_auto_delete_time_changed service message. --- td | 2 +- telegram-bot-api/Client.cpp | 18 +++++++++++++++++- telegram-bot-api/Client.h | 1 + 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/td b/td index db38757..3a657d9 160000 --- a/td +++ b/td @@ -1 +1 @@ -Subproject commit db3875710bcf9f29baa360d91d7b11b0199229a9 +Subproject commit 3a657d9072b324aad1143c6abe20a802f3b92cd5 diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 5dd25d5..b022706 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -1412,6 +1412,19 @@ class Client::JsonInviteVoiceChatParticipants : public Jsonable { const Client *client_; }; +class Client::JsonChatSetTtl : public Jsonable { + public: + explicit JsonChatSetTtl(const td_api::messageChatSetTtl *chat_set_ttl) : chat_set_ttl_(chat_set_ttl) { + } + void store(JsonValueScope *scope) const { + auto object = scope->enter_object(); + object("message_auto_delete_time", chat_set_ttl_->ttl_); + } + + private: + const td_api::messageChatSetTtl *chat_set_ttl_; +}; + class Client::JsonCallbackGame : public Jsonable { public: void store(JsonValueScope *scope) const { @@ -1752,8 +1765,11 @@ void Client::JsonMessage::store(JsonValueScope *scope) const { break; case td_api::messageScreenshotTaken::ID: break; - case td_api::messageChatSetTtl::ID: + case td_api::messageChatSetTtl::ID: { + auto content = static_cast(message_->content.get()); + object("message_auto_delete_time_changed", JsonChatSetTtl(content)); break; + } case td_api::messageUnsupported::ID: break; case td_api::messageContactRegistered::ID: diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index adc28db..b4be0b8 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -146,6 +146,7 @@ class Client : public WebhookActor::Callback { class JsonVoiceChatStarted; class JsonVoiceChatEnded; class JsonInviteVoiceChatParticipants; + class JsonChatSetTtl; class JsonUpdateTypes; class JsonWebhookInfo; class JsonStickerSet; From e605063da63379e2da4ac6b287a89d8ef8688b34 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 17 Feb 2021 17:23:58 +0300 Subject: [PATCH 18/39] Update TDLib. --- telegram-bot-api/Client.cpp | 42 +++++++++++++++++++++++++------------ telegram-bot-api/Client.h | 2 +- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index b022706..85ccd08 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -3150,9 +3150,9 @@ class Client::TdOnGetSupergroupMembersCountCallback : public TdQueryCallback { PromisedQueryPtr query_; }; -class Client::TdOnGenerateChatInviteLinkCallback : public TdQueryCallback { +class Client::TdOnReplacePermanentChatInviteLinkCallback : public TdQueryCallback { public: - explicit TdOnGenerateChatInviteLinkCallback(PromisedQueryPtr query) : query_(std::move(query)) { + explicit TdOnReplacePermanentChatInviteLinkCallback(PromisedQueryPtr query) : query_(std::move(query)) { } void on_result(object_ptr result) override { @@ -4131,8 +4131,11 @@ void Client::on_update(object_ptr result) { case td_api::updateBasicGroupFullInfo::ID: { auto update = move_object_as(result); auto group_id = update->basic_group_id_; - set_group_description(group_id, std::move(update->basic_group_full_info_->description_)); - set_group_invite_link(group_id, std::move(update->basic_group_full_info_->invite_link_)); + auto full_info = std::move(update->basic_group_full_info_); + set_group_description(group_id, std::move(full_info->description_)); + set_group_invite_link(group_id, full_info->invite_link_ != nullptr + ? std::move(full_info->invite_link_->invite_link_) + : td::string()); break; } case td_api::updateSupergroup::ID: { @@ -4143,13 +4146,16 @@ void Client::on_update(object_ptr result) { case td_api::updateSupergroupFullInfo::ID: { auto update = move_object_as(result); auto supergroup_id = update->supergroup_id_; - set_supergroup_description(supergroup_id, std::move(update->supergroup_full_info_->description_)); - set_supergroup_invite_link(supergroup_id, std::move(update->supergroup_full_info_->invite_link_)); - set_supergroup_sticker_set_id(supergroup_id, update->supergroup_full_info_->sticker_set_id_); - set_supergroup_can_set_sticker_set(supergroup_id, update->supergroup_full_info_->can_set_sticker_set_); - set_supergroup_slow_mode_delay(supergroup_id, update->supergroup_full_info_->slow_mode_delay_); - set_supergroup_linked_chat_id(supergroup_id, update->supergroup_full_info_->linked_chat_id_); - set_supergroup_location(supergroup_id, std::move(update->supergroup_full_info_->location_)); + auto full_info = std::move(update->supergroup_full_info_); + set_supergroup_description(supergroup_id, std::move(full_info->description_)); + set_supergroup_invite_link(supergroup_id, full_info->invite_link_ != nullptr + ? std::move(full_info->invite_link_->invite_link_) + : td::string()); + set_supergroup_sticker_set_id(supergroup_id, full_info->sticker_set_id_); + set_supergroup_can_set_sticker_set(supergroup_id, full_info->can_set_sticker_set_); + set_supergroup_slow_mode_delay(supergroup_id, full_info->slow_mode_delay_); + set_supergroup_linked_chat_id(supergroup_id, full_info->linked_chat_id_); + set_supergroup_location(supergroup_id, std::move(full_info->location_)); break; } case td_api::updateOption::ID: { @@ -6741,8 +6747,8 @@ td::Status Client::process_export_chat_invite_link_query(PromisedQueryPtr &query auto chat_id = query->arg("chat_id"); check_chat(chat_id, AccessRights::Write, std::move(query), [this](int64 chat_id, PromisedQueryPtr query) { - send_request(make_object(chat_id), - std::make_unique(std::move(query))); + send_request(make_object(chat_id), + std::make_unique(std::move(query))); }); return Status::OK(); } @@ -8441,6 +8447,11 @@ bool Client::need_skip_update_message(int64 chat_id, const object_ptrforward_info_ != nullptr && + message->forward_info_->origin_->get_id() == td_api::messageForwardOriginMessageImport::ID) { + return true; + } + switch (message->content_->get_id()) { case td_api::messagePhoto::ID: { auto message_photo = static_cast(message->content_.get()); @@ -8949,6 +8960,11 @@ Client::FullMessageId Client::add_message(object_ptr &&message, message_info->initial_author_signature = forward_info->author_signature_; break; } + case td_api::messageForwardOriginMessageImport::ID: { + auto forward_info = move_object_as(origin); + message_info->initial_sender_name = forward_info->sender_name_; + break; + } default: UNREACHABLE(); } diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index b4be0b8..6198f09 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -175,7 +175,7 @@ class Client : public WebhookActor::Callback { class TdOnGetGroupMembersCallback; class TdOnGetSupergroupMembersCallback; class TdOnGetSupergroupMembersCountCallback; - class TdOnGenerateChatInviteLinkCallback; + class TdOnReplacePermanentChatInviteLinkCallback; class TdOnGetGameHighScoresCallback; class TdOnReturnFileCallback; class TdOnReturnStickerSetCallback; From 2ab19c59488bf1dbbb7eee41af1e6ec781847ef2 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 17 Feb 2021 20:43:55 +0300 Subject: [PATCH 19/39] Support revoke_messages for groups in kickChatMember. --- telegram-bot-api/Client.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 85ccd08..cf239d2 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -7083,13 +7083,14 @@ td::Status Client::process_ban_chat_member_query(PromisedQueryPtr &query) { auto chat_id = query->arg("chat_id"); TRY_RESULT(user_id, get_user_id(query.get())); int32 until_date = get_integer_arg(query.get(), "until_date", 0); + auto revoke_messages = to_bool(query->arg("revoke_messages")); check_chat(chat_id, AccessRights::Write, std::move(query), - [this, user_id, until_date](int64 chat_id, PromisedQueryPtr query) { + [this, user_id, until_date, revoke_messages](int64 chat_id, PromisedQueryPtr query) { check_user_no_fail( - user_id, std::move(query), [this, chat_id, user_id, until_date](PromisedQueryPtr query) { - send_request(make_object( - chat_id, user_id, make_object(until_date)), + user_id, std::move(query), + [this, chat_id, user_id, until_date, revoke_messages](PromisedQueryPtr query) { + send_request(make_object(chat_id, user_id, until_date, revoke_messages), std::make_unique(std::move(query))); }); }); From ae56eee88fce553cbd4958fabc801a841fa530fc Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 18 Feb 2021 22:41:59 +0300 Subject: [PATCH 20/39] Avoid some string copies. --- telegram-bot-api/Client.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index cf239d2..79d9697 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -4160,7 +4160,7 @@ void Client::on_update(object_ptr result) { } case td_api::updateOption::ID: { auto update = move_object_as(result); - auto name = update->name_; + const td::string &name = update->name_; if (name == "my_id") { if (update->value_->get_id() == td_api::optionValueEmpty::ID) { CHECK(logging_out_); @@ -7821,10 +7821,10 @@ void Client::long_poll_wakeup(bool force_flag) { void Client::add_user(std::unordered_map &users, object_ptr &&user) { auto user_info = &users[user->id_]; - user_info->first_name = user->first_name_; - user_info->last_name = user->last_name_; - user_info->username = user->username_; - user_info->language_code = user->language_code_; + user_info->first_name = std::move(user->first_name_); + user_info->last_name = std::move(user->last_name_); + user_info->username = std::move(user->username_); + user_info->language_code = std::move(user->language_code_); user_info->have_access = user->have_access_; @@ -8946,24 +8946,24 @@ Client::FullMessageId Client::add_message(object_ptr &&message, case td_api::messageForwardOriginChat::ID: { auto forward_info = move_object_as(origin); message_info->initial_sender_chat_id = forward_info->sender_chat_id_; - message_info->initial_author_signature = forward_info->author_signature_; + message_info->initial_author_signature = std::move(forward_info->author_signature_); break; } case td_api::messageForwardOriginHiddenUser::ID: { auto forward_info = move_object_as(origin); - message_info->initial_sender_name = forward_info->sender_name_; + message_info->initial_sender_name = std::move(forward_info->sender_name_); break; } case td_api::messageForwardOriginChannel::ID: { auto forward_info = move_object_as(origin); message_info->initial_chat_id = forward_info->chat_id_; message_info->initial_message_id = forward_info->message_id_; - message_info->initial_author_signature = forward_info->author_signature_; + message_info->initial_author_signature = std::move(forward_info->author_signature_); break; } case td_api::messageForwardOriginMessageImport::ID: { auto forward_info = move_object_as(origin); - message_info->initial_sender_name = forward_info->sender_name_; + message_info->initial_sender_name = std::move(forward_info->sender_name_); break; } default: From 685e6bf87df06d472708ed80cf2ec41bab8fe01f Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 25 Feb 2021 21:29:30 +0300 Subject: [PATCH 21/39] Update TDLib to 1.7.2. Add createChatInviteLink method. --- td | 2 +- telegram-bot-api/Client.cpp | 74 +++++++++++++++++++++++++++++++++---- telegram-bot-api/Client.h | 5 ++- 3 files changed, 72 insertions(+), 9 deletions(-) diff --git a/td b/td index 3a657d9..3b3801a 160000 --- a/td +++ b/td @@ -1 +1 @@ -Subproject commit 3a657d9072b324aad1143c6abe20a802f3b92cd5 +Subproject commit 3b3801abbec641ac66a050760d198dfc7bca92be diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 79d9697..da533cf 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -212,6 +212,7 @@ bool Client::init_methods() { methods_.emplace("answershippingquery", &Client::process_answer_shipping_query_query); methods_.emplace("answerprecheckoutquery", &Client::process_answer_pre_checkout_query_query); methods_.emplace("exportchatinvitelink", &Client::process_export_chat_invite_link_query); + methods_.emplace("createchatinvitelink", &Client::process_create_chat_invite_link_query); methods_.emplace("getchat", &Client::process_get_chat_query); methods_.emplace("setchatphoto", &Client::process_set_chat_photo_query); methods_.emplace("deletechatphoto", &Client::process_delete_chat_photo_query); @@ -525,6 +526,30 @@ class Client::JsonChatLocation : public Jsonable { const td_api::chatLocation *chat_location_; }; +class Client::JsonChatInviteLink : public Jsonable { + public: + JsonChatInviteLink(const td_api::chatInviteLink *chat_invite_link, const Client *client) + : chat_invite_link_(chat_invite_link), client_(client) { + } + void store(JsonValueScope *scope) const { + auto object = scope->enter_object(); + object("invite_link", chat_invite_link_->invite_link_); + object("creator", JsonUser(chat_invite_link_->creator_user_id_, client_)); + if (chat_invite_link_->expire_date_ != 0) { + object("expire_date", chat_invite_link_->expire_date_); + } + if (chat_invite_link_->member_limit_ != 0) { + object("member_limit", chat_invite_link_->member_limit_); + } + object("is_primary", td::JsonBool(chat_invite_link_->is_primary_)); + object("is_revoked", td::JsonBool(chat_invite_link_->is_revoked_)); + } + + private: + const td_api::chatInviteLink *chat_invite_link_; + const Client *client_; +}; + class Client::JsonMessage : public Jsonable { public: JsonMessage(const MessageInfo *message, bool need_reply, const td::string &source, const Client *client) @@ -3150,9 +3175,9 @@ class Client::TdOnGetSupergroupMembersCountCallback : public TdQueryCallback { PromisedQueryPtr query_; }; -class Client::TdOnReplacePermanentChatInviteLinkCallback : public TdQueryCallback { +class Client::TdOnReplacePrimaryChatInviteLinkCallback : public TdQueryCallback { public: - explicit TdOnReplacePermanentChatInviteLinkCallback(PromisedQueryPtr query) : query_(std::move(query)) { + explicit TdOnReplacePrimaryChatInviteLinkCallback(PromisedQueryPtr query) : query_(std::move(query)) { } void on_result(object_ptr result) override { @@ -3169,6 +3194,27 @@ class Client::TdOnReplacePermanentChatInviteLinkCallback : public TdQueryCallbac PromisedQueryPtr query_; }; +class Client::TdOnGetChatInviteLinkCallback : public TdQueryCallback { + public: + TdOnGetChatInviteLinkCallback(const Client *client, PromisedQueryPtr query) + : client_(client), query_(std::move(query)) { + } + + void on_result(object_ptr result) override { + 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::chatInviteLink::ID); + auto invite_link = move_object_as(result); + return answer_query(JsonChatInviteLink(invite_link.get(), client_), std::move(query_)); + } + + private: + const Client *client_; + PromisedQueryPtr query_; +}; + class Client::TdOnGetGameHighScoresCallback : public TdQueryCallback { public: TdOnGetGameHighScoresCallback(const Client *client, PromisedQueryPtr query) @@ -6747,12 +6793,25 @@ td::Status Client::process_export_chat_invite_link_query(PromisedQueryPtr &query auto chat_id = query->arg("chat_id"); check_chat(chat_id, AccessRights::Write, std::move(query), [this](int64 chat_id, PromisedQueryPtr query) { - send_request(make_object(chat_id), - std::make_unique(std::move(query))); + send_request(make_object(chat_id), + std::make_unique(std::move(query))); }); return Status::OK(); } +td::Status Client::process_create_chat_invite_link_query(PromisedQueryPtr &query) { + auto chat_id = query->arg("chat_id"); + auto expire_date = get_integer_arg(query.get(), "expire_date", 0, 0); + auto member_limit = get_integer_arg(query.get(), "member_limit", 0, 0, 100000); + + check_chat(chat_id, AccessRights::Write, std::move(query), + [this, expire_date, member_limit](int64 chat_id, PromisedQueryPtr query) { + send_request(make_object(chat_id, expire_date, member_limit), + std::make_unique(this, std::move(query))); + }); + return Status::OK(); +} + td::Status Client::process_get_chat_query(PromisedQueryPtr &query) { auto chat_id = query->arg("chat_id"); @@ -7019,8 +7078,9 @@ td::Status Client::process_promote_chat_member_query(PromisedQueryPtr &query) { auto can_manage_voice_chats = to_bool(query->arg("can_manage_voice_chats")); auto is_anonymous = to_bool(query->arg("is_anonymous")); auto status = make_object( - td::string(), true, can_change_info, can_post_messages, can_edit_messages, can_delete_messages, can_invite_users, - can_restrict_members, can_pin_messages, can_promote_members, can_manage_voice_chats, is_anonymous); + td::string(), true, false, can_change_info, can_post_messages, can_edit_messages, can_delete_messages, + can_invite_users, can_restrict_members, can_pin_messages, can_promote_members, can_manage_voice_chats, + is_anonymous); check_chat(chat_id, AccessRights::Write, std::move(query), [this, user_id, status = std::move(status)](int64 chat_id, PromisedQueryPtr query) mutable { auto chat_info = get_chat(chat_id); @@ -8444,7 +8504,7 @@ bool Client::need_skip_update_message(int64 chat_id, const object_ptrttl_ > 0) { + if (message->ttl_ > 0 && message->ttl_expires_in_ == 0) { return true; } diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index 6198f09..a722179 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -91,6 +91,7 @@ class Client : public WebhookActor::Callback { class JsonChatPermissions; class JsonChatPhotoInfo; class JsonChatLocation; + class JsonChatInviteLink; class JsonChat; class JsonMessageSender; class JsonAnimation; @@ -175,7 +176,8 @@ class Client : public WebhookActor::Callback { class TdOnGetGroupMembersCallback; class TdOnGetSupergroupMembersCallback; class TdOnGetSupergroupMembersCountCallback; - class TdOnReplacePermanentChatInviteLinkCallback; + class TdOnReplacePrimaryChatInviteLinkCallback; + class TdOnGetChatInviteLinkCallback; class TdOnGetGameHighScoresCallback; class TdOnReturnFileCallback; class TdOnReturnStickerSetCallback; @@ -443,6 +445,7 @@ class Client : public WebhookActor::Callback { Status process_answer_shipping_query_query(PromisedQueryPtr &query); Status process_answer_pre_checkout_query_query(PromisedQueryPtr &query); Status process_export_chat_invite_link_query(PromisedQueryPtr &query); + Status process_create_chat_invite_link_query(PromisedQueryPtr &query); Status process_get_chat_query(PromisedQueryPtr &query); Status process_set_chat_photo_query(PromisedQueryPtr &query); Status process_delete_chat_photo_query(PromisedQueryPtr &query); From 90d29edcce8599721f6817474e7f1ac0ce82a7d9 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 25 Feb 2021 22:00:17 +0300 Subject: [PATCH 22/39] Add Chat.message_auto_delete_time field. --- telegram-bot-api/Client.cpp | 11 +++++++++++ telegram-bot-api/Client.h | 1 + 2 files changed, 12 insertions(+) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index da533cf..ea1848d 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -692,6 +692,9 @@ class Client::JsonChat : public Jsonable { LOG(ERROR) << "Pinned unknown, inaccessible or deleted message " << pinned_message_id_; } } + if (chat_info->message_auto_delete_time != 0) { + object("message_auto_delete_time", chat_info->message_auto_delete_time); + } } } @@ -4135,6 +4138,7 @@ void Client::on_update(object_ptr result) { chat_info->title = std::move(chat->title_); chat_info->photo = std::move(chat->photo_); chat_info->permissions = std::move(chat->permissions_); + chat_info->message_auto_delete_time = chat->message_ttl_setting_; break; } case td_api::updateChatTitle::ID: { @@ -4158,6 +4162,13 @@ void Client::on_update(object_ptr result) { chat_info->permissions = std::move(update->permissions_); break; } + case td_api::updateChatMessageTtlSetting::ID: { + auto update = move_object_as(result); + auto chat_info = add_chat(update->chat_id_); + CHECK(chat_info->type != ChatInfo::Type::Unknown); + chat_info->message_auto_delete_time = update->message_ttl_setting_; + break; + } case td_api::updateUser::ID: { auto update = move_object_as(result); add_user(users_, std::move(update->user_)); diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index a722179..5fa7601 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -595,6 +595,7 @@ class Client : public WebhookActor::Callback { enum class Type { Private, Group, Supergroup, Unknown }; Type type = Type::Unknown; td::string title; + int32 message_auto_delete_time = 0; object_ptr photo; object_ptr permissions; union { From 1db552102742c0794e24edee61deb45e7cb764a8 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 25 Feb 2021 22:11:11 +0300 Subject: [PATCH 23/39] Add fast path in check_message. --- telegram-bot-api/Client.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index ea1848d..a98a8c8 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -3723,11 +3723,16 @@ void Client::check_message(Slice chat_id_str, int64 message_id, bool allow_empty check_chat(chat_id_str, access_rights, std::move(query), [this, message_id, allow_empty, message_type, on_success = std::move(on_success)]( int64 chat_id, PromisedQueryPtr query) mutable { - if (!have_message_access(chat_id)) { + if ((message_id <= 0 && !allow_empty) || !have_message_access(chat_id)) { return fail_query_with_error(std::move(query), 400, "MESSAGE_NOT_FOUND", PSLICE() << message_type << " not found"); } + if (message_id <= 0) { + CHECK(allow_empty); + return on_success(chat_id, 0, std::move(query)); + } + send_request(make_object(chat_id, message_id), std::make_unique>( this, chat_id, allow_empty, message_type, std::move(query), std::move(on_success))); @@ -6460,7 +6465,7 @@ td::Status Client::process_send_media_group_query(PromisedQueryPtr &query) { std::make_unique(this, std::move(query))); }; check_message(chat_id, reply_to_message_id, reply_to_message_id <= 0 || allow_sending_without_reply, - AccessRights::Write, "reply message", std::move(query), std::move(on_success)); + AccessRights::Write, "replied message", std::move(query), std::move(on_success)); }); return Status::OK(); } @@ -7696,7 +7701,7 @@ void Client::do_send_message(object_ptr input_messa std::make_unique(this, std::move(query))); }; check_message(chat_id, reply_to_message_id, reply_to_message_id <= 0 || allow_sending_without_reply, - AccessRights::Write, "reply message", std::move(query), std::move(on_success)); + AccessRights::Write, "replied message", std::move(query), std::move(on_success)); }); } From c8bc4c9d3a225c7ba0933a9970a63b505df7da07 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 25 Feb 2021 22:25:33 +0300 Subject: [PATCH 24/39] Add editChatInviteLink method. --- telegram-bot-api/Client.cpp | 16 ++++++++++++++++ telegram-bot-api/Client.h | 1 + 2 files changed, 17 insertions(+) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index a98a8c8..0743b7a 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -213,6 +213,7 @@ bool Client::init_methods() { methods_.emplace("answerprecheckoutquery", &Client::process_answer_pre_checkout_query_query); methods_.emplace("exportchatinvitelink", &Client::process_export_chat_invite_link_query); methods_.emplace("createchatinvitelink", &Client::process_create_chat_invite_link_query); + methods_.emplace("editchatinvitelink", &Client::process_edit_chat_invite_link_query); methods_.emplace("getchat", &Client::process_get_chat_query); methods_.emplace("setchatphoto", &Client::process_set_chat_photo_query); methods_.emplace("deletechatphoto", &Client::process_delete_chat_photo_query); @@ -6828,6 +6829,21 @@ td::Status Client::process_create_chat_invite_link_query(PromisedQueryPtr &query return Status::OK(); } +td::Status Client::process_edit_chat_invite_link_query(PromisedQueryPtr &query) { + auto chat_id = query->arg("chat_id"); + auto invite_link = query->arg("invite_link"); + auto expire_date = get_integer_arg(query.get(), "expire_date", 0, 0); + auto member_limit = get_integer_arg(query.get(), "member_limit", 0, 0, 100000); + + check_chat( + chat_id, AccessRights::Write, std::move(query), + [this, invite_link = invite_link.str(), expire_date, member_limit](int64 chat_id, PromisedQueryPtr query) { + send_request(make_object(chat_id, invite_link, expire_date, member_limit), + std::make_unique(this, std::move(query))); + }); + return Status::OK(); +} + td::Status Client::process_get_chat_query(PromisedQueryPtr &query) { auto chat_id = query->arg("chat_id"); diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index 5fa7601..135bfd7 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -446,6 +446,7 @@ class Client : public WebhookActor::Callback { Status process_answer_pre_checkout_query_query(PromisedQueryPtr &query); Status process_export_chat_invite_link_query(PromisedQueryPtr &query); Status process_create_chat_invite_link_query(PromisedQueryPtr &query); + Status process_edit_chat_invite_link_query(PromisedQueryPtr &query); Status process_get_chat_query(PromisedQueryPtr &query); Status process_set_chat_photo_query(PromisedQueryPtr &query); Status process_delete_chat_photo_query(PromisedQueryPtr &query); From 6ab61f2fed3a46c69d29100a18831c34e7b28584 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 25 Feb 2021 22:32:23 +0300 Subject: [PATCH 25/39] Add revokeChatInviteLink method. --- telegram-bot-api/Client.cpp | 36 +++++++++++++++++++++++++++--------- telegram-bot-api/Client.h | 1 + 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 0743b7a..5a0d210 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -214,6 +214,7 @@ bool Client::init_methods() { methods_.emplace("exportchatinvitelink", &Client::process_export_chat_invite_link_query); methods_.emplace("createchatinvitelink", &Client::process_create_chat_invite_link_query); methods_.emplace("editchatinvitelink", &Client::process_edit_chat_invite_link_query); + methods_.emplace("revokechatinvitelink", &Client::process_revoke_chat_invite_link_query); methods_.emplace("getchat", &Client::process_get_chat_query); methods_.emplace("setchatphoto", &Client::process_set_chat_photo_query); methods_.emplace("deletechatphoto", &Client::process_delete_chat_photo_query); @@ -3209,9 +3210,15 @@ class Client::TdOnGetChatInviteLinkCallback : public TdQueryCallback { return fail_query_with_error(std::move(query_), move_object_as(result)); } - CHECK(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_)); + 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_)); + } 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_)); + } } private: @@ -6835,12 +6842,23 @@ td::Status Client::process_edit_chat_invite_link_query(PromisedQueryPtr &query) auto expire_date = get_integer_arg(query.get(), "expire_date", 0, 0); auto member_limit = get_integer_arg(query.get(), "member_limit", 0, 0, 100000); - check_chat( - chat_id, AccessRights::Write, std::move(query), - [this, invite_link = invite_link.str(), expire_date, member_limit](int64 chat_id, PromisedQueryPtr query) { - send_request(make_object(chat_id, invite_link, expire_date, member_limit), - std::make_unique(this, std::move(query))); - }); + check_chat(chat_id, AccessRights::Write, std::move(query), + [this, invite_link = invite_link.str(), expire_date, member_limit](int64 chat_id, PromisedQueryPtr query) { + send_request(make_object(chat_id, invite_link, expire_date, member_limit), + std::make_unique(this, std::move(query))); + }); + return Status::OK(); +} + +td::Status Client::process_revoke_chat_invite_link_query(PromisedQueryPtr &query) { + auto chat_id = query->arg("chat_id"); + auto invite_link = query->arg("invite_link"); + + check_chat(chat_id, AccessRights::Write, std::move(query), + [this, invite_link = invite_link.str()](int64 chat_id, PromisedQueryPtr query) { + send_request(make_object(chat_id, invite_link), + std::make_unique(this, std::move(query))); + }); return Status::OK(); } diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index 135bfd7..7025b42 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -447,6 +447,7 @@ class Client : public WebhookActor::Callback { Status process_export_chat_invite_link_query(PromisedQueryPtr &query); Status process_create_chat_invite_link_query(PromisedQueryPtr &query); Status process_edit_chat_invite_link_query(PromisedQueryPtr &query); + Status process_revoke_chat_invite_link_query(PromisedQueryPtr &query); Status process_get_chat_query(PromisedQueryPtr &query); Status process_set_chat_photo_query(PromisedQueryPtr &query); Status process_delete_chat_photo_query(PromisedQueryPtr &query); From 8323701b2743a8a47ff7ac08f29f7881e144fddf Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 25 Feb 2021 22:40:54 +0300 Subject: [PATCH 26/39] Add can_manage_chat administrator privilege. --- 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 5a0d210..9526796 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -2180,6 +2180,7 @@ class Client::JsonChatMember : public Jsonable { case td_api::chatMemberStatusAdministrator::ID: { auto administrator = static_cast(member_->status_.get()); object("can_be_edited", td::JsonBool(administrator->can_be_edited_)); + object("can_manage_chat", td::JsonBool(administrator->can_manage_chat_)); object("can_change_info", td::JsonBool(administrator->can_change_info_)); if (chat_type_ == Client::ChatType::Channel) { object("can_post_messages", td::JsonBool(administrator->can_post_messages_)); @@ -7117,6 +7118,7 @@ td::Status Client::process_leave_chat_query(PromisedQueryPtr &query) { td::Status Client::process_promote_chat_member_query(PromisedQueryPtr &query) { auto chat_id = query->arg("chat_id"); TRY_RESULT(user_id, get_user_id(query.get())); + auto can_manage_chat = to_bool(query->arg("can_manage_chat")); auto can_change_info = to_bool(query->arg("can_change_info")); auto can_post_messages = to_bool(query->arg("can_post_messages")); auto can_edit_messages = to_bool(query->arg("can_edit_messages")); @@ -7128,7 +7130,7 @@ td::Status Client::process_promote_chat_member_query(PromisedQueryPtr &query) { auto can_manage_voice_chats = to_bool(query->arg("can_manage_voice_chats")); auto is_anonymous = to_bool(query->arg("is_anonymous")); auto status = make_object( - td::string(), true, false, can_change_info, can_post_messages, can_edit_messages, can_delete_messages, + td::string(), true, can_manage_chat, can_change_info, can_post_messages, can_edit_messages, can_delete_messages, can_invite_users, can_restrict_members, can_pin_messages, can_promote_members, can_manage_voice_chats, is_anonymous); check_chat(chat_id, AccessRights::Write, std::move(query), From 418946b0e10e0b29e03aee18a3f85991ee59625f Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 26 Feb 2021 03:02:26 +0300 Subject: [PATCH 27/39] Add update 'chat_member'. --- telegram-bot-api/Client.cpp | 37 +++++++++++++++++++++++++++++++++++++ telegram-bot-api/Client.h | 8 ++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 9526796..bb72561 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -2266,6 +2266,29 @@ class Client::JsonChatMembers : public Jsonable { const Client *client_; }; +class Client::JsonChatMemberUpdated : public Jsonable { + public: + JsonChatMemberUpdated(const td_api::updateChatMember *update, const Client *client) + : update_(update), client_(client) { + } + void store(JsonValueScope *scope) const { + auto object = scope->enter_object(); + object("chat", JsonChat(update_->chat_id_, false, client_)); + object("actor", JsonUser(update_->actor_user_id_, client_)); + object("date", update_->date_); + auto chat_type = client_->get_chat_type(update_->chat_id_); + object("old_chat_member", JsonChatMember(update_->old_chat_member_.get(), chat_type, client_)); + object("new_chat_member", JsonChatMember(update_->new_chat_member_.get(), chat_type, client_)); + if (update_->invite_link_ != nullptr) { + object("invite_link", JsonChatInviteLink(update_->invite_link_.get(), client_)); + } + } + + private: + const td_api::updateChatMember *update_; + const Client *client_; +}; + class Client::JsonGameHighScore : public Jsonable { public: JsonGameHighScore(const td_api::gameHighScore *score, const Client *client) : score_(score), client_(client) { @@ -4313,6 +4336,9 @@ void Client::on_update(object_ptr result) { case td_api::updateNewCustomQuery::ID: add_new_custom_query(move_object_as(result)); break; + case td_api::updateChatMember::ID: + add_update_chat_member(move_object_as(result)); + break; default: // we are not interested in this updates break; @@ -8227,6 +8253,8 @@ Client::Slice Client::get_update_type_name(UpdateType update_type) { return Slice("poll"); case UpdateType::PollAnswer: return Slice("poll_answer"); + case UpdateType::ChatMember: + return Slice("chat_member"); default: UNREACHABLE(); return Slice(); @@ -8498,6 +8526,15 @@ void Client::add_new_custom_query(object_ptr &&que add_update(UpdateType::CustomQuery, JsonCustomJson(query->data_), timeout, 0); } +void Client::add_update_chat_member(object_ptr &&update) { + CHECK(update != nullptr); + auto left_time = update->date_ + 86400 - get_unix_time(); + if (left_time > 0) { + auto webhook_queue_id = update->chat_id_ + (static_cast(5) << 33); + add_update(UpdateType::ChatMember, JsonChatMemberUpdated(update.get(), this), left_time, webhook_queue_id); + } +} + td::int32 Client::choose_added_member_id(const td_api::messageChatAddMembers *message_add_members) const { CHECK(message_add_members != nullptr); for (auto &member_user_id : message_add_members->member_user_ids_) { diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index 7025b42..af028fb 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -136,6 +136,7 @@ class Client : public WebhookActor::Callback { class JsonChatPhotos; class JsonChatMember; class JsonChatMembers; + class JsonChatMemberUpdated; class JsonGameHighScore; class JsonAddress; class JsonOrderInfo; @@ -750,6 +751,8 @@ class Client : public WebhookActor::Callback { void add_new_custom_query(object_ptr &&query); + void add_update_chat_member(object_ptr &&update); + // append only before Size enum class UpdateType : int32 { Message, @@ -765,6 +768,7 @@ class Client : public WebhookActor::Callback { PreCheckoutQuery, Poll, PollAnswer, + ChatMember, Size }; @@ -792,8 +796,8 @@ class Client : public WebhookActor::Callback { bool have_message_access(int64 chat_id) const; - // by default all 13 update types up to PollAnswer are allowed - static constexpr td::uint32 DEFAULT_ALLOWED_UPDATE_TYPES = ((1 << 13) - 1); + // by default all 14 update types up to ChatMember are allowed + static constexpr td::uint32 DEFAULT_ALLOWED_UPDATE_TYPES = ((1 << 14) - 1); object_ptr authorization_state_; bool was_authorized_ = false; From 93158f05a742c1b27f594005737066ebc7797a04 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 26 Feb 2021 03:50:42 +0300 Subject: [PATCH 28/39] Add Internal Server Error logging. --- telegram-bot-api/Client.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index bb72561..14f244c 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -126,6 +126,7 @@ void Client::fail_query_with_error(PromisedQueryPtr query, int32 error_code, Sli break; case 500: prefix = Slice("Internal Server Error"); + LOG(ERROR) << "Receive Internal Server Error: " << real_error_message; break; default: LOG(ERROR) << "Unsupported error " << real_error_code << ": " << real_error_message; From 778c155b5c8e02abddf7b5a3a0c5fcb08f8898fc Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 27 Feb 2021 03:40:58 +0300 Subject: [PATCH 29/39] Add update "my_chat_member". --- telegram-bot-api/Client.cpp | 8 ++++++-- telegram-bot-api/Client.h | 6 ++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 14f244c..9239dbe 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -8254,6 +8254,8 @@ Client::Slice Client::get_update_type_name(UpdateType update_type) { return Slice("poll"); case UpdateType::PollAnswer: return Slice("poll_answer"); + case UpdateType::MyChatMember: + return Slice("my_chat_member"); case UpdateType::ChatMember: return Slice("chat_member"); default: @@ -8531,8 +8533,10 @@ void Client::add_update_chat_member(object_ptr &&updat CHECK(update != nullptr); auto left_time = update->date_ + 86400 - get_unix_time(); if (left_time > 0) { - auto webhook_queue_id = update->chat_id_ + (static_cast(5) << 33); - add_update(UpdateType::ChatMember, JsonChatMemberUpdated(update.get(), this), left_time, webhook_queue_id); + bool is_my = (update->old_chat_member_->user_id_ == my_id_); + auto webhook_queue_id = update->chat_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); } } diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index af028fb..b209109 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -768,6 +768,7 @@ class Client : public WebhookActor::Callback { PreCheckoutQuery, Poll, PollAnswer, + MyChatMember, ChatMember, Size }; @@ -796,8 +797,9 @@ class Client : public WebhookActor::Callback { bool have_message_access(int64 chat_id) const; - // by default all 14 update types up to ChatMember are allowed - static constexpr td::uint32 DEFAULT_ALLOWED_UPDATE_TYPES = ((1 << 14) - 1); + // by default ChatMember updates are disabled + static constexpr td::uint32 DEFAULT_ALLOWED_UPDATE_TYPES = + (1 << static_cast(UpdateType::Size)) - 1 - (1 << static_cast(UpdateType::ChatMember)); object_ptr authorization_state_; bool was_authorized_ = false; From e6eda8c31d5fb4649e7a285c77337fa85c5c25b6 Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 27 Feb 2021 22:32:50 +0300 Subject: [PATCH 30/39] Add Client::get_input_entities function. --- telegram-bot-api/Client.cpp | 45 ++++++++++++++++--------------------- telegram-bot-api/Client.h | 2 ++ 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 9239dbe..8db11f6 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -5579,16 +5579,23 @@ td::Result>> Cl return std::move(errors); } -td::Result> Client::get_caption(const Query *query) { - JsonValue entities; - auto r_value = json_decode(query->arg("caption_entities")); - if (r_value.is_ok()) { - entities = r_value.move_as_ok(); - } else { - LOG(INFO) << "Can't parse JSON object: " << r_value.error(); +JsonValue Client::get_input_entities(const Query *query, Slice field_name) { + auto entities = query->arg(field_name); + if (!entities.empty()) { + auto r_value = json_decode(entities); + if (r_value.is_ok()) { + return r_value.move_as_ok(); + } + + LOG(INFO) << "Can't parse entities JSON object: " << r_value.error(); } - return get_formatted_text(query->arg("caption").str(), query->arg("parse_mode").str(), std::move(entities)); + return JsonValue(); +} + +td::Result> Client::get_caption(const Query *query) { + return get_formatted_text(query->arg("caption").str(), query->arg("parse_mode").str(), + get_input_entities(query, "caption_entities")); } td::Result> Client::get_text_entity_type(td::JsonObject &object) { @@ -5697,16 +5704,8 @@ td::Result> Client::get_formatted_text } td::Result> Client::get_input_message_text(const Query *query) { - JsonValue entities; - auto r_value = json_decode(query->arg("entities")); - if (r_value.is_ok()) { - entities = r_value.move_as_ok(); - } else { - LOG(INFO) << "Can't parse JSON object: " << r_value.error(); - } - return get_input_message_text(query->arg("text").str(), to_bool(query->arg("disable_web_page_preview")), - query->arg("parse_mode").str(), std::move(entities)); + query->arg("parse_mode").str(), get_input_entities(query, "entities")); } td::Result> Client::get_input_message_text(td::string text, @@ -6401,15 +6400,9 @@ td::Status Client::process_send_poll_query(PromisedQueryPtr &query) { object_ptr poll_type; auto type = query->arg("type"); if (type == "quiz") { - JsonValue entities; - auto r_value = json_decode(query->arg("explanation_entities")); - if (r_value.is_ok()) { - entities = r_value.move_as_ok(); - } else { - LOG(INFO) << "Can't parse JSON object: " << r_value.error(); - } - TRY_RESULT(explanation, get_formatted_text(query->arg("explanation").str(), - query->arg("explanation_parse_mode").str(), std::move(entities))); + TRY_RESULT(explanation, + get_formatted_text(query->arg("explanation").str(), query->arg("explanation_parse_mode").str(), + get_input_entities(query.get(), "explanation_entities"))); poll_type = make_object(get_integer_arg(query.get(), "correct_option_id", -1), std::move(explanation)); diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index b209109..2ad425d 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -351,6 +351,8 @@ class Client : public WebhookActor::Callback { static td::Result>> get_passport_element_errors( const Query *query); + static td::JsonValue get_input_entities(const Query *query, Slice field_name); + static td::Result> get_caption(const Query *query); static td::Result> get_text_entity_type(td::JsonObject &object); From b510a323f2145735888ea7df2baba9045133c1be Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Mar 2021 23:50:35 +0300 Subject: [PATCH 31/39] Update TDLib. --- td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/td b/td index 3b3801a..b88f5ba 160000 --- a/td +++ b/td @@ -1 +1 @@ -Subproject commit 3b3801abbec641ac66a050760d198dfc7bca92be +Subproject commit b88f5ba6f30aa7aadbaf54c5fa01b65aba8bc1bd From e128906890babc0337eb267786fd454453456e14 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 2 Mar 2021 15:28:56 +0300 Subject: [PATCH 32/39] Don't log "Request aborted" errors. --- 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 8db11f6..28a7b77 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -126,7 +126,9 @@ void Client::fail_query_with_error(PromisedQueryPtr query, int32 error_code, Sli break; case 500: prefix = Slice("Internal Server Error"); - LOG(ERROR) << "Receive Internal Server Error: " << real_error_message; + if (real_error_message != Slice("Request aborted")) { + LOG(ERROR) << "Receive Internal Server Error: " << real_error_message; + } break; default: LOG(ERROR) << "Unsupported error " << real_error_code << ": " << real_error_message; From 871cbcfeeced6a671df4e472638d2393f5b4251b Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 5 Mar 2021 23:48:13 +0300 Subject: [PATCH 33/39] Update TDLib and improve field names. --- td | 2 +- telegram-bot-api/Client.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/td b/td index b88f5ba..29ded98 160000 --- a/td +++ b/td @@ -1 +1 @@ -Subproject commit b88f5ba6f30aa7aadbaf54c5fa01b65aba8bc1bd +Subproject commit 29ded98a46cf98e77de1d725ed33e28f76c0a23d diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 28a7b77..d0e3482 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -1800,7 +1800,7 @@ void Client::JsonMessage::store(JsonValueScope *scope) const { break; case td_api::messageChatSetTtl::ID: { auto content = static_cast(message_->content.get()); - object("message_auto_delete_time_changed", JsonChatSetTtl(content)); + object("message_auto_delete_timer_changed", JsonChatSetTtl(content)); break; } case td_api::messageUnsupported::ID: @@ -1850,7 +1850,7 @@ void Client::JsonMessage::store(JsonValueScope *scope) const { } case td_api::messageInviteVoiceChatParticipants::ID: { auto content = static_cast(message_->content.get()); - object("voice_chat_members_invited", JsonInviteVoiceChatParticipants(content, client_)); + object("voice_chat_participants_invited", JsonInviteVoiceChatParticipants(content, client_)); break; } default: From fcfb194c549c5d2d56d296fc6f6ea80c504f6123 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 9 Mar 2021 13:24:17 +0300 Subject: [PATCH 34/39] Use "from" instead of "actor" for consistency with most other updates. --- telegram-bot-api/Client.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index d0e3482..fa0a95c 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -2277,7 +2277,7 @@ class Client::JsonChatMemberUpdated : public Jsonable { void store(JsonValueScope *scope) const { auto object = scope->enter_object(); object("chat", JsonChat(update_->chat_id_, false, client_)); - object("actor", JsonUser(update_->actor_user_id_, client_)); + object("from", JsonUser(update_->actor_user_id_, client_)); object("date", update_->date_); auto chat_type = client_->get_chat_type(update_->chat_id_); object("old_chat_member", JsonChatMember(update_->old_chat_member_.get(), chat_type, client_)); From 202ddaffabcff16523dba672a27b35c92a050338 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 9 Mar 2021 13:30:42 +0300 Subject: [PATCH 35/39] Update version to 5.1. --- CMakeLists.txt | 2 +- telegram-bot-api/Client.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f3eed02..56b275e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR) -project(TelegramBotApi VERSION 5.0.1 LANGUAGES CXX) +project(TelegramBotApi VERSION 5.1 LANGUAGES CXX) add_subdirectory(td EXCLUDE_FROM_ALL) diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index fa0a95c..992ff67 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -3998,7 +3998,7 @@ void Client::on_update_authorization_state() { parameters->api_hash_ = parameters_->api_hash_; parameters->system_language_code_ = "en"; parameters->device_model_ = "server"; - parameters->application_version_ = "5.0.1"; + parameters->application_version_ = "5.1"; parameters->enable_storage_optimizer_ = true; parameters->ignore_file_names_ = true; From 0099943611d2cca6b7d8cb24435f64e49bbae6c0 Mon Sep 17 00:00:00 2001 From: Giuseppe Marino Date: Tue, 16 Mar 2021 18:49:09 +0100 Subject: [PATCH 36/39] update submodule --- td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/td b/td index 1ea79d2..ebeaf7f 160000 --- a/td +++ b/td @@ -1 +1 @@ -Subproject commit 1ea79d273976c22655742d4031ebbe62dba6cd7c +Subproject commit ebeaf7f90e733441f417a52dee7920f6b76c8f71 From ff7d232f420f6975b43de3a06d47554571b745ac Mon Sep 17 00:00:00 2001 From: Giuseppe Marino Date: Tue, 16 Mar 2021 20:24:58 +0100 Subject: [PATCH 37/39] Upstream merge: logout is invalid api id --- 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 d4d5dea..44a6484 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -2703,7 +2703,7 @@ class Client::TdOnAuthorizationQueryCallback : public TdQueryCallback { fail_query(401, "Unauthorized: Log in failed, logging out due to " + td::oneline(to_string(error)), std::move(query_)); LOG(WARNING) << "Logging out due to " << td::oneline(to_string(error)); - client_->log_out(); + client_->log_out(false); } else { if (client_->authorization_state_->get_id() == td_api::authorizationStateWaitRegistration::ID && !client_->parameters_->allow_users_registration_) { @@ -2711,7 +2711,7 @@ class Client::TdOnAuthorizationQueryCallback : public TdQueryCallback { "Unauthorized: It is not allowed to register users with this api. You can enable it with the " "command line option --allow-users-registration. Logging out", std::move(query_)); - return client_->log_out(); + return client_->log_out(false); } if (send_token_) { answer_query(JsonAuthorizationState(client_->authorization_state_.get(), client_->bot_token_), std::move(query_)); From 33877f740d70479fd3879944c1cf41430d26cdc1 Mon Sep 17 00:00:00 2001 From: Giuseppe Marino Date: Tue, 16 Mar 2021 20:26:37 +0100 Subject: [PATCH 38/39] Upstream merge: quick fix report chat now accepts a custom text for any reason Will have to think about adding an additional parameter --- 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 44a6484..68d5298 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -6649,7 +6649,7 @@ td::Result> Client::get_report_reas } else if (reason == "violence") { result = make_object(); } else { - result = make_object(reason.str()); + result = make_object(); } return std::move(result); } @@ -8494,7 +8494,8 @@ td::Status Client::process_report_chat_query(PromisedQueryPtr &query) { check_chat(chat_id, AccessRights::Read, std::move(query), [this, reason = std::move(reason), message_ids = std::move(message_ids)](int64 chat_id, PromisedQueryPtr query) mutable { - send_request(make_object(chat_id, std::move(reason), std::move(message_ids)), + + send_request(make_object(chat_id, std::move(message_ids), std::move(reason), reason->get_id() == td_api::chatReportReasonCustom::ID ? query->arg("reason").str() : td::string()), std::make_unique(std::move(query))); }); return Status::OK(); From d73fb848cda2704242119d4cb7bfb47444596769 Mon Sep 17 00:00:00 2001 From: Giuseppe Marino Date: Tue, 16 Mar 2021 20:27:04 +0100 Subject: [PATCH 39/39] Upstream merge: createNewSupergroupChat needs an extra bool for imported chats --- 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 68d5298..d8b943e 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -8508,10 +8508,10 @@ td::Status Client::process_create_chat_query(PromisedQueryPtr &query) { auto description = query->arg("description"); if (chat_type == "supergroup") { - send_request(make_object(title.str(), false, description.str(), nullptr), + send_request(make_object(title.str(), false, description.str(), nullptr, false), std::make_unique(this, std::move(query))); } else if (chat_type == "channel") { - send_request(make_object(title.str(), true, description.str(), nullptr), + send_request(make_object(title.str(), true, description.str(), nullptr, false), std::make_unique(this, std::move(query))); } else if (chat_type == "group") { TRY_RESULT(initial_members, get_int_array_arg(query.get(), "user_ids"))