Merge pull request #1131 from shdwchn10/feature/tba-support/7.1

Add TBA 7.1 support
This commit is contained in:
Сырцев Вадим Игоревич 2024-08-17 18:56:20 +00:00 committed by GitHub
commit 0d63d3a8ce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 297 additions and 43 deletions

View file

@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## unreleased ## unreleased
### Added
- Add `filter_boost_added` and `filter_reply_to_story` filters to `MessageFilterExt` trait
## 0.13.0 - 2024-08-16 ## 0.13.0 - 2024-08-16
### Added ### Added

View file

@ -11,7 +11,7 @@
<img src="https://img.shields.io/crates/v/teloxide.svg"> <img src="https://img.shields.io/crates/v/teloxide.svg">
</a> </a>
<a href="https://core.telegram.org/bots/api"> <a href="https://core.telegram.org/bots/api">
<img src="https://img.shields.io/badge/API%20coverage-Up%20to%207.0%20(inclusively)-green.svg"> <img src="https://img.shields.io/badge/API%20coverage-Up%20to%207.1%20(inclusively)-green.svg">
</a> </a>
<a href="https://t.me/teloxide"> <a href="https://t.me/teloxide">
<img src="https://img.shields.io/badge/support-t.me%2Fteloxide-blueviolet"> <img src="https://img.shields.io/badge/support-t.me%2Fteloxide-blueviolet">

View file

@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## unreleased ## 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 ## 0.10.1 - 2024-08-17
### Fixed ### Fixed

View file

@ -12,7 +12,7 @@
<img src="https://img.shields.io/badge/license-MIT-blue.svg"> <img src="https://img.shields.io/badge/license-MIT-blue.svg">
</a> </a>
<a href="https://core.telegram.org/bots/api"> <a href="https://core.telegram.org/bots/api">
<img src="https://img.shields.io/badge/API%20coverage-Up%20to%207.0%20(inclusively)-green.svg"> <img src="https://img.shields.io/badge/API%20coverage-Up%20to%207.1%20(inclusively)-green.svg">
</a> </a>
<a href="https://crates.io/crates/teloxide_core"> <a href="https://crates.io/crates/teloxide_core">
<img src="https://img.shields.io/crates/v/teloxide_core.svg"> <img src="https://img.shields.io/crates/v/teloxide_core.svg">

View file

@ -39,7 +39,7 @@
//! [github]: https://github.com/WaffleLapkin/tg-methods-schema //! [github]: https://github.com/WaffleLapkin/tg-methods-schema
Schema( Schema(
api_version: ApiVersion(ver: "7.0", date: "December 29, 2023"), api_version: ApiVersion(ver: "7.1", date: "February 16, 2024"),
methods: [ methods: [
Method( Method(
names: ("getUpdates", "GetUpdates", "get_updates"), names: ("getUpdates", "GetUpdates", "get_updates"),
@ -2098,17 +2098,17 @@ Schema(
Param( Param(
name: "can_post_stories", name: "can_post_stories",
ty: Option(bool), 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( Param(
name: "can_edit_stories", name: "can_edit_stories",
ty: Option(bool), 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( Param(
name: "can_delete_stories", name: "can_delete_stories",
ty: Option(bool), 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( Param(
name: "can_manage_video_chats", name: "can_manage_video_chats",

View file

@ -1,7 +1,7 @@
//! Core part of the [`teloxide`] library. //! Core part of the [`teloxide`] library.
//! //!
//! This library provides tools for making requests to the [Telegram Bot API] //! 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`]. //! asynchronous and built using [`tokio`].
//! //!
//!```toml //!```toml

View file

@ -25,11 +25,11 @@ impl_payload! {
pub can_edit_messages: bool, pub can_edit_messages: bool,
/// Pass True, if the administrator can delete messages of other users /// Pass True, if the administrator can delete messages of other users
pub can_delete_messages: bool, 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, 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, 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, pub can_delete_stories: bool,
/// Pass True, if the administrator can manage video chats, supergroups only /// Pass True, if the administrator can manage video chats, supergroups only
pub can_manage_video_chats: bool, pub can_manage_video_chats: bool,

View file

@ -14,6 +14,7 @@ pub use chat::*;
pub use chat_action::*; pub use chat_action::*;
pub use chat_administrator_rights::*; pub use chat_administrator_rights::*;
pub use chat_boost::*; pub use chat_boost::*;
pub use chat_boost_added::*;
pub use chat_boost_removed::*; pub use chat_boost_removed::*;
pub use chat_boost_source::*; pub use chat_boost_source::*;
pub use chat_boost_updated::*; pub use chat_boost_updated::*;
@ -125,6 +126,7 @@ pub use shipping_query::*;
pub use sticker::*; pub use sticker::*;
pub use sticker_set::*; pub use sticker_set::*;
pub use story::*; pub use story::*;
pub use story_id::*;
pub use successful_payment::*; pub use successful_payment::*;
pub use switch_inline_query_chosen_chat::*; pub use switch_inline_query_chosen_chat::*;
pub use target_message::*; pub use target_message::*;
@ -273,6 +275,7 @@ mod web_app_info;
mod webhook_info; mod webhook_info;
mod write_access_allowed; mod write_access_allowed;
mod chat_boost_added;
mod inline_query; mod inline_query;
mod inline_query_result; mod inline_query_result;
mod inline_query_result_article; mod inline_query_result_article;
@ -295,6 +298,7 @@ mod inline_query_result_photo;
mod inline_query_result_venue; mod inline_query_result_venue;
mod inline_query_result_video; mod inline_query_result_video;
mod inline_query_result_voice; mod inline_query_result_voice;
mod story_id;
mod encrypted_credentials; mod encrypted_credentials;
mod encrypted_passport_element; mod encrypted_passport_element;

View file

@ -197,6 +197,13 @@ pub struct PublicChatSupergroup {
/// [`GetChat`]: crate::payloads::GetChat /// [`GetChat`]: crate::payloads::GetChat
pub can_set_sticker_set: Option<bool>, pub can_set_sticker_set: Option<bool>,
/// 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<String>,
/// A default chat member permissions, for groups and supergroups. /// A default chat member permissions, for groups and supergroups.
/// Returned only from [`GetChat`]. /// Returned only from [`GetChat`].
/// ///
@ -209,6 +216,13 @@ pub struct PublicChatSupergroup {
/// [`GetChat`]: crate::payloads::GetChat /// [`GetChat`]: crate::payloads::GetChat
pub slow_mode_delay: Option<Seconds>, pub slow_mode_delay: Option<Seconds>,
/// 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<u16>,
/// Unique identifier for the linked chat, i.e. the discussion group /// Unique identifier for the linked chat, i.e. the discussion group
/// identifier for a channel and vice versa. Returned only in [`GetChat`]. /// identifier for a channel and vice versa. Returned only in [`GetChat`].
/// ///
@ -355,6 +369,22 @@ impl Chat {
None 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 /// The minimum allowed delay between consecutive messages sent by each
/// unpriviledged user. Returned only from [`GetChat`]. /// unpriviledged user. Returned only from [`GetChat`].
/// ///
@ -370,6 +400,21 @@ impl Chat {
None 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<u16> {
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 /// The location to which the supergroup is connected. Returned only in
/// [`GetChat`]. /// [`GetChat`].
/// ///

View file

@ -47,16 +47,13 @@ pub struct ChatAdministratorRights {
/// supergroups only /// supergroups only
pub can_pin_messages: Option<bool>, pub can_pin_messages: Option<bool>,
/// `true`, if the administrator can post stories in the channel; /// `true`, if the administrator can post stories to the chat
/// channels only
pub can_post_stories: Option<bool>, pub can_post_stories: Option<bool>,
/// `true`, if the administrator can edit stories posted by other users; /// `true`, if the administrator can edit stories posted by other users
/// channels only
pub can_edit_stories: Option<bool>, pub can_edit_stories: Option<bool>,
/// `true`, if the administrator can delete stories posted by other users; /// `true`, if the administrator can delete stories posted by other users
/// channels only
pub can_delete_stories: Option<bool>, pub can_delete_stories: Option<bool>,
/// `true`, if the user is allowed to create, rename, close, and reopen /// `true`, if the user is allowed to create, rename, close, and reopen

View file

@ -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::<ChatBoostAdded>(data).unwrap();
}
}

View file

@ -80,18 +80,15 @@ pub struct Administrator {
/// `true` if the administrator can delete messages of other users. /// `true` if the administrator can delete messages of other users.
pub can_delete_messages: bool, pub can_delete_messages: bool,
/// `true` if the administrator can post stories in the channel, channels /// `true` if the administrator can post stories to the chat.
/// only.
#[serde(default)] #[serde(default)]
pub can_post_stories: bool, pub can_post_stories: bool,
/// `true` if the administrator can edit stories posted by other users, /// `true` if the administrator can edit stories posted by other users.
/// channels only.
#[serde(default)] #[serde(default)]
pub can_edit_stories: bool, pub can_edit_stories: bool,
/// `true` if the administrator can delete stories posted by other users, /// `true` if the administrator can delete stories posted by other users.
/// channels only.
#[serde(default)] #[serde(default)]
pub can_delete_stories: bool, pub can_delete_stories: bool,
@ -447,8 +444,7 @@ impl ChatMemberKind {
} }
} }
/// Returns `true` if the user can post stories in the channel, channels /// Returns `true` if the administrator can post stories to the chat.
/// only.
/// ///
/// I.e. returns `true` if the user /// I.e. returns `true` if the user
/// - is the owner of the chat (even if the chat is not a channel) /// - 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, /// Returns `true` if the administrator can edit stories posted by other
/// channels only. /// users.
/// ///
/// I.e. returns `true` if the user /// I.e. returns `true` if the user
/// - is the owner of the chat (even if the chat is not a channel) /// - 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, /// Returns `true` if the administrator can delete stories posted by other
/// channels only. /// users.
/// ///
/// I.e. returns `true` if the user /// I.e. returns `true` if the user
/// - is the owner of the chat /// - is the owner of the chat

View file

@ -5,15 +5,15 @@ use serde::{Deserialize, Serialize};
use url::Url; use url::Url;
use crate::types::{ use crate::types::{
Animation, Audio, BareChatId, Chat, ChatId, ChatShared, Contact, Dice, Document, Animation, Audio, BareChatId, Chat, ChatBoostAdded, ChatId, ChatShared, Contact, Dice,
ExternalReplyInfo, ForumTopicClosed, ForumTopicCreated, ForumTopicEdited, ForumTopicReopened, Document, ExternalReplyInfo, ForumTopicClosed, ForumTopicCreated, ForumTopicEdited,
Game, GeneralForumTopicHidden, GeneralForumTopicUnhidden, Giveaway, GiveawayCompleted, ForumTopicReopened, Game, GeneralForumTopicHidden, GeneralForumTopicUnhidden, Giveaway,
GiveawayCreated, GiveawayWinners, InlineKeyboardMarkup, Invoice, LinkPreviewOptions, Location, GiveawayCompleted, GiveawayCreated, GiveawayWinners, InlineKeyboardMarkup, Invoice,
MaybeInaccessibleMessage, MessageAutoDeleteTimerChanged, MessageEntity, MessageEntityRef, LinkPreviewOptions, Location, MaybeInaccessibleMessage, MessageAutoDeleteTimerChanged,
MessageId, MessageOrigin, PassportData, PhotoSize, Poll, ProximityAlertTriggered, Sticker, MessageEntity, MessageEntityRef, MessageId, MessageOrigin, PassportData, PhotoSize, Poll,
Story, SuccessfulPayment, TextQuote, ThreadId, True, User, UsersShared, Venue, Video, ProximityAlertTriggered, Sticker, Story, SuccessfulPayment, TextQuote, ThreadId, True, User,
VideoChatEnded, VideoChatParticipantsInvited, VideoChatScheduled, VideoChatStarted, VideoNote, UsersShared, Venue, Video, VideoChatEnded, VideoChatParticipantsInvited, VideoChatScheduled,
Voice, WebAppData, WriteAccessAllowed, VideoChatStarted, VideoNote, Voice, WebAppData, WriteAccessAllowed,
}; };
/// This object represents a message. /// This object represents a message.
@ -84,6 +84,7 @@ pub enum MessageKind {
PassportData(MessagePassportData), PassportData(MessagePassportData),
Dice(MessageDice), Dice(MessageDice),
ProximityAlertTriggered(MessageProximityAlertTriggered), ProximityAlertTriggered(MessageProximityAlertTriggered),
ChatBoostAdded(MessageChatBoostAdded),
ForumTopicCreated(MessageForumTopicCreated), ForumTopicCreated(MessageForumTopicCreated),
ForumTopicEdited(MessageForumTopicEdited), ForumTopicEdited(MessageForumTopicEdited),
ForumTopicClosed(MessageForumTopicClosed), ForumTopicClosed(MessageForumTopicClosed),
@ -127,6 +128,13 @@ pub struct MessageCommon {
/// the message /// the message
pub quote: Option<TextQuote>, pub quote: Option<TextQuote>,
/// For replies to a story, the original story
pub reply_to_story: Option<Story>,
/// If the sender of the message boosted the chat, the number of boosts
/// added by the user
pub sender_boost_count: Option<u16>,
/// Date the message was last edited in Unix time. /// Date the message was last edited in Unix time.
#[serde(default, with = "crate::types::serde_opt_date_from_unix_timestamp")] #[serde(default, with = "crate::types::serde_opt_date_from_unix_timestamp")]
pub edit_date: Option<DateTime<Utc>>, pub edit_date: Option<DateTime<Utc>>,
@ -553,6 +561,13 @@ pub struct MessageProximityAlertTriggered {
pub proximity_alert_triggered: ProximityAlertTriggered, 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] #[serde_with::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct MessageWriteAccessAllowed { pub struct MessageWriteAccessAllowed {
@ -692,12 +707,12 @@ mod getters {
MessageInvoice, MessageLeftChatMember, MessageNewChatMembers, MessageNewChatPhoto, MessageInvoice, MessageLeftChatMember, MessageNewChatMembers, MessageNewChatPhoto,
MessageNewChatTitle, MessageOrigin, MessagePassportData, MessagePinned, MessageNewChatTitle, MessageOrigin, MessagePassportData, MessagePinned,
MessageProximityAlertTriggered, MessageSuccessfulPayment, MessageSupergroupChatCreated, MessageProximityAlertTriggered, MessageSuccessfulPayment, MessageSupergroupChatCreated,
MessageUsersShared, MessageVideoChatParticipantsInvited, PhotoSize, TextQuote, User, MessageUsersShared, MessageVideoChatParticipantsInvited, PhotoSize, Story, TextQuote, User,
}; };
use super::{ use super::{
MessageForumTopicClosed, MessageForumTopicCreated, MessageForumTopicEdited, MessageChatBoostAdded, MessageForumTopicClosed, MessageForumTopicCreated,
MessageForumTopicReopened, MessageGeneralForumTopicHidden, MessageForumTopicEdited, MessageForumTopicReopened, MessageGeneralForumTopicHidden,
MessageGeneralForumTopicUnhidden, MessageGiveaway, MessageGiveawayCompleted, MessageGeneralForumTopicUnhidden, MessageGiveaway, MessageGiveawayCompleted,
MessageGiveawayCreated, MessageGiveawayWinners, MessageMessageAutoDeleteTimerChanged, MessageGiveawayCreated, MessageGiveawayWinners, MessageMessageAutoDeleteTimerChanged,
MessageVideoChatEnded, MessageVideoChatScheduled, MessageVideoChatStarted, 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] #[must_use]
pub fn forward_date(&self) -> Option<DateTime<Utc>> { pub fn forward_date(&self) -> Option<DateTime<Utc>> {
self.forward_origin().map(|f| f.date()) 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] #[must_use]
pub fn forum_topic_created(&self) -> Option<&types::ForumTopicCreated> { pub fn forum_topic_created(&self) -> Option<&types::ForumTopicCreated> {
match &self.kind { match &self.kind {
@ -2083,8 +2114,10 @@ mod tests {
username: None, username: None,
sticker_set_name: None, sticker_set_name: None,
can_set_sticker_set: None, can_set_sticker_set: None,
custom_emoji_sticker_set_name: None,
permissions: None, permissions: None,
slow_mode_delay: None, slow_mode_delay: None,
unrestrict_boost_count: None,
linked_chat_id: None, linked_chat_id: None,
location: None, location: None,
join_by_request: 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 }
)
}
} }

View file

@ -1,5 +1,81 @@
use serde::{Deserialize, Serialize}; 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)] #[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<url::Url> {
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());
}
}

View file

@ -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());
}
}

View file

@ -548,6 +548,8 @@ mod test {
forward_origin: None, forward_origin: None,
external_reply: None, external_reply: None,
quote: None, quote: None,
reply_to_story: None,
sender_boost_count: None,
edit_date: None, edit_date: None,
media_kind: MediaKind::Text(MediaText { media_kind: MediaKind::Text(MediaText {
text: String::from("hello there"), text: String::from("hello there"),
@ -868,8 +870,10 @@ mod test {
is_forum: false, is_forum: false,
sticker_set_name: None, sticker_set_name: None,
can_set_sticker_set: None, can_set_sticker_set: None,
custom_emoji_sticker_set_name: None,
permissions: None, permissions: None,
slow_mode_delay: None, slow_mode_delay: None,
unrestrict_boost_count: None,
linked_chat_id: None, linked_chat_id: None,
location: None, location: None,
join_to_send_messages: None, join_to_send_messages: None,

View file

@ -96,6 +96,7 @@ define_message_ext! {
(filter_migration_to, Message::migrate_to_chat_id), (filter_migration_to, Message::migrate_to_chat_id),
(filter_reply_to_message, Message::reply_to_message), (filter_reply_to_message, Message::reply_to_message),
(filter_forward_origin, Message::forward_origin), (filter_forward_origin, Message::forward_origin),
(filter_reply_to_story, Message::reply_to_story),
// Rest variants of a MessageKind // Rest variants of a MessageKind
(filter_new_chat_members, Message::new_chat_members), (filter_new_chat_members, Message::new_chat_members),
(filter_left_chat_member, Message::left_chat_member), (filter_left_chat_member, Message::left_chat_member),
@ -114,6 +115,7 @@ define_message_ext! {
(filter_passport_data, Message::passport_data), (filter_passport_data, Message::passport_data),
(filter_dice, Message::dice), (filter_dice, Message::dice),
(filter_proximity_alert_triggered, Message::proximity_alert_triggered), (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_created, Message::forum_topic_created),
(filter_forum_topic_edited, Message::forum_topic_edited), (filter_forum_topic_edited, Message::forum_topic_edited),
(filter_forum_topic_closed, Message::forum_topic_closed), (filter_forum_topic_closed, Message::forum_topic_closed),

View file

@ -1,6 +1,6 @@
//! A full-featured framework that empowers you to easily build [Telegram bots] //! 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 //! 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. //! supported.
//! //!
//! For a high-level overview, see [our GitHub repository](https://github.com/teloxide/teloxide). //! For a high-level overview, see [our GitHub repository](https://github.com/teloxide/teloxide).