diff --git a/CHANGELOG.md b/CHANGELOG.md index be577e57..366d254b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `filter_web_app_data` - Implement `PostgresStorage`, a persistent dialogue storage based on [PostgreSQL](https://www.postgresql.org/)([PR 996](https://github.com/teloxide/teloxide/pull/996)). - Implement `GetChatId` for `teloxide_core::types::{Chat, ChatJoinRequest, ChatMemberUpdated}`. +- Add `MessageExt::filter_story` method for the corresponding `MediaKind::Story` variant ([PR 1087](https://github.com/teloxide/teloxide/pull/1087)) ### Fixed @@ -64,6 +65,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Sqlx version was bumped from `0.6` to `0.7.3`([PR 995](https://github.com/teloxide/teloxide/pull/995)) - Feature `sqlite-storage` was renamed to `sqlite-storage-nativetls`([PR 995](https://github.com/teloxide/teloxide/pull/995)) - MSRV (Minimal Supported Rust Version) was bumped from `1.68.0` to `1.70.0` ([PR 996][https://github.com/teloxide/teloxide/pull/996]) +- `axum` was bumped to `0.7`, along with related libraries used for webhooks ([PR 1093][https://github.com/teloxide/teloxide/pull/1093]) ### Removed diff --git a/Cargo.lock b/Cargo.lock index 0ba28d75..9e9fe940 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -122,18 +122,19 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "axum" -version = "0.6.20" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" dependencies = [ "async-trait", "axum-core", - "bitflags 1.3.2", "bytes", "futures-util", - "http", - "http-body", - "hyper", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.4.1", + "hyper-util", "itoa", "matchit", "memchr", @@ -145,28 +146,33 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 1.0.1", "tokio", "tower", "tower-layer", "tower-service", + "tracing", ] [[package]] name = "axum-core" -version = "0.3.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", "mime", + "pin-project-lite", "rustversion", + "sync_wrapper 0.1.2", "tower-layer", "tower-service", + "tracing", ] [[package]] @@ -240,15 +246,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" [[package]] name = "cc" -version = "1.0.105" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5208975e568d83b6b05cc0a063c8e7e9acc2b43bee6da15616a5b73e109d7437" +checksum = "324c74f2155653c90b04f25b2a47a8a631360cb908f92a772695f430c7e31052" [[package]] name = "cfg-if" @@ -531,12 +537,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" -[[package]] -name = "finl_unicode" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" - [[package]] name = "flume" version = "0.11.0" @@ -716,7 +716,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.12", "indexmap 2.2.5", "slab", "tokio", @@ -823,6 +823,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -830,15 +841,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", "pin-project-lite", ] [[package]] -name = "http-range-header" -version = "0.3.1" +name = "http-body" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "pin-project-lite", +] [[package]] name = "httparse" @@ -869,28 +897,47 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.29" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", "h2", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.6", + "socket2 0.4.10", "tokio", "tower-service", "tracing", "want", ] +[[package]] +name = "hyper" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", +] + [[package]] name = "hyper-rustls" version = "0.24.2" @@ -898,8 +945,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", - "hyper", + "http 0.2.12", + "hyper 0.14.30", "rustls", "tokio", "tokio-rustls", @@ -912,12 +959,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper", + "hyper 0.14.30", "native-tls", "tokio", "tokio-native-tls", ] +[[package]] +name = "hyper-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "hyper 1.4.1", + "pin-project-lite", + "tokio", +] + [[package]] name = "iana-time-zone" version = "0.1.60" @@ -1518,9 +1580,9 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", - "hyper", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.30", "hyper-rustls", "hyper-tls", "ipnet", @@ -1533,11 +1595,12 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls", + "rustls-native-certs", "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 0.1.2", "system-configuration", "tokio", "tokio-native-tls", @@ -1619,6 +1682,18 @@ dependencies = [ "sct", ] +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -1690,9 +1765,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ "core-foundation-sys", "libc", @@ -2064,6 +2139,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + [[package]] name = "system-configuration" version = "0.5.1" @@ -2202,18 +2283,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" dependencies = [ "proc-macro2", "quote", @@ -2222,9 +2303,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6b6a2fb3a985e99cebfaefa9faa3024743da73304ca1c683a36429613d3d22" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -2326,17 +2407,15 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.3.5" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" +checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", "bytes", - "futures-core", - "futures-util", - "http", - "http-body", - "http-range-header", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", "pin-project-lite", "tower-layer", "tower-service", @@ -2473,9 +2552,9 @@ checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "uuid" -version = "1.9.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ "getrandom", ] diff --git a/README.md b/README.md index 9d335b9e..6eda6f18 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ - + diff --git a/crates/teloxide-core/CHANGELOG.md b/crates/teloxide-core/CHANGELOG.md index 87cc89a9..99d1dd67 100644 --- a/crates/teloxide-core/CHANGELOG.md +++ b/crates/teloxide-core/CHANGELOG.md @@ -85,7 +85,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `set_my_name` - `get_my_name` - Add the ability to specify custom emoji entities using `HTML` and `MarkdownV2` formatting options for bots that purchased additional usernames on [Fragment](https://fragment.com/) - +- Support for TBA 6.8 ([#1087](pr1087)) + - Add the `MediaKind::Story` + - Add new fields + - `PollAnswer::voter` to support anonymous poll answers in chats + - `emoji_status_expiration_date` to `Chat` as part of the future `ChatFullInfo` type TBA type + - Add the `unpin_all_general_forum_topic_messages` method [pr851]: https://github.com/teloxide/teloxide/pull/851 [pr887]: https://github.com/teloxide/teloxide/pull/887 @@ -93,6 +98,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [pr982]: https://github.com/teloxide/teloxide/pull/982 [pr1040]: https://github.com/teloxide/teloxide/pull/1040 [pr1086]: https://github.com/teloxide/teloxide/pull/1086 +[pr1087]: https://github.com/teloxide/teloxide/pull/1087 ### Fixed diff --git a/crates/teloxide-core/Cargo.toml b/crates/teloxide-core/Cargo.toml index 669abaea..2b8db2b1 100644 --- a/crates/teloxide-core/Cargo.toml +++ b/crates/teloxide-core/Cargo.toml @@ -22,6 +22,7 @@ categories = ["api-bindings", "asynchronous"] default = ["native-tls"] rustls = ["reqwest/rustls-tls"] +rustls-native-roots = ["reqwest/rustls-tls-native-roots"] native-tls = ["reqwest/native-tls"] # Features which require nightly compiler. @@ -72,7 +73,7 @@ once_cell = "1.5.0" takecell = "0.1" take_mut = "0.2" rc-box = "1.1.1" -chrono = { version = "0.4.30", default-features = false } +chrono = { version = "0.4.32", default-features = false } either = "1.6.1" bitflags = { version = "1.2" } diff --git a/crates/teloxide-core/README.md b/crates/teloxide-core/README.md index 3ae43842..6a382bb3 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 6f985352..82ca86a4 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: "6.7", date: "April 21, 2023"), + api_version: ApiVersion(ver: "6.8", date: "August 18, 2023"), methods: [ Method( names: ("getUpdates", "GetUpdates", "get_updates"), @@ -2801,6 +2801,20 @@ Schema( ), ], ), + Method( + names: ("unpinAllGeneralForumTopicMessages", "UnpinAllGeneralForumTopicMessages", "unpin_all_general_forum_topic_messages"), + return_ty: True, + doc: Doc(md: "Use this method to clear the list of pinned messages in a General forum topic. The bot must be an administrator in the chat for this to work and must have the _can\\_pin\\_messages_ administrator right in the supergroup. Returns True on success."), + tg_doc: "https://core.telegram.org/bots/api#unpinallgeneralforumtopicmessages", + tg_category: "Available methods", + params: [ + Param( + name: "chat_id", + ty: RawTy("Recipient"), + descr: Doc(md: "Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername)") + ), + ], + ), Method( names: ("answerCallbackQuery", "AnswerCallbackQuery", "answer_callback_query"), return_ty: True, diff --git a/crates/teloxide-core/src/adaptors/cache_me.rs b/crates/teloxide-core/src/adaptors/cache_me.rs index 84b4887e..eecac8bc 100644 --- a/crates/teloxide-core/src/adaptors/cache_me.rs +++ b/crates/teloxide-core/src/adaptors/cache_me.rs @@ -156,6 +156,7 @@ where reopen_general_forum_topic, hide_general_forum_topic, unhide_general_forum_topic, + unpin_all_general_forum_topic_messages, answer_callback_query, set_my_commands, get_my_commands, diff --git a/crates/teloxide-core/src/adaptors/erased.rs b/crates/teloxide-core/src/adaptors/erased.rs index 0544b535..59ff77dc 100644 --- a/crates/teloxide-core/src/adaptors/erased.rs +++ b/crates/teloxide-core/src/adaptors/erased.rs @@ -251,6 +251,7 @@ where reopen_general_forum_topic, hide_general_forum_topic, unhide_general_forum_topic, + unpin_all_general_forum_topic_messages, answer_callback_query, set_my_commands, get_my_commands, @@ -699,6 +700,11 @@ trait ErasableRequester<'a> { chat_id: Recipient, ) -> ErasedRequest<'a, UnhideGeneralForumTopic, Self::Err>; + fn unpin_all_general_forum_topic_messages( + &self, + chat_id: Recipient, + ) -> ErasedRequest<'a, UnpinAllGeneralForumTopicMessages, Self::Err>; + fn answer_callback_query( &self, callback_query_id: String, @@ -1500,6 +1506,13 @@ where Requester::unhide_general_forum_topic(self, chat_id).erase() } + fn unpin_all_general_forum_topic_messages( + &self, + chat_id: Recipient, + ) -> ErasedRequest<'a, UnpinAllGeneralForumTopicMessages, Self::Err> { + Requester::unpin_all_general_forum_topic_messages(self, chat_id).erase() + } + fn answer_callback_query( &self, callback_query_id: String, diff --git a/crates/teloxide-core/src/adaptors/parse_mode.rs b/crates/teloxide-core/src/adaptors/parse_mode.rs index d7540115..216893a4 100644 --- a/crates/teloxide-core/src/adaptors/parse_mode.rs +++ b/crates/teloxide-core/src/adaptors/parse_mode.rs @@ -231,12 +231,13 @@ where close_forum_topic, reopen_forum_topic, delete_forum_topic, + unpin_all_forum_topic_messages, edit_general_forum_topic, close_general_forum_topic, reopen_general_forum_topic, hide_general_forum_topic, unhide_general_forum_topic, - unpin_all_forum_topic_messages, + unpin_all_general_forum_topic_messages, answer_callback_query, set_my_commands, get_my_commands, diff --git a/crates/teloxide-core/src/adaptors/throttle/requester_impl.rs b/crates/teloxide-core/src/adaptors/throttle/requester_impl.rs index 436f6488..28d82051 100644 --- a/crates/teloxide-core/src/adaptors/throttle/requester_impl.rs +++ b/crates/teloxide-core/src/adaptors/throttle/requester_impl.rs @@ -139,6 +139,7 @@ where reopen_general_forum_topic, hide_general_forum_topic, unhide_general_forum_topic, + unpin_all_general_forum_topic_messages, answer_callback_query, set_my_commands, get_my_commands, diff --git a/crates/teloxide-core/src/adaptors/trace.rs b/crates/teloxide-core/src/adaptors/trace.rs index 466674d1..bf4141bc 100644 --- a/crates/teloxide-core/src/adaptors/trace.rs +++ b/crates/teloxide-core/src/adaptors/trace.rs @@ -185,6 +185,7 @@ where reopen_general_forum_topic, hide_general_forum_topic, unhide_general_forum_topic, + unpin_all_general_forum_topic_messages, answer_callback_query, set_my_commands, get_my_commands, diff --git a/crates/teloxide-core/src/bot/api.rs b/crates/teloxide-core/src/bot/api.rs index 1a1a3ef6..1eea1f74 100644 --- a/crates/teloxide-core/src/bot/api.rs +++ b/crates/teloxide-core/src/bot/api.rs @@ -802,6 +802,22 @@ impl Requester for Bot { ) } + type UnpinAllGeneralForumTopicMessages = + JsonRequest; + + fn unpin_all_general_forum_topic_messages( + &self, + chat_id: C, + ) -> Self::UnpinAllGeneralForumTopicMessages + where + C: Into, + { + Self::UnpinAllGeneralForumTopicMessages::new( + self.clone(), + payloads::UnpinAllGeneralForumTopicMessages::new(chat_id), + ) + } + type AnswerCallbackQuery = JsonRequest; fn answer_callback_query(&self, callback_query_id: C) -> Self::AnswerCallbackQuery diff --git a/crates/teloxide-core/src/local_macros.rs b/crates/teloxide-core/src/local_macros.rs index 9be73d5f..aa285426 100644 --- a/crates/teloxide-core/src/local_macros.rs +++ b/crates/teloxide-core/src/local_macros.rs @@ -1009,6 +1009,14 @@ macro_rules! requester_forward { $body!(unhide_general_forum_topic this (chat_id: C)) } }; + (@method unpin_all_general_forum_topic_messages $body:ident $ty:ident) => { + type UnpinAllGeneralForumTopicMessages = $ty![UnpinAllGeneralForumTopicMessages]; + + fn unpin_all_general_forum_topic_messages(&self, chat_id: C) -> Self::UnpinAllGeneralForumTopicMessages where C: Into { + let this = self; + $body!(unpin_all_general_forum_topic_messages this (chat_id: C)) + } + }; (@method answer_callback_query $body:ident $ty:ident) => { type AnswerCallbackQuery = $ty![AnswerCallbackQuery]; diff --git a/crates/teloxide-core/src/payloads.rs b/crates/teloxide-core/src/payloads.rs index 97d2e61d..7f3cf308 100644 --- a/crates/teloxide-core/src/payloads.rs +++ b/crates/teloxide-core/src/payloads.rs @@ -135,6 +135,7 @@ mod unban_chat_sender_chat; mod unhide_general_forum_topic; mod unpin_all_chat_messages; mod unpin_all_forum_topic_messages; +mod unpin_all_general_forum_topic_messages; mod unpin_chat_message; mod upload_sticker_file; @@ -276,6 +277,9 @@ pub use unpin_all_chat_messages::{UnpinAllChatMessages, UnpinAllChatMessagesSett pub use unpin_all_forum_topic_messages::{ UnpinAllForumTopicMessages, UnpinAllForumTopicMessagesSetters, }; +pub use unpin_all_general_forum_topic_messages::{ + UnpinAllGeneralForumTopicMessages, UnpinAllGeneralForumTopicMessagesSetters, +}; pub use unpin_chat_message::{UnpinChatMessage, UnpinChatMessageSetters}; pub use upload_sticker_file::{UploadStickerFile, UploadStickerFileSetters}; // END BLOCK payload_modules diff --git a/crates/teloxide-core/src/payloads/setters.rs b/crates/teloxide-core/src/payloads/setters.rs index 6faa7d16..9771e38b 100644 --- a/crates/teloxide-core/src/payloads/setters.rs +++ b/crates/teloxide-core/src/payloads/setters.rs @@ -47,6 +47,6 @@ pub use crate::payloads::{ StopMessageLiveLocationInlineSetters as _, StopMessageLiveLocationSetters as _, StopPollSetters as _, UnbanChatMemberSetters as _, UnbanChatSenderChatSetters as _, UnhideGeneralForumTopicSetters as _, UnpinAllChatMessagesSetters as _, - UnpinAllForumTopicMessagesSetters as _, UnpinChatMessageSetters as _, - UploadStickerFileSetters as _, + UnpinAllForumTopicMessagesSetters as _, UnpinAllGeneralForumTopicMessagesSetters as _, + UnpinChatMessageSetters as _, UploadStickerFileSetters as _, }; diff --git a/crates/teloxide-core/src/payloads/unpin_all_general_forum_topic_messages.rs b/crates/teloxide-core/src/payloads/unpin_all_general_forum_topic_messages.rs new file mode 100644 index 00000000..776b066a --- /dev/null +++ b/crates/teloxide-core/src/payloads/unpin_all_general_forum_topic_messages.rs @@ -0,0 +1,16 @@ +//! Generated by `codegen_payloads`, do not edit by hand. + +use serde::Serialize; + +use crate::types::{Recipient, True}; + +impl_payload! { + /// Use this method to clear the list of pinned messages in a General forum topic. The bot must be an administrator in the chat for this to work and must have the _can\_pin\_messages_ administrator right in the supergroup. Returns True on success. + #[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize)] + pub UnpinAllGeneralForumTopicMessages (UnpinAllGeneralForumTopicMessagesSetters) => True { + required { + /// Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername) + pub chat_id: Recipient [into], + } + } +} diff --git a/crates/teloxide-core/src/requests/requester.rs b/crates/teloxide-core/src/requests/requester.rs index e9390088..0428d50b 100644 --- a/crates/teloxide-core/src/requests/requester.rs +++ b/crates/teloxide-core/src/requests/requester.rs @@ -758,6 +758,19 @@ pub trait Requester { where C: Into; + type UnpinAllGeneralForumTopicMessages: Request< + Payload = UnpinAllGeneralForumTopicMessages, + Err = Self::Err, + >; + + /// For Telegram documentation see [`UnpinAllGeneralForumTopicMessages`]. + fn unpin_all_general_forum_topic_messages( + &self, + chat_id: C, + ) -> Self::UnpinAllGeneralForumTopicMessages + where + C: Into; + type AnswerCallbackQuery: Request; /// For Telegram documentation see [`AnswerCallbackQuery`]. @@ -1297,6 +1310,7 @@ macro_rules! forward_all { reopen_general_forum_topic, hide_general_forum_topic, unhide_general_forum_topic, + unpin_all_general_forum_topic_messages, answer_callback_query, set_my_commands, get_my_commands, diff --git a/crates/teloxide-core/src/types.rs b/crates/teloxide-core/src/types.rs index 26128929..f142825d 100644 --- a/crates/teloxide-core/src/types.rs +++ b/crates/teloxide-core/src/types.rs @@ -13,6 +13,7 @@ pub use callback_query::*; pub use chat::*; pub use chat_action::*; pub use chat_administrator_rights::*; +pub use chat_full_info::*; pub use chat_invite_link::*; pub use chat_join_request::*; pub use chat_location::*; @@ -105,6 +106,7 @@ pub use shipping_option::*; pub use shipping_query::*; pub use sticker::*; pub use sticker_set::*; +pub use story::*; pub use successful_payment::*; pub use switch_inline_query_chosen_chat::*; pub use target_message::*; @@ -141,6 +143,7 @@ mod callback_query; mod chat; mod chat_action; mod chat_administrator_rights; +mod chat_full_info; mod chat_invite_link; mod chat_join_request; mod chat_location; @@ -206,6 +209,7 @@ mod shipping_option; mod shipping_query; mod sticker; mod sticker_set; +mod story; mod successful_payment; mod switch_inline_query_chosen_chat; mod target_message; diff --git a/crates/teloxide-core/src/types/chat.rs b/crates/teloxide-core/src/types/chat.rs index 2bd38dd9..6f12745d 100644 --- a/crates/teloxide-core/src/types/chat.rs +++ b/crates/teloxide-core/src/types/chat.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use crate::types::{ - ChatId, ChatLocation, ChatPermissions, ChatPhoto, Message, Seconds, True, User, + ChatFullInfo, ChatId, ChatLocation, ChatPermissions, ChatPhoto, Message, Seconds, True, User, }; /// This object represents a chat. @@ -47,6 +47,9 @@ pub struct Chat { /// [`GetChat`]: crate::payloads::GetChat #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub has_aggressive_anti_spam_enabled: bool, + + #[serde(flatten)] + pub chat_full_info: ChatFullInfo, } #[serde_with_macros::skip_serializing_none] @@ -615,6 +618,7 @@ mod tests { message_auto_delete_time: None, has_hidden_members: false, has_aggressive_anti_spam_enabled: false, + chat_full_info: ChatFullInfo { emoji_status_expiration_date: None }, }; let actual = from_str(r#"{"id":-1,"type":"channel","username":"channel_name"}"#).unwrap(); assert_eq!(expected, actual); @@ -639,6 +643,7 @@ mod tests { message_auto_delete_time: None, has_hidden_members: false, has_aggressive_anti_spam_enabled: false, + chat_full_info: ChatFullInfo { emoji_status_expiration_date: None } }, from_str(r#"{"id":0,"type":"private","username":"username","first_name":"Anon"}"#) .unwrap() @@ -663,6 +668,7 @@ mod tests { message_auto_delete_time: None, has_hidden_members: false, has_aggressive_anti_spam_enabled: false, + chat_full_info: ChatFullInfo { emoji_status_expiration_date: None }, }; let json = to_string(&chat).unwrap(); diff --git a/crates/teloxide-core/src/types/chat_full_info.rs b/crates/teloxide-core/src/types/chat_full_info.rs new file mode 100644 index 00000000..9857ce7d --- /dev/null +++ b/crates/teloxide-core/src/types/chat_full_info.rs @@ -0,0 +1,35 @@ +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; + +// TODO: in the TBA7.3 the Chat will be splitted into Chat and ChatInfo +// Currently it's just a container for the some fields of the Chat struct +#[serde_with_macros::skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct ChatFullInfo { + /// Expiration date of the emoji status of the chat or the other party in a + /// private chat, in Unix time, if any + #[serde(default, with = "crate::types::serde_opt_date_from_unix_timestamp")] + pub emoji_status_expiration_date: Option>, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_chat_full_info_de() { + assert_eq!( + serde_json::from_str::("{}").unwrap(), + ChatFullInfo { emoji_status_expiration_date: None } + ); + assert_eq!( + serde_json::from_str::( + r#"{ + "emoji_status_expiration_date": 1720708004 + }"# + ) + .unwrap(), + ChatFullInfo { emoji_status_expiration_date: DateTime::from_timestamp(1720708004, 0) } + ); + } +} diff --git a/crates/teloxide-core/src/types/message.rs b/crates/teloxide-core/src/types/message.rs index b80c4bbb..0eb7f353 100644 --- a/crates/teloxide-core/src/types/message.rs +++ b/crates/teloxide-core/src/types/message.rs @@ -9,9 +9,9 @@ use crate::types::{ ForumTopicClosed, ForumTopicCreated, ForumTopicEdited, ForumTopicReopened, Game, GeneralForumTopicHidden, GeneralForumTopicUnhidden, InlineKeyboardMarkup, Invoice, Location, MessageAutoDeleteTimerChanged, MessageEntity, MessageEntityRef, MessageId, PassportData, - PhotoSize, Poll, ProximityAlertTriggered, Sticker, SuccessfulPayment, ThreadId, True, User, - UserShared, Venue, Video, VideoChatEnded, VideoChatParticipantsInvited, VideoChatScheduled, - VideoChatStarted, VideoNote, Voice, WebAppData, WriteAccessAllowed, + PhotoSize, Poll, ProximityAlertTriggered, Sticker, Story, SuccessfulPayment, ThreadId, True, + User, UserShared, Venue, Video, VideoChatEnded, VideoChatParticipantsInvited, + VideoChatScheduled, VideoChatStarted, VideoNote, Voice, WebAppData, WriteAccessAllowed, }; /// This object represents a message. @@ -366,6 +366,7 @@ pub enum MediaKind { Photo(MediaPhoto), Poll(MediaPoll), Sticker(MediaSticker), + Story(MediaStory), Text(MediaText), Video(MediaVideo), VideoNote(MediaVideoNote), @@ -494,6 +495,13 @@ pub struct MediaSticker { pub sticker: Sticker, } +#[serde_with_macros::skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct MediaStory { + /// Message is a forwarded story + pub story: Story, +} + #[serde_with_macros::skip_serializing_none] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct MediaText { @@ -668,14 +676,14 @@ mod getters { use crate::types::{ self, message::MessageKind::*, Chat, ChatId, ChatMigration, Forward, ForwardedFrom, MediaAnimation, MediaAudio, MediaContact, MediaDocument, MediaGame, MediaKind, - MediaLocation, MediaPhoto, MediaPoll, MediaSticker, MediaText, MediaVenue, MediaVideo, - MediaVideoNote, MediaVoice, Message, MessageChannelChatCreated, MessageChatShared, - MessageCommon, MessageConnectedWebsite, MessageDeleteChatPhoto, MessageDice, MessageEntity, - MessageGroupChatCreated, MessageId, MessageInvoice, MessageLeftChatMember, - MessageNewChatMembers, MessageNewChatPhoto, MessageNewChatTitle, MessagePassportData, - MessagePinned, MessageProximityAlertTriggered, MessageSuccessfulPayment, - MessageSupergroupChatCreated, MessageUserShared, MessageVideoChatParticipantsInvited, - PhotoSize, User, + MediaLocation, MediaPhoto, MediaPoll, MediaSticker, MediaStory, MediaText, MediaVenue, + MediaVideo, MediaVideoNote, MediaVoice, Message, MessageChannelChatCreated, + MessageChatShared, MessageCommon, MessageConnectedWebsite, MessageDeleteChatPhoto, + MessageDice, MessageEntity, MessageGroupChatCreated, MessageId, MessageInvoice, + MessageLeftChatMember, MessageNewChatMembers, MessageNewChatPhoto, MessageNewChatTitle, + MessagePassportData, MessagePinned, MessageProximityAlertTriggered, + MessageSuccessfulPayment, MessageSupergroupChatCreated, MessageUserShared, + MessageVideoChatParticipantsInvited, PhotoSize, User, }; use super::{ @@ -899,6 +907,7 @@ mod getters { | MediaKind::Location(_) | MediaKind::Poll(_) | MediaKind::Sticker(_) + | MediaKind::Story(_) | MediaKind::Text(_) | MediaKind::VideoNote(_) | MediaKind::Voice(_) @@ -973,6 +982,17 @@ mod getters { } } + #[must_use] + pub fn story(&self) -> Option<&types::Story> { + match &self.kind { + Common(MessageCommon { + media_kind: MediaKind::Story(MediaStory { story, .. }), + .. + }) => Some(story), + _ => None, + } + } + #[must_use] pub fn video(&self) -> Option<&types::Video> { match &self.kind { @@ -1763,7 +1783,8 @@ mod tests { has_aggressive_anti_spam_enabled: false, pinned_message: None, message_auto_delete_time: None, - has_hidden_members: false + has_hidden_members: false, + chat_full_info: ChatFullInfo { emoji_status_expiration_date: None } }, kind: MessageKind::ChatShared(MessageChatShared { chat_shared: ChatShared { request_id: 348349, chat_id: ChatId(384939) } @@ -1996,6 +2017,7 @@ mod tests { pinned_message: None, has_hidden_members: false, has_aggressive_anti_spam_enabled: false, + chat_full_info: ChatFullInfo { emoji_status_expiration_date: None }, }; assert!(message.from().unwrap().is_anonymous()); diff --git a/crates/teloxide-core/src/types/poll_answer.rs b/crates/teloxide-core/src/types/poll_answer.rs index e87e0878..f40b55fb 100644 --- a/crates/teloxide-core/src/types/poll_answer.rs +++ b/crates/teloxide-core/src/types/poll_answer.rs @@ -1,17 +1,117 @@ -use crate::types::User; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; + +use crate::types::{Chat, User}; #[serde_with_macros::skip_serializing_none] -#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct PollAnswer { /// Unique poll identifier. pub poll_id: String, - /// The user, who changed the answer to the poll. - pub user: User, + /// If the voter is anonymous, stores the chat that changed the answer to + /// the poll. + /// + /// If the voter isn't anonymous, stores the user that changed + /// the answer to the poll + #[serde(deserialize_with = "deserialize_voter", flatten)] + pub voter: Voter, /// 0-based identifiers of answer options, chosen by the user. /// /// May be empty if the user retracted their vote. pub option_ids: Vec, } + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[serde(untagged)] +pub enum Voter { + Chat(Chat), + User(User), +} + +impl Voter { + #[must_use] + pub fn chat(&self) -> Option<&Chat> { + match self { + Self::Chat(chat) => Some(chat), + _ => None, + } + } + + #[must_use] + pub fn user(&self) -> Option<&User> { + match self { + Self::User(user) => Some(user), + _ => None, + } + } +} + +/// These fields `chat` and `user` from the original [`PollAnswer`] should be +/// exclusive, but in cases when the `voter_chat` is presented the `user` isn't +/// `None`, but rather actual value for backward compatibility, the field `user` +/// in such objects will contain the user 136817688 (@Channel_Bot). +#[derive(Deserialize)] +struct VoterDe { + /// The chat that changed the answer to the poll, if the voter is anonymous + pub voter_chat: Option, + + /// The user that changed the answer to the poll, if the voter isn't + /// anonymous + pub user: Option, +} + +fn deserialize_voter<'d, D: Deserializer<'d>>(d: D) -> Result { + let VoterDe { voter_chat, user } = VoterDe::deserialize(d)?; + Ok(voter_chat.map(Voter::Chat).or(user.map(Voter::User)).unwrap()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_poll_answer_with_user_de() { + let json = r#"{ + "poll_id":"POLL_ID", + "user": {"id":42,"is_bot":false,"first_name":"blah"}, + "option_ids": [] + }"#; + + let poll_answer: PollAnswer = serde_json::from_str(json).unwrap(); + assert!(matches!(poll_answer.voter, Voter::User(_))); + } + + #[test] + fn test_poll_answer_with_voter_chat_de() { + let json = r#"{ + "poll_id":"POLL_ID", + "voter_chat": { + "id": -1001160242915, + "title": "a", + "type": "group" + }, + "option_ids": [] + }"#; + + let poll_answer: PollAnswer = serde_json::from_str(json).unwrap(); + assert!(matches!(poll_answer.voter, Voter::Chat(_))); + } + + #[test] + fn test_poll_answer_with_both_user_and_voter_chat_de() { + let json = r#"{ + "poll_id":"POLL_ID", + "voter_chat": { + "id": -1001160242915, + "title": "a", + "type": "group" + }, + "user": {"id":136817688,"is_bot":true,"first_name":"Channel_Bot"}, + "option_ids": [] + }"#; + + let poll_answer: PollAnswer = serde_json::from_str(json).unwrap(); + assert!(matches!(poll_answer.voter, Voter::Chat(_))); + } +} diff --git a/crates/teloxide-core/src/types/story.rs b/crates/teloxide-core/src/types/story.rs new file mode 100644 index 00000000..a59e1568 --- /dev/null +++ b/crates/teloxide-core/src/types/story.rs @@ -0,0 +1,5 @@ +use serde::{Deserialize, Serialize}; + +/// TBA 6.8: currently it holds no information +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Story {} diff --git a/crates/teloxide-core/src/types/update.rs b/crates/teloxide-core/src/types/update.rs index caff4c50..adc8056a 100644 --- a/crates/teloxide-core/src/types/update.rs +++ b/crates/teloxide-core/src/types/update.rs @@ -136,7 +136,7 @@ impl Update { InlineQuery(query) => &query.from, ShippingQuery(query) => &query.from, PreCheckoutQuery(query) => &query.from, - PollAnswer(answer) => &answer.user, + PollAnswer(answer) => return answer.voter.user(), MyChatMember(m) | ChatMember(m) => &m.from, ChatJoinRequest(r) => &r.from, @@ -198,7 +198,12 @@ impl Update { UpdateKind::PreCheckoutQuery(query) => i1(once(&query.from)), UpdateKind::Poll(poll) => i3(poll.mentioned_users()), - UpdateKind::PollAnswer(answer) => i1(once(&answer.user)), + UpdateKind::PollAnswer(answer) => { + if let Some(user) = answer.voter.user() { + return i1(once(user)); + } + i6(empty()) + } UpdateKind::MyChatMember(member) | UpdateKind::ChatMember(member) => { i4(member.mentioned_users()) @@ -380,8 +385,8 @@ fn empty_error() -> UpdateKind { #[cfg(test)] mod test { use crate::types::{ - Chat, ChatId, ChatKind, ChatPrivate, MediaKind, MediaText, Message, MessageCommon, - MessageId, MessageKind, Update, UpdateId, UpdateKind, User, UserId, + Chat, ChatFullInfo, ChatId, ChatKind, ChatPrivate, MediaKind, MediaText, Message, + MessageCommon, MessageId, MessageKind, Update, UpdateId, UpdateKind, User, UserId, }; use chrono::DateTime; @@ -437,6 +442,7 @@ mod test { message_auto_delete_time: None, has_hidden_members: false, has_aggressive_anti_spam_enabled: false, + chat_full_info: ChatFullInfo { emoji_status_expiration_date: None }, }, kind: MessageKind::Common(MessageCommon { from: Some(User { diff --git a/crates/teloxide/Cargo.toml b/crates/teloxide/Cargo.toml index 823d4099..48116b65 100644 --- a/crates/teloxide/Cargo.toml +++ b/crates/teloxide/Cargo.toml @@ -42,6 +42,7 @@ ctrlc_handler = ["tokio/signal"] native-tls = ["teloxide-core/native-tls"] rustls = ["teloxide-core/rustls"] +rustls-native-roots = ["teloxide-core/rustls-native-roots"] throttle = ["teloxide-core/throttle"] cache-me = [ "teloxide-core/cache_me", @@ -111,9 +112,9 @@ sqlx = { version = "0.7.3", optional = true, default-features = false, features redis = { version = "0.24", features = ["tokio-comp"], optional = true } serde_cbor = { version = "0.11", optional = true } bincode = { version = "1.3", optional = true } -axum = { version = "0.6.0", optional = true } -tower = { version = "0.4.12", optional = true } -tower-http = { version = "0.3.4", features = ["trace"], optional = true } +axum = { version = "0.7.0", optional = true } +tower = { version = "0.4.13", optional = true } +tower-http = { version = "0.5.2", features = ["trace"], optional = true } rand = { version = "0.8.5", optional = true } # HACK: ahash 0.8.7 bumped MSRV to 1.72, to keep MVSR 1.68 we need to depend on an older version. diff --git a/crates/teloxide/src/dispatching/filter_ext.rs b/crates/teloxide/src/dispatching/filter_ext.rs index c0ab8e04..532f614f 100644 --- a/crates/teloxide/src/dispatching/filter_ext.rs +++ b/crates/teloxide/src/dispatching/filter_ext.rs @@ -83,6 +83,7 @@ define_message_ext! { (filter_photo, Message::photo), (filter_poll, Message::poll), (filter_sticker, Message::sticker), + (filter_story, Message::story), (filter_text, Message::text), (filter_video, Message::video), (filter_video_note, Message::video_note), diff --git a/crates/teloxide/src/update_listeners/webhooks/axum.rs b/crates/teloxide/src/update_listeners/webhooks/axum.rs index 2a915a55..784848dd 100644 --- a/crates/teloxide/src/update_listeners/webhooks/axum.rs +++ b/crates/teloxide/src/update_listeners/webhooks/axum.rs @@ -52,8 +52,14 @@ where let stop_token = update_listener.stop_token(); tokio::spawn(async move { - axum::Server::bind(&address) - .serve(app.into_make_service()) + let tcp_listener = tokio::net::TcpListener::bind(address) + .await + .map_err(|err| { + stop_token.stop(); + err + }) + .expect("Couldn't bind to the address"); + axum::serve(tcp_listener, app) .with_graceful_shutdown(stop_flag) .await .map_err(|err| { @@ -90,7 +96,7 @@ where /// [`delete_webhook`]: crate::payloads::DeleteWebhook /// [`stop`]: crate::stop::StopToken::stop /// [`options.address`]: Options::address -/// [`with_graceful_shutdown`]: axum::Server::with_graceful_shutdown +/// [`with_graceful_shutdown`]: axum::serve::Serve::with_graceful_shutdown /// /// ## Returns ///