diff --git a/examples/axum_and_echo_bot/src/main.rs b/examples/axum_and_echo_bot/src/main.rs index 52b29115..07e78cb9 100644 --- a/examples/axum_and_echo_bot/src/main.rs +++ b/examples/axum_and_echo_bot/src/main.rs @@ -40,11 +40,8 @@ async fn main() { .with(EnvFilter::from_env("RUST_LOG")) .init(); - let Ok(bot_token) = std::env::var("BOT_TOKEN") else { - panic!("BOT_TOKEN env variable is not set!"); - }; - - let bot = Bot::new(bot_token); + let token = std::env::var("BOT_TOKEN").expect("BOT_TOKEN env variable is not set!"); + let bot = Bot::new(token); let mut router = TelersRouter::new("main"); router.message.register(echo_handler); diff --git a/examples/bot_http_client/src/main.rs b/examples/bot_http_client/src/main.rs index e0a9b601..d4d509c0 100644 --- a/examples/bot_http_client/src/main.rs +++ b/examples/bot_http_client/src/main.rs @@ -92,11 +92,8 @@ async fn main() { .with(EnvFilter::from_env("RUST_LOG")) .init(); - let Ok(bot_token) = std::env::var("BOT_TOKEN") else { - panic!("BOT_TOKEN env variable is not set!"); - }; - - let bot = Bot::with_client(bot_token, CustomClient::default()); + let token = std::env::var("BOT_TOKEN").expect("BOT_TOKEN env variable is not set!"); + let bot = Bot::with_client(token, CustomClient::default()); let mut router = Router::new("main"); router.message.register(echo_handler); diff --git a/examples/business_connection/Cargo.toml b/examples/business_connection/Cargo.toml new file mode 100644 index 00000000..aaa0b723 --- /dev/null +++ b/examples/business_connection/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "business_connection" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +telers = { path = "../../telers", features = ["default"] } +tokio = { version = "1.36", features = ["macros"] } +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/examples/business_connection/src/main.rs b/examples/business_connection/src/main.rs new file mode 100644 index 00000000..728cf694 --- /dev/null +++ b/examples/business_connection/src/main.rs @@ -0,0 +1,82 @@ +//! This example shows how to receive updates from business connections. +//! +//! You can run this example by setting `BOT_TOKEN` and optional `RUST_LOG` environment variable and running: +//! ```bash +//! RUST_LOG={log_level} BOT_TOKEN={your_bot_token} cargo run --package business_connection +//! ``` + +use telers::{ + event::{telegram::HandlerResult, EventReturn, ToServiceProvider as _}, + methods::SendMessage, + types::{BusinessConnection, BusinessMessagesDeleted, Message}, + Bot, Dispatcher, Router, +}; +use tracing::{event, Level}; +use tracing_subscriber::{fmt, layer::SubscriberExt as _, util::SubscriberInitExt as _, EnvFilter}; + +async fn connection(business_connection: BusinessConnection) -> HandlerResult { + event!( + Level::DEBUG, + ?business_connection, + "Received business connection", + ); + + Ok(EventReturn::Finish) +} + +async fn message(bot: Bot, message: Message) -> HandlerResult { + event!(Level::DEBUG, ?message, "Received message"); + + bot.send( + SendMessage::new(message.chat().id(), "Hello world!") + .business_connection_id(message.business_connection_id().unwrap()), + ) + .await?; + + Ok(EventReturn::Finish) +} + +async fn message_edited(message: Message) -> HandlerResult { + event!(Level::DEBUG, ?message, "Received edited message"); + + Ok(EventReturn::Finish) +} + +async fn messages_deleted(messages_deleted: BusinessMessagesDeleted) -> HandlerResult { + event!(Level::DEBUG, ?messages_deleted, "Received deleted messages"); + + Ok(EventReturn::Finish) +} + +#[tokio::main(flavor = "current_thread")] +async fn main() { + tracing_subscriber::registry() + .with(fmt::layer()) + .with(EnvFilter::from_env("RUST_LOG")) + .init(); + + let token = std::env::var("BOT_TOKEN").expect("BOT_TOKEN env variable is not set!"); + let bot = Bot::new(token); + + let mut router = Router::new("main"); + router.business_connection.register(connection); + router.business_message.register(message); + router.edited_business_message.register(message_edited); + router.deleted_business_messages.register(messages_deleted); + + let dispatcher = Dispatcher::builder() + .allowed_updates(router.resolve_used_update_types()) + .main_router(router) + .bot(bot) + .build(); + + match dispatcher + .to_service_provider_default() + .unwrap() + .run_polling() + .await + { + Ok(()) => event!(Level::INFO, "Bot stopped"), + Err(err) => event!(Level::ERROR, error = %err, "Bot stopped"), + } +} diff --git a/examples/echo_bot/src/main.rs b/examples/echo_bot/src/main.rs index a167949d..19c421d0 100644 --- a/examples/echo_bot/src/main.rs +++ b/examples/echo_bot/src/main.rs @@ -33,11 +33,8 @@ async fn main() { .with(EnvFilter::from_env("RUST_LOG")) .init(); - let Ok(bot_token) = std::env::var("BOT_TOKEN") else { - panic!("BOT_TOKEN env variable is not set!"); - }; - - let bot = Bot::new(bot_token); + let token = std::env::var("BOT_TOKEN").expect("BOT_TOKEN env variable is not set!"); + let bot = Bot::new(token); let mut router = Router::new("main"); router.message.register(echo_handler); diff --git a/examples/finite_state_machine/src/main.rs b/examples/finite_state_machine/src/main.rs index dd920f50..e869385e 100644 --- a/examples/finite_state_machine/src/main.rs +++ b/examples/finite_state_machine/src/main.rs @@ -164,11 +164,8 @@ async fn main() { .with(EnvFilter::from_env("RUST_LOG")) .init(); - let Ok(bot_token) = std::env::var("BOT_TOKEN") else { - panic!("BOT_TOKEN env variable is not set!"); - }; - - let bot = Bot::new(bot_token); + let token = std::env::var("BOT_TOKEN").expect("BOT_TOKEN env variable is not set!"); + let bot = Bot::new(token); // You can use any storage, which implements `Storage` trait let storage = MemoryStorage::new(); diff --git a/examples/from_event_and_context/src/main.rs b/examples/from_event_and_context/src/main.rs index 1d7a2318..842beebf 100644 --- a/examples/from_event_and_context/src/main.rs +++ b/examples/from_event_and_context/src/main.rs @@ -138,11 +138,8 @@ async fn main() { .with(EnvFilter::from_env("RUST_LOG")) .init(); - let Ok(bot_token) = std::env::var("BOT_TOKEN") else { - panic!("BOT_TOKEN env variable is not set!"); - }; - - let bot = Bot::new(bot_token); + let token = std::env::var("BOT_TOKEN").expect("BOT_TOKEN env variable is not set!"); + let bot = Bot::new(token); let mut router = Router::new("main"); diff --git a/examples/input_file/src/main.rs b/examples/input_file/src/main.rs index 6d79b17d..4edc0a8b 100644 --- a/examples/input_file/src/main.rs +++ b/examples/input_file/src/main.rs @@ -144,11 +144,8 @@ async fn main() { .with(EnvFilter::from_env("RUST_LOG")) .init(); - let Ok(bot_token) = std::env::var("BOT_TOKEN") else { - panic!("BOT_TOKEN env variable is not set!"); - }; - - let bot = Bot::new(bot_token); + let token = std::env::var("BOT_TOKEN").expect("BOT_TOKEN env variable is not set!"); + let bot = Bot::new(token); let mut router = Router::new("main"); router.message.register(input_file_handler); diff --git a/examples/router_tree/src/main.rs b/examples/router_tree/src/main.rs index 8187b086..c339f87d 100644 --- a/examples/router_tree/src/main.rs +++ b/examples/router_tree/src/main.rs @@ -94,11 +94,8 @@ async fn main() { .with(EnvFilter::from_env("RUST_LOG")) .init(); - let Ok(bot_token) = std::env::var("BOT_TOKEN") else { - panic!("BOT_TOKEN env variable is not set!"); - }; - - let bot = Bot::new(bot_token); + let token = std::env::var("BOT_TOKEN").expect("BOT_TOKEN env variable is not set!"); + let bot = Bot::new(token); let mut main_router = Router::new("main"); diff --git a/examples/stats_incoming_updates_middleware/src/main.rs b/examples/stats_incoming_updates_middleware/src/main.rs index 7c2c2c2b..e6fbb251 100644 --- a/examples/stats_incoming_updates_middleware/src/main.rs +++ b/examples/stats_incoming_updates_middleware/src/main.rs @@ -104,11 +104,8 @@ async fn main() { .with(EnvFilter::from_env("RUST_LOG")) .init(); - let Ok(bot_token) = std::env::var("BOT_TOKEN") else { - panic!("BOT_TOKEN env variable is not set!"); - }; - - let bot = Bot::new(bot_token); + let token = std::env::var("BOT_TOKEN").expect("BOT_TOKEN env variable is not set!"); + let bot = Bot::new(token); let mut router = Router::new("main"); // Register outer middleware for update diff --git a/examples/text_case_filters/src/main.rs b/examples/text_case_filters/src/main.rs index 974d61ca..d94a16ac 100644 --- a/examples/text_case_filters/src/main.rs +++ b/examples/text_case_filters/src/main.rs @@ -70,11 +70,8 @@ async fn main() { .with(EnvFilter::from_env("RUST_LOG")) .init(); - let Ok(bot_token) = std::env::var("BOT_TOKEN") else { - panic!("BOT_TOKEN env variable is not set!"); - }; - - let bot = Bot::new(bot_token); + let token = std::env::var("BOT_TOKEN").expect("BOT_TOKEN env variable is not set!"); + let bot = Bot::new(token); let mut router = Router::new("main"); router diff --git a/examples/text_formatting/src/main.rs b/examples/text_formatting/src/main.rs index 19bf2995..3de9f992 100644 --- a/examples/text_formatting/src/main.rs +++ b/examples/text_formatting/src/main.rs @@ -63,11 +63,8 @@ async fn main() { .with(EnvFilter::from_env("RUST_LOG")) .init(); - let Ok(bot_token) = std::env::var("BOT_TOKEN") else { - panic!("BOT_TOKEN env variable is not set!"); - }; - - let bot = Bot::new(bot_token); + let token = std::env::var("BOT_TOKEN").expect("BOT_TOKEN env variable is not set!"); + let bot = Bot::new(token); let mut router = Router::new("main"); router.message.register(handler); diff --git a/justfile b/justfile index 3d007478..e8750fcb 100644 --- a/justfile +++ b/justfile @@ -6,7 +6,7 @@ help: # Run the tests with cargo test: - cargo test --lib --tests --all --all-features --verbose -- --nocapture + cargo test --lib --tests --all --all-features -- --nocapture # Run the clippy linter clippy: diff --git a/telers/Cargo.toml b/telers/Cargo.toml index 8f7cd726..5c326bfc 100644 --- a/telers/Cargo.toml +++ b/telers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "telers" -version = "1.0.0-alpha.16" +version = "1.0.0-alpha.17" edition = "2021" description = "An asynchronous framework for Telegram Bot API written in Rust" rust-version = "1.65" diff --git a/telers/README.md b/telers/README.md index e03e271c..7ba0aa7d 100644 --- a/telers/README.md +++ b/telers/README.md @@ -9,7 +9,7 @@ - +

diff --git a/telers/src/enums/content_type.rs b/telers/src/enums/content_type.rs index ed7245fb..e479c61b 100644 --- a/telers/src/enums/content_type.rs +++ b/telers/src/enums/content_type.rs @@ -67,8 +67,8 @@ pub enum ContentType { Invoice, #[strum(serialize = "successful_payment")] SuccessfulPayment, - #[strum(serialize = "user_shared")] - UserShared, + #[strum(serialize = "users_shared")] + UsersShared, #[strum(serialize = "chat_shared")] ChatShared, #[strum(serialize = "connected_website")] @@ -147,7 +147,7 @@ impl ContentType { ContentType::PinnedMessage, ContentType::Invoice, ContentType::SuccessfulPayment, - ContentType::UserShared, + ContentType::UsersShared, ContentType::ChatShared, ContentType::ConnectedWebsite, ContentType::WriteAccessAllowed, @@ -224,7 +224,7 @@ impl From<&Message> for ContentType { Message::Pinned(_) => ContentType::PinnedMessage, Message::Invoice(_) => ContentType::Invoice, Message::SuccessfulPayment(_) => ContentType::SuccessfulPayment, - Message::UsersShared(_) => ContentType::UserShared, + Message::UsersShared(_) => ContentType::UsersShared, Message::ChatShared(_) => ContentType::ChatShared, Message::ConnectedWebsite(_) => ContentType::ConnectedWebsite, Message::WriteAccessAllowed(_) => ContentType::WriteAccessAllowed, diff --git a/telers/src/enums/observer_name.rs b/telers/src/enums/observer_name.rs index 72cc8b42..6958c835 100644 --- a/telers/src/enums/observer_name.rs +++ b/telers/src/enums/observer_name.rs @@ -19,6 +19,14 @@ pub enum Telegram { EditedMessage, #[strum(serialize = "edited_channel_post")] EditedChannelPost, + #[strum(serialize = "business_connection")] + BusinessConnection, + #[strum(serialize = "business_message")] + BusinessMessage, + #[strum(serialize = "edited_business_message")] + EditedBusinessMessage, + #[strum(serialize = "deleted_business_messages")] + DeletedBusinessMessages, #[strum(serialize = "message_reaction")] MessageReaction, #[strum(serialize = "message_reaction_count")] @@ -47,7 +55,7 @@ pub enum Telegram { impl Telegram { #[must_use] - pub const fn all() -> [Telegram; 19] { + pub const fn all() -> [Telegram; 23] { [ Telegram::Message, Telegram::InlineQuery, @@ -56,6 +64,10 @@ impl Telegram { Telegram::ChannelPost, Telegram::EditedMessage, Telegram::EditedChannelPost, + Telegram::BusinessConnection, + Telegram::BusinessMessage, + Telegram::EditedBusinessMessage, + Telegram::DeletedBusinessMessages, Telegram::MessageReaction, Telegram::MessageReactionCount, Telegram::ShippingQuery, @@ -82,6 +94,10 @@ impl From for Option { Telegram::ChannelPost => Some(UpdateType::ChannelPost), Telegram::EditedMessage => Some(UpdateType::EditedMessage), Telegram::EditedChannelPost => Some(UpdateType::EditedChannelPost), + Telegram::BusinessConnection => Some(UpdateType::BusinessConnection), + Telegram::BusinessMessage => Some(UpdateType::BusinessMessage), + Telegram::EditedBusinessMessage => Some(UpdateType::EditedBusinessMessage), + Telegram::DeletedBusinessMessages => Some(UpdateType::DeletedBusinessMessages), Telegram::MessageReaction => Some(UpdateType::MessageReaction), Telegram::MessageReactionCount => Some(UpdateType::MessageReactionCount), Telegram::ShippingQuery => Some(UpdateType::ShippingQuery), @@ -108,6 +124,10 @@ impl PartialEq for Telegram { Telegram::ChannelPost => *other == UpdateType::ChannelPost, Telegram::EditedMessage => *other == UpdateType::EditedMessage, Telegram::EditedChannelPost => *other == UpdateType::EditedChannelPost, + Telegram::BusinessConnection => *other == UpdateType::BusinessConnection, + Telegram::BusinessMessage => *other == UpdateType::BusinessMessage, + Telegram::EditedBusinessMessage => *other == UpdateType::EditedBusinessMessage, + Telegram::DeletedBusinessMessages => *other == UpdateType::DeletedBusinessMessages, Telegram::MessageReaction => *other == UpdateType::MessageReaction, Telegram::MessageReactionCount => *other == UpdateType::MessageReactionCount, Telegram::ShippingQuery => *other == UpdateType::ShippingQuery, diff --git a/telers/src/enums/update_type.rs b/telers/src/enums/update_type.rs index 1b3d2fc9..8b1722c6 100644 --- a/telers/src/enums/update_type.rs +++ b/telers/src/enums/update_type.rs @@ -21,6 +21,14 @@ pub enum UpdateType { EditedMessage, #[strum(serialize = "edited_channel_post")] EditedChannelPost, + #[strum(serialize = "business_connection")] + BusinessConnection, + #[strum(serialize = "business_message")] + BusinessMessage, + #[strum(serialize = "edited_business_message")] + EditedBusinessMessage, + #[strum(serialize = "deleted_business_messages")] + DeletedBusinessMessages, #[strum(serialize = "message_reaction")] MessageReaction, #[strum(serialize = "message_reaction_count")] @@ -47,7 +55,7 @@ pub enum UpdateType { impl UpdateType { #[must_use] - pub const fn all() -> [Self; 18] { + pub const fn all() -> [Self; 22] { [ UpdateType::Message, UpdateType::InlineQuery, @@ -56,6 +64,10 @@ impl UpdateType { UpdateType::ChannelPost, UpdateType::EditedMessage, UpdateType::EditedChannelPost, + UpdateType::BusinessConnection, + UpdateType::BusinessMessage, + UpdateType::EditedBusinessMessage, + UpdateType::DeletedBusinessMessages, UpdateType::MessageReaction, UpdateType::MessageReactionCount, UpdateType::ShippingQuery, @@ -78,6 +90,10 @@ impl<'a> From<&'a UpdateKind> for UpdateType { UpdateKind::EditedMessage(_) => UpdateType::EditedMessage, UpdateKind::ChannelPost(_) => UpdateType::ChannelPost, UpdateKind::EditedChannelPost(_) => UpdateType::EditedChannelPost, + UpdateKind::BusinessConnection(_) => UpdateType::BusinessConnection, + UpdateKind::BusinessMessage(_) => UpdateType::BusinessMessage, + UpdateKind::EditedBusinessMessage(_) => UpdateType::EditedBusinessMessage, + UpdateKind::DeletedBusinessMessages(_) => UpdateType::DeletedBusinessMessages, UpdateKind::MessageReaction(_) => UpdateType::MessageReaction, UpdateKind::MessageReactionCount(_) => UpdateType::MessageReactionCount, UpdateKind::InlineQuery(_) => UpdateType::InlineQuery, diff --git a/telers/src/methods.rs b/telers/src/methods.rs index 023f0702..a6d8766d 100644 --- a/telers/src/methods.rs +++ b/telers/src/methods.rs @@ -62,6 +62,7 @@ pub mod edit_message_text; pub mod export_chat_invite_link; pub mod forward_message; pub mod forward_messages; +pub mod get_business_connection; pub mod get_chat; pub mod get_chat_administrators; pub mod get_chat_member; @@ -88,6 +89,7 @@ pub mod pin_chat_message; pub mod promote_chat_member; pub mod reopen_forum_topic; pub mod reopen_general_forum_topic; +pub mod replace_sticker_in_set; pub mod restrict_chat_member; pub mod revoke_chat_invite_link; pub mod send_animation; @@ -178,6 +180,7 @@ pub use edit_message_text::EditMessageText; pub use export_chat_invite_link::ExportChatInviteLink; pub use forward_message::ForwardMessage; pub use forward_messages::ForwardMessages; +pub use get_business_connection::GetBusinessConnection; pub use get_chat::GetChat; pub use get_chat_administrators::GetChatAdministrators; pub use get_chat_member::GetChatMember; @@ -204,6 +207,7 @@ pub use pin_chat_message::PinChatMessage; pub use promote_chat_member::PromoteChatMember; pub use reopen_forum_topic::ReopenForumTopic; pub use reopen_general_forum_topic::ReopenGeneralForumTopic; +pub use replace_sticker_in_set::ReplaceStickerInSet; pub use restrict_chat_member::RestrictChatMember; pub use revoke_chat_invite_link::RevokeChatInviteLink; pub use send_animation::SendAnimation; diff --git a/telers/src/methods/create_new_sticker_set.rs b/telers/src/methods/create_new_sticker_set.rs index a0d204ef..967ab186 100644 --- a/telers/src/methods/create_new_sticker_set.rs +++ b/telers/src/methods/create_new_sticker_set.rs @@ -21,8 +21,6 @@ pub struct CreateNewStickerSet<'a> { pub title: String, /// A JSON-serialized list of 1-50 initial stickers to be added to the sticker set pub stickers: Vec>, - /// Format of stickers in the set, must be one of `static`, `animated`, `video` - pub sticker_format: String, /// Type of stickers in the set, pass `regular`, `mask` or `custom_emoji`. By default, a regular sticker set is created. pub sticker_type: Option, /// Pass `true` if stickers in the sticker set must be repainted to the color of text when used in messages, the accent color if used as emoji status, white on chat photos, or another appropriate color based on context; for custom emoji sticker sets only @@ -36,14 +34,12 @@ impl<'a> CreateNewStickerSet<'a> { name: impl Into, title: impl Into, stickers: impl IntoIterator>, - sticker_format: impl Into, ) -> Self { Self { user_id, name: name.into(), title: title.into(), stickers: stickers.into_iter().collect(), - sticker_format: sticker_format.into(), sticker_type: None, needs_repainting: None, } @@ -89,14 +85,6 @@ impl<'a> CreateNewStickerSet<'a> { } } - #[must_use] - pub fn sticker_format(self, val: impl Into) -> Self { - Self { - sticker_format: val.into(), - ..self - } - } - #[must_use] pub fn sticker_type(self, val: impl Into) -> Self { Self { diff --git a/telers/src/methods/get_business_connection.rs b/telers/src/methods/get_business_connection.rs new file mode 100644 index 00000000..ba62f504 --- /dev/null +++ b/telers/src/methods/get_business_connection.rs @@ -0,0 +1,49 @@ +use super::base::{Request, TelegramMethod}; + +use crate::{client::Bot, types::BusinessConnection}; + +use serde::Serialize; +use serde_with::skip_serializing_none; + +/// Use this method to get information about the connection of the bot with a business account +/// # Documentation +/// +/// # Returns +/// Returns [`BusinessConnection`] on success +#[skip_serializing_none] +#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize)] +pub struct GetBusinessConnection { + /// Unique identifier of the business connection + pub business_connection_id: String, +} + +impl GetBusinessConnection { + #[must_use] + pub fn new(business_connection_id: impl Into) -> Self { + Self { + business_connection_id: business_connection_id.into(), + } + } + + #[must_use] + pub fn business_connection_id(self, val: impl Into) -> Self { + Self { + business_connection_id: val.into(), + } + } +} + +impl TelegramMethod for GetBusinessConnection { + type Method = Self; + type Return = BusinessConnection; + + fn build_request(&self, _bot: &Bot) -> Request { + Request::new("getBusinessConnection", self, None) + } +} + +impl AsRef for GetBusinessConnection { + fn as_ref(&self) -> &Self { + self + } +} diff --git a/telers/src/methods/replace_sticker_in_set.rs b/telers/src/methods/replace_sticker_in_set.rs new file mode 100644 index 00000000..aeed99b1 --- /dev/null +++ b/telers/src/methods/replace_sticker_in_set.rs @@ -0,0 +1,89 @@ +use super::base::{prepare_input_sticker, Request, TelegramMethod}; + +use crate::{client::Bot, types::InputSticker}; + +use serde::Serialize; + +/// Use this method to replace an existing sticker in a sticker set with a new one. The method is equivalent to calling [`DeleteStickerFromSet`](crate::methods::DeleteStickerFromSet), then [`AddStickerToSet`](crate::methods::AddStickerToSet), then [`SetStickerPositionInSet`](crate::methods::SetStickerPositionInSet). +/// # Documentation +/// +/// # Returns +/// `true` on success +#[derive(Debug, Clone, PartialEq, Serialize)] +pub struct ReplaceStickerInSet<'a> { + /// User identifier of the sticker set owner + pub user_id: i64, + /// Sticker set name + pub name: String, + /// File identifier of the replaced sticker + pub old_sticker: String, + /// A JSON-serialized object with information about the added sticker. If exactly the same sticker had already been added to the set, then the set remains unchanged. + pub sticker: InputSticker<'a>, +} + +impl<'a> ReplaceStickerInSet<'a> { + #[must_use] + pub fn new( + user_id: i64, + name: impl Into, + old_sticker: impl Into, + sticker: impl Into>, + ) -> Self { + Self { + user_id, + name: name.into(), + old_sticker: old_sticker.into(), + sticker: sticker.into(), + } + } + + #[must_use] + pub fn user_id(self, val: i64) -> Self { + Self { + user_id: val, + ..self + } + } + + #[must_use] + pub fn name(self, val: impl Into) -> Self { + Self { + name: val.into(), + ..self + } + } + + #[must_use] + pub fn old_sticker(self, val: impl Into) -> Self { + Self { + old_sticker: val.into(), + ..self + } + } + + #[must_use] + pub fn sticker(self, val: impl Into>) -> Self { + Self { + sticker: val.into(), + ..self + } + } +} + +impl<'a> TelegramMethod for ReplaceStickerInSet<'a> { + type Method = Self; + type Return = bool; + + fn build_request(&self, _bot: &Bot) -> Request { + let mut files = vec![]; + prepare_input_sticker(&mut files, &self.sticker); + + Request::new("replaceStickerInSet", self, Some(files.into())) + } +} + +impl<'a> AsRef> for ReplaceStickerInSet<'a> { + fn as_ref(&self) -> &Self { + self + } +} diff --git a/telers/src/methods/send_animation.rs b/telers/src/methods/send_animation.rs index 6be3dbae..3b90b240 100644 --- a/telers/src/methods/send_animation.rs +++ b/telers/src/methods/send_animation.rs @@ -16,6 +16,8 @@ use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Debug, Clone, Hash, PartialEq, Serialize)] pub struct SendAnimation<'a> { + /// Unique identifier of the business connection on behalf of which the message will be sent + pub business_connection_id: Option, /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: ChatIdKind, /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -54,6 +56,7 @@ impl<'a> SendAnimation<'a> { #[must_use] pub fn new(chat_id: impl Into, animation: impl Into>) -> Self { Self { + business_connection_id: None, chat_id: chat_id.into(), message_thread_id: None, animation: animation.into(), @@ -73,6 +76,14 @@ impl<'a> SendAnimation<'a> { } } + #[must_use] + pub fn business_connection_id(self, val: impl Into) -> Self { + Self { + business_connection_id: Some(val.into()), + ..self + } + } + #[must_use] pub fn chat_id(self, val: impl Into) -> Self { Self { @@ -223,6 +234,14 @@ impl<'a> SendAnimation<'a> { } impl<'a> SendAnimation<'a> { + #[must_use] + pub fn business_connection_id_option(self, val: Option>) -> Self { + Self { + business_connection_id: val.map(Into::into), + ..self + } + } + #[must_use] pub fn message_thread_id_option(self, val: Option) -> Self { Self { diff --git a/telers/src/methods/send_audio.rs b/telers/src/methods/send_audio.rs index c19b1e58..fafb81ae 100644 --- a/telers/src/methods/send_audio.rs +++ b/telers/src/methods/send_audio.rs @@ -16,6 +16,8 @@ use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Debug, Clone, Hash, PartialEq, Serialize)] pub struct SendAudio<'a> { + /// Unique identifier of the business connection on behalf of which the message will be sent + pub business_connection_id: Option, /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: ChatIdKind, /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -50,6 +52,7 @@ impl<'a> SendAudio<'a> { #[must_use] pub fn new(chat_id: impl Into, audio: impl Into>) -> Self { Self { + business_connection_id: None, chat_id: chat_id.into(), message_thread_id: None, audio: audio.into(), @@ -67,6 +70,14 @@ impl<'a> SendAudio<'a> { } } + #[must_use] + pub fn business_connection_id(self, val: impl Into) -> Self { + Self { + business_connection_id: Some(val.into()), + ..self + } + } + #[must_use] pub fn chat_id(self, val: impl Into) -> Self { Self { @@ -201,6 +212,14 @@ impl<'a> SendAudio<'a> { } impl<'a> SendAudio<'a> { + #[must_use] + pub fn business_connection_id_option(self, val: Option>) -> Self { + Self { + business_connection_id: val.map(Into::into), + ..self + } + } + #[must_use] pub fn message_thread_id_option(self, val: Option) -> Self { Self { diff --git a/telers/src/methods/send_chat_action.rs b/telers/src/methods/send_chat_action.rs index 28e812e7..24f76d64 100644 --- a/telers/src/methods/send_chat_action.rs +++ b/telers/src/methods/send_chat_action.rs @@ -17,6 +17,8 @@ use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize)] pub struct SendChatAction { + /// Unique identifier of the business connection on behalf of which the action will be sent + pub business_connection_id: Option, /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: ChatIdKind, /// Unique identifier for the target message thread; supergroups only @@ -29,12 +31,21 @@ impl SendChatAction { #[must_use] pub fn new(chat_id: impl Into, action: impl Into) -> Self { Self { + business_connection_id: None, chat_id: chat_id.into(), message_thread_id: None, action: action.into(), } } + #[must_use] + pub fn business_connection_id(self, val: impl Into) -> Self { + Self { + business_connection_id: Some(val.into()), + ..self + } + } + #[must_use] pub fn chat_id(self, val: impl Into) -> Self { Self { @@ -61,6 +72,14 @@ impl SendChatAction { } impl SendChatAction { + #[must_use] + pub fn business_connection_id_option(self, val: Option) -> Self { + Self { + business_connection_id: val, + ..self + } + } + #[must_use] pub fn message_thread_id_option(self, val: Option) -> Self { Self { diff --git a/telers/src/methods/send_contact.rs b/telers/src/methods/send_contact.rs index aca3b18f..25ac03bb 100644 --- a/telers/src/methods/send_contact.rs +++ b/telers/src/methods/send_contact.rs @@ -16,6 +16,8 @@ use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize)] pub struct SendContact { + /// Unique identifier of the business connection on behalf of which the message will be sent + pub business_connection_id: Option, /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: ChatIdKind, /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -46,6 +48,7 @@ impl SendContact { first_name: impl Into, ) -> Self { Self { + business_connection_id: None, chat_id: chat_id.into(), message_thread_id: None, phone_number: phone_number.into(), @@ -59,6 +62,14 @@ impl SendContact { } } + #[must_use] + pub fn business_connection_id(self, val: impl Into) -> Self { + Self { + business_connection_id: Some(val.into()), + ..self + } + } + #[must_use] pub fn chat_id(self, val: impl Into) -> Self { Self { @@ -141,6 +152,14 @@ impl SendContact { } impl SendContact { + #[must_use] + pub fn business_connection_id_option(self, val: Option>) -> Self { + Self { + business_connection_id: val.map(Into::into), + ..self + } + } + #[must_use] pub fn message_thread_id_option(self, val: Option) -> Self { Self { diff --git a/telers/src/methods/send_dice.rs b/telers/src/methods/send_dice.rs index a25a4007..bf0908a2 100644 --- a/telers/src/methods/send_dice.rs +++ b/telers/src/methods/send_dice.rs @@ -16,6 +16,8 @@ use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize)] pub struct SendDice { + /// Unique identifier of the business connection on behalf of which the message will be sent + pub business_connection_id: Option, /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: ChatIdKind, /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -36,6 +38,7 @@ impl SendDice { #[must_use] pub fn new(chat_id: impl Into) -> Self { Self { + business_connection_id: None, chat_id: chat_id.into(), message_thread_id: None, emoji: None, @@ -46,6 +49,14 @@ impl SendDice { } } + #[must_use] + pub fn business_connection_id(self, val: impl Into) -> Self { + Self { + business_connection_id: Some(val.into()), + ..self + } + } + #[must_use] pub fn chat_id(self, val: impl Into) -> Self { Self { @@ -104,6 +115,14 @@ impl SendDice { } impl SendDice { + #[must_use] + pub fn business_connection_id_option(self, val: Option>) -> Self { + Self { + business_connection_id: val.map(Into::into), + ..self + } + } + #[must_use] pub fn message_thread_id_option(self, val: Option) -> Self { Self { diff --git a/telers/src/methods/send_document.rs b/telers/src/methods/send_document.rs index 0b94a800..52d8371b 100644 --- a/telers/src/methods/send_document.rs +++ b/telers/src/methods/send_document.rs @@ -16,6 +16,8 @@ use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Debug, Clone, Hash, PartialEq, Serialize)] pub struct SendDocument<'a> { + /// Unique identifier of the business connection on behalf of which the message will be sent + pub business_connection_id: Option, /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: ChatIdKind, /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -46,6 +48,7 @@ impl<'a> SendDocument<'a> { #[must_use] pub fn new(chat_id: impl Into, document: impl Into>) -> Self { Self { + business_connection_id: None, chat_id: chat_id.into(), message_thread_id: None, document: document.into(), @@ -61,6 +64,14 @@ impl<'a> SendDocument<'a> { } } + #[must_use] + pub fn business_connection_id(self, val: impl Into) -> Self { + Self { + business_connection_id: Some(val.into()), + ..self + } + } + #[must_use] pub fn chat_id(self, val: impl Into) -> Self { Self { @@ -179,6 +190,14 @@ impl<'a> SendDocument<'a> { } impl<'a> SendDocument<'a> { + #[must_use] + pub fn business_connection_id_option(self, val: Option>) -> Self { + Self { + business_connection_id: val.map(Into::into), + ..self + } + } + #[must_use] pub fn message_thread_id_option(self, val: Option) -> Self { Self { diff --git a/telers/src/methods/send_game.rs b/telers/src/methods/send_game.rs index 515515ec..b71c6954 100644 --- a/telers/src/methods/send_game.rs +++ b/telers/src/methods/send_game.rs @@ -16,6 +16,8 @@ use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize)] pub struct SendGame { + /// Unique identifier of the business connection on behalf of which the message will be sent + pub business_connection_id: Option, /// Unique identifier for the target chat pub chat_id: i64, /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -36,6 +38,7 @@ impl SendGame { #[must_use] pub fn new(chat_id: i64, game_short_name: impl Into) -> Self { Self { + business_connection_id: None, chat_id, message_thread_id: None, game_short_name: game_short_name.into(), @@ -46,6 +49,14 @@ impl SendGame { } } + #[must_use] + pub fn business_connection_id(self, val: impl Into) -> Self { + Self { + business_connection_id: Some(val.into()), + ..self + } + } + #[must_use] pub fn chat_id(self, val: i64) -> Self { Self { @@ -104,6 +115,14 @@ impl SendGame { } impl SendGame { + #[must_use] + pub fn business_connection_id_option(self, val: Option>) -> Self { + Self { + business_connection_id: val.map(Into::into), + ..self + } + } + #[must_use] pub fn message_thread_id_option(self, val: Option) -> Self { Self { diff --git a/telers/src/methods/send_location.rs b/telers/src/methods/send_location.rs index a5c17c4a..3eda5e7d 100644 --- a/telers/src/methods/send_location.rs +++ b/telers/src/methods/send_location.rs @@ -16,6 +16,8 @@ use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Debug, Clone, PartialEq, Serialize)] pub struct SendLocation { + /// Unique identifier of the business connection on behalf of which the message will be sent + pub business_connection_id: Option, /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: ChatIdKind, /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -46,6 +48,7 @@ impl SendLocation { #[must_use] pub fn new(chat_id: impl Into, longitude: f64, latitude: f64) -> Self { Self { + business_connection_id: None, chat_id: chat_id.into(), message_thread_id: None, longitude, @@ -61,6 +64,14 @@ impl SendLocation { } } + #[must_use] + pub fn business_connection_id(self, val: String) -> Self { + Self { + business_connection_id: Some(val), + ..self + } + } + #[must_use] pub fn chat_id(self, val: impl Into) -> Self { Self { @@ -159,6 +170,14 @@ impl SendLocation { } impl SendLocation { + #[must_use] + pub fn business_connection_id_option(self, val: Option) -> Self { + Self { + business_connection_id: val, + ..self + } + } + #[must_use] pub fn message_thread_id_option(self, val: Option) -> Self { Self { diff --git a/telers/src/methods/send_media_group.rs b/telers/src/methods/send_media_group.rs index b8778acb..8ef4a060 100644 --- a/telers/src/methods/send_media_group.rs +++ b/telers/src/methods/send_media_group.rs @@ -16,6 +16,8 @@ use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Debug, Clone, Hash, PartialEq, Serialize)] pub struct SendMediaGroup<'a> { + /// Unique identifier of the business connection on behalf of which the message will be sent + pub business_connection_id: Option, /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: ChatIdKind, /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -38,6 +40,7 @@ impl<'a> SendMediaGroup<'a> { I: IntoIterator, { Self { + business_connection_id: None, chat_id: chat_id.into(), message_thread_id: None, media: media.into_iter().map(Into::into).collect(), @@ -47,6 +50,14 @@ impl<'a> SendMediaGroup<'a> { } } + #[must_use] + pub fn business_connection_id(self, val: impl Into) -> Self { + Self { + business_connection_id: Some(val.into()), + ..self + } + } + #[must_use] pub fn chat_id(self, val: impl Into) -> Self { Self { @@ -113,6 +124,14 @@ impl<'a> SendMediaGroup<'a> { } impl<'a> SendMediaGroup<'a> { + #[must_use] + pub fn business_connection_id_option(self, val: Option) -> Self { + Self { + business_connection_id: val, + ..self + } + } + #[must_use] pub fn message_thread_id_option(self, val: Option) -> Self { Self { diff --git a/telers/src/methods/send_message.rs b/telers/src/methods/send_message.rs index 8b9f660a..b725c67e 100644 --- a/telers/src/methods/send_message.rs +++ b/telers/src/methods/send_message.rs @@ -16,6 +16,8 @@ use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize)] pub struct SendMessage { + /// Unique identifier of the business connection on behalf of which the message will be sent + pub business_connection_id: Option, /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: ChatIdKind, /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -42,6 +44,7 @@ impl SendMessage { #[must_use] pub fn new(chat_id: impl Into, text: impl Into) -> Self { Self { + business_connection_id: None, chat_id: chat_id.into(), message_thread_id: None, text: text.into(), @@ -55,6 +58,14 @@ impl SendMessage { } } + #[must_use] + pub fn business_connection_id(self, val: impl Into) -> Self { + Self { + business_connection_id: Some(val.into()), + ..self + } + } + #[must_use] pub fn chat_id(self, val: impl Into) -> Self { Self { @@ -157,6 +168,14 @@ impl SendMessage { } impl SendMessage { + #[must_use] + pub fn business_connection_id_option(self, val: Option>) -> Self { + Self { + business_connection_id: val.map(Into::into), + ..self + } + } + #[must_use] pub fn message_thread_id_option(self, val: Option) -> Self { Self { diff --git a/telers/src/methods/send_photo.rs b/telers/src/methods/send_photo.rs index cdc0cc61..1a9ddc3f 100644 --- a/telers/src/methods/send_photo.rs +++ b/telers/src/methods/send_photo.rs @@ -16,6 +16,8 @@ use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Debug, Clone, Hash, PartialEq, Serialize)] pub struct SendPhoto<'a> { + /// Unique identifier of the business connection on behalf of which the message will be sent + pub business_connection_id: Option, /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: ChatIdKind, /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -44,6 +46,7 @@ impl<'a> SendPhoto<'a> { #[must_use] pub fn new(chat_id: impl Into, photo: impl Into>) -> Self { Self { + business_connection_id: None, chat_id: chat_id.into(), message_thread_id: None, photo: photo.into(), @@ -58,6 +61,14 @@ impl<'a> SendPhoto<'a> { } } + #[must_use] + pub fn business_connection_id(self, val: impl Into) -> Self { + Self { + business_connection_id: Some(val.into()), + ..self + } + } + #[must_use] pub fn chat_id(self, val: impl Into) -> Self { Self { @@ -168,6 +179,14 @@ impl<'a> SendPhoto<'a> { } impl<'a> SendPhoto<'a> { + #[must_use] + pub fn business_connection_id_option(self, val: Option>) -> Self { + Self { + business_connection_id: val.map(Into::into), + ..self + } + } + #[must_use] pub fn message_thread_id_option(self, val: Option) -> Self { Self { diff --git a/telers/src/methods/send_poll.rs b/telers/src/methods/send_poll.rs index e42a6280..9562f2b9 100644 --- a/telers/src/methods/send_poll.rs +++ b/telers/src/methods/send_poll.rs @@ -16,6 +16,8 @@ use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize)] pub struct SendPoll { + /// Unique identifier of the business connection on behalf of which the message will be sent + pub business_connection_id: Option, /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: ChatIdKind, /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -63,6 +65,7 @@ impl SendPoll { I: IntoIterator, { Self { + business_connection_id: None, chat_id: chat_id.into(), message_thread_id: None, question: question.into(), @@ -84,6 +87,14 @@ impl SendPoll { } } + #[must_use] + pub fn business_connection_id(self, val: impl Into) -> Self { + Self { + business_connection_id: Some(val.into()), + ..self + } + } + #[must_use] pub fn chat_id(self, val: impl Into) -> Self { Self { @@ -266,6 +277,14 @@ impl SendPoll { } impl SendPoll { + #[must_use] + pub fn business_connection_id_option(self, val: Option>) -> Self { + Self { + business_connection_id: val.map(Into::into), + ..self + } + } + #[must_use] pub fn message_thread_id_option(self, val: Option) -> Self { Self { diff --git a/telers/src/methods/send_sticker.rs b/telers/src/methods/send_sticker.rs index ed773d94..bf38ddb0 100644 --- a/telers/src/methods/send_sticker.rs +++ b/telers/src/methods/send_sticker.rs @@ -16,11 +16,13 @@ use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Debug, Clone, Hash, PartialEq, Serialize)] pub struct SendSticker<'a> { + /// Unique identifier of the business connection on behalf of which the message will be sent + pub business_connection_id: Option, /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: ChatIdKind, /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only pub message_thread_id: Option, - /// Sticker to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a .WEBP file from the Internet, or upload a new one using multipart/form-data. [More info on Sending Files »](https://core.telegram.org/bots/api#sending-files) + /// Sticker to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a .WEBP sticker from the Internet, or upload a new .WEBP, .TGS, or .WEBM sticker using multipart/form-data. [More info on Sending Files »](https://core.telegram.org/bots/api#sending-files). Video and animated stickers can't be sent via an HTTP URL. pub sticker: InputFile<'a>, /// Emoji associated with the sticker; only for just uploaded stickers pub emoji: Option, @@ -38,6 +40,7 @@ impl<'a> SendSticker<'a> { #[must_use] pub fn new(chat_id: impl Into, sticker: impl Into>) -> Self { Self { + business_connection_id: None, chat_id: chat_id.into(), message_thread_id: None, sticker: sticker.into(), @@ -49,6 +52,14 @@ impl<'a> SendSticker<'a> { } } + #[must_use] + pub fn business_connection_id(self, val: impl Into) -> Self { + Self { + business_connection_id: Some(val.into()), + ..self + } + } + #[must_use] pub fn chat_id(self, val: impl Into) -> Self { Self { @@ -115,6 +126,14 @@ impl<'a> SendSticker<'a> { } impl<'a> SendSticker<'a> { + #[must_use] + pub fn business_connection_id_option(self, val: Option>) -> Self { + Self { + business_connection_id: val.map(Into::into), + ..self + } + } + #[must_use] pub fn message_thread_id_option(self, val: Option) -> Self { Self { diff --git a/telers/src/methods/send_venue.rs b/telers/src/methods/send_venue.rs index cca94123..bba81fb2 100644 --- a/telers/src/methods/send_venue.rs +++ b/telers/src/methods/send_venue.rs @@ -16,6 +16,8 @@ use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Debug, Clone, PartialEq, Serialize)] pub struct SendVenue { + /// Unique identifier of the business connection on behalf of which the message will be sent + pub business_connection_id: Option, /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: ChatIdKind, /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -56,6 +58,7 @@ impl SendVenue { address: impl Into, ) -> Self { Self { + business_connection_id: None, chat_id: chat_id.into(), message_thread_id: None, longitude, @@ -73,6 +76,14 @@ impl SendVenue { } } + #[must_use] + pub fn business_connection_id(self, val: impl Into) -> Self { + Self { + business_connection_id: Some(val.into()), + ..self + } + } + #[must_use] pub fn chat_id(self, val: impl Into) -> Self { Self { @@ -187,6 +198,14 @@ impl SendVenue { } impl SendVenue { + #[must_use] + pub fn business_connection_id_option(self, val: Option>) -> Self { + Self { + business_connection_id: val.map(Into::into), + ..self + } + } + #[must_use] pub fn message_thread_id_option(self, val: Option) -> Self { Self { diff --git a/telers/src/methods/send_video.rs b/telers/src/methods/send_video.rs index 6110d222..7ef03522 100644 --- a/telers/src/methods/send_video.rs +++ b/telers/src/methods/send_video.rs @@ -16,6 +16,8 @@ use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Debug, Clone, Hash, PartialEq, Serialize)] pub struct SendVideo<'a> { + /// Unique identifier of the business connection on behalf of which the message will be sent + pub business_connection_id: Option, /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: ChatIdKind, /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -54,6 +56,7 @@ impl<'a> SendVideo<'a> { #[must_use] pub fn new(chat_id: impl Into, video: impl Into>) -> Self { Self { + business_connection_id: None, chat_id: chat_id.into(), message_thread_id: None, video: video.into(), @@ -73,6 +76,14 @@ impl<'a> SendVideo<'a> { } } + #[must_use] + pub fn business_connection_id(self, val: impl Into) -> Self { + Self { + business_connection_id: Some(val.into()), + ..self + } + } + #[must_use] pub fn chat_id(self, val: impl Into) -> Self { Self { @@ -223,6 +234,14 @@ impl<'a> SendVideo<'a> { } impl<'a> SendVideo<'a> { + #[must_use] + pub fn business_connection_id_option(self, val: Option>) -> Self { + Self { + business_connection_id: val.map(Into::into), + ..self + } + } + #[must_use] pub fn message_thread_id_option(self, val: Option) -> Self { Self { diff --git a/telers/src/methods/send_video_note.rs b/telers/src/methods/send_video_note.rs index 62ab53f3..0a0b93f8 100644 --- a/telers/src/methods/send_video_note.rs +++ b/telers/src/methods/send_video_note.rs @@ -16,6 +16,8 @@ use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Debug, Clone, Hash, PartialEq, Serialize)] pub struct SendVideoNote<'a> { + /// Unique identifier of the business connection on behalf of which the message will be sent + pub business_connection_id: Option, /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: ChatIdKind, /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -42,6 +44,7 @@ impl<'a> SendVideoNote<'a> { #[must_use] pub fn new(chat_id: impl Into, video_note: impl Into>) -> Self { Self { + business_connection_id: None, chat_id: chat_id.into(), message_thread_id: None, video_note: video_note.into(), @@ -55,6 +58,14 @@ impl<'a> SendVideoNote<'a> { } } + #[must_use] + pub fn business_connection_id(self, val: impl Into) -> Self { + Self { + business_connection_id: Some(val.into()), + ..self + } + } + #[must_use] pub fn chat_id(self, val: impl Into) -> Self { Self { @@ -137,6 +148,14 @@ impl<'a> SendVideoNote<'a> { } impl<'a> SendVideoNote<'a> { + #[must_use] + pub fn business_connection_id_option(self, val: Option>) -> Self { + Self { + business_connection_id: val.map(Into::into), + ..self + } + } + #[must_use] pub fn message_thread_id_option(self, val: Option) -> Self { Self { diff --git a/telers/src/methods/send_voice.rs b/telers/src/methods/send_voice.rs index 9d13f13a..f24a44cf 100644 --- a/telers/src/methods/send_voice.rs +++ b/telers/src/methods/send_voice.rs @@ -16,6 +16,8 @@ use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Debug, Clone, Hash, PartialEq, Serialize)] pub struct SendVoice<'a> { + /// Unique identifier of the business connection on behalf of which the message will be sent + pub business_connection_id: Option, /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: ChatIdKind, /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -44,6 +46,7 @@ impl<'a> SendVoice<'a> { #[must_use] pub fn new(chat_id: impl Into, voice: impl Into>) -> Self { Self { + business_connection_id: None, chat_id: chat_id.into(), message_thread_id: None, voice: voice.into(), @@ -58,6 +61,14 @@ impl<'a> SendVoice<'a> { } } + #[must_use] + pub fn business_connection_id(self, val: impl Into) -> Self { + Self { + business_connection_id: Some(val.into()), + ..self + } + } + #[must_use] pub fn chat_id(self, val: impl Into) -> Self { Self { @@ -168,6 +179,14 @@ impl<'a> SendVoice<'a> { } impl<'a> SendVoice<'a> { + #[must_use] + pub fn business_connection_id_option(self, val: Option>) -> Self { + Self { + business_connection_id: val.map(Into::into), + ..self + } + } + #[must_use] pub fn message_thread_id_option(self, val: Option) -> Self { Self { diff --git a/telers/src/methods/set_sticker_set_thumbnail.rs b/telers/src/methods/set_sticker_set_thumbnail.rs index b6a440e7..703f67f2 100644 --- a/telers/src/methods/set_sticker_set_thumbnail.rs +++ b/telers/src/methods/set_sticker_set_thumbnail.rs @@ -5,7 +5,7 @@ use crate::{client::Bot, types::InputFile}; use serde::Serialize; use serde_with::skip_serializing_none; -/// Use this method to set the thumbnail of a sticker set. Animated thumbnails can be set for animated sticker sets only. Video thumbnails can be set only for video sticker sets only. +/// Use this method to set the thumbnail of a regular or mask sticker set. The format of the thumbnail file must match the format of the stickers in the set /// # Documentation /// /// # Returns @@ -19,15 +19,18 @@ pub struct SetStickerSetThumbnail<'a> { pub user_id: i64, /// A *PNG* image with the thumbnail, must be up to 128 kilobytes in size and have width and height exactly 100px, or a *TGS* animation with the thumbnail up to 32 kilobytes in size; see for animated sticker technical requirements, or a *WEBM* video with the thumbnail up to 32 kilobytes in size; see for video sticker technical requirements. Pass a `file_id` as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. [`More info on Sending Files`](https://core.telegram.org/bots/api#sending-files). Animated sticker set thumbnails can't be uploaded via HTTP URL. pub thumbnail: Option>, + /// Format of the thumbnail, must be one of "static" for a **.WEBP** or **.PNG** image, "animated" for a **.TGS** animation, "video" for a **WEBM** video + pub format: String, } impl<'a> SetStickerSetThumbnail<'a> { #[must_use] - pub fn new(name: impl Into, user_id: i64) -> Self { + pub fn new(name: impl Into, user_id: i64, format: impl Into) -> Self { Self { name: name.into(), user_id, thumbnail: None, + format: format.into(), } } @@ -54,6 +57,14 @@ impl<'a> SetStickerSetThumbnail<'a> { ..self } } + + #[must_use] + pub fn format(self, val: impl Into) -> Self { + Self { + format: val.into(), + ..self + } + } } impl<'a> SetStickerSetThumbnail<'a> { diff --git a/telers/src/router.rs b/telers/src/router.rs index 4e416aae..2494f7c9 100644 --- a/telers/src/router.rs +++ b/telers/src/router.rs @@ -368,6 +368,10 @@ pub struct Router { pub edited_message: TelegramObserver, pub channel_post: TelegramObserver, pub edited_channel_post: TelegramObserver, + pub business_connection: TelegramObserver, + pub business_message: TelegramObserver, + pub edited_business_message: TelegramObserver, + pub deleted_business_messages: TelegramObserver, pub message_reaction: TelegramObserver, pub message_reaction_count: TelegramObserver, pub inline_query: TelegramObserver, @@ -408,6 +412,10 @@ where edited_message: TelegramObserver::new(TelegramObserverName::EditedMessage), channel_post: TelegramObserver::new(TelegramObserverName::ChannelPost), edited_channel_post: TelegramObserver::new(TelegramObserverName::EditedChannelPost), + business_connection: TelegramObserver::new(TelegramObserverName::BusinessConnection), + business_message: TelegramObserver::new(TelegramObserverName::BusinessMessage), + edited_business_message: TelegramObserver::new(TelegramObserverName::EditedBusinessMessage), + deleted_business_messages: TelegramObserver::new(TelegramObserverName::DeletedBusinessMessages), message_reaction: TelegramObserver::new(TelegramObserverName::MessageReaction), message_reaction_count: TelegramObserver::new(TelegramObserverName::MessageReactionCount), inline_query: TelegramObserver::new(TelegramObserverName::InlineQuery), @@ -453,12 +461,16 @@ where impl Router { /// Get all telegram event observers #[must_use] - pub const fn telegram_observers(&self) -> [&TelegramObserver; 19] { + pub const fn telegram_observers(&self) -> [&TelegramObserver; 23] { [ &self.message, &self.edited_message, &self.channel_post, &self.edited_channel_post, + &self.business_connection, + &self.business_message, + &self.edited_business_message, + &self.deleted_business_messages, &self.message_reaction, &self.message_reaction_count, &self.inline_query, @@ -482,13 +494,17 @@ impl Router { /// This method is useful for registering middlewares to the many observers without code duplication and macros #[must_use] pub fn telegram_observers_mut(&mut self) -> Vec<&mut TelegramObserver> { - let mut observers = Vec::with_capacity(19); + let mut observers = Vec::with_capacity(23); observers.extend([ &mut self.message, &mut self.edited_message, &mut self.channel_post, &mut self.edited_channel_post, + &mut self.business_connection, + &mut self.business_message, + &mut self.edited_business_message, + &mut self.deleted_business_messages, &mut self.message_reaction, &mut self.message_reaction_count, &mut self.inline_query, @@ -623,6 +639,10 @@ where edited_message, channel_post, edited_channel_post, + business_connection, + business_message, + edited_business_message, + deleted_business_messages, message_reaction, message_reaction_count, inline_query, @@ -665,6 +685,10 @@ where edited_message, channel_post, edited_channel_post, + business_connection, + business_message, + edited_business_message, + deleted_business_messages, message_reaction, message_reaction_count, inline_query, @@ -696,6 +720,12 @@ where edited_message: self.edited_message.to_service_provider_default()?, channel_post: self.channel_post.to_service_provider_default()?, edited_channel_post: self.edited_channel_post.to_service_provider_default()?, + business_connection: self.business_connection.to_service_provider_default()?, + business_message: self.business_message.to_service_provider_default()?, + edited_business_message: self.edited_business_message.to_service_provider_default()?, + deleted_business_messages: self + .deleted_business_messages + .to_service_provider_default()?, message_reaction: self.message_reaction.to_service_provider_default()?, message_reaction_count: self.message_reaction_count.to_service_provider_default()?, inline_query: self.inline_query.to_service_provider_default()?, @@ -725,6 +755,10 @@ pub struct Service { edited_message: TelegramObserverService, channel_post: TelegramObserverService, edited_channel_post: TelegramObserverService, + business_connection: TelegramObserverService, + business_message: TelegramObserverService, + edited_business_message: TelegramObserverService, + deleted_business_messages: TelegramObserverService, message_reaction: TelegramObserverService, message_reaction_count: TelegramObserverService, inline_query: TelegramObserverService, @@ -978,12 +1012,16 @@ impl PropagateEvent for Service { impl Service { #[must_use] - pub const fn telegram_observers(&self) -> [&TelegramObserverService; 19] { + pub const fn telegram_observers(&self) -> [&TelegramObserverService; 23] { [ &self.message, &self.edited_message, &self.channel_post, &self.edited_channel_post, + &self.business_connection, + &self.business_message, + &self.edited_business_message, + &self.deleted_business_messages, &self.message_reaction, &self.message_reaction_count, &self.inline_query, @@ -1017,6 +1055,10 @@ impl Service { UpdateType::EditedMessage => &self.edited_message, UpdateType::ChannelPost => &self.channel_post, UpdateType::EditedChannelPost => &self.edited_channel_post, + UpdateType::BusinessConnection => &self.business_connection, + UpdateType::BusinessMessage => &self.business_message, + UpdateType::EditedBusinessMessage => &self.edited_business_message, + UpdateType::DeletedBusinessMessages => &self.deleted_business_messages, UpdateType::MessageReaction => &self.message_reaction, UpdateType::MessageReactionCount => &self.message_reaction_count, UpdateType::InlineQuery => &self.inline_query, @@ -1089,6 +1131,10 @@ pub struct OuterMiddlewaresConfig { pub edited_message: Box<[Arc>]>, pub channel_post: Box<[Arc>]>, pub edited_channel_post: Box<[Arc>]>, + pub business_connection: Box<[Arc>]>, + pub business_message: Box<[Arc>]>, + pub edited_business_message: Box<[Arc>]>, + pub deleted_business_messages: Box<[Arc>]>, pub message_reaction: Box<[Arc>]>, pub message_reaction_count: Box<[Arc>]>, pub inline_query: Box<[Arc>]>, @@ -1135,6 +1181,10 @@ impl Clone for OuterMiddlewaresConfig { edited_message: self.edited_message.clone(), channel_post: self.channel_post.clone(), edited_channel_post: self.edited_channel_post.clone(), + business_connection: self.business_connection.clone(), + business_message: self.business_message.clone(), + edited_business_message: self.edited_business_message.clone(), + deleted_business_messages: self.deleted_business_messages.clone(), message_reaction: self.message_reaction.clone(), message_reaction_count: self.message_reaction_count.clone(), inline_query: self.inline_query.clone(), @@ -1159,6 +1209,10 @@ pub struct OuterMiddlewaresConfigBuilder { pub edited_message: Vec>>, pub channel_post: Vec>>, pub edited_channel_post: Vec>>, + pub business_connection: Vec>>, + pub business_message: Vec>>, + pub edited_business_message: Vec>>, + pub deleted_business_messages: Vec>>, pub message_reaction: Vec>>, pub message_reaction_count: Vec>>, pub inline_query: Vec>>, @@ -1201,6 +1255,33 @@ impl OuterMiddlewaresConfigBuilder { self } + #[must_use] + pub fn business_connection(mut self, val: impl OuterMiddleware + 'static) -> Self { + self.business_connection.push(Arc::new(val)); + self + } + + #[must_use] + pub fn business_message(mut self, val: impl OuterMiddleware + 'static) -> Self { + self.business_message.push(Arc::new(val)); + self + } + + #[must_use] + pub fn edited_business_message(mut self, val: impl OuterMiddleware + 'static) -> Self { + self.edited_business_message.push(Arc::new(val)); + self + } + + #[must_use] + pub fn deleted_business_messages( + mut self, + val: impl OuterMiddleware + 'static, + ) -> Self { + self.deleted_business_messages.push(Arc::new(val)); + self + } + #[must_use] pub fn message_reaction(mut self, val: impl OuterMiddleware + 'static) -> Self { self.message_reaction.push(Arc::new(val)); @@ -1298,6 +1379,10 @@ impl OuterMiddlewaresConfigBuilder { edited_message: self.edited_message.into(), channel_post: self.channel_post.into(), edited_channel_post: self.edited_channel_post.into(), + business_connection: self.business_connection.into(), + business_message: self.business_message.into(), + edited_business_message: self.edited_business_message.into(), + deleted_business_messages: self.deleted_business_messages.into(), message_reaction: self.message_reaction.into(), message_reaction_count: self.message_reaction_count.into(), inline_query: self.inline_query.into(), @@ -1325,6 +1410,10 @@ impl Default for OuterMiddlewaresConfigBuilder { edited_message: vec![], channel_post: vec![], edited_channel_post: vec![], + business_connection: vec![], + business_message: vec![], + edited_business_message: vec![], + deleted_business_messages: vec![], message_reaction: vec![], message_reaction_count: vec![], inline_query: vec![], @@ -1349,6 +1438,10 @@ pub struct InnerMiddlewaresConfig { pub edited_message: Box<[Arc>]>, pub channel_post: Box<[Arc>]>, pub edited_channel_post: Box<[Arc>]>, + pub business_connection: Box<[Arc>]>, + pub business_message: Box<[Arc>]>, + pub edited_business_message: Box<[Arc>]>, + pub deleted_business_messages: Box<[Arc>]>, pub message_reaction: Box<[Arc>]>, pub message_reaction_count: Box<[Arc>]>, pub inline_query: Box<[Arc>]>, @@ -1391,6 +1484,10 @@ where .edited_message(logging_middleware.clone()) .channel_post(logging_middleware.clone()) .edited_channel_post(logging_middleware.clone()) + .business_connection(logging_middleware.clone()) + .business_message(logging_middleware.clone()) + .edited_business_message(logging_middleware.clone()) + .deleted_business_messages(logging_middleware.clone()) .message_reaction(logging_middleware.clone()) .message_reaction_count(logging_middleware.clone()) .inline_query(logging_middleware.clone()) @@ -1417,6 +1514,10 @@ impl Clone for InnerMiddlewaresConfig { edited_message: self.edited_message.clone(), channel_post: self.channel_post.clone(), edited_channel_post: self.edited_channel_post.clone(), + business_connection: self.business_connection.clone(), + business_message: self.business_message.clone(), + edited_business_message: self.edited_business_message.clone(), + deleted_business_messages: self.deleted_business_messages.clone(), message_reaction: self.message_reaction.clone(), message_reaction_count: self.message_reaction_count.clone(), inline_query: self.inline_query.clone(), @@ -1441,6 +1542,10 @@ pub struct InnerMiddlewaresConfigBuilder { pub edited_message: Vec>>, pub channel_post: Vec>>, pub edited_channel_post: Vec>>, + pub business_connection: Vec>>, + pub business_message: Vec>>, + pub edited_business_message: Vec>>, + pub deleted_business_messages: Vec>>, pub message_reaction: Vec>>, pub message_reaction_count: Vec>>, pub inline_query: Vec>>, @@ -1483,6 +1588,33 @@ impl InnerMiddlewaresConfigBuilder { self } + #[must_use] + pub fn business_connection(mut self, val: impl InnerMiddleware + 'static) -> Self { + self.business_connection.push(Arc::new(val)); + self + } + + #[must_use] + pub fn business_message(mut self, val: impl InnerMiddleware + 'static) -> Self { + self.business_message.push(Arc::new(val)); + self + } + + #[must_use] + pub fn edited_business_message(mut self, val: impl InnerMiddleware + 'static) -> Self { + self.edited_business_message.push(Arc::new(val)); + self + } + + #[must_use] + pub fn deleted_business_messages( + mut self, + val: impl InnerMiddleware + 'static, + ) -> Self { + self.deleted_business_messages.push(Arc::new(val)); + self + } + #[must_use] pub fn message_reaction(mut self, val: impl InnerMiddleware + 'static) -> Self { self.message_reaction.push(Arc::new(val)); @@ -1580,6 +1712,10 @@ impl InnerMiddlewaresConfigBuilder { edited_message: self.edited_message.into(), channel_post: self.channel_post.into(), edited_channel_post: self.edited_channel_post.into(), + business_connection: self.business_connection.into(), + business_message: self.business_message.into(), + edited_business_message: self.edited_business_message.into(), + deleted_business_messages: self.deleted_business_messages.into(), message_reaction: self.message_reaction.into(), message_reaction_count: self.message_reaction_count.into(), inline_query: self.inline_query.into(), @@ -1607,6 +1743,10 @@ impl Default for InnerMiddlewaresConfigBuilder { edited_message: vec![], channel_post: vec![], edited_channel_post: vec![], + business_connection: vec![], + business_message: vec![], + edited_business_message: vec![], + deleted_business_messages: vec![], message_reaction: vec![], message_reaction_count: vec![], inline_query: vec![], @@ -1740,6 +1880,10 @@ mod tests { router.edited_message.register(telegram_handler); router.channel_post.register(telegram_handler); router.edited_channel_post.register(telegram_handler); + router.business_connection.register(telegram_handler); + router.business_message.register(telegram_handler); + router.edited_business_message.register(telegram_handler); + router.deleted_business_messages.register(telegram_handler); router.message_reaction.register(telegram_handler); router.message_reaction_count.register(telegram_handler); router.inline_query.register(telegram_handler); diff --git a/telers/src/types.rs b/telers/src/types.rs index dd0be61e..6560aedb 100644 --- a/telers/src/types.rs +++ b/telers/src/types.rs @@ -39,6 +39,7 @@ pub mod animation; pub mod audio; +pub mod birthdate; pub mod bot_command; pub mod bot_command_scope; pub mod bot_command_scope_all_chat_administrators; @@ -51,6 +52,12 @@ pub mod bot_command_scope_default; pub mod bot_description; pub mod bot_name; pub mod bot_short_description; +pub mod business_connection; +pub mod business_intro; +pub mod business_location; +pub mod business_messages_deleted; +pub mod business_opening_hours; +pub mod business_opening_hours_interval; pub mod callback_game; pub mod callback_query; pub mod chat; @@ -196,6 +203,7 @@ pub mod reply_markup; pub mod reply_parameters; pub mod response_parameters; pub mod sent_web_app_message; +pub mod shared_user; pub mod shipping_address; pub mod shipping_option; pub mod shipping_query; @@ -226,6 +234,7 @@ pub mod write_access_allowed; pub use animation::Animation; pub use audio::Audio; +pub use birthdate::Birthdate; pub use bot_command::BotCommand; pub use bot_command_scope::BotCommandScope; pub use bot_command_scope_all_chat_administrators::BotCommandScopeAllChatAdministrators; @@ -238,6 +247,12 @@ pub use bot_command_scope_default::BotCommandScopeDefault; pub use bot_description::BotDescription; pub use bot_name::BotName; pub use bot_short_description::BotShortDescription; +pub use business_connection::BusinessConnection; +pub use business_intro::BusinessIntro; +pub use business_location::BusinessLocation; +pub use business_messages_deleted::BusinessMessagesDeleted; +pub use business_opening_hours::BusinessOpeningHours; +pub use business_opening_hours_interval::BusinessOpeningHoursInterval; pub use callback_game::CallbackGame; pub use callback_query::CallbackQuery; pub use chat::{ @@ -459,6 +474,7 @@ pub use reply_markup::ReplyMarkup; pub use reply_parameters::ReplyParameters; pub use response_parameters::ResponseParameters; pub use sent_web_app_message::SentWebAppMessage; +pub use shared_user::SharedUser; pub use shipping_address::ShippingAddress; pub use shipping_option::ShippingOption; pub use shipping_query::ShippingQuery; diff --git a/telers/src/types/birthdate.rs b/telers/src/types/birthdate.rs new file mode 100644 index 00000000..71767118 --- /dev/null +++ b/telers/src/types/birthdate.rs @@ -0,0 +1,13 @@ +use serde::Deserialize; + +/// # Documentation +/// +#[derive(Debug, Default, Clone, PartialEq, Deserialize)] +pub struct Birthdate { + /// Day of the user's birth; 1-31 + pub day: i8, + /// Month of the user's birth; 1-12 + pub month: i8, + /// Year of the user's birth + pub year: i16, +} diff --git a/telers/src/types/business_connection.rs b/telers/src/types/business_connection.rs new file mode 100644 index 00000000..68c46f8b --- /dev/null +++ b/telers/src/types/business_connection.rs @@ -0,0 +1,36 @@ +use super::{Update, UpdateKind, User}; + +use crate::{errors::ConvertToTypeError, FromEvent}; + +use serde::Deserialize; + +/// Describes the connection of the bot with a business account. +/// # Documentation +/// +#[derive(Debug, Default, Clone, Hash, PartialEq, Eq, Deserialize, FromEvent)] +#[event(try_from = Update)] +pub struct BusinessConnection { + /// Unique identifier of the business connection + pub id: Box, + /// Business account user that created the business connection + pub user: User, + /// Identifier of a private chat with the user who created the business connection. This number may have more than 32 significant bits and some programming languages may have difficulty/silent defects in interpreting it. But it has at most 52 significant bits, so a 64-bit integer or double-precision float type are safe for storing this identifier. + pub user_chat_id: i64, + /// Date the connection was established in Unix time + pub date: i64, + /// `true`, if the bot can act on behalf of the business account in chats that were active in the last 24 hours + pub can_reply: bool, + /// `true`, if the connection is active + pub is_enabled: bool, +} + +impl TryFrom for BusinessConnection { + type Error = ConvertToTypeError; + + fn try_from(update: Update) -> Result { + match update.kind { + UpdateKind::BusinessConnection(val) => Ok(val), + _ => Err(ConvertToTypeError::new("Update", "BusinessConnection")), + } + } +} diff --git a/telers/src/types/business_intro.rs b/telers/src/types/business_intro.rs new file mode 100644 index 00000000..9b83631c --- /dev/null +++ b/telers/src/types/business_intro.rs @@ -0,0 +1,15 @@ +use super::Sticker; + +use serde::Deserialize; + +/// # Documentation +/// +#[derive(Debug, Default, Clone, PartialEq, Deserialize)] +pub struct BusinessIntro { + /// Title text of the business intro + pub title: Option>, + /// Message text of the business intro + pub message: Option>, + /// Sticker of the business intro + pub sticker: Option, +} diff --git a/telers/src/types/business_location.rs b/telers/src/types/business_location.rs new file mode 100644 index 00000000..94af0ced --- /dev/null +++ b/telers/src/types/business_location.rs @@ -0,0 +1,13 @@ +use super::Location; + +use serde::Deserialize; + +/// # Documentation +/// +#[derive(Debug, Default, Clone, PartialEq, Deserialize)] +pub struct BusinessLocation { + /// Address of the business + pub address: Box, + /// Location of the business + pub location: Option, +} diff --git a/telers/src/types/business_messages_deleted.rs b/telers/src/types/business_messages_deleted.rs new file mode 100644 index 00000000..53d2392f --- /dev/null +++ b/telers/src/types/business_messages_deleted.rs @@ -0,0 +1,30 @@ +use super::{Chat, Update, UpdateKind}; + +use crate::{errors::ConvertToTypeError, FromEvent}; + +use serde::Deserialize; + +/// This object is received when messages are deleted from a connected business account. +/// # Documentation +/// +#[derive(Debug, Clone, PartialEq, Deserialize, FromEvent)] +#[event(try_from = Update)] +pub struct BusinessMessagesDeleted { + /// Unique identifier of the business connection + pub business_connection_id: Box, + /// Information about a chat in the business account. The bot may not have access to the chat or the corresponding user. + pub chat: Chat, + /// A JSON-serialized list of identifiers of deleted messages in the chat of the business account + pub message_ids: Box<[i64]>, +} + +impl TryFrom for BusinessMessagesDeleted { + type Error = ConvertToTypeError; + + fn try_from(update: Update) -> Result { + match update.kind { + UpdateKind::DeletedBusinessMessages(val) => Ok(val), + _ => Err(ConvertToTypeError::new("Update", "DeletedBusinessMessages")), + } + } +} diff --git a/telers/src/types/business_opening_hours.rs b/telers/src/types/business_opening_hours.rs new file mode 100644 index 00000000..aa574133 --- /dev/null +++ b/telers/src/types/business_opening_hours.rs @@ -0,0 +1,13 @@ +use super::BusinessOpeningHoursInterval; + +use serde::Deserialize; + +/// # Documentation +/// +#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize)] +pub struct BusinessOpeningHours { + /// Unique name of the time zone for which the opening hours are defined + pub time_zone_name: Box, + /// List of time intervals describing business opening hours + pub opening_hours: Box<[BusinessOpeningHoursInterval]>, +} diff --git a/telers/src/types/business_opening_hours_interval.rs b/telers/src/types/business_opening_hours_interval.rs new file mode 100644 index 00000000..7e6a7c5f --- /dev/null +++ b/telers/src/types/business_opening_hours_interval.rs @@ -0,0 +1,11 @@ +use serde::Deserialize; + +/// # Documentation +/// +#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize)] +pub struct BusinessOpeningHoursInterval { + /// The minute's sequence number in a week, starting on Monday, marking the start of the time interval during which the business is open; 0 - 7 * 24 * 60 + pub opening_minute: i64, + /// The minute's sequence number in a week, starting on Monday, marking the end of the time interval during which the business is open; 0 - 8 * 24 * 60 + pub closing_minute: i64, +} diff --git a/telers/src/types/chat.rs b/telers/src/types/chat.rs index 6dcf79f8..e5138d9c 100644 --- a/telers/src/types/chat.rs +++ b/telers/src/types/chat.rs @@ -1,4 +1,7 @@ -use super::{ChatLocation, ChatPermissions, ChatPhoto, Message}; +use super::{ + Birthdate, BusinessIntro, BusinessLocation, BusinessOpeningHours, ChatLocation, + ChatPermissions, ChatPhoto, Message, +}; use crate::extractors::FromContext; @@ -15,10 +18,10 @@ use serde::Deserialize; )] #[serde(tag = "type", rename_all = "snake_case")] pub enum Chat { - Private(Private), - Group(Group), - Supergroup(Supergroup), - Channel(Channel), + Private(Box), + Group(Box), + Supergroup(Box), + Channel(Box), } #[derive(Debug, Default, Clone, PartialEq, Deserialize)] @@ -35,6 +38,16 @@ pub struct Private { pub photo: Option, /// If non-empty, the list of all [active chat usernames](https://telegram.org/blog/topics-in-groups-collectible-usernames/ru?ln=a#collectible-usernames). Returned only in [`GetChat`](crate::methods::GetChat). pub active_usernames: Option]>>, + /// The date of birth of the user. Returned only in [`GetChat`](crate::methods::GetChat). + pub birthdate: Option, + /// The intro of the business. Returned only in [`GetChat`](crate::methods::GetChat). + pub business_intro: Option, + /// The location of the business. Returned only in [`GetChat`](crate::methods::GetChat). + pub business_location: Option, + /// The opening hours of the business. Returned only in [`GetChat`](crate::methods::GetChat). + pub business_opening_hours: Option, + /// The personal channel of the user. Returned only in [`GetChat`](crate::methods::GetChat). + pub personal_chat: Option, /// Identifier of the accent color for the chat name and backgrounds of the chat photo, reply header, and link preview. See [accent colors](https://core.telegram.org/bots/api#accent-colors) for more details. Returned only in [`GetChat`](crate::methods::GetChat). Always returned in [`GetChat`](crate::methods::GetChat). pub accent_color_id: Option, /// Custom emoji identifier of emoji chosen by the chat for the reply header and link preview background. Returned only in [`GetChat`](crate::methods::GetChat). @@ -195,21 +208,28 @@ impl Chat { #[must_use] pub const fn id(&self) -> i64 { match self { - Self::Private(Private { id, .. }) - | Self::Group(Group { id, .. }) - | Self::Supergroup(Supergroup { id, .. }) - | Self::Channel(Channel { id, .. }) => *id, + Self::Private(chat) => chat.id, + Self::Group(chat) => chat.id, + Self::Supergroup(chat) => chat.id, + Self::Channel(chat) => chat.id, } } + #[allow(clippy::match_as_ref)] #[must_use] pub const fn username(&self) -> Option<&str> { match self { Self::Group(_) => None, - Self::Private(Private { username, .. }) - | Self::Supergroup(Supergroup { username, .. }) - | Self::Channel(Channel { username, .. }) => match username { - Some(username) => Some(username), + Self::Private(chat) => match chat.username { + Some(ref username) => Some(username), + None => None, + }, + Self::Supergroup(chat) => match chat.username { + Some(ref username) => Some(username), + None => None, + }, + Self::Channel(chat) => match chat.username { + Some(ref username) => Some(username), None => None, }, } @@ -218,10 +238,10 @@ impl Chat { #[must_use] pub const fn photo(&self) -> Option<&ChatPhoto> { match self { - Self::Private(Private { photo, .. }) - | Self::Group(Group { photo, .. }) - | Self::Supergroup(Supergroup { photo, .. }) - | Self::Channel(Channel { photo, .. }) => photo.as_ref(), + Self::Private(chat) => chat.photo.as_ref(), + Self::Group(chat) => chat.photo.as_ref(), + Self::Supergroup(chat) => chat.photo.as_ref(), + Self::Channel(chat) => chat.photo.as_ref(), } } @@ -229,44 +249,87 @@ impl Chat { pub const fn title(&self) -> Option<&str> { match self { Self::Private(_) => None, - Self::Group(Group { title, .. }) - | Self::Supergroup(Supergroup { title, .. }) - | Self::Channel(Channel { title, .. }) => Some(title), + Self::Group(chat) => Some(&chat.title), + Self::Supergroup(chat) => Some(&chat.title), + Self::Channel(chat) => Some(&chat.title), } } + #[allow(clippy::match_as_ref)] #[must_use] pub const fn active_usernames(&self) -> Option<&[Box]> { match self { Self::Group(_) => None, - Self::Private(Private { - active_usernames, .. - }) - | Self::Supergroup(Supergroup { - active_usernames, .. - }) - | Self::Channel(Channel { - active_usernames, .. - }) => match active_usernames { - Some(active_usernames) => Some(active_usernames), + Self::Private(chat) => match chat.active_usernames { + Some(ref active_usernames) => Some(active_usernames), + None => None, + }, + Self::Supergroup(chat) => match chat.active_usernames { + Some(ref active_usernames) => Some(active_usernames), + None => None, + }, + Self::Channel(chat) => match chat.active_usernames { + Some(ref active_usernames) => Some(active_usernames), + None => None, + }, + } + } + + #[must_use] + pub const fn birthdate(&self) -> Option<&Birthdate> { + match self { + Self::Group(_) | Self::Supergroup(_) | Self::Channel(_) => None, + Self::Private(chat) => chat.birthdate.as_ref(), + } + } + + #[must_use] + pub const fn business_intro(&self) -> Option<&BusinessIntro> { + match self { + Self::Group(_) | Self::Supergroup(_) | Self::Channel(_) => None, + Self::Private(chat) => chat.business_intro.as_ref(), + } + } + + #[allow(clippy::match_as_ref)] + #[must_use] + pub const fn business_location(&self) -> Option<&BusinessLocation> { + match self { + Self::Group(_) | Self::Supergroup(_) | Self::Channel(_) => None, + Self::Private(chat) => match chat.business_location { + Some(ref business_location) => Some(business_location), None => None, }, } } + #[must_use] + pub const fn business_opening_hours(&self) -> Option<&BusinessOpeningHours> { + match self { + Self::Group(_) | Self::Supergroup(_) | Self::Channel(_) => None, + Self::Private(chat) => chat.business_opening_hours.as_ref(), + } + } + + #[must_use] + pub const fn personal_chat(&self) -> Option<&Chat> { + match self { + Self::Group(_) | Self::Supergroup(_) | Self::Channel(_) => None, + Self::Private(chat) => chat.personal_chat.as_ref(), + } + } + + #[allow(clippy::match_as_ref)] #[must_use] pub const fn available_reactions(&self) -> Option<&[Box]> { match self { Self::Group(_) | Self::Private(_) => None, - Self::Supergroup(Supergroup { - available_reactions, - .. - }) - | Self::Channel(Channel { - available_reactions, - .. - }) => match available_reactions { - Some(available_reactions) => Some(available_reactions), + Self::Supergroup(chat) => match chat.available_reactions { + Some(ref available_reactions) => Some(available_reactions), + None => None, + }, + Self::Channel(chat) => match chat.available_reactions { + Some(ref available_reactions) => Some(available_reactions), None => None, }, } @@ -276,28 +339,22 @@ impl Chat { pub const fn accent_color_id(&self) -> Option { match self { Self::Group(_) | Self::Private(_) => None, - Self::Supergroup(Supergroup { - accent_color_id, .. - }) - | Self::Channel(Channel { - accent_color_id, .. - }) => *accent_color_id, + Self::Supergroup(chat) => chat.accent_color_id, + Self::Channel(chat) => chat.accent_color_id, } } + #[allow(clippy::match_as_ref)] #[must_use] pub const fn background_custom_emoji_id(&self) -> Option<&str> { match self { Self::Group(_) | Self::Private(_) => None, - Self::Supergroup(Supergroup { - background_custom_emoji_id, - .. - }) - | Self::Channel(Channel { - background_custom_emoji_id, - .. - }) => match background_custom_emoji_id { - Some(background_custom_emoji_id) => Some(background_custom_emoji_id), + Self::Supergroup(chat) => match chat.background_custom_emoji_id { + Some(ref background_custom_emoji_id) => Some(background_custom_emoji_id), + None => None, + }, + Self::Channel(chat) => match chat.background_custom_emoji_id { + Some(ref background_custom_emoji_id) => Some(background_custom_emoji_id), None => None, }, } @@ -307,30 +364,24 @@ impl Chat { pub const fn profile_accent_color_id(&self) -> Option { match self { Self::Group(_) | Self::Private(_) => None, - Self::Supergroup(Supergroup { - profile_accent_color_id, - .. - }) - | Self::Channel(Channel { - profile_accent_color_id, - .. - }) => *profile_accent_color_id, + Self::Supergroup(chat) => chat.profile_accent_color_id, + Self::Channel(chat) => chat.profile_accent_color_id, } } + #[allow(clippy::match_as_ref)] #[must_use] pub const fn profile_background_custom_emoji_id(&self) -> Option<&str> { match self { Self::Group(_) | Self::Private(_) => None, - Self::Supergroup(Supergroup { - profile_background_custom_emoji_id, - .. - }) - | Self::Channel(Channel { - profile_background_custom_emoji_id, - .. - }) => match profile_background_custom_emoji_id { - Some(profile_background_custom_emoji_id) => { + Self::Supergroup(chat) => match chat.profile_background_custom_emoji_id { + Some(ref profile_background_custom_emoji_id) => { + Some(profile_background_custom_emoji_id) + } + None => None, + }, + Self::Channel(chat) => match chat.profile_background_custom_emoji_id { + Some(ref profile_background_custom_emoji_id) => { Some(profile_background_custom_emoji_id) } None => None, @@ -342,38 +393,46 @@ impl Chat { pub const fn has_visible_history(&self) -> Option { match self { Self::Private(_) | Self::Channel(_) => None, - Self::Group(Group { - has_visible_history, - .. - }) - | Self::Supergroup(Supergroup { - has_visible_history, - .. - }) => *has_visible_history, + Self::Group(chat) => chat.has_visible_history, + Self::Supergroup(chat) => chat.has_visible_history, } } + #[allow(clippy::match_as_ref)] #[must_use] pub const fn description(&self) -> Option<&str> { match self { Self::Private(_) => None, - Self::Group(Group { description, .. }) - | Self::Supergroup(Supergroup { description, .. }) - | Self::Channel(Channel { description, .. }) => match description { - Some(description) => Some(description), + Self::Group(chat) => match chat.description { + Some(ref description) => Some(description), + None => None, + }, + Self::Supergroup(chat) => match chat.description { + Some(ref description) => Some(description), + None => None, + }, + Self::Channel(chat) => match chat.description { + Some(ref description) => Some(description), None => None, }, } } + #[allow(clippy::match_as_ref)] #[must_use] pub const fn invite_link(&self) -> Option<&str> { match self { Self::Private(_) => None, - Self::Group(Group { invite_link, .. }) - | Self::Supergroup(Supergroup { invite_link, .. }) - | Self::Channel(Channel { invite_link, .. }) => match invite_link { - Some(invite_link) => Some(invite_link), + Self::Group(chat) => match chat.invite_link { + Some(ref invite_link) => Some(invite_link), + None => None, + }, + Self::Supergroup(chat) => match chat.invite_link { + Some(ref invite_link) => Some(invite_link), + None => None, + }, + Self::Channel(chat) => match chat.invite_link { + Some(ref invite_link) => Some(invite_link), None => None, }, } @@ -383,18 +442,9 @@ impl Chat { pub const fn has_protected_content(&self) -> Option { match self { Self::Private(_) => None, - Self::Group(Group { - has_protected_content, - .. - }) - | Self::Supergroup(Supergroup { - has_protected_content, - .. - }) - | Self::Channel(Channel { - has_protected_content, - .. - }) => *has_protected_content, + Self::Group(chat) => chat.has_protected_content, + Self::Supergroup(chat) => chat.has_protected_content, + Self::Channel(chat) => chat.has_protected_content, } } @@ -402,8 +452,8 @@ impl Chat { pub const fn linked_chat_id(&self) -> Option { match self { Self::Private(_) | Self::Group(_) => None, - Self::Supergroup(Supergroup { linked_chat_id, .. }) - | Self::Channel(Channel { linked_chat_id, .. }) => *linked_chat_id, + Self::Supergroup(chat) => chat.linked_chat_id, + Self::Channel(chat) => chat.linked_chat_id, } } } @@ -411,6 +461,6 @@ impl Chat { impl Default for Chat { #[must_use] fn default() -> Self { - Self::Private(Private::default()) + Self::Private(Box::default()) } } diff --git a/telers/src/types/chat_shared.rs b/telers/src/types/chat_shared.rs index ede9801a..ba99cd2f 100644 --- a/telers/src/types/chat_shared.rs +++ b/telers/src/types/chat_shared.rs @@ -1,6 +1,8 @@ +use super::PhotoSize; + use serde::Deserialize; -/// This object contains information about the chat whose identifier was shared with the bot using a [`KeyboardButtonRequestChat`](crate::types::KeyboardButtonRequestChat) button. +/// This object contains information about a chat that was shared with the bot using a [`KeyboardButtonRequestChat`](crate::types::KeyboardButtonRequestChat) button. /// # Documentation /// #[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize)] @@ -9,4 +11,10 @@ pub struct ChatShared { pub request_id: i64, /// Identifier of the shared chat. This number may have more than 32 significant bits and some programming languages may have difficulty/silent defects in interpreting it. But it has at most 52 significant bits, so a 64-bit integer or double-precision float type are safe for storing this identifier. The bot may not have access to the chat and could be unable to use this identifier, unless the chat is already known to the bot by some other means. pub chat_id: i64, + /// Title of the chat, if the title was requested by the bot. + pub title: Option>, + /// Username of the chat, if the username was requested by the bot and available. + pub username: Option>, + /// Available sizes of the chat photo, if the photo was requested by the bot + pub photo: Option>, } diff --git a/telers/src/types/external_reply_info.rs b/telers/src/types/external_reply_info.rs index c0ed8fdc..69752a42 100644 --- a/telers/src/types/external_reply_info.rs +++ b/telers/src/types/external_reply_info.rs @@ -10,25 +10,25 @@ use serde::Deserialize; #[derive(Debug, Clone, PartialEq, Deserialize)] #[serde(untagged)] pub enum ExternalReplyInfo { - Animation(Animation), - Audio(Audio), - Document(Document), - Photo(Photo), - Sticker(Sticker), - Story(Story), - Video(Video), - VideoNote(VideoNote), - Voice(Voice), - Contact(Contact), - Dice(Dice), - Game(Game), - Giveaway(Giveaway), - GiveawayWinners(GiveawayWinners), - Invoice(Invoice), - Venue(Venue), - Location(Location), - Poll(Poll), - Text(Text), + Animation(Box), + Audio(Box