diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e84df63..353e0c0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -305,14 +305,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Export `teloxide_macros::teloxide` in `prelude`. - `dispatching::dialogue::serializer::{JSON -> Json, CBOR -> Cbor}` - Allow `bot_name` be `N`, where `N: Into + ...` in `commands_repl` & `commands_repl_with_listener`. -- 'Edit methods' (namely `edit_message_live_location`, `stop_message_live_location`, `edit_message_text`, - `edit_message_caption`, `edit_message_media` and `edit_message_reply_markup`) are split into common and inline +- 'Edit methods' (namely `edit_message_live_location`, `stop_message_live_location`, `edit_message_text`, + `edit_message_caption`, `edit_message_media` and `edit_message_reply_markup`) are split into common and inline versions (e.g.: `edit_message_text` and `edit_inline_message_text`). Instead of `ChatOrInlineMessage` common versions - accept `chat_id: impl Into` and `message_id: i32` whereas inline versions accept + accept `chat_id: impl Into` and `message_id: i32` whereas inline versions accept `inline_message_id: impl Into`. Also note that return type of inline versions is `True` ([issue 253], [pr 257]) -- `ChatOrInlineMessage` is renamed to `TargetMessage`, it's `::Chat` variant is renamed to `::Common`, - `#[non_exhaustive]` annotation is removed from the enum, type of `TargetMessage::Inline::inline_message_id` changed - `i32` => `String`. `TargetMessage` now implements `From`, `get_game_high_scores` and `set_game_score` use +- `ChatOrInlineMessage` is renamed to `TargetMessage`, it's `::Chat` variant is renamed to `::Common`, + `#[non_exhaustive]` annotation is removed from the enum, type of `TargetMessage::Inline::inline_message_id` changed + `i32` => `String`. `TargetMessage` now implements `From`, `get_game_high_scores` and `set_game_score` use `Into` to accept `String`s. ([issue 253], [pr 257]) - Remove `ResponseResult` from `prelude`. diff --git a/crates/teloxide-core/CHANGELOG.md b/crates/teloxide-core/CHANGELOG.md index a0f27f5d..c9e9d582 100644 --- a/crates/teloxide-core/CHANGELOG.md +++ b/crates/teloxide-core/CHANGELOG.md @@ -7,9 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## unreleased +### Changed + +- The methods `ChatMember::{can_pin_messages, can_invite_users, can_change_info}` now take into account the permissions of `Restricted` chat member kind ([#764][pr764]) +- The method `ChatMemberKind::is_present` now takes into account the value of `Restricted::is_member` field ([#764][pr764]) + +### Added + +- `Restricted::{is_member, can_change_info, can_invite_users, can_pin_messages, can_send_polls}` fields ([#764][pr764]) +- `ChatMember::can_send_polls` method ([#764][pr764]) + +[pr764]: https://github.com/teloxide/teloxide/pull/764 + ## 0.8.0 - 2022-10-03 -### Added +### Added - Support for Telegram Bot API [version 6.2](https://core.telegram.org/bots/api#august-12-2022) ([#251][pr251]) @@ -37,7 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [pr244]: https://github.com/teloxide/teloxide-core/pull/246 -### Fixed +### Fixed - `SetWebhook` request can now properly send certificate ([#250][pr250]) - Serialization of `InputSticker::Webm` ([#252][pr252]) diff --git a/crates/teloxide-core/src/types/chat_member.rs b/crates/teloxide-core/src/types/chat_member.rs index 79c2e79f..d4af17ea 100644 --- a/crates/teloxide-core/src/types/chat_member.rs +++ b/crates/teloxide-core/src/types/chat_member.rs @@ -101,6 +101,9 @@ pub struct Restricted { /// Date when restrictions will be lifted for this user. pub until_date: UntilDate, + /// `true` if the user is a member of the chat at the moment of the request. + pub is_member: bool, + /// `true` if the user can send text messages, contacts, locations and /// venues. pub can_send_messages: bool, @@ -116,6 +119,19 @@ pub struct Restricted { /// `true` if the user is allowed to add web page previews to their /// messages. pub can_add_web_page_previews: bool, + + /// `true` if the user is allowed to change the chat title, photo + /// and other settings. + pub can_change_info: bool, + + /// `true` if the user is allowed to invite new users to the chat. + pub can_invite_users: bool, + + /// `true` if the user is allowed to pin messages. + pub can_pin_messages: bool, + + /// `true` if the user is allowed to send polls. + pub can_send_polls: bool, } /// User that was banned in the chat and can't return to it or view chat @@ -244,13 +260,18 @@ impl ChatMemberKind { } /// Returns `true` if the user is currently present in the chat. i.e. if the - /// user **hasn't** [left] or been [banned]. + /// user **hasn't** [left] or been [banned]. It also returns `false` if the + /// user left the chat, but was [restricted]. /// /// [left]: ChatMemberKind::Left /// [banned]: ChatMemberKind::Banned + /// [restricted]: ChatMemberKind::Restricted #[must_use] pub fn is_present(&self) -> bool { - !(self.is_left() || self.is_banned()) + let is_restricted_non_member = + matches!(self, Self::Restricted(Restricted { is_member: false, .. })); + + !(self.is_left() || self.is_banned() || is_restricted_non_member) } } @@ -334,17 +355,17 @@ impl ChatMemberKind { /// /// I.e. returns `true` if the user /// - is the owner of the chat - /// - is an administrator in the given chat and has the [`can_change_info`] - /// privilege. + /// - is an administrator in the given chat and has the + /// [`Administrator::can_change_info`] privilege. + /// - is restricted, but does have [`Restricted::can_change_info`] privilege /// Returns `false` otherwise. - /// - /// [`can_change_info`]: Administrator::can_change_info #[must_use] pub fn can_change_info(&self) -> bool { match self { Self::Owner(_) => true, - Self::Administrator(Administrator { can_change_info, .. }) => *can_change_info, - Self::Member | Self::Restricted(_) | Self::Left | Self::Banned(_) => false, + Self::Administrator(Administrator { can_change_info, .. }) + | Self::Restricted(Restricted { can_change_info, .. }) => *can_change_info, + Self::Member | Self::Left | Self::Banned(_) => false, } } @@ -437,17 +458,18 @@ impl ChatMemberKind { /// /// I.e. returns `true` if the user /// - is the owner of the chat - /// - is an administrator in the given chat and has the [`can_invite_users`] - /// privilege. + /// - is an administrator in the given chat and has the + /// [`Administrator::can_invite_users`] privilege. + /// - is restricted, but does have [`Restricted::can_invite_users`] + /// privilege /// Returns `false` otherwise. - /// - /// [`can_invite_users`]: Administrator::can_invite_users #[must_use] pub fn can_invite_users(&self) -> bool { match &self { Self::Owner(_) => true, - Self::Administrator(Administrator { can_invite_users, .. }) => *can_invite_users, - Self::Member | Self::Restricted(_) | Self::Left | Self::Banned(_) => false, + Self::Administrator(Administrator { can_invite_users, .. }) + | Self::Restricted(Restricted { can_invite_users, .. }) => *can_invite_users, + Self::Member | Self::Left | Self::Banned(_) => false, } } @@ -475,11 +497,11 @@ impl ChatMemberKind { /// /// I.e. returns `true` if the user /// - is the owner of the chat (even if the chat is not a supergroup) - /// - is an administrator in the given chat and has the [`can_pin_messages`] - /// privilege. + /// - is an administrator in the given chat and has the + /// [`Administrator::can_pin_messages`] privilege. + /// - is restricted, but does have [`Restricted::can_pin_messages`] + /// privilege /// Returns `false` otherwise. - /// - /// [`can_pin_messages`]: Administrator::can_pin_messages #[must_use] pub fn can_pin_messages(&self) -> bool { match self { @@ -487,7 +509,8 @@ impl ChatMemberKind { Self::Administrator(Administrator { can_pin_messages, .. }) => { can_pin_messages.unwrap_or_default() } - Self::Member | Self::Restricted(_) | Self::Left | Self::Banned(_) => false, + Self::Restricted(Restricted { can_pin_messages, .. }) => *can_pin_messages, + Self::Member | Self::Left | Self::Banned(_) => false, } } @@ -592,6 +615,23 @@ impl ChatMemberKind { Self::Left | Self::Banned(_) => false, } } + + /// Returns `true` if the user is allowed to send polls. + /// + /// I.e. returns **`false`** if the user + /// - has left or has been banned from the chat + /// - is restricted and doesn't have the [`can_send_polls`] right + /// Returns `true` otherwise. + /// + /// [`can_send_polls`]: Restricted::can_send_polls + #[must_use] + pub fn can_send_polls(&self) -> bool { + match &self { + Self::Restricted(Restricted { can_send_polls, .. }) => *can_send_polls, + Self::Owner(_) | Self::Administrator(_) | Self::Member => true, + Self::Left | Self::Banned(_) => false, + } + } } #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]