diff --git a/CHANGELOG.md b/CHANGELOG.md index ec039ebe..3b993d45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## unreleased +### Added + +- Add `filter_boost_added` and `filter_reply_to_story` filters to `MessageFilterExt` trait + ## 0.13.0 - 2024-08-16 ### Added diff --git a/README.md b/README.md index 77b613fa..95999e11 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ - + diff --git a/crates/teloxide-core/CHANGELOG.md b/crates/teloxide-core/CHANGELOG.md index 07218555..525b3455 100644 --- a/crates/teloxide-core/CHANGELOG.md +++ b/crates/teloxide-core/CHANGELOG.md @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## unreleased +### Added + +- Support for TBA 7.1 ([#1131](pr1131)) + - Updated docs for `can_post_stories`, `can_edit_stories` and `can_delete_stories` admin privileges + - Add `ChatBoostAdded` and `StoryId` structs + - Add `ChatBoostAdded` variant to `MessageKind` enum + - Add `sender_boost_count` and `reply_to_story` fields to `MessageCommon` struct + - Add `chat` and `id` fields to `Story` struct + - Add `unrestrict_boost_count` and `custom_emoji_sticker_set_name` fields to `PublicChatSupergroup` struct + - Add `boost_added` and `reply_to_story` getters to `Message` struct + - Add `unrestrict_boost_count` and `custom_emoji_sticker_set_name` getters to `Chat` struct + +[pr1131]: https://github.com/teloxide/teloxide/pull/1131 + ## 0.10.1 - 2024-08-17 ### Fixed diff --git a/crates/teloxide-core/README.md b/crates/teloxide-core/README.md index 31886935..d4bd5edc 100644 --- a/crates/teloxide-core/README.md +++ b/crates/teloxide-core/README.md @@ -12,7 +12,7 @@ - + diff --git a/crates/teloxide-core/schema.ron b/crates/teloxide-core/schema.ron index c7a9a3b4..4a0c41e8 100644 --- a/crates/teloxide-core/schema.ron +++ b/crates/teloxide-core/schema.ron @@ -39,7 +39,7 @@ //! [github]: https://github.com/WaffleLapkin/tg-methods-schema Schema( - api_version: ApiVersion(ver: "7.0", date: "December 29, 2023"), + api_version: ApiVersion(ver: "7.1", date: "February 16, 2024"), methods: [ Method( names: ("getUpdates", "GetUpdates", "get_updates"), @@ -2098,17 +2098,17 @@ Schema( Param( name: "can_post_stories", ty: Option(bool), - descr: Doc(md: "Pass True, if the administrator can post stories in the channel, channels only") + descr: Doc(md: "Pass True, if the administrator can post stories to the chat") ), Param( name: "can_edit_stories", ty: Option(bool), - descr: Doc(md: "Pass True, if the administrator can edit stories posted by other users, channels only") + descr: Doc(md: "Pass True, if the administrator can edit stories posted by other users") ), Param( name: "can_delete_stories", ty: Option(bool), - descr: Doc(md: "Pass True, if the administrator can delete stories posted by other users, channels only") + descr: Doc(md: "Pass True, if the administrator can delete stories posted by other users") ), Param( name: "can_manage_video_chats", diff --git a/crates/teloxide-core/src/lib.rs b/crates/teloxide-core/src/lib.rs index 483a4546..84e1a1a2 100644 --- a/crates/teloxide-core/src/lib.rs +++ b/crates/teloxide-core/src/lib.rs @@ -1,7 +1,7 @@ //! Core part of the [`teloxide`] library. //! //! This library provides tools for making requests to the [Telegram Bot API] -//! (Currently, version `7.0` is supported) with ease. The library is fully +//! (Currently, version `7.1` is supported) with ease. The library is fully //! asynchronous and built using [`tokio`]. //! //!```toml diff --git a/crates/teloxide-core/src/payloads/promote_chat_member.rs b/crates/teloxide-core/src/payloads/promote_chat_member.rs index 851abdd4..7512ee97 100644 --- a/crates/teloxide-core/src/payloads/promote_chat_member.rs +++ b/crates/teloxide-core/src/payloads/promote_chat_member.rs @@ -25,11 +25,11 @@ impl_payload! { pub can_edit_messages: bool, /// Pass True, if the administrator can delete messages of other users pub can_delete_messages: bool, - /// Pass True, if the administrator can post stories in the channel, channels only + /// Pass True, if the administrator can post stories to the chat pub can_post_stories: bool, - /// Pass True, if the administrator can edit stories posted by other users, channels only + /// Pass True, if the administrator can edit stories posted by other users pub can_edit_stories: bool, - /// Pass True, if the administrator can delete stories posted by other users, channels only + /// Pass True, if the administrator can delete stories posted by other users pub can_delete_stories: bool, /// Pass True, if the administrator can manage video chats, supergroups only pub can_manage_video_chats: bool, diff --git a/crates/teloxide-core/src/types.rs b/crates/teloxide-core/src/types.rs index 407394da..bbdd499c 100644 --- a/crates/teloxide-core/src/types.rs +++ b/crates/teloxide-core/src/types.rs @@ -14,6 +14,7 @@ pub use chat::*; pub use chat_action::*; pub use chat_administrator_rights::*; pub use chat_boost::*; +pub use chat_boost_added::*; pub use chat_boost_removed::*; pub use chat_boost_source::*; pub use chat_boost_updated::*; @@ -125,6 +126,7 @@ pub use shipping_query::*; pub use sticker::*; pub use sticker_set::*; pub use story::*; +pub use story_id::*; pub use successful_payment::*; pub use switch_inline_query_chosen_chat::*; pub use target_message::*; @@ -273,6 +275,7 @@ mod web_app_info; mod webhook_info; mod write_access_allowed; +mod chat_boost_added; mod inline_query; mod inline_query_result; mod inline_query_result_article; @@ -295,6 +298,7 @@ mod inline_query_result_photo; mod inline_query_result_venue; mod inline_query_result_video; mod inline_query_result_voice; +mod story_id; mod encrypted_credentials; mod encrypted_passport_element; diff --git a/crates/teloxide-core/src/types/chat.rs b/crates/teloxide-core/src/types/chat.rs index efa276d2..b4adaa5a 100644 --- a/crates/teloxide-core/src/types/chat.rs +++ b/crates/teloxide-core/src/types/chat.rs @@ -197,6 +197,13 @@ pub struct PublicChatSupergroup { /// [`GetChat`]: crate::payloads::GetChat pub can_set_sticker_set: Option, + /// For supergroups, the name of the group's custom emoji sticker set. + /// Custom emoji from this set can be used by all users and bots in the + /// group. Returned only from [`GetChat`]. + /// + /// [`GetChat`]: crate::payloads::GetChat + pub custom_emoji_sticker_set_name: Option, + /// A default chat member permissions, for groups and supergroups. /// Returned only from [`GetChat`]. /// @@ -209,6 +216,13 @@ pub struct PublicChatSupergroup { /// [`GetChat`]: crate::payloads::GetChat pub slow_mode_delay: Option, + /// For supergroups, the minimum number of boosts that a non-administrator + /// user needs to add in order to ignore slow mode and chat permissions. + /// Returned only from [`GetChat`]. + /// + /// [`GetChat`]: crate::payloads::GetChat + pub unrestrict_boost_count: Option, + /// Unique identifier for the linked chat, i.e. the discussion group /// identifier for a channel and vice versa. Returned only in [`GetChat`]. /// @@ -355,6 +369,22 @@ impl Chat { None } + /// For supergroups, the name of the group's custom emoji sticker set. + /// Custom emoji from this set can be used by all users and bots in the + /// group. Returned only from [`GetChat`]. + /// + /// [`GetChat`]: crate::payloads::GetChat + #[must_use] + pub fn custom_emoji_sticker_set_name(&self) -> Option<&str> { + if let ChatKind::Public(this) = &self.kind { + if let PublicChatKind::Supergroup(this) = &this.kind { + return this.custom_emoji_sticker_set_name.as_deref(); + } + } + + None + } + /// The minimum allowed delay between consecutive messages sent by each /// unpriviledged user. Returned only from [`GetChat`]. /// @@ -370,6 +400,21 @@ impl Chat { None } + /// Unique identifier for the linked chat, i.e. the discussion group + /// identifier for a channel and vice versa. Returned only in [`GetChat`]. + /// + /// [`GetChat`]: crate::payloads::GetChat + #[must_use] + pub fn unrestrict_boost_count(&self) -> Option { + if let ChatKind::Public(this) = &self.kind { + if let PublicChatKind::Supergroup(this) = &this.kind { + return this.unrestrict_boost_count; + } + } + + None + } + /// The location to which the supergroup is connected. Returned only in /// [`GetChat`]. /// diff --git a/crates/teloxide-core/src/types/chat_administrator_rights.rs b/crates/teloxide-core/src/types/chat_administrator_rights.rs index c3e9c62c..3a80c8c6 100644 --- a/crates/teloxide-core/src/types/chat_administrator_rights.rs +++ b/crates/teloxide-core/src/types/chat_administrator_rights.rs @@ -47,16 +47,13 @@ pub struct ChatAdministratorRights { /// supergroups only pub can_pin_messages: Option, - /// `true`, if the administrator can post stories in the channel; - /// channels only + /// `true`, if the administrator can post stories to the chat pub can_post_stories: Option, - /// `true`, if the administrator can edit stories posted by other users; - /// channels only + /// `true`, if the administrator can edit stories posted by other users pub can_edit_stories: Option, - /// `true`, if the administrator can delete stories posted by other users; - /// channels only + /// `true`, if the administrator can delete stories posted by other users pub can_delete_stories: Option, /// `true`, if the user is allowed to create, rename, close, and reopen diff --git a/crates/teloxide-core/src/types/chat_boost_added.rs b/crates/teloxide-core/src/types/chat_boost_added.rs new file mode 100644 index 00000000..1f37dccf --- /dev/null +++ b/crates/teloxide-core/src/types/chat_boost_added.rs @@ -0,0 +1,24 @@ +use serde::{Deserialize, Serialize}; + +/// This object represents a service message about a user boosting a chat. +#[serde_with::skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct ChatBoostAdded { + /// Number of boosts added by the user + pub boost_count: u16, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn deserialize() { + let data = r#" + { + "boost_count": 4 + } + "#; + serde_json::from_str::(data).unwrap(); + } +} diff --git a/crates/teloxide-core/src/types/chat_member.rs b/crates/teloxide-core/src/types/chat_member.rs index 5aec15ee..458474f7 100644 --- a/crates/teloxide-core/src/types/chat_member.rs +++ b/crates/teloxide-core/src/types/chat_member.rs @@ -80,18 +80,15 @@ pub struct Administrator { /// `true` if the administrator can delete messages of other users. pub can_delete_messages: bool, - /// `true` if the administrator can post stories in the channel, channels - /// only. + /// `true` if the administrator can post stories to the chat. #[serde(default)] pub can_post_stories: bool, - /// `true` if the administrator can edit stories posted by other users, - /// channels only. + /// `true` if the administrator can edit stories posted by other users. #[serde(default)] pub can_edit_stories: bool, - /// `true` if the administrator can delete stories posted by other users, - /// channels only. + /// `true` if the administrator can delete stories posted by other users. #[serde(default)] pub can_delete_stories: bool, @@ -447,8 +444,7 @@ impl ChatMemberKind { } } - /// Returns `true` if the user can post stories in the channel, channels - /// only. + /// Returns `true` if the administrator can post stories to the chat. /// /// I.e. returns `true` if the user /// - is the owner of the chat (even if the chat is not a channel) @@ -467,8 +463,8 @@ impl ChatMemberKind { } } - /// Returns `true` if the user can edit stories posted by other users, - /// channels only. + /// Returns `true` if the administrator can edit stories posted by other + /// users. /// /// I.e. returns `true` if the user /// - is the owner of the chat (even if the chat is not a channel) @@ -487,8 +483,8 @@ impl ChatMemberKind { } } - /// Returns `true` if the user can delete stories posted by other users, - /// channels only. + /// Returns `true` if the administrator can delete stories posted by other + /// users. /// /// I.e. returns `true` if the user /// - is the owner of the chat diff --git a/crates/teloxide-core/src/types/message.rs b/crates/teloxide-core/src/types/message.rs index 750700e8..9a749ea9 100644 --- a/crates/teloxide-core/src/types/message.rs +++ b/crates/teloxide-core/src/types/message.rs @@ -5,15 +5,15 @@ use serde::{Deserialize, Serialize}; use url::Url; use crate::types::{ - Animation, Audio, BareChatId, Chat, ChatId, ChatShared, Contact, Dice, Document, - ExternalReplyInfo, ForumTopicClosed, ForumTopicCreated, ForumTopicEdited, ForumTopicReopened, - Game, GeneralForumTopicHidden, GeneralForumTopicUnhidden, Giveaway, GiveawayCompleted, - GiveawayCreated, GiveawayWinners, InlineKeyboardMarkup, Invoice, LinkPreviewOptions, Location, - MaybeInaccessibleMessage, MessageAutoDeleteTimerChanged, MessageEntity, MessageEntityRef, - MessageId, MessageOrigin, PassportData, PhotoSize, Poll, ProximityAlertTriggered, Sticker, - Story, SuccessfulPayment, TextQuote, ThreadId, True, User, UsersShared, Venue, Video, - VideoChatEnded, VideoChatParticipantsInvited, VideoChatScheduled, VideoChatStarted, VideoNote, - Voice, WebAppData, WriteAccessAllowed, + Animation, Audio, BareChatId, Chat, ChatBoostAdded, ChatId, ChatShared, Contact, Dice, + Document, ExternalReplyInfo, ForumTopicClosed, ForumTopicCreated, ForumTopicEdited, + ForumTopicReopened, Game, GeneralForumTopicHidden, GeneralForumTopicUnhidden, Giveaway, + GiveawayCompleted, GiveawayCreated, GiveawayWinners, InlineKeyboardMarkup, Invoice, + LinkPreviewOptions, Location, MaybeInaccessibleMessage, MessageAutoDeleteTimerChanged, + MessageEntity, MessageEntityRef, MessageId, MessageOrigin, PassportData, PhotoSize, Poll, + ProximityAlertTriggered, Sticker, Story, SuccessfulPayment, TextQuote, ThreadId, True, User, + UsersShared, Venue, Video, VideoChatEnded, VideoChatParticipantsInvited, VideoChatScheduled, + VideoChatStarted, VideoNote, Voice, WebAppData, WriteAccessAllowed, }; /// This object represents a message. @@ -84,6 +84,7 @@ pub enum MessageKind { PassportData(MessagePassportData), Dice(MessageDice), ProximityAlertTriggered(MessageProximityAlertTriggered), + ChatBoostAdded(MessageChatBoostAdded), ForumTopicCreated(MessageForumTopicCreated), ForumTopicEdited(MessageForumTopicEdited), ForumTopicClosed(MessageForumTopicClosed), @@ -127,6 +128,13 @@ pub struct MessageCommon { /// the message pub quote: Option, + /// For replies to a story, the original story + pub reply_to_story: Option, + + /// If the sender of the message boosted the chat, the number of boosts + /// added by the user + pub sender_boost_count: Option, + /// Date the message was last edited in Unix time. #[serde(default, with = "crate::types::serde_opt_date_from_unix_timestamp")] pub edit_date: Option>, @@ -553,6 +561,13 @@ pub struct MessageProximityAlertTriggered { pub proximity_alert_triggered: ProximityAlertTriggered, } +#[serde_with::skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct MessageChatBoostAdded { + /// Service message. User boosted the chat. + pub boost_added: ChatBoostAdded, +} + #[serde_with::skip_serializing_none] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct MessageWriteAccessAllowed { @@ -692,12 +707,12 @@ mod getters { MessageInvoice, MessageLeftChatMember, MessageNewChatMembers, MessageNewChatPhoto, MessageNewChatTitle, MessageOrigin, MessagePassportData, MessagePinned, MessageProximityAlertTriggered, MessageSuccessfulPayment, MessageSupergroupChatCreated, - MessageUsersShared, MessageVideoChatParticipantsInvited, PhotoSize, TextQuote, User, + MessageUsersShared, MessageVideoChatParticipantsInvited, PhotoSize, Story, TextQuote, User, }; use super::{ - MessageForumTopicClosed, MessageForumTopicCreated, MessageForumTopicEdited, - MessageForumTopicReopened, MessageGeneralForumTopicHidden, + MessageChatBoostAdded, MessageForumTopicClosed, MessageForumTopicCreated, + MessageForumTopicEdited, MessageForumTopicReopened, MessageGeneralForumTopicHidden, MessageGeneralForumTopicUnhidden, MessageGiveaway, MessageGiveawayCompleted, MessageGiveawayCreated, MessageGiveawayWinners, MessageMessageAutoDeleteTimerChanged, MessageVideoChatEnded, MessageVideoChatScheduled, MessageVideoChatStarted, @@ -746,6 +761,14 @@ mod getters { } } + #[must_use] + pub fn reply_to_story(&self) -> Option<&Story> { + match &self.kind { + Common(MessageCommon { reply_to_story, .. }) => reply_to_story.as_ref(), + _ => None, + } + } + #[must_use] pub fn forward_date(&self) -> Option> { self.forward_origin().map(|f| f.date()) @@ -1367,6 +1390,14 @@ mod getters { } } + #[must_use] + pub fn boost_added(&self) -> Option<&types::ChatBoostAdded> { + match &self.kind { + ChatBoostAdded(MessageChatBoostAdded { boost_added }) => Some(boost_added), + _ => None, + } + } + #[must_use] pub fn forum_topic_created(&self) -> Option<&types::ForumTopicCreated> { match &self.kind { @@ -2083,8 +2114,10 @@ mod tests { username: None, sticker_set_name: None, can_set_sticker_set: None, + custom_emoji_sticker_set_name: None, permissions: None, slow_mode_delay: None, + unrestrict_boost_count: None, linked_chat_id: None, location: None, join_by_request: None, @@ -2675,4 +2708,30 @@ mod tests { } ) } + + #[test] + fn chat_boost_added() { + let json = r#"{ + "message_id": 28, + "sender_chat": { + "id": -1002236736395, + "title": "Test", + "type": "channel" + }, + "chat": { + "id": -1002236736395, + "title": "Test", + "type": "channel" + }, + "date": 1721162702, + "boost_added": { + "boost_count": 4 + } + }"#; + let message: Message = from_str(json).unwrap(); + assert_eq!( + message.boost_added().expect("Failed to get ChatBoostAdded from Message!"), + &ChatBoostAdded { boost_count: 4 } + ) + } } diff --git a/crates/teloxide-core/src/types/story.rs b/crates/teloxide-core/src/types/story.rs index a59e1568..41ac32c5 100644 --- a/crates/teloxide-core/src/types/story.rs +++ b/crates/teloxide-core/src/types/story.rs @@ -1,5 +1,81 @@ use serde::{Deserialize, Serialize}; -/// TBA 6.8: currently it holds no information +use crate::types::{Chat, ChatKind, StoryId}; + +/// This object represents a story. #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -pub struct Story {} +pub struct Story { + /// Unique identifier for the story in the chat. + pub id: StoryId, + + /// Chat that posted the story. + pub chat: Chat, +} + +impl Story { + /// Returns an URL that links to the story with it's id and chat username in + /// the form of `tg://resolve?domain=<…>&story=<…>`. + #[must_use] + pub fn url(&self) -> Option { + let username = match &self.chat.kind { + ChatKind::Public(c) => match &c.kind { + super::PublicChatKind::Channel(c) => c.username.as_ref(), + super::PublicChatKind::Group(_) => None, + super::PublicChatKind::Supergroup(g) => g.username.as_ref(), + }, + ChatKind::Private(c) => c.username.as_ref(), + }; + username.map(|username| { + reqwest::Url::parse(&format!("tg://resolve?domain={username}&story={}", self.id)) + .unwrap() + }) + } +} + +#[cfg(test)] +mod tests { + use crate::types::{ + Chat, ChatFullInfo, ChatId, ChatKind, ChatPublic, PublicChatKind, PublicChatSupergroup, + Story, StoryId, + }; + + #[test] + fn url_works() { + let story = Story { + chat: Chat { + id: ChatId(-1001389841361), + kind: ChatKind::Public(ChatPublic { + title: Some("GNOME".to_owned()), + kind: PublicChatKind::Supergroup(PublicChatSupergroup { + username: Some("gnome_ru".to_owned()), + active_usernames: None, + is_forum: false, + sticker_set_name: None, + can_set_sticker_set: None, + custom_emoji_sticker_set_name: None, + permissions: None, + slow_mode_delay: None, + unrestrict_boost_count: None, + linked_chat_id: None, + location: None, + join_to_send_messages: None, + join_by_request: None, + }), + description: None, + invite_link: None, + has_protected_content: None, + }), + photo: None, + available_reactions: None, + pinned_message: None, + message_auto_delete_time: None, + has_hidden_members: false, + has_aggressive_anti_spam_enabled: false, + chat_full_info: ChatFullInfo::default(), + }, + id: StoryId(420), + }; + + assert_eq!(story.url().unwrap(), "tg://resolve?domain=gnome_ru&story=420".parse().unwrap()); + } +} diff --git a/crates/teloxide-core/src/types/story_id.rs b/crates/teloxide-core/src/types/story_id.rs new file mode 100644 index 00000000..59dcdee9 --- /dev/null +++ b/crates/teloxide-core/src/types/story_id.rs @@ -0,0 +1,29 @@ +use serde::{Deserialize, Serialize}; + +/// Identifier of a story. +#[derive(Clone, Copy)] +#[derive(Debug, derive_more::Display)] +#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Serialize, Deserialize)] +#[serde(transparent)] +pub struct StoryId(pub u64); + +#[cfg(test)] +mod tests { + use super::*; + + /// Test that `StoryId` is serialized as the underlying integer + #[test] + fn deser() { + let story_id = S { id: StoryId(17) }; + let json = r#"{"id":17}"#; + + #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] + struct S { + id: StoryId, + } + + assert_eq!(serde_json::to_string(&story_id).unwrap(), json); + assert_eq!(story_id, serde_json::from_str(json).unwrap()); + } +} diff --git a/crates/teloxide-core/src/types/update.rs b/crates/teloxide-core/src/types/update.rs index 33d3f4a0..92bebc8f 100644 --- a/crates/teloxide-core/src/types/update.rs +++ b/crates/teloxide-core/src/types/update.rs @@ -548,6 +548,8 @@ mod test { forward_origin: None, external_reply: None, quote: None, + reply_to_story: None, + sender_boost_count: None, edit_date: None, media_kind: MediaKind::Text(MediaText { text: String::from("hello there"), @@ -868,8 +870,10 @@ mod test { is_forum: false, sticker_set_name: None, can_set_sticker_set: None, + custom_emoji_sticker_set_name: None, permissions: None, slow_mode_delay: None, + unrestrict_boost_count: None, linked_chat_id: None, location: None, join_to_send_messages: None, diff --git a/crates/teloxide/src/dispatching/filter_ext.rs b/crates/teloxide/src/dispatching/filter_ext.rs index 1f7394e3..e9cb3f4c 100644 --- a/crates/teloxide/src/dispatching/filter_ext.rs +++ b/crates/teloxide/src/dispatching/filter_ext.rs @@ -96,6 +96,7 @@ define_message_ext! { (filter_migration_to, Message::migrate_to_chat_id), (filter_reply_to_message, Message::reply_to_message), (filter_forward_origin, Message::forward_origin), + (filter_reply_to_story, Message::reply_to_story), // Rest variants of a MessageKind (filter_new_chat_members, Message::new_chat_members), (filter_left_chat_member, Message::left_chat_member), @@ -114,6 +115,7 @@ define_message_ext! { (filter_passport_data, Message::passport_data), (filter_dice, Message::dice), (filter_proximity_alert_triggered, Message::proximity_alert_triggered), + (filter_boost_added, Message::boost_added), (filter_forum_topic_created, Message::forum_topic_created), (filter_forum_topic_edited, Message::forum_topic_edited), (filter_forum_topic_closed, Message::forum_topic_closed), diff --git a/crates/teloxide/src/lib.rs b/crates/teloxide/src/lib.rs index 097643af..f4c9995c 100644 --- a/crates/teloxide/src/lib.rs +++ b/crates/teloxide/src/lib.rs @@ -1,6 +1,6 @@ //! A full-featured framework that empowers you to easily build [Telegram bots] //! using [Rust]. It handles all the difficult stuff so you can focus only on -//! your business logic. Currently, version `7.0` of [Telegram Bot API] is +//! your business logic. Currently, version `7.1` of [Telegram Bot API] is //! supported. //! //! For a high-level overview, see [our GitHub repository](https://github.com/teloxide/teloxide).