diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 9060e777..44a3a086 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -466,6 +466,7 @@ supergroup id:int32 username:string date:int32 status:ChatMemberStatus member_co //@restricted_count Number of restricted users in the supergroup; 0 if unknown //@banned_count Number of users banned from chat; 0 if unknown //@linked_chat_id Chat identifier of a discussion group for the channel, or a channel, for which the supergroup is a discussion group; 0 if none or unknown +//@slow_mode_delay Delay between consecutive sent messages for non-administrator supergroup members, in seconds //@can_get_members True, if members of the chat can be retrieved //@can_set_username True, if the chat username can be changed //@can_set_sticker_set True, if the supergroup sticker set can be changed @@ -477,7 +478,7 @@ supergroup id:int32 username:string date:int32 status:ChatMemberStatus member_co //@invite_link Invite link for this chat //@upgraded_from_basic_group_id Identifier of the basic group from which supergroup was upgraded; 0 if none //@upgraded_from_max_message_id Identifier of the last message in the basic group from which supergroup was upgraded; 0 if none -supergroupFullInfo description:string member_count:int32 administrator_count:int32 restricted_count:int32 banned_count:int32 linked_chat_id:int53 can_get_members:Bool can_set_username:Bool can_set_sticker_set:Bool can_set_location:Bool can_view_statistics:Bool is_all_history_available:Bool sticker_set_id:int64 location:chatLocation invite_link:string upgraded_from_basic_group_id:int32 upgraded_from_max_message_id:int53 = SupergroupFullInfo; +supergroupFullInfo description:string member_count:int32 administrator_count:int32 restricted_count:int32 banned_count:int32 linked_chat_id:int53 slow_mode_delay:int32 can_get_members:Bool can_set_username:Bool can_set_sticker_set:Bool can_set_location:Bool can_view_statistics:Bool is_all_history_available:Bool sticker_set_id:int64 location:chatLocation invite_link:string upgraded_from_basic_group_id:int32 upgraded_from_max_message_id:int53 = SupergroupFullInfo; //@class SecretChatState @description Describes the current secret chat state diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index fda9c34b..687b597f 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 74a7f86a..a51c2417 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -1355,6 +1355,47 @@ class EditLocationQuery : public Td::ResultHandler { } void on_error(uint64 id, Status status) override { + td->contacts_manager_->on_get_channel_error(channel_id_, status, "EditLocationQuery"); + promise_.set_error(std::move(status)); + } +}; + +class ToggleSlowModeQuery : public Td::ResultHandler { + Promise promise_; + ChannelId channel_id_; + int32 slow_mode_delay_ = 0; + + public: + explicit ToggleSlowModeQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(ChannelId channel_id, int32 slow_mode_delay) { + channel_id_ = channel_id; + slow_mode_delay_ = slow_mode_delay; + + auto input_channel = td->contacts_manager_->get_input_channel(channel_id); + CHECK(input_channel != nullptr); + + send_query(G()->net_query_creator().create( + create_storer(telegram_api::channels_toggleSlowMode(std::move(input_channel), slow_mode_delay)))); + } + + void on_result(uint64 id, BufferSlice packet) override { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(id, result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for toggleSlowMode: " << to_string(ptr); + td->updates_manager_->on_get_updates(std::move(ptr)); + + td->contacts_manager_->on_update_channel_slow_mode_delay(channel_id_, slow_mode_delay_); + promise_.set_value(Unit()); + } + + void on_error(uint64 id, Status status) override { + td->contacts_manager_->on_get_channel_error(channel_id_, status, "ToggleSlowModeQuery"); promise_.set_error(std::move(status)); } }; @@ -3245,6 +3286,7 @@ void ContactsManager::ChannelFull::store(StorerT &storer) const { bool has_migrated_from_chat_id = migrated_from_chat_id.is_valid(); bool has_location = !location.empty(); bool has_bot_user_ids = !bot_user_ids.empty(); + bool is_slow_mode_enabled = slow_mode_delay != 0; BEGIN_STORE_FLAGS(); STORE_FLAG(has_description); STORE_FLAG(has_administrator_count); @@ -3263,6 +3305,7 @@ void ContactsManager::ChannelFull::store(StorerT &storer) const { STORE_FLAG(can_set_location); STORE_FLAG(has_location); STORE_FLAG(has_bot_user_ids); + STORE_FLAG(is_slow_mode_enabled); END_STORE_FLAGS(); if (has_description) { store(description, storer); @@ -3298,6 +3341,9 @@ void ContactsManager::ChannelFull::store(StorerT &storer) const { if (has_migrated_from_chat_id) { store(migrated_from_chat_id, storer); } + if (is_slow_mode_enabled) { + store(slow_mode_delay, storer); + } store_time(expires_at, storer); } @@ -3315,6 +3361,7 @@ void ContactsManager::ChannelFull::parse(ParserT &parser) { bool has_migrated_from_chat_id; bool has_location; bool has_bot_user_ids; + bool is_slow_mode_enabled; BEGIN_PARSE_FLAGS(); PARSE_FLAG(has_description); PARSE_FLAG(has_administrator_count); @@ -3333,6 +3380,7 @@ void ContactsManager::ChannelFull::parse(ParserT &parser) { PARSE_FLAG(can_set_location); PARSE_FLAG(has_location); PARSE_FLAG(has_bot_user_ids); + PARSE_FLAG(is_slow_mode_enabled); END_PARSE_FLAGS(); if (has_description) { parse(description, parser); @@ -3368,6 +3416,9 @@ void ContactsManager::ChannelFull::parse(ParserT &parser) { if (has_migrated_from_chat_id) { parse(migrated_from_chat_id, parser); } + if (is_slow_mode_enabled) { + parse(slow_mode_delay, parser); + } parse_time(expires_at, parser); } @@ -5114,6 +5165,38 @@ void ContactsManager::set_channel_location(DialogId dialog_id, const DialogLocat td_->create_handler(std::move(promise))->send(channel_id, location); } +void ContactsManager::set_channel_slow_mode_delay(DialogId dialog_id, int32 slow_mode_delay, Promise &&promise) { + std::vector allowed_slow_mode_delays{0, 10, 30, 60, 300, 900, 3600}; + if (!td::contains(allowed_slow_mode_delays, slow_mode_delay)) { + return promise.set_error(Status::Error(400, "Invalid new value for slow mode delay")); + } + + if (!dialog_id.is_valid()) { + return promise.set_error(Status::Error(400, "Invalid chat 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_restrict_members()) { + return promise.set_error(Status::Error(400, "Have not enough rights in the supergroup")); + } + + td_->create_handler(std::move(promise))->send(channel_id, slow_mode_delay); +} + void ContactsManager::report_channel_spam(ChannelId channel_id, UserId user_id, const vector &message_ids, Promise &&promise) { auto c = get_channel(channel_id); @@ -8378,6 +8461,8 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c on_update_channel_full_location(channel, channel_id, DialogLocation(std::move(channel_full->location_))); + on_update_channel_full_slow_mode_delay(channel, channel_id, channel_full->slowmode_seconds_); + ChatId migrated_from_chat_id; MessageId migrated_from_max_message_id; @@ -9596,6 +9681,23 @@ void ContactsManager::on_update_channel_full_location(ChannelFull *channel_full, } } +void ContactsManager::on_update_channel_full_slow_mode_delay(ChannelFull *channel_full, ChannelId channel_id, + int32 slow_mode_delay) { + if (channel_full->slow_mode_delay != slow_mode_delay) { + channel_full->slow_mode_delay = slow_mode_delay; + channel_full->is_changed = true; + } + + Channel *c = get_channel(channel_id); + CHECK(c != nullptr); + bool is_slow_mode_enabled = slow_mode_delay != 0; + if (is_slow_mode_enabled == c->is_slow_mode_enabled) { + c->is_slow_mode_enabled = is_slow_mode_enabled; + c->is_changed = true; + update_channel(c, channel_id); + } +} + void ContactsManager::on_get_dialog_invite_link_info(const string &invite_link, tl_object_ptr &&chat_invite_ptr) { auto &invite_link_info = invite_link_infos_[invite_link]; @@ -10378,6 +10480,14 @@ void ContactsManager::on_update_channel_location(ChannelId channel_id, const Dia } } +void ContactsManager::on_update_channel_slow_mode_delay(ChannelId channel_id, int32 slow_mode_delay) { + auto channel_full = get_channel_full_force(channel_id); + if (channel_full != nullptr) { + on_update_channel_full_slow_mode_delay(channel_full, channel_id, slow_mode_delay); + update_channel_full(channel_full, channel_id); + } +} + void ContactsManager::on_update_channel_bot_user_ids(ChannelId channel_id, vector &&bot_user_ids) { CHECK(channel_id.is_valid()); if (!have_channel(channel_id)) { @@ -12364,9 +12474,10 @@ tl_object_ptr ContactsManager::get_supergroup_full_i return td_api::make_object( channel_full->description, channel_full->participant_count, channel_full->administrator_count, channel_full->restricted_count, channel_full->banned_count, DialogId(channel_full->linked_channel_id).get(), - channel_full->can_get_participants, channel_full->can_set_username, channel_full->can_set_sticker_set, - channel_full->can_set_location, channel_full->can_view_statistics, channel_full->is_all_history_available, - channel_full->sticker_set_id.get(), channel_full->location.get_chat_location_object(), channel_full->invite_link, + channel_full->slow_mode_delay, channel_full->can_get_participants, channel_full->can_set_username, + channel_full->can_set_sticker_set, channel_full->can_set_location, channel_full->can_view_statistics, + channel_full->is_all_history_available, channel_full->sticker_set_id.get(), + channel_full->location.get_chat_location_object(), channel_full->invite_link, get_basic_group_id_object(channel_full->migrated_from_chat_id, "get_supergroup_full_info_object"), channel_full->migrated_from_max_message_id.get()); } diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 2ea2df82..15cef35b 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -185,6 +185,7 @@ class ContactsManager : public Actor { void on_update_channel_sticker_set(ChannelId channel_id, StickerSetId sticker_set_id); void on_update_channel_linked_channel_id(ChannelId channel_id, ChannelId group_channel_id); void on_update_channel_location(ChannelId channel_id, const DialogLocation &location); + void on_update_channel_slow_mode_delay(ChannelId channel_id, int32 slow_mode_delay); void on_update_channel_is_all_history_available(ChannelId channel_id, bool is_all_history_available); void on_update_channel_default_permissions(ChannelId channel_id, RestrictedRights default_permissions); void on_update_channel_administrator_count(ChannelId channel_id, int32 administrator_count); @@ -328,6 +329,8 @@ class ContactsManager : public Actor { void set_channel_location(DialogId dialog_id, const DialogLocation &location, Promise &&promise); + void set_channel_slow_mode_delay(DialogId dialog_id, int32 slow_mode_delay, Promise &&promise); + void report_channel_spam(ChannelId channel_id, UserId user_id, const vector &message_ids, Promise &&promise); @@ -746,6 +749,8 @@ class ContactsManager : public Actor { DialogLocation location; + int32 slow_mode_delay = 0; + MessageId migrated_from_max_message_id; ChatId migrated_from_chat_id; @@ -923,6 +928,7 @@ class ContactsManager : public Actor { static constexpr int32 CHANNEL_FULL_FLAG_HAS_LINKED_CHANNEL_ID = 1 << 14; static constexpr int32 CHANNEL_FULL_FLAG_HAS_LOCATION = 1 << 15; static constexpr int32 CHANNEL_FULL_FLAG_CAN_SET_LOCATION = 1 << 16; + static constexpr int32 CHANNEL_FULL_FLAG_HAS_SLOW_MODE_DELAY = 1 << 17; static constexpr int32 CHAT_INVITE_FLAG_IS_CHANNEL = 1 << 0; static constexpr int32 CHAT_INVITE_FLAG_IS_BROADCAST = 1 << 1; @@ -1069,6 +1075,7 @@ class ContactsManager : public Actor { void on_update_channel_full_linked_channel_id(ChannelFull *channel_full, ChannelId channel_id, ChannelId linked_channel_id); void on_update_channel_full_location(ChannelFull *channel_full, ChannelId channel_id, const DialogLocation &location); + void on_update_channel_full_slow_mode_delay(ChannelFull *channel_full, ChannelId channel_id, int32 slow_mode_delay); void on_update_channel_full_bot_user_ids(ChannelFull *channel_full, ChannelId channel_id, vector &&bot_user_ids);