mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 06:25:10 +01:00
Merge pull request #1131 from shdwchn10/feature/tba-support/7.1
Add TBA 7.1 support
This commit is contained in:
commit
0d63d3a8ce
18 changed files with 297 additions and 43 deletions
|
@ -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
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<img src="https://img.shields.io/crates/v/teloxide.svg">
|
||||
</a>
|
||||
<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 href="https://t.me/teloxide">
|
||||
<img src="https://img.shields.io/badge/support-t.me%2Fteloxide-blueviolet">
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<img src="https://img.shields.io/badge/license-MIT-blue.svg">
|
||||
</a>
|
||||
<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 href="https://crates.io/crates/teloxide_core">
|
||||
<img src="https://img.shields.io/crates/v/teloxide_core.svg">
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -197,6 +197,13 @@ pub struct PublicChatSupergroup {
|
|||
/// [`GetChat`]: crate::payloads::GetChat
|
||||
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.
|
||||
/// Returned only from [`GetChat`].
|
||||
///
|
||||
|
@ -209,6 +216,13 @@ pub struct PublicChatSupergroup {
|
|||
/// [`GetChat`]: crate::payloads::GetChat
|
||||
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
|
||||
/// 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<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
|
||||
/// [`GetChat`].
|
||||
///
|
||||
|
|
|
@ -47,16 +47,13 @@ pub struct ChatAdministratorRights {
|
|||
/// supergroups only
|
||||
pub can_pin_messages: Option<bool>,
|
||||
|
||||
/// `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<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
|
||||
pub can_edit_stories: Option<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
|
||||
pub can_delete_stories: Option<bool>,
|
||||
|
||||
/// `true`, if the user is allowed to create, rename, close, and reopen
|
||||
|
|
24
crates/teloxide-core/src/types/chat_boost_added.rs
Normal file
24
crates/teloxide-core/src/types/chat_boost_added.rs
Normal 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();
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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<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.
|
||||
#[serde(default, with = "crate::types::serde_opt_date_from_unix_timestamp")]
|
||||
pub edit_date: Option<DateTime<Utc>>,
|
||||
|
@ -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<DateTime<Utc>> {
|
||||
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 }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<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());
|
||||
}
|
||||
}
|
||||
|
|
29
crates/teloxide-core/src/types/story_id.rs
Normal file
29
crates/teloxide-core/src/types/story_id.rs
Normal 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());
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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).
|
||||
|
|
Loading…
Reference in a new issue