mirror of
https://github.com/tdlight-team/tdlight-telegram-bot-api.git
synced 2024-12-04 17:42:55 +01:00
Merge remote-tracking branch 'upstream/master' into merge-upstream
This commit is contained in:
commit
188fa9d8b0
@ -6,7 +6,7 @@ if (POLICY CMP0065)
|
|||||||
cmake_policy(SET CMP0065 NEW)
|
cmake_policy(SET CMP0065 NEW)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
project(TelegramBotApi VERSION 5.3.3 LANGUAGES CXX)
|
project(TelegramBotApi VERSION 5.4 LANGUAGES CXX)
|
||||||
|
|
||||||
if (POLICY CMP0069)
|
if (POLICY CMP0069)
|
||||||
option(TELEGRAM_BOT_API_ENABLE_LTO "Use \"ON\" to enable Link Time Optimization.")
|
option(TELEGRAM_BOT_API_ENABLE_LTO "Use \"ON\" to enable Link Time Optimization.")
|
||||||
|
@ -250,7 +250,7 @@ function onOptionsChanged() {
|
|||||||
pre_text.push('Download and install <a href="https://git-scm.com/download/win">Git</a>.');
|
pre_text.push('Download and install <a href="https://git-scm.com/download/win">Git</a>.');
|
||||||
}
|
}
|
||||||
if (os_linux && linux_distro === 'Other') {
|
if (os_linux && linux_distro === 'Other') {
|
||||||
var compiler = use_clang ? 'clang >= 3.4' : 'g++ >= 4.9.2';
|
var compiler = use_clang ? 'clang >= 3.4, libc++' : 'g++ >= 4.9.2';
|
||||||
pre_text.push('Install Git, ' + compiler + ', make, CMake >= 3.0.2, OpenSSL-dev, zlib-dev, gperf using your package manager.');
|
pre_text.push('Install Git, ' + compiler + ', make, CMake >= 3.0.2, OpenSSL-dev, zlib-dev, gperf using your package manager.');
|
||||||
}
|
}
|
||||||
if (os_freebsd) {
|
if (os_freebsd) {
|
||||||
|
2
td
2
td
@ -1 +1 @@
|
|||||||
Subproject commit 0126cec2686e3b95cc1b6dfb5676d364da0e091b
|
Subproject commit eb346f5573040803d4424049dd2ba8aaa039fa56
|
@ -75,8 +75,8 @@ void Client::fail_query_with_error(PromisedQueryPtr query, int32 error_code, Sli
|
|||||||
}
|
}
|
||||||
int32 real_error_code = error_code;
|
int32 real_error_code = error_code;
|
||||||
Slice real_error_message = error_message;
|
Slice real_error_message = error_message;
|
||||||
if (error_code < 300 || error_code == 404) {
|
if (error_code < 400 || error_code == 404) {
|
||||||
if (error_code <= 0) {
|
if (error_code < 200) {
|
||||||
LOG(ERROR) << "Receive error \"" << real_error_message << "\" with code " << error_code << " from " << *query;
|
LOG(ERROR) << "Receive error \"" << real_error_message << "\" with code " << error_code << " from " << *query;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,6 +278,8 @@ bool Client::init_methods() {
|
|||||||
methods_.emplace("kickchatmember", &Client::process_ban_chat_member_query);
|
methods_.emplace("kickchatmember", &Client::process_ban_chat_member_query);
|
||||||
methods_.emplace("restrictchatmember", &Client::process_restrict_chat_member_query);
|
methods_.emplace("restrictchatmember", &Client::process_restrict_chat_member_query);
|
||||||
methods_.emplace("unbanchatmember", &Client::process_unban_chat_member_query);
|
methods_.emplace("unbanchatmember", &Client::process_unban_chat_member_query);
|
||||||
|
methods_.emplace("approvechatjoinrequest", &Client::process_approve_chat_join_request_query);
|
||||||
|
methods_.emplace("declinechatjoinrequest", &Client::process_decline_chat_join_request_query);
|
||||||
methods_.emplace("getstickerset", &Client::process_get_sticker_set_query);
|
methods_.emplace("getstickerset", &Client::process_get_sticker_set_query);
|
||||||
methods_.emplace("uploadstickerfile", &Client::process_upload_sticker_file_query);
|
methods_.emplace("uploadstickerfile", &Client::process_upload_sticker_file_query);
|
||||||
methods_.emplace("createnewstickerset", &Client::process_create_new_sticker_set_query);
|
methods_.emplace("createnewstickerset", &Client::process_create_new_sticker_set_query);
|
||||||
@ -624,6 +626,9 @@ class Client::JsonChatInviteLink : public Jsonable {
|
|||||||
void store(JsonValueScope *scope) const {
|
void store(JsonValueScope *scope) const {
|
||||||
auto object = scope->enter_object();
|
auto object = scope->enter_object();
|
||||||
object("invite_link", chat_invite_link_->invite_link_);
|
object("invite_link", chat_invite_link_->invite_link_);
|
||||||
|
if (!chat_invite_link_->name_.empty()) {
|
||||||
|
object("name", chat_invite_link_->name_);
|
||||||
|
}
|
||||||
object("creator", JsonUser(chat_invite_link_->creator_user_id_, client_));
|
object("creator", JsonUser(chat_invite_link_->creator_user_id_, client_));
|
||||||
if (chat_invite_link_->expire_date_ != 0) {
|
if (chat_invite_link_->expire_date_ != 0) {
|
||||||
object("expire_date", chat_invite_link_->expire_date_);
|
object("expire_date", chat_invite_link_->expire_date_);
|
||||||
@ -631,6 +636,10 @@ class Client::JsonChatInviteLink : public Jsonable {
|
|||||||
if (chat_invite_link_->member_limit_ != 0) {
|
if (chat_invite_link_->member_limit_ != 0) {
|
||||||
object("member_limit", chat_invite_link_->member_limit_);
|
object("member_limit", chat_invite_link_->member_limit_);
|
||||||
}
|
}
|
||||||
|
if (chat_invite_link_->pending_join_request_count_ != 0) {
|
||||||
|
object("pending_join_request_count", chat_invite_link_->pending_join_request_count_);
|
||||||
|
}
|
||||||
|
object("creates_join_request", td::JsonBool(chat_invite_link_->creates_join_request_));
|
||||||
object("is_primary", td::JsonBool(chat_invite_link_->is_primary_));
|
object("is_primary", td::JsonBool(chat_invite_link_->is_primary_));
|
||||||
object("is_revoked", td::JsonBool(chat_invite_link_->is_revoked_));
|
object("is_revoked", td::JsonBool(chat_invite_link_->is_revoked_));
|
||||||
}
|
}
|
||||||
@ -1519,54 +1528,54 @@ class Client::JsonProximityAlertTriggered : public Jsonable {
|
|||||||
const Client *client_;
|
const Client *client_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Client::JsonVoiceChatScheduled : public Jsonable {
|
class Client::JsonVideoChatScheduled : public Jsonable {
|
||||||
public:
|
public:
|
||||||
explicit JsonVoiceChatScheduled(const td_api::messageVoiceChatScheduled *voice_chat_scheduled)
|
explicit JsonVideoChatScheduled(const td_api::messageVideoChatScheduled *video_chat_scheduled)
|
||||||
: voice_chat_scheduled_(voice_chat_scheduled) {
|
: video_chat_scheduled_(video_chat_scheduled) {
|
||||||
}
|
}
|
||||||
void store(JsonValueScope *scope) const {
|
void store(JsonValueScope *scope) const {
|
||||||
auto object = scope->enter_object();
|
auto object = scope->enter_object();
|
||||||
object("start_date", voice_chat_scheduled_->start_date_);
|
object("start_date", video_chat_scheduled_->start_date_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const td_api::messageVoiceChatScheduled *voice_chat_scheduled_;
|
const td_api::messageVideoChatScheduled *video_chat_scheduled_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Client::JsonVoiceChatStarted : public Jsonable {
|
class Client::JsonVideoChatStarted : public Jsonable {
|
||||||
public:
|
public:
|
||||||
void store(JsonValueScope *scope) const {
|
void store(JsonValueScope *scope) const {
|
||||||
auto object = scope->enter_object();
|
auto object = scope->enter_object();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Client::JsonVoiceChatEnded : public Jsonable {
|
class Client::JsonVideoChatEnded : public Jsonable {
|
||||||
public:
|
public:
|
||||||
explicit JsonVoiceChatEnded(const td_api::messageVoiceChatEnded *voice_chat_ended)
|
explicit JsonVideoChatEnded(const td_api::messageVideoChatEnded *video_chat_ended)
|
||||||
: voice_chat_ended_(voice_chat_ended) {
|
: video_chat_ended_(video_chat_ended) {
|
||||||
}
|
}
|
||||||
void store(JsonValueScope *scope) const {
|
void store(JsonValueScope *scope) const {
|
||||||
auto object = scope->enter_object();
|
auto object = scope->enter_object();
|
||||||
object("duration", voice_chat_ended_->duration_);
|
object("duration", video_chat_ended_->duration_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const td_api::messageVoiceChatEnded *voice_chat_ended_;
|
const td_api::messageVideoChatEnded *video_chat_ended_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Client::JsonInviteVoiceChatParticipants : public Jsonable {
|
class Client::JsonInviteVideoChatParticipants : public Jsonable {
|
||||||
public:
|
public:
|
||||||
JsonInviteVoiceChatParticipants(const td_api::messageInviteVoiceChatParticipants *invite_voice_chat_participants,
|
JsonInviteVideoChatParticipants(const td_api::messageInviteVideoChatParticipants *invite_video_chat_participants,
|
||||||
const Client *client)
|
const Client *client)
|
||||||
: invite_voice_chat_participants_(invite_voice_chat_participants), client_(client) {
|
: invite_video_chat_participants_(invite_video_chat_participants), client_(client) {
|
||||||
}
|
}
|
||||||
void store(JsonValueScope *scope) const {
|
void store(JsonValueScope *scope) const {
|
||||||
auto object = scope->enter_object();
|
auto object = scope->enter_object();
|
||||||
object("users", JsonUsers(invite_voice_chat_participants_->user_ids_, client_));
|
object("users", JsonUsers(invite_video_chat_participants_->user_ids_, client_));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const td_api::messageInviteVoiceChatParticipants *invite_voice_chat_participants_;
|
const td_api::messageInviteVideoChatParticipants *invite_video_chat_participants_;
|
||||||
const Client *client_;
|
const Client *client_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1862,6 +1871,14 @@ void Client::JsonMessage::store(JsonValueScope *scope) const {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case td_api::messageChatJoinByRequest::ID: {
|
||||||
|
if (message_->sender_user_id > 0) {
|
||||||
|
object("new_chat_participant", JsonUser(message_->sender_user_id, client_));
|
||||||
|
object("new_chat_member", JsonUser(message_->sender_user_id, client_));
|
||||||
|
object("new_chat_members", JsonUsers({message_->sender_user_id}, client_));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case td_api::messageChatDeleteMember::ID: {
|
case td_api::messageChatDeleteMember::ID: {
|
||||||
auto message_delete_member = static_cast<const td_api::messageChatDeleteMember *>(message_->content.get());
|
auto message_delete_member = static_cast<const td_api::messageChatDeleteMember *>(message_->content.get());
|
||||||
int64 user_id = message_delete_member->user_id_;
|
int64 user_id = message_delete_member->user_id_;
|
||||||
@ -1959,6 +1976,9 @@ void Client::JsonMessage::store(JsonValueScope *scope) const {
|
|||||||
break;
|
break;
|
||||||
case td_api::messageChatSetTheme::ID:
|
case td_api::messageChatSetTheme::ID:
|
||||||
break;
|
break;
|
||||||
|
case td_api::messageAnimatedEmoji::ID:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
case td_api::messageWebsiteConnected::ID: {
|
case td_api::messageWebsiteConnected::ID: {
|
||||||
auto chat = client_->get_chat(message_->chat_id);
|
auto chat = client_->get_chat(message_->chat_id);
|
||||||
if (chat->type != ChatInfo::Type::Private) {
|
if (chat->type != ChatInfo::Type::Private) {
|
||||||
@ -1984,22 +2004,22 @@ void Client::JsonMessage::store(JsonValueScope *scope) const {
|
|||||||
object("proximity_alert_triggered", JsonProximityAlertTriggered(content, client_));
|
object("proximity_alert_triggered", JsonProximityAlertTriggered(content, client_));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case td_api::messageVoiceChatScheduled::ID: {
|
case td_api::messageVideoChatScheduled::ID: {
|
||||||
auto content = static_cast<const td_api::messageVoiceChatScheduled *>(message_->content.get());
|
auto content = static_cast<const td_api::messageVideoChatScheduled *>(message_->content.get());
|
||||||
object("voice_chat_scheduled", JsonVoiceChatScheduled(content));
|
object("voice_chat_scheduled", JsonVideoChatScheduled(content));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case td_api::messageVoiceChatStarted::ID:
|
case td_api::messageVideoChatStarted::ID:
|
||||||
object("voice_chat_started", JsonVoiceChatStarted());
|
object("voice_chat_started", JsonVideoChatStarted());
|
||||||
break;
|
break;
|
||||||
case td_api::messageVoiceChatEnded::ID: {
|
case td_api::messageVideoChatEnded::ID: {
|
||||||
auto content = static_cast<const td_api::messageVoiceChatEnded *>(message_->content.get());
|
auto content = static_cast<const td_api::messageVideoChatEnded *>(message_->content.get());
|
||||||
object("voice_chat_ended", JsonVoiceChatEnded(content));
|
object("voice_chat_ended", JsonVideoChatEnded(content));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case td_api::messageInviteVoiceChatParticipants::ID: {
|
case td_api::messageInviteVideoChatParticipants::ID: {
|
||||||
auto content = static_cast<const td_api::messageInviteVoiceChatParticipants *>(message_->content.get());
|
auto content = static_cast<const td_api::messageInviteVideoChatParticipants *>(message_->content.get());
|
||||||
object("voice_chat_participants_invited", JsonInviteVoiceChatParticipants(content, client_));
|
object("voice_chat_participants_invited", JsonInviteVideoChatParticipants(content, client_));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -2370,7 +2390,7 @@ class Client::JsonChatMember : public Jsonable {
|
|||||||
object("can_pin_messages", td::JsonBool(administrator->can_pin_messages_));
|
object("can_pin_messages", td::JsonBool(administrator->can_pin_messages_));
|
||||||
}
|
}
|
||||||
object("can_promote_members", td::JsonBool(administrator->can_promote_members_));
|
object("can_promote_members", td::JsonBool(administrator->can_promote_members_));
|
||||||
object("can_manage_voice_chats", td::JsonBool(administrator->can_manage_voice_chats_));
|
object("can_manage_voice_chats", td::JsonBool(administrator->can_manage_video_chats_));
|
||||||
if (!administrator->custom_title_.empty()) {
|
if (!administrator->custom_title_.empty()) {
|
||||||
object("custom_title", administrator->custom_title_);
|
object("custom_title", administrator->custom_title_);
|
||||||
}
|
}
|
||||||
@ -2474,6 +2494,29 @@ class Client::JsonChatMemberUpdated : public Jsonable {
|
|||||||
const Client *client_;
|
const Client *client_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Client::JsonChatJoinRequest : public Jsonable {
|
||||||
|
public:
|
||||||
|
JsonChatJoinRequest(const td_api::updateNewChatJoinRequest *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("from", JsonUser(update_->request_->user_id_, client_));
|
||||||
|
object("date", update_->request_->date_);
|
||||||
|
if (!update_->request_->bio_.empty()) {
|
||||||
|
object("bio", update_->request_->bio_);
|
||||||
|
}
|
||||||
|
if (update_->invite_link_ != nullptr) {
|
||||||
|
object("invite_link", JsonChatInviteLink(update_->invite_link_.get(), client_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const td_api::updateNewChatJoinRequest *update_;
|
||||||
|
const Client *client_;
|
||||||
|
};
|
||||||
|
|
||||||
class Client::JsonGameHighScore : public Jsonable {
|
class Client::JsonGameHighScore : public Jsonable {
|
||||||
public:
|
public:
|
||||||
JsonGameHighScore(const td_api::gameHighScore *score, const Client *client) : score_(score), client_(client) {
|
JsonGameHighScore(const td_api::gameHighScore *score, const Client *client) : score_(score), client_(client) {
|
||||||
@ -4116,7 +4159,7 @@ void Client::raw_event(const td::Event::Raw &event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Client::loop() {
|
void Client::loop() {
|
||||||
if (logging_out_ || closing_ || was_authorized_ || waiting_for_auth_input_) {
|
if (was_authorized_ || logging_out_ || closing_ || waiting_for_auth_input_) {
|
||||||
while (!cmd_queue_.empty()) {
|
while (!cmd_queue_.empty()) {
|
||||||
auto query = std::move(cmd_queue_.front());
|
auto query = std::move(cmd_queue_.front());
|
||||||
cmd_queue_.pop();
|
cmd_queue_.pop();
|
||||||
@ -4741,6 +4784,7 @@ void Client::on_update_authorization_state() {
|
|||||||
if (!was_authorized_) {
|
if (!was_authorized_) {
|
||||||
LOG(WARNING) << "Logged in as @" << user_info->username;
|
LOG(WARNING) << "Logged in as @" << user_info->username;
|
||||||
was_authorized_ = true;
|
was_authorized_ = true;
|
||||||
|
td::send_event(parent_, td::Event::raw(static_cast<void *>(this)));
|
||||||
update_shared_unix_time_difference();
|
update_shared_unix_time_difference();
|
||||||
if (!pending_updates_.empty()) {
|
if (!pending_updates_.empty()) {
|
||||||
LOG(INFO) << "Process " << pending_updates_.size() << " pending updates";
|
LOG(INFO) << "Process " << pending_updates_.size() << " pending updates";
|
||||||
@ -4757,15 +4801,21 @@ void Client::on_update_authorization_state() {
|
|||||||
if (!logging_out_) {
|
if (!logging_out_) {
|
||||||
LOG(WARNING) << "Logging out";
|
LOG(WARNING) << "Logging out";
|
||||||
logging_out_ = true;
|
logging_out_ = true;
|
||||||
|
if (was_authorized_ && !closing_) {
|
||||||
|
td::send_event(parent_, td::Event::raw(nullptr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
return loop();
|
||||||
case td_api::authorizationStateClosing::ID:
|
case td_api::authorizationStateClosing::ID:
|
||||||
waiting_for_auth_input_ = false;
|
waiting_for_auth_input_ = false;
|
||||||
if (!closing_) {
|
if (!closing_) {
|
||||||
LOG(WARNING) << "Closing";
|
LOG(WARNING) << "Closing";
|
||||||
closing_ = true;
|
closing_ = true;
|
||||||
|
if (was_authorized_ && !logging_out_) {
|
||||||
|
td::send_event(parent_, td::Event::raw(nullptr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
return loop();
|
||||||
case td_api::authorizationStateClosed::ID:
|
case td_api::authorizationStateClosed::ID:
|
||||||
return on_closed();
|
return on_closed();
|
||||||
default:
|
default:
|
||||||
@ -5064,6 +5114,9 @@ void Client::on_update(object_ptr<td_api::Object> result) {
|
|||||||
case td_api::updateChatMember::ID:
|
case td_api::updateChatMember::ID:
|
||||||
add_update_chat_member(move_object_as<td_api::updateChatMember>(result));
|
add_update_chat_member(move_object_as<td_api::updateChatMember>(result));
|
||||||
break;
|
break;
|
||||||
|
case td_api::updateNewChatJoinRequest::ID:
|
||||||
|
add_update_chat_join_request(move_object_as<td_api::updateNewChatJoinRequest>(result));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// we are not interested in this update
|
// we are not interested in this update
|
||||||
break;
|
break;
|
||||||
@ -5121,6 +5174,7 @@ void Client::on_closed() {
|
|||||||
}
|
}
|
||||||
on_message_send_failed(chat_id, message_id, 0, Status::Error(http_status_code, description));
|
on_message_send_failed(chat_id, message_id, 0, Status::Error(http_status_code, description));
|
||||||
}
|
}
|
||||||
|
CHECK(yet_unsent_message_count_.empty());
|
||||||
|
|
||||||
while (!pending_bot_resolve_queries_.empty()) {
|
while (!pending_bot_resolve_queries_.empty()) {
|
||||||
auto it = pending_bot_resolve_queries_.begin();
|
auto it = pending_bot_resolve_queries_.begin();
|
||||||
@ -5615,6 +5669,9 @@ td_api::object_ptr<td_api::ChatAction> Client::get_chat_action(const Query *quer
|
|||||||
if (action == "upload_document") {
|
if (action == "upload_document") {
|
||||||
return make_object<td_api::chatActionUploadingDocument>();
|
return make_object<td_api::chatActionUploadingDocument>();
|
||||||
}
|
}
|
||||||
|
if (action == "choose_sticker") {
|
||||||
|
return make_object<td_api::chatActionChoosingSticker>();
|
||||||
|
}
|
||||||
if (action == "pick_up_location" || action == "find_location") {
|
if (action == "pick_up_location" || action == "find_location") {
|
||||||
return make_object<td_api::chatActionChoosingLocation>();
|
return make_object<td_api::chatActionChoosingLocation>();
|
||||||
}
|
}
|
||||||
@ -6869,6 +6926,13 @@ td::int64 Client::extract_yet_unsent_message_query_id(int64 chat_id, int64 messa
|
|||||||
|
|
||||||
yet_unsent_messages_.erase(yet_unsent_message_it);
|
yet_unsent_messages_.erase(yet_unsent_message_it);
|
||||||
|
|
||||||
|
auto count_it = yet_unsent_message_count_.find(chat_id);
|
||||||
|
CHECK(count_it != yet_unsent_message_count_.end());
|
||||||
|
CHECK(count_it->second > 0);
|
||||||
|
if (--count_it->second == 0) {
|
||||||
|
yet_unsent_message_count_.erase(count_it);
|
||||||
|
}
|
||||||
|
|
||||||
if (reply_to_message_id > 0) {
|
if (reply_to_message_id > 0) {
|
||||||
auto it = yet_unsent_reply_message_ids_.find({chat_id, reply_to_message_id});
|
auto it = yet_unsent_reply_message_ids_.find({chat_id, reply_to_message_id});
|
||||||
CHECK(it != yet_unsent_reply_message_ids_.end());
|
CHECK(it != yet_unsent_reply_message_ids_.end());
|
||||||
@ -7536,6 +7600,10 @@ td::Status Client::process_send_media_group_query(PromisedQueryPtr &query) {
|
|||||||
auto on_success = [this, disable_notification, input_message_contents = std::move(input_message_contents),
|
auto on_success = [this, disable_notification, input_message_contents = std::move(input_message_contents),
|
||||||
reply_markup = std::move(reply_markup), send_at = std::move(send_at)](
|
reply_markup = std::move(reply_markup), send_at = std::move(send_at)](
|
||||||
int64 chat_id, int64 reply_to_message_id, PromisedQueryPtr query) mutable {
|
int64 chat_id, int64 reply_to_message_id, PromisedQueryPtr query) mutable {
|
||||||
|
auto it = yet_unsent_message_count_.find(chat_id);
|
||||||
|
if (it != yet_unsent_message_count_.end() && it->second > MAX_CONCURRENTLY_SENT_CHAT_MESSAGES) {
|
||||||
|
return query->set_retry_after_error(60);
|
||||||
|
}
|
||||||
send_request(make_object<td_api::sendMessageAlbum>(chat_id, 0, reply_to_message_id,
|
send_request(make_object<td_api::sendMessageAlbum>(chat_id, 0, reply_to_message_id,
|
||||||
get_message_send_options(disable_notification, std::move(send_at)),
|
get_message_send_options(disable_notification, std::move(send_at)),
|
||||||
std::move(input_message_contents)),
|
std::move(input_message_contents)),
|
||||||
@ -7906,12 +7974,16 @@ td::Status Client::process_export_chat_invite_link_query(PromisedQueryPtr &query
|
|||||||
|
|
||||||
td::Status Client::process_create_chat_invite_link_query(PromisedQueryPtr &query) {
|
td::Status Client::process_create_chat_invite_link_query(PromisedQueryPtr &query) {
|
||||||
auto chat_id = query->arg("chat_id");
|
auto chat_id = query->arg("chat_id");
|
||||||
|
auto name = query->arg("name");
|
||||||
auto expire_date = get_integer_arg(query.get(), "expire_date", 0, 0);
|
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);
|
auto member_limit = get_integer_arg(query.get(), "member_limit", 0, 0, 100000);
|
||||||
|
auto creates_join_request = to_bool(query->arg("creates_join_request"));
|
||||||
|
|
||||||
check_chat(chat_id, AccessRights::Write, std::move(query),
|
check_chat(chat_id, AccessRights::Write, std::move(query),
|
||||||
[this, expire_date, member_limit](int64 chat_id, PromisedQueryPtr query) {
|
[this, name = name.str(), expire_date, member_limit, creates_join_request](int64 chat_id,
|
||||||
send_request(make_object<td_api::createChatInviteLink>(chat_id, expire_date, member_limit),
|
PromisedQueryPtr query) {
|
||||||
|
send_request(make_object<td_api::createChatInviteLink>(chat_id, name, expire_date, member_limit,
|
||||||
|
creates_join_request),
|
||||||
std::make_unique<TdOnGetChatInviteLinkCallback>(this, std::move(query)));
|
std::make_unique<TdOnGetChatInviteLinkCallback>(this, std::move(query)));
|
||||||
});
|
});
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
@ -7920,12 +7992,16 @@ td::Status Client::process_create_chat_invite_link_query(PromisedQueryPtr &query
|
|||||||
td::Status Client::process_edit_chat_invite_link_query(PromisedQueryPtr &query) {
|
td::Status Client::process_edit_chat_invite_link_query(PromisedQueryPtr &query) {
|
||||||
auto chat_id = query->arg("chat_id");
|
auto chat_id = query->arg("chat_id");
|
||||||
auto invite_link = query->arg("invite_link");
|
auto invite_link = query->arg("invite_link");
|
||||||
|
auto name = query->arg("name");
|
||||||
auto expire_date = get_integer_arg(query.get(), "expire_date", 0, 0);
|
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);
|
auto member_limit = get_integer_arg(query.get(), "member_limit", 0, 0, 100000);
|
||||||
|
auto creates_join_request = to_bool(query->arg("creates_join_request"));
|
||||||
|
|
||||||
check_chat(chat_id, AccessRights::Write, 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) {
|
[this, invite_link = invite_link.str(), name = name.str(), expire_date, member_limit,
|
||||||
send_request(make_object<td_api::editChatInviteLink>(chat_id, invite_link, expire_date, member_limit),
|
creates_join_request](int64 chat_id, PromisedQueryPtr query) {
|
||||||
|
send_request(make_object<td_api::editChatInviteLink>(chat_id, invite_link, name, expire_date,
|
||||||
|
member_limit, creates_join_request),
|
||||||
std::make_unique<TdOnGetChatInviteLinkCallback>(this, std::move(query)));
|
std::make_unique<TdOnGetChatInviteLinkCallback>(this, std::move(query)));
|
||||||
});
|
});
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
@ -8231,11 +8307,11 @@ td::Status Client::process_promote_chat_member_query(PromisedQueryPtr &query) {
|
|||||||
auto can_restrict_members = to_bool(query->arg("can_restrict_members"));
|
auto can_restrict_members = to_bool(query->arg("can_restrict_members"));
|
||||||
auto can_pin_messages = to_bool(query->arg("can_pin_messages"));
|
auto can_pin_messages = to_bool(query->arg("can_pin_messages"));
|
||||||
auto can_promote_members = to_bool(query->arg("can_promote_members"));
|
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 can_manage_video_chats = to_bool(query->arg("can_manage_voice_chats"));
|
||||||
auto is_anonymous = to_bool(query->arg("is_anonymous"));
|
auto is_anonymous = to_bool(query->arg("is_anonymous"));
|
||||||
auto status = make_object<td_api::chatMemberStatusAdministrator>(
|
auto status = make_object<td_api::chatMemberStatusAdministrator>(
|
||||||
td::string(), true, can_manage_chat, 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,
|
can_invite_users, can_restrict_members, can_pin_messages, can_promote_members, can_manage_video_chats,
|
||||||
is_anonymous);
|
is_anonymous);
|
||||||
check_chat(chat_id, AccessRights::Write, std::move(query),
|
check_chat(chat_id, AccessRights::Write, std::move(query),
|
||||||
[this, user_id, status = std::move(status)](int64 chat_id, PromisedQueryPtr query) mutable {
|
[this, user_id, status = std::move(status)](int64 chat_id, PromisedQueryPtr query) mutable {
|
||||||
@ -8394,6 +8470,32 @@ td::Status Client::process_unban_chat_member_query(PromisedQueryPtr &query) {
|
|||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
td::Status Client::process_approve_chat_join_request_query(PromisedQueryPtr &query) {
|
||||||
|
auto chat_id = query->arg("chat_id");
|
||||||
|
TRY_RESULT(user_id, get_user_id(query.get()));
|
||||||
|
|
||||||
|
check_chat(chat_id, AccessRights::Write, std::move(query), [this, user_id](int64 chat_id, PromisedQueryPtr query) {
|
||||||
|
check_user_no_fail(user_id, std::move(query), [this, chat_id, user_id](PromisedQueryPtr query) {
|
||||||
|
send_request(make_object<td_api::approveChatJoinRequest>(chat_id, user_id),
|
||||||
|
std::make_unique<TdOnOkQueryCallback>(std::move(query)));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return Status::OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
td::Status Client::process_decline_chat_join_request_query(PromisedQueryPtr &query) {
|
||||||
|
auto chat_id = query->arg("chat_id");
|
||||||
|
TRY_RESULT(user_id, get_user_id(query.get()));
|
||||||
|
|
||||||
|
check_chat(chat_id, AccessRights::Write, std::move(query), [this, user_id](int64 chat_id, PromisedQueryPtr query) {
|
||||||
|
check_user_no_fail(user_id, std::move(query), [this, chat_id, user_id](PromisedQueryPtr query) {
|
||||||
|
send_request(make_object<td_api::declineChatJoinRequest>(chat_id, user_id),
|
||||||
|
std::make_unique<TdOnOkQueryCallback>(std::move(query)));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return Status::OK();
|
||||||
|
}
|
||||||
|
|
||||||
td::Status Client::process_get_sticker_set_query(PromisedQueryPtr &query) {
|
td::Status Client::process_get_sticker_set_query(PromisedQueryPtr &query) {
|
||||||
auto name = query->arg("name");
|
auto name = query->arg("name");
|
||||||
if (td::trim(to_lower(name)) == to_lower(GREAT_MINDS_SET_NAME)) {
|
if (td::trim(to_lower(name)) == to_lower(GREAT_MINDS_SET_NAME)) {
|
||||||
@ -9335,6 +9437,10 @@ void Client::do_send_message(object_ptr<td_api::InputMessageContent> input_messa
|
|||||||
auto on_success = [this, disable_notification, input_message_content = std::move(input_message_content),
|
auto on_success = [this, disable_notification, input_message_content = std::move(input_message_content),
|
||||||
reply_markup = std::move(reply_markup), send_at = std::move(send_at)](
|
reply_markup = std::move(reply_markup), send_at = std::move(send_at)](
|
||||||
int64 chat_id, int64 reply_to_message_id, PromisedQueryPtr query) mutable {
|
int64 chat_id, int64 reply_to_message_id, PromisedQueryPtr query) mutable {
|
||||||
|
auto it = yet_unsent_message_count_.find(chat_id);
|
||||||
|
if (it != yet_unsent_message_count_.end() && it->second > MAX_CONCURRENTLY_SENT_CHAT_MESSAGES) {
|
||||||
|
return query->set_retry_after_error(60);
|
||||||
|
}
|
||||||
send_request(make_object<td_api::sendMessage>(chat_id, 0, reply_to_message_id,
|
send_request(make_object<td_api::sendMessage>(chat_id, 0, reply_to_message_id,
|
||||||
get_message_send_options(disable_notification, std::move(send_at)),
|
get_message_send_options(disable_notification, std::move(send_at)),
|
||||||
std::move(reply_markup), std::move(input_message_content)),
|
std::move(reply_markup), std::move(input_message_content)),
|
||||||
@ -9370,6 +9476,7 @@ void Client::on_sent_message(object_ptr<td_api::message> &&message, int64 query_
|
|||||||
yet_unsent_message.send_message_query_id = query_id;
|
yet_unsent_message.send_message_query_id = query_id;
|
||||||
auto emplace_result = yet_unsent_messages_.emplace(yet_unsent_message_id, yet_unsent_message);
|
auto emplace_result = yet_unsent_messages_.emplace(yet_unsent_message_id, yet_unsent_message);
|
||||||
CHECK(emplace_result.second);
|
CHECK(emplace_result.second);
|
||||||
|
yet_unsent_message_count_[chat_id]++;
|
||||||
pending_send_message_queries_[query_id].awaited_message_count++;
|
pending_send_message_queries_[query_id].awaited_message_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9848,6 +9955,8 @@ Client::Slice Client::get_update_type_name(UpdateType update_type) {
|
|||||||
return Slice("my_chat_member");
|
return Slice("my_chat_member");
|
||||||
case UpdateType::ChatMember:
|
case UpdateType::ChatMember:
|
||||||
return Slice("chat_member");
|
return Slice("chat_member");
|
||||||
|
case UpdateType::ChatJoinRequest:
|
||||||
|
return Slice("chat_join_request");
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return Slice();
|
return Slice();
|
||||||
@ -10136,6 +10245,16 @@ void Client::add_update_chat_member(object_ptr<td_api::updateChatMember> &&updat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::add_update_chat_join_request(object_ptr<td_api::updateNewChatJoinRequest> &&update) {
|
||||||
|
CHECK(update != nullptr);
|
||||||
|
CHECK(update->request_ != nullptr);
|
||||||
|
auto left_time = update->request_->date_ + 86400 - get_unix_time();
|
||||||
|
if (left_time > 0) {
|
||||||
|
auto webhook_queue_id = update->chat_id_ + (static_cast<int64>(6) << 33);
|
||||||
|
add_update(UpdateType::ChatJoinRequest, JsonChatJoinRequest(update.get(), this), left_time, webhook_queue_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
td::int64 Client::choose_added_member_id(const td_api::messageChatAddMembers *message_add_members) const {
|
td::int64 Client::choose_added_member_id(const td_api::messageChatAddMembers *message_add_members) const {
|
||||||
CHECK(message_add_members != nullptr);
|
CHECK(message_add_members != nullptr);
|
||||||
for (auto &member_user_id : message_add_members->member_user_ids_) {
|
for (auto &member_user_id : message_add_members->member_user_ids_) {
|
||||||
@ -10158,12 +10277,13 @@ bool Client::need_skip_update_message(int64 chat_id, const object_ptr<td_api::me
|
|||||||
case td_api::messageChatChangePhoto::ID:
|
case td_api::messageChatChangePhoto::ID:
|
||||||
case td_api::messageChatDeletePhoto::ID:
|
case td_api::messageChatDeletePhoto::ID:
|
||||||
case td_api::messageChatDeleteMember::ID:
|
case td_api::messageChatDeleteMember::ID:
|
||||||
|
case td_api::messageChatSetTheme::ID:
|
||||||
case td_api::messagePinMessage::ID:
|
case td_api::messagePinMessage::ID:
|
||||||
case td_api::messageProximityAlertTriggered::ID:
|
case td_api::messageProximityAlertTriggered::ID:
|
||||||
case td_api::messageVoiceChatScheduled::ID:
|
case td_api::messageVideoChatScheduled::ID:
|
||||||
case td_api::messageVoiceChatStarted::ID:
|
case td_api::messageVideoChatStarted::ID:
|
||||||
case td_api::messageVoiceChatEnded::ID:
|
case td_api::messageVideoChatEnded::ID:
|
||||||
case td_api::messageInviteVoiceChatParticipants::ID:
|
case td_api::messageInviteVideoChatParticipants::ID:
|
||||||
// don't skip
|
// don't skip
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -63,6 +63,8 @@ class Client : public WebhookActor::Callback {
|
|||||||
static constexpr int32 MAX_CERTIFICATE_FILE_SIZE = 3 << 20;
|
static constexpr int32 MAX_CERTIFICATE_FILE_SIZE = 3 << 20;
|
||||||
static constexpr int32 MAX_DOWNLOAD_FILE_SIZE = 20 << 20;
|
static constexpr int32 MAX_DOWNLOAD_FILE_SIZE = 20 << 20;
|
||||||
|
|
||||||
|
static constexpr int32 MAX_CONCURRENTLY_SENT_CHAT_MESSAGES = 1000; // some unreasonably big value
|
||||||
|
|
||||||
static constexpr int32 MESSAGES_CACHE_TIME = 3600;
|
static constexpr int32 MESSAGES_CACHE_TIME = 3600;
|
||||||
|
|
||||||
static constexpr std::size_t MIN_PENDING_UPDATES_WARNING = 200;
|
static constexpr std::size_t MIN_PENDING_UPDATES_WARNING = 200;
|
||||||
@ -143,6 +145,7 @@ class Client : public WebhookActor::Callback {
|
|||||||
class JsonChatMember;
|
class JsonChatMember;
|
||||||
class JsonChatMembers;
|
class JsonChatMembers;
|
||||||
class JsonChatMemberUpdated;
|
class JsonChatMemberUpdated;
|
||||||
|
class JsonChatJoinRequest;
|
||||||
class JsonGameHighScore;
|
class JsonGameHighScore;
|
||||||
class JsonAddress;
|
class JsonAddress;
|
||||||
class JsonOrderInfo;
|
class JsonOrderInfo;
|
||||||
@ -151,10 +154,10 @@ class Client : public WebhookActor::Callback {
|
|||||||
class JsonEncryptedCredentials;
|
class JsonEncryptedCredentials;
|
||||||
class JsonPassportData;
|
class JsonPassportData;
|
||||||
class JsonProximityAlertTriggered;
|
class JsonProximityAlertTriggered;
|
||||||
class JsonVoiceChatScheduled;
|
class JsonVideoChatScheduled;
|
||||||
class JsonVoiceChatStarted;
|
class JsonVideoChatStarted;
|
||||||
class JsonVoiceChatEnded;
|
class JsonVideoChatEnded;
|
||||||
class JsonInviteVoiceChatParticipants;
|
class JsonInviteVideoChatParticipants;
|
||||||
class JsonChatSetTtl;
|
class JsonChatSetTtl;
|
||||||
class JsonUpdateTypes;
|
class JsonUpdateTypes;
|
||||||
class JsonWebhookInfo;
|
class JsonWebhookInfo;
|
||||||
@ -557,6 +560,8 @@ class Client : public WebhookActor::Callback {
|
|||||||
Status process_ban_chat_member_query(PromisedQueryPtr &query);
|
Status process_ban_chat_member_query(PromisedQueryPtr &query);
|
||||||
Status process_restrict_chat_member_query(PromisedQueryPtr &query);
|
Status process_restrict_chat_member_query(PromisedQueryPtr &query);
|
||||||
Status process_unban_chat_member_query(PromisedQueryPtr &query);
|
Status process_unban_chat_member_query(PromisedQueryPtr &query);
|
||||||
|
Status process_approve_chat_join_request_query(PromisedQueryPtr &query);
|
||||||
|
Status process_decline_chat_join_request_query(PromisedQueryPtr &query);
|
||||||
Status process_get_sticker_set_query(PromisedQueryPtr &query);
|
Status process_get_sticker_set_query(PromisedQueryPtr &query);
|
||||||
Status process_upload_sticker_file_query(PromisedQueryPtr &query);
|
Status process_upload_sticker_file_query(PromisedQueryPtr &query);
|
||||||
Status process_create_new_sticker_set_query(PromisedQueryPtr &query);
|
Status process_create_new_sticker_set_query(PromisedQueryPtr &query);
|
||||||
@ -900,6 +905,8 @@ class Client : public WebhookActor::Callback {
|
|||||||
|
|
||||||
void add_update_chat_member(object_ptr<td_api::updateChatMember> &&update);
|
void add_update_chat_member(object_ptr<td_api::updateChatMember> &&update);
|
||||||
|
|
||||||
|
void add_update_chat_join_request(object_ptr<td_api::updateNewChatJoinRequest> &&update);
|
||||||
|
|
||||||
// append only before Size
|
// append only before Size
|
||||||
enum class UpdateType : int32 {
|
enum class UpdateType : int32 {
|
||||||
Message,
|
Message,
|
||||||
@ -917,6 +924,7 @@ class Client : public WebhookActor::Callback {
|
|||||||
PollAnswer,
|
PollAnswer,
|
||||||
MyChatMember,
|
MyChatMember,
|
||||||
ChatMember,
|
ChatMember,
|
||||||
|
ChatJoinRequest,
|
||||||
Size
|
Size
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -998,6 +1006,8 @@ class Client : public WebhookActor::Callback {
|
|||||||
};
|
};
|
||||||
std::unordered_map<FullMessageId, YetUnsentMessage, FullMessageIdHash> yet_unsent_messages_;
|
std::unordered_map<FullMessageId, YetUnsentMessage, FullMessageIdHash> yet_unsent_messages_;
|
||||||
|
|
||||||
|
std::unordered_map<int64, int32> yet_unsent_message_count_;
|
||||||
|
|
||||||
struct PendingSendMessageQuery {
|
struct PendingSendMessageQuery {
|
||||||
PromisedQueryPtr query;
|
PromisedQueryPtr query;
|
||||||
bool is_multisend = false;
|
bool is_multisend = false;
|
||||||
|
@ -93,12 +93,18 @@ void ClientManager::send(PromisedQueryPtr query) {
|
|||||||
if (!check_flood_limits(query)) {
|
if (!check_flood_limits(query)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto id = clients_.create(ClientInfo{BotStatActor(stat_.actor_id(&stat_)), token, td::ActorOwn<Client>()});
|
|
||||||
|
auto tqueue_id = get_tqueue_id(r_user_id.ok(), query->is_test_dc());
|
||||||
|
if (active_client_count_.find(tqueue_id) != active_client_count_.end()) {
|
||||||
|
// return query->set_retry_after_error(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto id =
|
||||||
|
clients_.create(ClientInfo{BotStatActor(stat_.actor_id(&stat_)), token, tqueue_id, td::ActorOwn<Client>()});
|
||||||
auto *client_info = clients_.get(id);
|
auto *client_info = clients_.get(id);
|
||||||
client_info->client_ =
|
client_info->client_ = td::create_actor<Client>(PSLICE() << "Client/" << token, actor_shared(this, id),
|
||||||
td::create_actor<Client>(PSLICE() << "Client/" << token, actor_shared(this, id), query->token().str(), query->is_user(),
|
query->token().str(), query->is_user(), query->is_test_dc(),
|
||||||
query->is_test_dc(), get_tqueue_id(r_user_id.ok(), query->is_test_dc()), parameters_,
|
tqueue_id, parameters_, client_info->stat_.actor_id(&client_info->stat_));
|
||||||
client_info->stat_.actor_id(&client_info->stat_));
|
|
||||||
|
|
||||||
auto method = query->method();
|
auto method = query->method();
|
||||||
if (method != "deletewebhook" && method != "setwebhook") {
|
if (method != "deletewebhook" && method != "setwebhook") {
|
||||||
@ -139,7 +145,12 @@ void ClientManager::user_login(PromisedQueryPtr query) {
|
|||||||
|
|
||||||
long token_hash = std::hash<td::string>{}(user_token);
|
long token_hash = std::hash<td::string>{}(user_token);
|
||||||
|
|
||||||
auto id = clients_.create(ClientInfo{BotStatActor(stat_.actor_id(&stat_)), user_token, td::ActorOwn<Client>()});
|
auto tqueue_id = get_tqueue_id(token_hash, query->is_test_dc());
|
||||||
|
if (active_client_count_.find(tqueue_id) != active_client_count_.end()) {
|
||||||
|
// return query->set_retry_after_error(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto id = clients_.create(ClientInfo{BotStatActor(stat_.actor_id(&stat_)), user_token, tqueue_id, td::ActorOwn<Client>()});
|
||||||
auto *client_info = clients_.get(id);
|
auto *client_info = clients_.get(id);
|
||||||
auto stat_actor = client_info->stat_.actor_id(&client_info->stat_);
|
auto stat_actor = client_info->stat_.actor_id(&client_info->stat_);
|
||||||
auto client_id = td::create_actor<Client>(PSLICE() << "Client/" << user_token, actor_shared(this, id), user_token,
|
auto client_id = td::create_actor<Client>(PSLICE() << "Client/" << user_token, actor_shared(this, id), user_token,
|
||||||
@ -270,23 +281,23 @@ void ClientManager::get_stats(td::PromiseActor<td::BufferSlice> promise,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!as_json) {
|
if(!as_json) {
|
||||||
sb << stat_.get_description() << "\n";
|
sb << stat_.get_description() << '\n';
|
||||||
}
|
}
|
||||||
if (id_filter.empty()) {
|
if (id_filter.empty()) {
|
||||||
if(as_json) {
|
if(as_json) {
|
||||||
jb_root("uptime", td::JsonFloat(now - parameters_->start_time_));
|
jb_root("uptime", td::JsonFloat(now - parameters_->start_time_));
|
||||||
} else {
|
} else {
|
||||||
sb << "uptime\t" << now - parameters_->start_time_ << "\n";
|
sb << "uptime\t" << now - parameters_->start_time_ << '\n';
|
||||||
}
|
}
|
||||||
if(as_json) {
|
if(as_json) {
|
||||||
jb_root("bot_count", td::JsonLong(clients_.size()));
|
jb_root("bot_count", td::JsonLong(clients_.size()));
|
||||||
} else {
|
} else {
|
||||||
sb << "bot_count\t" << clients_.size() << "\n";
|
sb << "bot_count\t" << clients_.size() << '\n';
|
||||||
}
|
}
|
||||||
if(as_json) {
|
if(as_json) {
|
||||||
jb_root("active_bot_count", td::JsonInt(active_bot_count));
|
jb_root("active_bot_count", td::JsonInt(active_bot_count));
|
||||||
} else {
|
} else {
|
||||||
sb << "active_bot_count\t" << active_bot_count << "\n";
|
sb << "active_bot_count\t" << active_bot_count << '\n';
|
||||||
}
|
}
|
||||||
auto r_mem_stat = td::mem_stat();
|
auto r_mem_stat = td::mem_stat();
|
||||||
if (r_mem_stat.is_ok()) {
|
if (r_mem_stat.is_ok()) {
|
||||||
@ -294,10 +305,10 @@ void ClientManager::get_stats(td::PromiseActor<td::BufferSlice> promise,
|
|||||||
if(as_json) {
|
if(as_json) {
|
||||||
jb_root("memory", JsonStatsMem(mem_stat));
|
jb_root("memory", JsonStatsMem(mem_stat));
|
||||||
} else {
|
} else {
|
||||||
sb << "rss\t" << td::format::as_size(mem_stat.resident_size_) << "\n";
|
sb << "rss\t" << td::format::as_size(mem_stat.resident_size_) << '\n';
|
||||||
sb << "vm\t" << td::format::as_size(mem_stat.virtual_size_) << "\n";
|
sb << "vm\t" << td::format::as_size(mem_stat.virtual_size_) << '\n';
|
||||||
sb << "rss_peak\t" << td::format::as_size(mem_stat.resident_size_peak_) << "\n";
|
sb << "rss_peak\t" << td::format::as_size(mem_stat.resident_size_peak_) << '\n';
|
||||||
sb << "vm_peak\t" << td::format::as_size(mem_stat.virtual_size_peak_) << "\n";
|
sb << "vm_peak\t" << td::format::as_size(mem_stat.virtual_size_peak_) << '\n';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(as_json) {
|
if(as_json) {
|
||||||
@ -314,7 +325,7 @@ void ClientManager::get_stats(td::PromiseActor<td::BufferSlice> promise,
|
|||||||
} else {
|
} else {
|
||||||
auto cpu_stats = ServerCpuStat::instance().as_vector(td::Time::now());
|
auto cpu_stats = ServerCpuStat::instance().as_vector(td::Time::now());
|
||||||
for (auto &stat : cpu_stats) {
|
for (auto &stat : cpu_stats) {
|
||||||
sb << stat.key_ << "\t" << stat.value_ << "\n";
|
sb << stat.key_ << "\t" << stat.value_ << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,16 +335,16 @@ void ClientManager::get_stats(td::PromiseActor<td::BufferSlice> promise,
|
|||||||
jb_root("active_requests", td::JsonLong(parameters_->shared_data_->query_count_.load()));
|
jb_root("active_requests", td::JsonLong(parameters_->shared_data_->query_count_.load()));
|
||||||
jb_root("active_network_queries", td::JsonLong(td::get_pending_network_query_count(*parameters_->net_query_stats_)));
|
jb_root("active_network_queries", td::JsonLong(td::get_pending_network_query_count(*parameters_->net_query_stats_)));
|
||||||
} else {
|
} else {
|
||||||
sb << "buffer_memory\t" << td::format::as_size(td::BufferAllocator::get_buffer_mem()) << "\n";
|
sb << "buffer_memory\t" << td::format::as_size(td::BufferAllocator::get_buffer_mem()) << '\n';
|
||||||
sb << "active_webhook_connections\t" << WebhookActor::get_total_connections_count() << "\n";
|
sb << "active_webhook_connections\t" << WebhookActor::get_total_connections_count() << '\n';
|
||||||
sb << "active_requests\t" << parameters_->shared_data_->query_count_.load() << "\n";
|
sb << "active_requests\t" << parameters_->shared_data_->query_count_.load() << '\n';
|
||||||
sb << "active_network_queries\t" << td::get_pending_network_query_count(*parameters_->net_query_stats_) << "\n";
|
sb << "active_network_queries\t" << td::get_pending_network_query_count(*parameters_->net_query_stats_) << '\n';
|
||||||
}
|
}
|
||||||
if(as_json) {
|
if(as_json) {
|
||||||
} else {
|
} else {
|
||||||
auto stats = stat_.as_vector(now);
|
auto stats = stat_.as_vector(now);
|
||||||
for (auto &stat : stats) {
|
for (auto &stat : stats) {
|
||||||
sb << stat.key_ << "\t" << stat.value_ << "\n";
|
sb << stat.key_ << "\t" << stat.value_ << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -358,30 +369,30 @@ void ClientManager::get_stats(td::PromiseActor<td::BufferSlice> promise,
|
|||||||
CHECK(client_info);
|
CHECK(client_info);
|
||||||
auto bot_info = client_info->client_->get_actor_unsafe()->get_bot_info();
|
auto bot_info = client_info->client_->get_actor_unsafe()->get_bot_info();
|
||||||
|
|
||||||
sb << "\n";
|
sb << '\n';
|
||||||
sb << "id\t" << bot_info.id_ << "\n";
|
sb << "id\t" << bot_info.id_ << '\n';
|
||||||
sb << "uptime\t" << now - bot_info.start_time_ << "\n";
|
sb << "uptime\t" << now - bot_info.start_time_ << '\n';
|
||||||
if (!parameters_->stats_hide_sensible_data_) {
|
if (!parameters_->stats_hide_sensible_data_) {
|
||||||
sb << "token\t" << bot_info.token_ << "\n";
|
sb << "token\t" << bot_info.token_ << '\n';
|
||||||
}
|
}
|
||||||
sb << "username\t" << bot_info.username_ << "\n";
|
sb << "username\t" << bot_info.username_ << '\n';
|
||||||
if (!parameters_->stats_hide_sensible_data_) {
|
if (!parameters_->stats_hide_sensible_data_) {
|
||||||
sb << "webhook\t" << bot_info.webhook_ << "\n";
|
sb << "webhook\t" << bot_info.webhook_ << '\n';
|
||||||
} else if (bot_info.webhook_.empty()) {
|
} else if (bot_info.webhook_.empty()) {
|
||||||
sb << "webhook disabled" << "\n";
|
sb << "webhook disabled" << '\n';
|
||||||
} else {
|
} else {
|
||||||
sb << "webhook enabled" << "\n";
|
sb << "webhook enabled" << '\n';
|
||||||
}
|
}
|
||||||
sb << "has_custom_certificate\t" << bot_info.has_webhook_certificate_ << "\n";
|
sb << "has_custom_certificate\t" << bot_info.has_webhook_certificate_ << '\n';
|
||||||
sb << "head_update_id\t" << bot_info.head_update_id_ << "\n";
|
sb << "head_update_id\t" << bot_info.head_update_id_ << '\n';
|
||||||
sb << "tail_update_id\t" << bot_info.tail_update_id_ << "\n";
|
sb << "tail_update_id\t" << bot_info.tail_update_id_ << '\n';
|
||||||
sb << "pending_update_count\t" << bot_info.pending_update_count_ << "\n";
|
sb << "pending_update_count\t" << bot_info.pending_update_count_ << '\n';
|
||||||
sb << "webhook_max_connections\t" << bot_info.webhook_max_connections_ << "\n";
|
sb << "webhook_max_connections\t" << bot_info.webhook_max_connections_ << '\n';
|
||||||
|
|
||||||
auto stats = client_info->stat_.as_vector(now);
|
auto stats = client_info->stat_.as_vector(now);
|
||||||
for (auto &stat : stats) {
|
for (auto &stat : stats) {
|
||||||
if (stat.key_ == "update_count" || stat.key_ == "request_count") {
|
if (stat.key_ == "update_count" || stat.key_ == "request_count") {
|
||||||
sb << stat.key_ << "/sec\t" << stat.value_ << "\n";
|
sb << stat.key_ << "/sec\t" << stat.value_ << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sb.is_error()) {
|
if (sb.is_error()) {
|
||||||
@ -526,6 +537,21 @@ PromisedQueryPtr ClientManager::get_webhook_restore_query(td::Slice token, bool
|
|||||||
return PromisedQueryPtr(query.release(), PromiseDeleter(td::PromiseActor<td::unique_ptr<Query>>()));
|
return PromisedQueryPtr(query.release(), PromiseDeleter(td::PromiseActor<td::unique_ptr<Query>>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientManager::raw_event(const td::Event::Raw &event) {
|
||||||
|
auto id = get_link_token();
|
||||||
|
auto *info = clients_.get(id);
|
||||||
|
CHECK(info != nullptr);
|
||||||
|
auto &value = active_client_count_[info->tqueue_id_];
|
||||||
|
if (event.ptr != nullptr) {
|
||||||
|
value++;
|
||||||
|
} else {
|
||||||
|
CHECK(value > 0);
|
||||||
|
if (--value == 0) {
|
||||||
|
active_client_count_.erase(info->tqueue_id_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ClientManager::hangup_shared() {
|
void ClientManager::hangup_shared() {
|
||||||
auto id = get_link_token();
|
auto id = get_link_token();
|
||||||
auto *info = clients_.get(id);
|
auto *info = clients_.get(id);
|
||||||
@ -535,19 +561,23 @@ void ClientManager::hangup_shared() {
|
|||||||
clients_.erase(id);
|
clients_.erase(id);
|
||||||
|
|
||||||
if (close_flag_ && clients_.empty()) {
|
if (close_flag_ && clients_.empty()) {
|
||||||
|
CHECK(active_client_count_.empty());
|
||||||
close_db();
|
close_db();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientManager::close_db() {
|
void ClientManager::close_db() {
|
||||||
LOG(WARNING) << "Closing databases";
|
LOG(WARNING) << "Closing databases";
|
||||||
td::MultiPromiseActorSafe mpromise("close binlogs");
|
td::MultiPromiseActorSafe mpas("close binlogs");
|
||||||
mpromise.add_promise(td::PromiseCreator::lambda(
|
mpas.add_promise(td::PromiseCreator::lambda(
|
||||||
[actor_id = actor_id(this)](td::Unit) { send_closure(actor_id, &ClientManager::finish_close); }));
|
[actor_id = actor_id(this)](td::Unit) { send_closure(actor_id, &ClientManager::finish_close); }));
|
||||||
|
mpas.set_ignore_errors(true);
|
||||||
|
|
||||||
parameters_->shared_data_->tqueue_->close(mpromise.get_promise());
|
auto lock = mpas.get_promise();
|
||||||
parameters_->shared_data_->webhook_db_->close(mpromise.get_promise());
|
parameters_->shared_data_->tqueue_->close(mpas.get_promise());
|
||||||
parameters_->shared_data_->user_db_->close(mpromise.get_promise());
|
parameters_->shared_data_->webhook_db_->close(mpas.get_promise());
|
||||||
|
parameters_->shared_data_->user_db_->close(mpas.get_promise());
|
||||||
|
lock.set_value(td::Unit());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientManager::finish_close() {
|
void ClientManager::finish_close() {
|
||||||
|
@ -55,6 +55,7 @@ class ClientManager final : public td::Actor {
|
|||||||
public:
|
public:
|
||||||
BotStatActor stat_;
|
BotStatActor stat_;
|
||||||
td::string token_;
|
td::string token_;
|
||||||
|
td::int64 tqueue_id_;
|
||||||
td::ActorOwn<Client> client_;
|
td::ActorOwn<Client> client_;
|
||||||
};
|
};
|
||||||
td::Container<ClientInfo> clients_;
|
td::Container<ClientInfo> clients_;
|
||||||
@ -65,6 +66,7 @@ class ClientManager final : public td::Actor {
|
|||||||
|
|
||||||
std::unordered_map<td::string, td::uint64> token_to_id_;
|
std::unordered_map<td::string, td::uint64> token_to_id_;
|
||||||
std::unordered_map<td::string, td::FloodControlFast> flood_controls_;
|
std::unordered_map<td::string, td::FloodControlFast> flood_controls_;
|
||||||
|
std::unordered_map<td::int64, td::uint64> active_client_count_;
|
||||||
|
|
||||||
bool close_flag_ = false;
|
bool close_flag_ = false;
|
||||||
td::vector<td::Promise<td::Unit>> close_promises_;
|
td::vector<td::Promise<td::Unit>> close_promises_;
|
||||||
@ -75,6 +77,7 @@ class ClientManager final : public td::Actor {
|
|||||||
std::shared_ptr<SharedData> shared_data);
|
std::shared_ptr<SharedData> shared_data);
|
||||||
|
|
||||||
void start_up() override;
|
void start_up() override;
|
||||||
|
void raw_event(const td::Event::Raw &event) override;
|
||||||
void hangup_shared() override;
|
void hangup_shared() override;
|
||||||
void close_db();
|
void close_db();
|
||||||
void finish_close();
|
void finish_close();
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "td/net/HttpInboundConnection.h"
|
#include "td/net/HttpInboundConnection.h"
|
||||||
#include "td/net/TcpListener.h"
|
#include "td/net/TcpListener.h"
|
||||||
|
|
||||||
|
#include "td/utils/BufferedFd.h"
|
||||||
#include "td/utils/FloodControlFast.h"
|
#include "td/utils/FloodControlFast.h"
|
||||||
#include "td/utils/format.h"
|
#include "td/utils/format.h"
|
||||||
#include "td/utils/logging.h"
|
#include "td/utils/logging.h"
|
||||||
@ -64,8 +65,8 @@ class HttpServer : public td::TcpListener::Callback {
|
|||||||
if (scheduler_id > 0) {
|
if (scheduler_id > 0) {
|
||||||
scheduler_id--;
|
scheduler_id--;
|
||||||
}
|
}
|
||||||
td::create_actor<td::HttpInboundConnection>("HttpInboundConnection", std::move(fd), 0, 20, 500, creator_(),
|
td::create_actor<td::HttpInboundConnection>("HttpInboundConnection", td::BufferedFd<td::SocketFd>(std::move(fd)), 0,
|
||||||
scheduler_id)
|
20, 500, creator_(), scheduler_id)
|
||||||
.release();
|
.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ td::Status WebhookActor::create_connection() {
|
|||||||
public:
|
public:
|
||||||
Callback(td::ActorId<WebhookActor> actor, td::int64 id) : actor_(actor), id_(id) {
|
Callback(td::ActorId<WebhookActor> actor, td::int64 id) : actor_(actor), id_(id) {
|
||||||
}
|
}
|
||||||
void set_result(td::Result<td::SocketFd> result) override {
|
void set_result(td::Result<td::BufferedFd<td::SocketFd>> result) override {
|
||||||
send_closure(std::move(actor_), &WebhookActor::on_socket_ready_async, std::move(result), id_);
|
send_closure(std::move(actor_), &WebhookActor::on_socket_ready_async, std::move(result), id_);
|
||||||
CHECK(actor_.empty());
|
CHECK(actor_.empty());
|
||||||
}
|
}
|
||||||
@ -195,7 +195,7 @@ td::Status WebhookActor::create_connection() {
|
|||||||
on_error(r_fd.move_as_error());
|
on_error(r_fd.move_as_error());
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
return create_connection(r_fd.move_as_ok());
|
return create_connection(td::BufferedFd<td::SocketFd>(r_fd.move_as_ok()));
|
||||||
}
|
}
|
||||||
|
|
||||||
td::Result<td::SslStream> WebhookActor::create_ssl_stream() {
|
td::Result<td::SslStream> WebhookActor::create_ssl_stream() {
|
||||||
@ -215,7 +215,7 @@ td::Result<td::SslStream> WebhookActor::create_ssl_stream() {
|
|||||||
return r_ssl_stream.move_as_ok();
|
return r_ssl_stream.move_as_ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
td::Status WebhookActor::create_connection(td::SocketFd fd) {
|
td::Status WebhookActor::create_connection(td::BufferedFd<td::SocketFd> fd) {
|
||||||
TRY_RESULT(ssl_stream, create_ssl_stream());
|
TRY_RESULT(ssl_stream, create_ssl_stream());
|
||||||
|
|
||||||
auto id = connections_.create(Connection());
|
auto id = connections_.create(Connection());
|
||||||
@ -237,7 +237,7 @@ td::Status WebhookActor::create_connection(td::SocketFd fd) {
|
|||||||
return td::Status::OK();
|
return td::Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebhookActor::on_socket_ready_async(td::Result<td::SocketFd> r_fd, td::int64 id) {
|
void WebhookActor::on_socket_ready_async(td::Result<td::BufferedFd<td::SocketFd>> r_fd, td::int64 id) {
|
||||||
pending_sockets_.erase(id);
|
pending_sockets_.erase(id);
|
||||||
if (r_fd.is_ok()) {
|
if (r_fd.is_ok()) {
|
||||||
VLOG(webhook) << "Socket " << id << " is ready";
|
VLOG(webhook) << "Socket " << id << " is ready";
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "td/actor/actor.h"
|
#include "td/actor/actor.h"
|
||||||
#include "td/actor/PromiseFuture.h"
|
#include "td/actor/PromiseFuture.h"
|
||||||
|
|
||||||
|
#include "td/utils/BufferedFd.h"
|
||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
#include "td/utils/Container.h"
|
#include "td/utils/Container.h"
|
||||||
#include "td/utils/FloodControlFast.h"
|
#include "td/utils/FloodControlFast.h"
|
||||||
@ -159,7 +160,7 @@ class WebhookActor : public td::HttpOutboundConnection::Callback {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
td::Container<td::ActorOwn<>> pending_sockets_;
|
td::Container<td::ActorOwn<>> pending_sockets_;
|
||||||
td::vector<td::SocketFd> ready_sockets_;
|
td::vector<td::BufferedFd<td::SocketFd>> ready_sockets_;
|
||||||
|
|
||||||
td::int32 max_connections_ = 0;
|
td::int32 max_connections_ = 0;
|
||||||
td::Container<Connection> connections_;
|
td::Container<Connection> connections_;
|
||||||
@ -176,8 +177,8 @@ class WebhookActor : public td::HttpOutboundConnection::Callback {
|
|||||||
|
|
||||||
td::Result<td::SslStream> create_ssl_stream();
|
td::Result<td::SslStream> create_ssl_stream();
|
||||||
td::Status create_connection() TD_WARN_UNUSED_RESULT;
|
td::Status create_connection() TD_WARN_UNUSED_RESULT;
|
||||||
td::Status create_connection(td::SocketFd fd) TD_WARN_UNUSED_RESULT;
|
td::Status create_connection(td::BufferedFd<td::SocketFd> fd) TD_WARN_UNUSED_RESULT;
|
||||||
void on_socket_ready_async(td::Result<td::SocketFd> r_fd, td::int64 id);
|
void on_socket_ready_async(td::Result<td::BufferedFd<td::SocketFd>> r_fd, td::int64 id);
|
||||||
|
|
||||||
void create_new_connections();
|
void create_new_connections();
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ int main(int argc, char *argv[]) {
|
|||||||
auto start_time = td::Time::now();
|
auto start_time = td::Time::now();
|
||||||
auto shared_data = std::make_shared<SharedData>();
|
auto shared_data = std::make_shared<SharedData>();
|
||||||
auto parameters = std::make_unique<ClientParameters>();
|
auto parameters = std::make_unique<ClientParameters>();
|
||||||
parameters->version_ = "5.3.3";
|
parameters->version_ = "5.4";
|
||||||
parameters->shared_data_ = shared_data;
|
parameters->shared_data_ = shared_data;
|
||||||
parameters->start_time_ = start_time;
|
parameters->start_time_ = start_time;
|
||||||
auto net_query_stats = td::create_net_query_stats();
|
auto net_query_stats = td::create_net_query_stats();
|
||||||
|
Loading…
Reference in New Issue
Block a user