diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index c6f86ba36..648287590 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -4290,6 +4290,10 @@ sendCallRating call_id:int32 rating:int32 comment:string problems:vectorcreate_handler(std::move(promise))->send(channel_id, slow_mode_delay); } +void ContactsManager::create_channel_group_call(DialogId dialog_id, Promise &&promise) { + if (!dialog_id.is_valid()) { + return promise.set_error(Status::Error(400, "Invalid chat identifier specified")); + } + if (!td_->messages_manager_->have_dialog_force(dialog_id)) { + return promise.set_error(Status::Error(400, "Chat not found")); + } + + if (dialog_id.get_type() != DialogType::Channel) { + return promise.set_error(Status::Error(400, "Chat is not a supergroup")); + } + + auto channel_id = dialog_id.get_channel_id(); + const Channel *c = get_channel(channel_id); + if (c == nullptr) { + return promise.set_error(Status::Error(400, "Chat info not found")); + } + if (!c->is_megagroup) { + return promise.set_error(Status::Error(400, "Chat is not a supergroup")); + } + if (!get_channel_permissions(c).can_manage_calls()) { + return promise.set_error(Status::Error(400, "Not enough rights in the supergroup")); + } + + auto new_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), channel_id, promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + send_closure(actor_id, &ContactsManager::on_create_channel_group_call, channel_id, result.move_as_ok(), + std::move(promise)); + } + }); + send_closure(G()->group_call_manager(), &GroupCallManager::create_group_call, channel_id, std::move(new_promise)); +} + +void ContactsManager::on_create_channel_group_call(ChannelId channel_id, InputGroupCallId group_call_id, + Promise &&promise) { + if (G()->close_flag()) { + return promise.set_error(Status::Error(500, "Request aborted")); + } + if (!group_call_id.is_valid()) { + return promise.set_error(Status::Error(500, "Receive invalid group call identifier")); + } + + Channel *c = get_channel(channel_id); + CHECK(c != nullptr); + if (!c->has_active_group_call) { + c->has_active_group_call = true; + c->is_changed = true; + update_channel(c, channel_id); + } + + auto channel_full = get_channel_full_force(channel_id, "on_create_channel_group_call"); + if (channel_full != nullptr && channel_full->active_group_call_id != group_call_id) { + channel_full->active_group_call_id = group_call_id; + channel_full->is_changed = true; + update_channel_full(channel_full, channel_id); + } + promise.set_value(std::move(group_call_id)); +} + void ContactsManager::get_channel_statistics_dc_id(DialogId dialog_id, bool for_full_statistics, Promise &&promise) { if (!dialog_id.is_valid()) { @@ -9553,6 +9616,10 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c InputGroupCallId group_call_id; if (channel_full->call_ != nullptr) { group_call_id = InputGroupCallId(channel_full->call_); + if (group_call_id.is_valid() && !c->is_megagroup) { + LOG(ERROR) << "Receive " << group_call_id << " in " << channel_id; + group_call_id = InputGroupCallId(); + } } channel->repair_request_version = 0; @@ -9595,7 +9662,7 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c bool has_active_group_call = group_call_id.is_valid(); if (c->has_active_group_call != has_active_group_call) { LOG(ERROR) << "Receive invalid has_active_group_call flag " << c->has_active_group_call << ", but have " - << group_call_id; + << group_call_id << " in " << channel_id; c->has_active_group_call = has_active_group_call; c->is_changed = true; update_channel(c, channel_id); diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 0c7415e6b..e1981f4f0 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -365,6 +365,8 @@ class ContactsManager : public Actor { void set_channel_slow_mode_delay(DialogId dialog_id, int32 slow_mode_delay, Promise &&promise); + void create_channel_group_call(DialogId dialog_id, Promise &&promise); + void report_channel_spam(ChannelId channel_id, UserId user_id, const vector &message_ids, Promise &&promise); @@ -1315,6 +1317,9 @@ class ContactsManager : public Actor { void update_bot_info(BotInfo *bot_info, UserId user_id, bool send_update, bool from_database); + void on_create_channel_group_call(ChannelId channel_id, InputGroupCallId group_call_id, + Promise &&promise); + bool is_chat_full_outdated(const ChatFull *chat_full, const Chat *c, ChatId chat_id); bool is_user_contact(const User *u, UserId user_id) const; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 502fa9dfc..d61fd3ca9 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6027,6 +6027,20 @@ void Td::on_request(uint64 id, td_api::sendCallDebugInformation &request) { std::move(request.debug_information_), std::move(promise)); } +void Td::on_request(uint64 id, const td_api::createChatGroupCall &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(td_api::make_object(result.ok().get_group_call_id())); + } + }); + + contacts_manager_->create_channel_group_call(DialogId(request.chat_id_), std::move(query_promise)); +} + void Td::on_request(uint64 id, const td_api::upgradeBasicGroupChatToSupergroupChat &request) { CHECK_IS_USER(); CREATE_REQUEST(UpgradeGroupChatToSupergroupChatRequest, request.chat_id_); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index e3df46310..b2dffcd9a 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -692,6 +692,8 @@ class Td final : public NetQueryCallback { void on_request(uint64 id, td_api::sendCallDebugInformation &request); + void on_request(uint64 id, const td_api::createChatGroupCall &request); + void on_request(uint64 id, const td_api::upgradeBasicGroupChatToSupergroupChat &request); void on_request(uint64 id, const td_api::getChatListsToAddChat &request); diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 8e54ba631..b516143a1 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -901,6 +901,30 @@ vector *> UpdatesManager::get_new_mes return messages; } +vector UpdatesManager::get_update_new_group_call_ids(const telegram_api::Updates *updates_ptr) { + vector group_call_ids; + auto updates = get_updates(updates_ptr); + if (updates != nullptr) { + for (auto &update : *updates) { + InputGroupCallId group_call_id; + if (update->get_id() == telegram_api::updateGroupCall::ID) { + auto group_call_ptr = static_cast(update.get())->call_.get(); + if (group_call_ptr->get_id() == telegram_api::groupCall::ID) { + auto group_call = static_cast(group_call_ptr); + group_call_id = InputGroupCallId(group_call->id_, group_call->access_hash_); + } + } + + if (group_call_id.is_valid()) { + group_call_ids.push_back(group_call_id); + } else { + LOG(ERROR) << "Receive unexpected " << to_string(update); + } + } + } + return group_call_ids; +} + vector UpdatesManager::get_update_notify_settings_dialog_ids(const telegram_api::Updates *updates_ptr) { vector dialog_ids; auto updates = get_updates(updates_ptr); diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index 9cc8ec416..1a58c698c 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -9,6 +9,7 @@ #include "td/telegram/ChannelId.h" #include "td/telegram/ChatId.h" #include "td/telegram/DialogId.h" +#include "td/telegram/InputGroupCallId.h" #include "td/telegram/PtsManager.h" #include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" @@ -44,6 +45,8 @@ class UpdatesManager : public Actor { static vector *> get_new_messages( const telegram_api::Updates *updates_ptr); + static vector get_update_new_group_call_ids(const telegram_api::Updates *updates_ptr); + static vector get_update_notify_settings_dialog_ids(const telegram_api::Updates *updates_ptr); static vector get_chat_dialog_ids(const telegram_api::Updates *updates_ptr); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index d7c032afc..56d7bb13b 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2834,6 +2834,8 @@ class CliClient final : public Actor { as_call_id(call_id), to_integer(rating), "Wow, such good call! (TDLib test)", std::move(problems))); } else if (op == "scdi" || op == "SendCallDebugInformation") { send_request(td_api::make_object(as_call_id(args), "{}")); + } else if (op == "ccgc") { + send_request(td_api::make_object(as_chat_id(args))); } else if (op == "gcil") { send_request(td_api::make_object(as_chat_id(args))); } else if (op == "ccil") {