Merge pull request #809 from teloxide/TBA6.4

Telegram bot API 6.4
This commit is contained in:
Waffle Maybe 2023-01-17 01:19:07 +04:00 committed by GitHub
commit a791900944
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 694 additions and 67 deletions

View file

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

View file

@ -24,9 +24,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `Restricted::{is_member, can_change_info, can_invite_users, can_pin_messages, can_send_polls}` fields ([#764][pr764])
- `ChatMember::can_send_polls` method ([#764][pr764])
- Support for Telegram Bot API [version 6.3](https://core.telegram.org/bots/api#november-5-2022) ([#789][pr789])
- Support for Telegram Bot API [version 6.4](https://core.telegram.org/bots/api#december-30-2022) ([#809][pr809])
[pr764]: https://github.com/teloxide/teloxide/pull/764
[pr764]: https://github.com/teloxide/teloxide/pull/789
[pr800]: https://github.com/teloxide/teloxide/pull/800
[pr809]: https://github.com/teloxide/teloxide/pull/809
### Deprecated

View file

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

View file

@ -468,6 +468,11 @@ Schema(
name: "caption_entities",
ty: Option(ArrayOf(RawTy("MessageEntity"))),
descr: Doc(md: "List of special entities that appear in the photo caption, which can be specified instead of _parse\\_mode_"),
),
Param(
name: "has_spoiler",
ty: Option(bool),
descr: Doc(md: "Pass True if the photo needs to be covered with a spoiler animation"),
),
Param(
name: "disable_notification",
@ -780,6 +785,11 @@ Schema(
ty: Option(ArrayOf(RawTy("MessageEntity"))),
descr: Doc(md: "List of special entities that appear in the caption, which can be specified instead of _parse\\_mode_"),
),
Param(
name: "has_spoiler",
ty: Option(bool),
descr: Doc(md: "Pass True if the video needs to be covered with a spoiler animation"),
),
Param(
name: "supports_streaming",
ty: Option(bool),
@ -891,6 +901,11 @@ Schema(
ty: Option(ArrayOf(RawTy("MessageEntity"))),
descr: Doc(md: "List of special entities that appear in the photo caption, which can be specified instead of _parse\\_mode_"),
),
Param(
name: "has_spoiler",
ty: Option(bool),
descr: Doc(md: "Pass True if the animation needs to be covered with a spoiler animation"),
),
Param(
name: "disable_notification",
ty: Option(bool),
@ -1809,7 +1824,7 @@ Schema(
name: "chat_id",
ty: RawTy("Recipient"),
descr: Doc(md: "Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)")
),
),
Param(
name: "action",
ty: RawTy("ChatAction"),
@ -1827,6 +1842,11 @@ Schema(
}
),
),
Param(
name: "message_thread_id",
ty: Option(i32),
descr: Doc(md: "Unique identifier for the target message thread; supergroups only")
),
],
),
Method(
@ -2631,13 +2651,13 @@ Schema(
),
Param(
name: "name",
ty: String,
descr: Doc(md: "Topic name, 1-128 characters")
ty: Option(String),
descr: Doc(md: "Topic name, 0-128 characters. If not specified or empty, the current name of the topic will be kept")
),
Param(
name: "icon_custom_emoji_id",
ty: String,
descr: Doc(md: "Unique identifier of the custom emoji shown as the topic icon. Use `getForumTopicIconStickers` to get all allowed custom emoji identifiers.")
ty: Option(String),
descr: Doc(md: "Unique identifier of the custom emoji shown as the topic icon. Use `getForumTopicIconStickers` to get all allowed custom emoji identifiers. Pass an empty string to remove the icon. If not specified, the current icon will be kept")
),
],
),
@ -2702,7 +2722,7 @@ Schema(
names: ("unpinAllForumTopicMessages", "UnpinAllForumTopicMessages", "unpin_all_forum_topic_messages"),
return_ty: True,
doc: Doc(md: "Use this method to clear the list of pinned messages in a 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#deleteforumtopic",
tg_doc: "https://core.telegram.org/bots/api#unpinallforumtopicmessages",
tg_category: "Available methods",
params: [
Param(
@ -2717,6 +2737,81 @@ Schema(
),
],
),
Method(
names: ("editGeneralForumTopic", "EditGeneralForumTopic", "edit_general_forum_topic"),
return_ty: True,
doc: Doc(md: "Use this method to edit the name of the 'General' topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have _can\\_manage\\_topics_ administrator rights. Returns True on success."),
tg_doc: "https://core.telegram.org/bots/api#editgeneralforumtopic",
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 channel (in the format `@channelusername`)")
),
Param(
name: "name",
ty: String,
descr: Doc(md: "New topic name, 1-128 characters"),
),
],
),
Method(
names: ("closeGeneralForumTopic", "CloseGeneralForumTopic", "close_general_forum_topic"),
return_ty: True,
doc: Doc(md: "Use this method to close an open 'General' topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the _can\\_manage\\_topics_ administrator rights. Returns True on success."),
tg_doc: "https://core.telegram.org/bots/api#closegeneralforumtopic",
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 channel (in the format `@channelusername`)")
),
],
),
Method(
names: ("reopenGeneralForumTopic", "ReopenGeneralForumTopic", "reopen_general_forum_topic"),
return_ty: True,
doc: Doc(md: "Use this method to reopen a closed 'General' topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the _can\\_manage\\_topics_ administrator rights. The topic will be automatically unhidden if it was hidden. Returns True on success."),
tg_doc: "https://core.telegram.org/bots/api#reopengeneralforumtopic",
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 channel (in the format `@channelusername`)")
),
],
),
Method(
names: ("hideGeneralForumTopic", "HideGeneralForumTopic", "hide_general_forum_topic"),
return_ty: True,
doc: Doc(md: "Use this method to hide the 'General' topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the _can\\_manage\\_topics_ administrator rights. The topic will be automatically closed if it was open. Returns True on success."),
tg_doc: "https://core.telegram.org/bots/api#hidegeneralforumtopic",
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 channel (in the format `@channelusername`)")
),
],
),
Method(
names: ("unhideGeneralForumTopic", "UnhideGeneralForumTopic", "unhide_general_forum_topic"),
return_ty: True,
doc: Doc(md: "Use this method to unhide the 'General' topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the _can\\_manage\\_topics_ administrator rights. Returns True on success."),
tg_doc: "https://core.telegram.org/bots/api#unhidegeneralforumtopic",
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 channel (in the format `@channelusername`)")
),
],
),
Method(
names: ("answerCallbackQuery", "AnswerCallbackQuery", "answer_callback_query"),
return_ty: True,

View file

@ -127,6 +127,11 @@ where
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,
answer_callback_query,
set_my_commands,
get_my_commands,

View file

@ -151,6 +151,11 @@ where
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,
answer_callback_query,
set_my_commands,
get_my_commands,

View file

@ -240,6 +240,11 @@ where
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,
answer_callback_query,
set_my_commands,
get_my_commands,
@ -628,8 +633,6 @@ trait ErasableRequester<'a> {
&self,
chat_id: Recipient,
message_thread_id: i32,
name: String,
icon_custom_emoji_id: String,
) -> ErasedRequest<'a, EditForumTopic, Self::Err>;
fn close_forum_topic(
@ -656,6 +659,32 @@ trait ErasableRequester<'a> {
message_thread_id: i32,
) -> ErasedRequest<'a, UnpinAllForumTopicMessages, Self::Err>;
fn edit_general_forum_topic(
&self,
chat_id: Recipient,
name: String,
) -> ErasedRequest<'a, EditGeneralForumTopic, Self::Err>;
fn close_general_forum_topic(
&self,
chat_id: Recipient,
) -> ErasedRequest<'a, CloseGeneralForumTopic, Self::Err>;
fn reopen_general_forum_topic(
&self,
chat_id: Recipient,
) -> ErasedRequest<'a, ReopenGeneralForumTopic, Self::Err>;
fn hide_general_forum_topic(
&self,
chat_id: Recipient,
) -> ErasedRequest<'a, HideGeneralForumTopic, Self::Err>;
fn unhide_general_forum_topic(
&self,
chat_id: Recipient,
) -> ErasedRequest<'a, UnhideGeneralForumTopic, Self::Err>;
fn answer_callback_query(
&self,
callback_query_id: String,
@ -1350,11 +1379,8 @@ where
&self,
chat_id: Recipient,
message_thread_id: i32,
name: String,
icon_custom_emoji_id: String,
) -> ErasedRequest<'a, EditForumTopic, Self::Err> {
Requester::edit_forum_topic(self, chat_id, message_thread_id, name, icon_custom_emoji_id)
.erase()
Requester::edit_forum_topic(self, chat_id, message_thread_id).erase()
}
fn close_forum_topic(
@ -1389,6 +1415,42 @@ where
Requester::unpin_all_forum_topic_messages(self, chat_id, message_thread_id).erase()
}
fn edit_general_forum_topic(
&self,
chat_id: Recipient,
name: String,
) -> ErasedRequest<'a, EditGeneralForumTopic, Self::Err> {
Requester::edit_general_forum_topic(self, chat_id, name).erase()
}
fn close_general_forum_topic(
&self,
chat_id: Recipient,
) -> ErasedRequest<'a, CloseGeneralForumTopic, Self::Err> {
Requester::close_general_forum_topic(self, chat_id).erase()
}
fn reopen_general_forum_topic(
&self,
chat_id: Recipient,
) -> ErasedRequest<'a, ReopenGeneralForumTopic, Self::Err> {
Requester::reopen_general_forum_topic(self, chat_id).erase()
}
fn hide_general_forum_topic(
&self,
chat_id: Recipient,
) -> ErasedRequest<'a, HideGeneralForumTopic, Self::Err> {
Requester::hide_general_forum_topic(self, chat_id).erase()
}
fn unhide_general_forum_topic(
&self,
chat_id: Recipient,
) -> ErasedRequest<'a, UnhideGeneralForumTopic, Self::Err> {
Requester::unhide_general_forum_topic(self, chat_id).erase()
}
fn answer_callback_query(
&self,
callback_query_id: String,

View file

@ -149,6 +149,11 @@ impl<B: Requester> Requester for DefaultParseMode<B> {
close_forum_topic,
reopen_forum_topic,
delete_forum_topic,
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,
answer_callback_query,
set_my_commands,

View file

@ -134,6 +134,11 @@ where
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,
answer_callback_query,
set_my_commands,
get_my_commands,

View file

@ -180,6 +180,11 @@ where
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,
answer_callback_query,
set_my_commands,
get_my_commands,

View file

@ -675,21 +675,13 @@ impl Requester for Bot {
type EditForumTopic = JsonRequest<payloads::EditForumTopic>;
fn edit_forum_topic<C, N, I>(
&self,
chat_id: C,
message_thread_id: i32,
name: N,
icon_custom_emoji_id: I,
) -> Self::EditForumTopic
fn edit_forum_topic<C>(&self, chat_id: C, message_thread_id: i32) -> Self::EditForumTopic
where
C: Into<Recipient>,
N: Into<String>,
I: Into<String>,
{
Self::EditForumTopic::new(
self.clone(),
payloads::EditForumTopic::new(chat_id, message_thread_id, name, icon_custom_emoji_id),
payloads::EditForumTopic::new(chat_id, message_thread_id),
)
}
@ -745,6 +737,67 @@ impl Requester for Bot {
)
}
type EditGeneralForumTopic = JsonRequest<payloads::EditGeneralForumTopic>;
fn edit_general_forum_topic<C, N>(&self, chat_id: C, name: N) -> Self::EditGeneralForumTopic
where
C: Into<Recipient>,
N: Into<String>,
{
Self::EditGeneralForumTopic::new(
self.clone(),
payloads::EditGeneralForumTopic::new(chat_id, name),
)
}
type CloseGeneralForumTopic = JsonRequest<payloads::CloseGeneralForumTopic>;
fn close_general_forum_topic<C>(&self, chat_id: C) -> Self::CloseGeneralForumTopic
where
C: Into<Recipient>,
{
Self::CloseGeneralForumTopic::new(
self.clone(),
payloads::CloseGeneralForumTopic::new(chat_id),
)
}
type ReopenGeneralForumTopic = JsonRequest<payloads::ReopenGeneralForumTopic>;
fn reopen_general_forum_topic<C>(&self, chat_id: C) -> Self::ReopenGeneralForumTopic
where
C: Into<Recipient>,
{
Self::ReopenGeneralForumTopic::new(
self.clone(),
payloads::ReopenGeneralForumTopic::new(chat_id),
)
}
type HideGeneralForumTopic = JsonRequest<payloads::HideGeneralForumTopic>;
fn hide_general_forum_topic<C>(&self, chat_id: C) -> Self::HideGeneralForumTopic
where
C: Into<Recipient>,
{
Self::HideGeneralForumTopic::new(
self.clone(),
payloads::HideGeneralForumTopic::new(chat_id),
)
}
type UnhideGeneralForumTopic = JsonRequest<payloads::UnhideGeneralForumTopic>;
fn unhide_general_forum_topic<C>(&self, chat_id: C) -> Self::UnhideGeneralForumTopic
where
C: Into<Recipient>,
{
Self::UnhideGeneralForumTopic::new(
self.clone(),
payloads::UnhideGeneralForumTopic::new(chat_id),
)
}
type AnswerCallbackQuery = JsonRequest<payloads::AnswerCallbackQuery>;
fn answer_callback_query<C>(&self, callback_query_id: C) -> Self::AnswerCallbackQuery

View file

@ -78,11 +78,13 @@ pub fn ensure_files_contents<'a>(
let mut err_count = 0;
for (path, contents) in files_and_contents {
let old_contents = fs::read_to_string(path).unwrap();
if path.exists() {
let old_contents = fs::read_to_string(path).unwrap();
if normalize_newlines(&old_contents) == normalize_newlines(contents) {
// File is already up to date.
continue;
if normalize_newlines(&old_contents) == normalize_newlines(contents) {
// File is already up to date.
continue;
}
}
err_count += 1;

View file

@ -1,7 +1,7 @@
//! Core part of the [`teloxide`] library.
//!
//! This library provides tools for making requests to the [Telegram Bot API]
//! (Currently, version `6.2` is supported) with ease. The library is fully
//! (Currently, version `6.4` is supported) with ease. The library is fully
//! asynchronous and built using [`tokio`].
//!
//!```toml

View file

@ -931,11 +931,9 @@ macro_rules! requester_forward {
(@method edit_forum_topic $body:ident $ty:ident) => {
type EditForumTopic = $ty![EditForumTopic];
fn edit_forum_topic<C, N, I>(&self, chat_id: C, message_thread_id: i32, name: N, icon_custom_emoji_id: I) -> Self::EditForumTopic where C: Into<Recipient>,
N: Into<String>,
I: Into<String> {
fn edit_forum_topic<C>(&self, chat_id: C, message_thread_id: i32) -> Self::EditForumTopic where C: Into<Recipient> {
let this = self;
$body!(edit_forum_topic this (chat_id: C, message_thread_id: i32, name: N, icon_custom_emoji_id: I))
$body!(edit_forum_topic this (chat_id: C, message_thread_id: i32))
}
};
(@method close_forum_topic $body:ident $ty:ident) => {
@ -970,6 +968,47 @@ macro_rules! requester_forward {
$body!(unpin_all_forum_topic_messages this (chat_id: C, message_thread_id: i32))
}
};
(@method edit_general_forum_topic $body:ident $ty:ident) => {
type EditGeneralForumTopic = $ty![EditGeneralForumTopic];
fn edit_general_forum_topic<C, N>(&self, chat_id: C, name: N) -> Self::EditGeneralForumTopic where C: Into<Recipient>,
N: Into<String> {
let this = self;
$body!(edit_general_forum_topic this (chat_id: C, name: N))
}
};
(@method close_general_forum_topic $body:ident $ty:ident) => {
type CloseGeneralForumTopic = $ty![CloseGeneralForumTopic];
fn close_general_forum_topic<C>(&self, chat_id: C) -> Self::CloseGeneralForumTopic where C: Into<Recipient> {
let this = self;
$body!(close_general_forum_topic this (chat_id: C))
}
};
(@method reopen_general_forum_topic $body:ident $ty:ident) => {
type ReopenGeneralForumTopic = $ty![ReopenGeneralForumTopic];
fn reopen_general_forum_topic<C>(&self, chat_id: C) -> Self::ReopenGeneralForumTopic where C: Into<Recipient> {
let this = self;
$body!(reopen_general_forum_topic this (chat_id: C))
}
};
(@method hide_general_forum_topic $body:ident $ty:ident) => {
type HideGeneralForumTopic = $ty![HideGeneralForumTopic];
fn hide_general_forum_topic<C>(&self, chat_id: C) -> Self::HideGeneralForumTopic where C: Into<Recipient> {
let this = self;
$body!(hide_general_forum_topic this (chat_id: C))
}
};
(@method unhide_general_forum_topic $body:ident $ty:ident) => {
type UnhideGeneralForumTopic = $ty![UnhideGeneralForumTopic];
fn unhide_general_forum_topic<C>(&self, chat_id: C) -> Self::UnhideGeneralForumTopic where C: Into<Recipient> {
let this = self;
$body!(unhide_general_forum_topic this (chat_id: C))
}
};
(@method answer_callback_query $body:ident $ty:ident) => {
type AnswerCallbackQuery = $ty![AnswerCallbackQuery];

View file

@ -26,6 +26,7 @@ mod ban_chat_member;
mod ban_chat_sender_chat;
mod close;
mod close_forum_topic;
mod close_general_forum_topic;
mod copy_message;
mod create_chat_invite_link;
mod create_forum_topic;
@ -41,6 +42,7 @@ mod delete_sticker_from_set;
mod delete_webhook;
mod edit_chat_invite_link;
mod edit_forum_topic;
mod edit_general_forum_topic;
mod edit_message_caption;
mod edit_message_caption_inline;
mod edit_message_live_location;
@ -70,12 +72,14 @@ mod get_sticker_set;
mod get_updates;
mod get_user_profile_photos;
mod get_webhook_info;
mod hide_general_forum_topic;
mod kick_chat_member;
mod leave_chat;
mod log_out;
mod pin_chat_message;
mod promote_chat_member;
mod reopen_forum_topic;
mod reopen_general_forum_topic;
mod restrict_chat_member;
mod revoke_chat_invite_link;
mod send_animation;
@ -116,6 +120,7 @@ mod stop_message_live_location_inline;
mod stop_poll;
mod unban_chat_member;
mod unban_chat_sender_chat;
mod unhide_general_forum_topic;
mod unpin_all_chat_messages;
mod unpin_all_forum_topic_messages;
mod unpin_chat_message;
@ -132,6 +137,7 @@ pub use ban_chat_member::{BanChatMember, BanChatMemberSetters};
pub use ban_chat_sender_chat::{BanChatSenderChat, BanChatSenderChatSetters};
pub use close::{Close, CloseSetters};
pub use close_forum_topic::{CloseForumTopic, CloseForumTopicSetters};
pub use close_general_forum_topic::{CloseGeneralForumTopic, CloseGeneralForumTopicSetters};
pub use copy_message::{CopyMessage, CopyMessageSetters};
pub use create_chat_invite_link::{CreateChatInviteLink, CreateChatInviteLinkSetters};
pub use create_forum_topic::{CreateForumTopic, CreateForumTopicSetters};
@ -147,6 +153,7 @@ pub use delete_sticker_from_set::{DeleteStickerFromSet, DeleteStickerFromSetSett
pub use delete_webhook::{DeleteWebhook, DeleteWebhookSetters};
pub use edit_chat_invite_link::{EditChatInviteLink, EditChatInviteLinkSetters};
pub use edit_forum_topic::{EditForumTopic, EditForumTopicSetters};
pub use edit_general_forum_topic::{EditGeneralForumTopic, EditGeneralForumTopicSetters};
pub use edit_message_caption::{EditMessageCaption, EditMessageCaptionSetters};
pub use edit_message_caption_inline::{EditMessageCaptionInline, EditMessageCaptionInlineSetters};
pub use edit_message_live_location::{EditMessageLiveLocation, EditMessageLiveLocationSetters};
@ -184,12 +191,14 @@ pub use get_sticker_set::{GetStickerSet, GetStickerSetSetters};
pub use get_updates::{GetUpdates, GetUpdatesSetters};
pub use get_user_profile_photos::{GetUserProfilePhotos, GetUserProfilePhotosSetters};
pub use get_webhook_info::{GetWebhookInfo, GetWebhookInfoSetters};
pub use hide_general_forum_topic::{HideGeneralForumTopic, HideGeneralForumTopicSetters};
pub use kick_chat_member::{KickChatMember, KickChatMemberSetters};
pub use leave_chat::{LeaveChat, LeaveChatSetters};
pub use log_out::{LogOut, LogOutSetters};
pub use pin_chat_message::{PinChatMessage, PinChatMessageSetters};
pub use promote_chat_member::{PromoteChatMember, PromoteChatMemberSetters};
pub use reopen_forum_topic::{ReopenForumTopic, ReopenForumTopicSetters};
pub use reopen_general_forum_topic::{ReopenGeneralForumTopic, ReopenGeneralForumTopicSetters};
pub use restrict_chat_member::{RestrictChatMember, RestrictChatMemberSetters};
pub use revoke_chat_invite_link::{RevokeChatInviteLink, RevokeChatInviteLinkSetters};
pub use send_animation::{SendAnimation, SendAnimationSetters};
@ -236,6 +245,7 @@ pub use stop_message_live_location_inline::{
pub use stop_poll::{StopPoll, StopPollSetters};
pub use unban_chat_member::{UnbanChatMember, UnbanChatMemberSetters};
pub use unban_chat_sender_chat::{UnbanChatSenderChat, UnbanChatSenderChatSetters};
pub use unhide_general_forum_topic::{UnhideGeneralForumTopic, UnhideGeneralForumTopicSetters};
pub use unpin_all_chat_messages::{UnpinAllChatMessages, UnpinAllChatMessagesSetters};
pub use unpin_all_forum_topic_messages::{
UnpinAllForumTopicMessages, UnpinAllForumTopicMessagesSetters,

View file

@ -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 close an open 'General' topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the _can\_manage\_topics_ administrator rights. Returns True on success.
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize)]
pub CloseGeneralForumTopic (CloseGeneralForumTopicSetters) => True {
required {
/// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
pub chat_id: Recipient [into],
}
}
}

View file

@ -13,9 +13,11 @@ impl_payload! {
pub chat_id: Recipient [into],
/// Unique identifier for the target message thread of the forum topic
pub message_thread_id: i32,
/// Topic name, 1-128 characters
}
optional {
/// Topic name, 0-128 characters. If not specified or empty, the current name of the topic will be kept
pub name: String [into],
/// Unique identifier of the custom emoji shown as the topic icon. Use `getForumTopicIconStickers` to get all allowed custom emoji identifiers.
/// Unique identifier of the custom emoji shown as the topic icon. Use `getForumTopicIconStickers` to get all allowed custom emoji identifiers. Pass an empty string to remove the icon. If not specified, the current icon will be kept
pub icon_custom_emoji_id: String [into],
}
}

View file

@ -0,0 +1,18 @@
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Recipient, True};
impl_payload! {
/// Use this method to edit the name of the 'General' topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have _can\_manage\_topics_ administrator rights. Returns True on success.
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize)]
pub EditGeneralForumTopic (EditGeneralForumTopicSetters) => True {
required {
/// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
pub chat_id: Recipient [into],
/// New topic name, 1-128 characters
pub name: String [into],
}
}
}

View file

@ -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 hide the 'General' topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the _can\_manage\_topics_ administrator rights. The topic will be automatically closed if it was open. Returns True on success.
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize)]
pub HideGeneralForumTopic (HideGeneralForumTopicSetters) => True {
required {
/// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
pub chat_id: Recipient [into],
}
}
}

View file

@ -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 reopen a closed 'General' topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the _can\_manage\_topics_ administrator rights. The topic will be automatically unhidden if it was hidden. Returns True on success.
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize)]
pub ReopenGeneralForumTopic (ReopenGeneralForumTopicSetters) => True {
required {
/// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
pub chat_id: Recipient [into],
}
}
}

View file

@ -42,6 +42,8 @@ impl_payload! {
pub parse_mode: ParseMode,
/// List of special entities that appear in the photo caption, which can be specified instead of _parse\_mode_
pub caption_entities: Vec<MessageEntity> [collect],
/// Pass True if the animation needs to be covered with a spoiler animation
pub has_spoiler: bool,
/// Sends the message [silently]. Users will receive a notification with no sound.
///
/// [silently]: https://telegram.org/blog/channels-2-0#silent-messages

View file

@ -29,5 +29,9 @@ impl_payload! {
/// [video notes]: crate::payloads::SendVideoNote
pub action: ChatAction,
}
optional {
/// Unique identifier for the target message thread; supergroups only
pub message_thread_id: i32,
}
}
}

View file

@ -32,6 +32,8 @@ impl_payload! {
pub parse_mode: ParseMode,
/// List of special entities that appear in the photo caption, which can be specified instead of _parse\_mode_
pub caption_entities: Vec<MessageEntity> [collect],
/// Pass True if the photo needs to be covered with a spoiler animation
pub has_spoiler: bool,
/// Sends the message [silently]. Users will receive a notification with no sound.
///
/// [silently]: https://telegram.org/blog/channels-2-0#silent-messages

View file

@ -43,6 +43,8 @@ impl_payload! {
pub parse_mode: ParseMode,
/// List of special entities that appear in the caption, which can be specified instead of _parse\_mode_
pub caption_entities: Vec<MessageEntity> [collect],
/// Pass True if the video needs to be covered with a spoiler animation
pub has_spoiler: bool,
/// Pass _True_, if the uploaded video is suitable for streaming
pub supports_streaming: bool,
/// Sends the message [silently]. Users will receive a notification with no sound.

View file

@ -5,13 +5,13 @@ pub use crate::payloads::{
AddStickerToSetSetters as _, AnswerCallbackQuerySetters as _, AnswerInlineQuerySetters as _,
AnswerPreCheckoutQuerySetters as _, AnswerShippingQuerySetters as _,
AnswerWebAppQuerySetters as _, ApproveChatJoinRequestSetters as _, BanChatMemberSetters as _,
BanChatSenderChatSetters as _, CloseForumTopicSetters as _, CloseSetters as _,
CopyMessageSetters as _, CreateChatInviteLinkSetters as _, CreateForumTopicSetters as _,
CreateInvoiceLinkSetters as _, CreateNewStickerSetSetters as _,
BanChatSenderChatSetters as _, CloseForumTopicSetters as _, CloseGeneralForumTopicSetters as _,
CloseSetters as _, CopyMessageSetters as _, CreateChatInviteLinkSetters as _,
CreateForumTopicSetters as _, CreateInvoiceLinkSetters as _, CreateNewStickerSetSetters as _,
DeclineChatJoinRequestSetters as _, DeleteChatPhotoSetters as _,
DeleteChatStickerSetSetters as _, DeleteForumTopicSetters as _, DeleteMessageSetters as _,
DeleteMyCommandsSetters as _, DeleteStickerFromSetSetters as _, DeleteWebhookSetters as _,
EditChatInviteLinkSetters as _, EditForumTopicSetters as _,
EditChatInviteLinkSetters as _, EditForumTopicSetters as _, EditGeneralForumTopicSetters as _,
EditMessageCaptionInlineSetters as _, EditMessageCaptionSetters as _,
EditMessageLiveLocationInlineSetters as _, EditMessageLiveLocationSetters as _,
EditMessageMediaInlineSetters as _, EditMessageMediaSetters as _,
@ -23,12 +23,13 @@ pub use crate::payloads::{
GetCustomEmojiStickersSetters as _, GetFileSetters as _, GetForumTopicIconStickersSetters as _,
GetGameHighScoresSetters as _, GetMeSetters as _, GetMyCommandsSetters as _,
GetMyDefaultAdministratorRightsSetters as _, GetStickerSetSetters as _, GetUpdatesSetters as _,
GetUserProfilePhotosSetters as _, GetWebhookInfoSetters as _, KickChatMemberSetters as _,
LeaveChatSetters as _, LogOutSetters as _, PinChatMessageSetters as _,
PromoteChatMemberSetters as _, ReopenForumTopicSetters as _, RestrictChatMemberSetters as _,
RevokeChatInviteLinkSetters as _, SendAnimationSetters as _, SendAudioSetters as _,
SendChatActionSetters as _, SendContactSetters as _, SendDiceSetters as _,
SendDocumentSetters as _, SendGameSetters as _, SendInvoiceSetters as _,
GetUserProfilePhotosSetters as _, GetWebhookInfoSetters as _,
HideGeneralForumTopicSetters as _, KickChatMemberSetters as _, LeaveChatSetters as _,
LogOutSetters as _, PinChatMessageSetters as _, PromoteChatMemberSetters as _,
ReopenForumTopicSetters as _, ReopenGeneralForumTopicSetters as _,
RestrictChatMemberSetters as _, RevokeChatInviteLinkSetters as _, SendAnimationSetters as _,
SendAudioSetters as _, SendChatActionSetters as _, SendContactSetters as _,
SendDiceSetters as _, SendDocumentSetters as _, SendGameSetters as _, SendInvoiceSetters as _,
SendLocationSetters as _, SendMediaGroupSetters as _, SendMessageSetters as _,
SendPhotoSetters as _, SendPollSetters as _, SendStickerSetters as _, SendVenueSetters as _,
SendVideoNoteSetters as _, SendVideoSetters as _, SendVoiceSetters as _,
@ -40,6 +41,7 @@ pub use crate::payloads::{
SetStickerPositionInSetSetters as _, SetStickerSetThumbSetters as _, SetWebhookSetters as _,
StopMessageLiveLocationInlineSetters as _, StopMessageLiveLocationSetters as _,
StopPollSetters as _, UnbanChatMemberSetters as _, UnbanChatSenderChatSetters as _,
UnpinAllChatMessagesSetters as _, UnpinAllForumTopicMessagesSetters as _,
UnpinChatMessageSetters as _, UploadStickerFileSetters as _,
UnhideGeneralForumTopicSetters as _, UnpinAllChatMessagesSetters as _,
UnpinAllForumTopicMessagesSetters as _, UnpinChatMessageSetters as _,
UploadStickerFileSetters as _,
};

View file

@ -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 unhide the 'General' topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the _can\_manage\_topics_ administrator rights. Returns True on success.
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize)]
pub UnhideGeneralForumTopic (UnhideGeneralForumTopicSetters) => True {
required {
/// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
pub chat_id: Recipient [into],
}
}
}

View file

@ -682,17 +682,9 @@ pub trait Requester {
type EditForumTopic: Request<Payload = EditForumTopic, Err = Self::Err>;
/// For Telegram documentation see [`EditForumTopic`].
fn edit_forum_topic<C, N, I>(
&self,
chat_id: C,
message_thread_id: i32,
name: N,
icon_custom_emoji_id: I,
) -> Self::EditForumTopic
fn edit_forum_topic<C>(&self, chat_id: C, message_thread_id: i32) -> Self::EditForumTopic
where
C: Into<Recipient>,
N: Into<String>,
I: Into<String>;
C: Into<Recipient>;
type CloseForumTopic: Request<Payload = CloseForumTopic, Err = Self::Err>;
@ -726,6 +718,42 @@ pub trait Requester {
where
C: Into<Recipient>;
type EditGeneralForumTopic: Request<Payload = EditGeneralForumTopic, Err = Self::Err>;
/// For Telegram documentation see [`EditGeneralForumTopic`].
fn edit_general_forum_topic<C, N>(&self, chat_id: C, name: N) -> Self::EditGeneralForumTopic
where
C: Into<Recipient>,
N: Into<String>;
type CloseGeneralForumTopic: Request<Payload = CloseGeneralForumTopic, Err = Self::Err>;
/// For Telegram documentation see [`CloseGeneralForumTopic`].
fn close_general_forum_topic<C>(&self, chat_id: C) -> Self::CloseGeneralForumTopic
where
C: Into<Recipient>;
type ReopenGeneralForumTopic: Request<Payload = ReopenGeneralForumTopic, Err = Self::Err>;
/// For Telegram documentation see [`ReopenGeneralForumTopic`].
fn reopen_general_forum_topic<C>(&self, chat_id: C) -> Self::ReopenGeneralForumTopic
where
C: Into<Recipient>;
type HideGeneralForumTopic: Request<Payload = HideGeneralForumTopic, Err = Self::Err>;
/// For Telegram documentation see [`HideGeneralForumTopic`].
fn hide_general_forum_topic<C>(&self, chat_id: C) -> Self::HideGeneralForumTopic
where
C: Into<Recipient>;
type UnhideGeneralForumTopic: Request<Payload = UnhideGeneralForumTopic, Err = Self::Err>;
/// For Telegram documentation see [`UnhideGeneralForumTopic`].
fn unhide_general_forum_topic<C>(&self, chat_id: C) -> Self::UnhideGeneralForumTopic
where
C: Into<Recipient>;
type AnswerCallbackQuery: Request<Payload = AnswerCallbackQuery, Err = Self::Err>;
/// For Telegram documentation see [`AnswerCallbackQuery`].
@ -1177,6 +1205,11 @@ macro_rules! forward_all {
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,
answer_callback_query,
set_my_commands,
get_my_commands,

View file

@ -30,9 +30,12 @@ pub use force_reply::*;
pub use forum_topic::*;
pub use forum_topic_closed::*;
pub use forum_topic_created::*;
pub use forum_topic_edited::*;
pub use forum_topic_reopened::*;
pub use game::*;
pub use game_high_score::*;
pub use general_forum_topic_hidden::*;
pub use general_forum_topic_unhidden::*;
pub use inline_keyboard_button::*;
pub use inline_keyboard_markup::*;
pub use inline_query::*;
@ -113,6 +116,7 @@ pub use voice::*;
pub use web_app_data::*;
pub use web_app_info::*;
pub use webhook_info::*;
pub use write_access_allowed::*;
mod allowed_update;
mod animation;
@ -142,9 +146,12 @@ mod force_reply;
mod forum_topic;
mod forum_topic_closed;
mod forum_topic_created;
mod forum_topic_edited;
mod forum_topic_reopened;
mod game;
mod game_high_score;
mod general_forum_topic_hidden;
mod general_forum_topic_unhidden;
mod inline_keyboard_button;
mod inline_keyboard_markup;
mod input_file;
@ -200,6 +207,7 @@ mod voice;
mod web_app_data;
mod web_app_info;
mod webhook_info;
mod write_access_allowed;
mod inline_query;
mod inline_query_result;

View file

@ -30,6 +30,21 @@ pub struct Chat {
///
/// [`GetChat`]: crate::payloads::GetChat
pub message_auto_delete_time: Option<u32>,
/// `true`, if non-administrators can only get the list of bots and
/// administrators in the chat. Returned only in [`GetChat`].
///
/// [`GetChat`]: crate::payloads::GetChat
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub has_hidden_members: bool,
/// `true`, if aggressive anti-spam checks are enabled in the supergroup.
/// The field is only available to chat administrators. Returned only in
/// [`GetChat`].
///
/// [`GetChat`]: crate::payloads::GetChat
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub has_aggressive_anti_spam_enabled: bool,
}
#[serde_with_macros::skip_serializing_none]
@ -579,6 +594,8 @@ mod tests {
photo: None,
pinned_message: None,
message_auto_delete_time: None,
has_hidden_members: false,
has_aggressive_anti_spam_enabled: false,
};
let actual = from_str(r#"{"id":-1,"type":"channel","username":"channel_name"}"#).unwrap();
assert_eq!(expected, actual);
@ -601,6 +618,8 @@ mod tests {
photo: None,
pinned_message: None,
message_auto_delete_time: None,
has_hidden_members: false,
has_aggressive_anti_spam_enabled: false,
},
from_str(r#"{"id":0,"type":"private","username":"username","first_name":"Anon"}"#)
.unwrap()
@ -623,6 +642,8 @@ mod tests {
photo: None,
pinned_message: None,
message_auto_delete_time: None,
has_hidden_members: false,
has_aggressive_anti_spam_enabled: false,
};
let json = to_string(&chat).unwrap();

View file

@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
/// This object represents a service message about a forum topic closed in the
/// chat. Currently holds no information.
///
/// [The official docs](https://core.telegram.org/bots/api#forumtopiccreated).
/// [The official docs](https://core.telegram.org/bots/api#forumtopicclosed).
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ForumTopicClosed;

View file

@ -0,0 +1,15 @@
use serde::{Deserialize, Serialize};
/// This object represents a service message about an edited forum topic.
///
/// [The official docs](https://core.telegram.org/bots/api#forumtopicedited).
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ForumTopicEdited {
/// New name of the topic, if it was edited
pub name: Option<String>,
/// New identifier of the custom emoji shown as the topic icon, if it was
/// edited; an empty string if the icon was removed
pub icon_custom_emoji_id: Option<String>,
}

View file

@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
/// This object represents a service message about a forum topic reopened in the
/// chat. Currently holds no information.
///
/// [The official docs](https://core.telegram.org/bots/api#forumtopiccreated).
/// [The official docs](https://core.telegram.org/bots/api#forumtopicreopened).
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ForumTopicReopened;

View file

@ -0,0 +1,9 @@
use serde::{Deserialize, Serialize};
/// This object represents a service message about General forum topic hidden in
/// the chat. Currently holds no information.
///
/// [The official docs](https://core.telegram.org/bots/api#generalforumtopichidden).
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct GeneralForumTopicHidden;

View file

@ -0,0 +1,9 @@
use serde::{Deserialize, Serialize};
/// This object represents a service message about General forum topic unhidden
/// in the chat. Currently holds no information.
///
/// [The official docs](https://core.telegram.org/bots/api#generalforumtopicunhidden).
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct GeneralForumTopicUnhidden;

View file

@ -41,11 +41,15 @@ pub struct InputMediaPhoto {
/// List of special entities that appear in the caption, which can be
/// specified instead of `parse_mode`.
pub caption_entities: Option<Vec<MessageEntity>>,
/// Pass `true` if the photo needs to be covered with a spoiler animation.
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub has_spoiler: bool,
}
impl InputMediaPhoto {
pub const fn new(media: InputFile) -> Self {
Self { media, caption: None, parse_mode: None, caption_entities: None }
Self { media, caption: None, parse_mode: None, caption_entities: None, has_spoiler: false }
}
pub fn media(mut self, val: InputFile) -> Self {
@ -73,6 +77,14 @@ impl InputMediaPhoto {
self.caption_entities = Some(val.into_iter().collect());
self
}
/// Sets [`has_spoiler`] to `true`.
///
/// [`has_spoiler`]: InputMediaPhoto::has_spoiler
pub fn spoiler(mut self) -> Self {
self.has_spoiler = true;
self
}
}
/// Represents a video to be sent.
@ -117,6 +129,10 @@ pub struct InputMediaVideo {
/// Pass `true`, if the uploaded video is suitable for streaming.
pub supports_streaming: Option<bool>,
/// Pass `true` if the video needs to be covered with a spoiler animation.
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub has_spoiler: bool,
}
impl InputMediaVideo {
@ -131,6 +147,7 @@ impl InputMediaVideo {
height: None,
duration: None,
supports_streaming: None,
has_spoiler: false,
}
}
@ -184,6 +201,14 @@ impl InputMediaVideo {
self.supports_streaming = Some(val);
self
}
/// Sets [`has_spoiler`] to `true`.
///
/// [`has_spoiler`]: InputMediaVideo::has_spoiler
pub fn spoiler(mut self) -> Self {
self.has_spoiler = true;
self
}
}
/// Represents an animation file (GIF or H.264/MPEG-4 AVC video without
@ -226,6 +251,11 @@ pub struct InputMediaAnimation {
/// Animation duration.
pub duration: Option<u16>,
/// Pass `true` if the animation needs to be covered with a spoiler
/// animation.
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub has_spoiler: bool,
}
impl InputMediaAnimation {
@ -239,6 +269,7 @@ impl InputMediaAnimation {
height: None,
duration: None,
caption_entities: None,
has_spoiler: false,
}
}
@ -287,6 +318,14 @@ impl InputMediaAnimation {
self.duration = Some(val);
self
}
/// Sets [`has_spoiler`] to `true`.
///
/// [`has_spoiler`]: InputMediaAnimation::has_spoiler
pub fn spoiler(mut self) -> Self {
self.has_spoiler = true;
self
}
}
/// Represents an audio file to be treated as music to be sent.
@ -534,6 +573,7 @@ mod tests {
caption: None,
parse_mode: None,
caption_entities: None,
has_spoiler: false,
});
let actual_json = serde_json::to_string(&photo).unwrap();
@ -553,6 +593,7 @@ mod tests {
duration: None,
supports_streaming: None,
caption_entities: None,
has_spoiler: false,
});
let actual_json = serde_json::to_string(&video).unwrap();
@ -571,6 +612,7 @@ mod tests {
height: None,
duration: None,
caption_entities: None,
has_spoiler: false,
});
let actual_json = serde_json::to_string(&video).unwrap();

View file

@ -6,11 +6,12 @@ use url::Url;
use crate::types::{
Animation, Audio, BareChatId, Chat, ChatId, Contact, Dice, Document, ForumTopicClosed,
ForumTopicCreated, ForumTopicReopened, Game, InlineKeyboardMarkup, Invoice, Location,
ForumTopicCreated, ForumTopicEdited, ForumTopicReopened, Game, GeneralForumTopicHidden,
GeneralForumTopicUnhidden, InlineKeyboardMarkup, Invoice, Location,
MessageAutoDeleteTimerChanged, MessageEntity, MessageEntityRef, MessageId, PassportData,
PhotoSize, Poll, ProximityAlertTriggered, Sticker, SuccessfulPayment, True, User, Venue, Video,
VideoChatEnded, VideoChatParticipantsInvited, VideoChatScheduled, VideoChatStarted, VideoNote,
Voice, WebAppData,
Voice, WebAppData, WriteAccessAllowed,
};
/// This object represents a message.
@ -41,6 +42,9 @@ pub struct Message {
pub kind: MessageKind,
}
// FIXME: this could be a use-case for serde mixed-tags, some variants need to
// untagged (`MessageCommon` as an example), while other need to be
// tagged (e.g.: Forum*)
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum MessageKind {
@ -58,12 +62,16 @@ pub enum MessageKind {
Invoice(MessageInvoice),
SuccessfulPayment(MessageSuccessfulPayment),
ConnectedWebsite(MessageConnectedWebsite),
WriteAccessAllowed(MessageWriteAccessAllowed),
PassportData(MessagePassportData),
Dice(MessageDice),
ProximityAlertTriggered(MessageProximityAlertTriggered),
ForumTopicCreated(ForumTopicCreated),
ForumTopicClosed(ForumTopicClosed),
ForumTopicReopened(ForumTopicReopened),
ForumTopicCreated(MessageForumTopicCreated),
ForumTopicEdited(MessageForumTopicEdited),
ForumTopicClosed(MessageForumTopicClosed),
ForumTopicReopened(MessageForumTopicReopened),
GeneralForumTopicHidden(MessageGeneralForumTopicHidden),
GeneralForumTopicUnhidden(MessageGeneralForumTopicUnhidden),
VideoChatScheduled(MessageVideoChatScheduled),
VideoChatStarted(MessageVideoChatStarted),
VideoChatEnded(MessageVideoChatEnded),
@ -339,6 +347,10 @@ pub struct MediaAnimation {
/// bot commands, etc. that appear in the caption.
#[serde(default = "Vec::new")]
pub caption_entities: Vec<MessageEntity>,
/// `true`, if the message media is covered by a spoiler animation.
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub has_media_spoiler: bool,
// Note: for backward compatibility telegram also sends `document` field, but we ignore it
}
@ -415,6 +427,10 @@ pub struct MediaPhoto {
#[serde(default = "Vec::new")]
pub caption_entities: Vec<MessageEntity>,
/// `true`, if the message media is covered by a spoiler animation.
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub has_media_spoiler: bool,
/// The unique identifier of a media message group this message belongs
/// to.
pub media_group_id: Option<String>,
@ -458,6 +474,10 @@ pub struct MediaVideo {
#[serde(default = "Vec::new")]
pub caption_entities: Vec<MessageEntity>,
/// `true`, if the message media is covered by a spoiler animation.
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub has_media_spoiler: bool,
/// The unique identifier of a media message group this message belongs
/// to.
pub media_group_id: Option<String>,
@ -506,12 +526,25 @@ pub struct MessageProximityAlertTriggered {
pub proximity_alert_triggered: ProximityAlertTriggered,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct MessageWriteAccessAllowed {
/// Service message: the user allowed the bot added to the attachment menu
/// to write messages.
pub write_access_allowed: WriteAccessAllowed,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct MessageForumTopicCreated {
/// Service message: forum topic created.
pub forum_topic_created: ForumTopicCreated,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct MessageForumTopicEdited {
/// Service message: forum topic edited.
pub forum_topic_edited: ForumTopicEdited,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct MessageForumTopicClosed {
/// Service message: forum topic closed.
@ -524,6 +557,18 @@ pub struct MessageForumTopicReopened {
pub forum_topic_reopened: ForumTopicReopened,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct MessageGeneralForumTopicHidden {
/// Service message: the 'General' forum topic hidden.
pub general_forum_topic_hidden: GeneralForumTopicHidden,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct MessageGeneralForumTopicUnhidden {
/// Service message: the 'General' forum topic unhidden.
pub general_forum_topic_unhidden: GeneralForumTopicUnhidden,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct MessageVideoChatScheduled {
/// Service message: video chat scheduled
@ -767,6 +812,35 @@ mod getters {
}
}
/// Returns `true` if the message media is covered by a spoiler
/// animation.
///
/// Getter for [`MediaPhoto::has_media_spoiler`],
/// [`MediaVideo::has_media_spoiler`] and
/// [`MediaAnimation::has_media_spoiler`].
#[must_use]
pub fn has_media_spoiler(&self) -> bool {
self.common()
.map(|m| match m.media_kind {
MediaKind::Animation(MediaAnimation { has_media_spoiler, .. })
| MediaKind::Photo(MediaPhoto { has_media_spoiler, .. })
| MediaKind::Video(MediaVideo { has_media_spoiler, .. }) => has_media_spoiler,
MediaKind::Audio(_)
| MediaKind::Contact(_)
| MediaKind::Document(_)
| MediaKind::Game(_)
| MediaKind::Venue(_)
| MediaKind::Location(_)
| MediaKind::Poll(_)
| MediaKind::Sticker(_)
| MediaKind::Text(_)
| MediaKind::VideoNote(_)
| MediaKind::Voice(_)
| MediaKind::Migration(_) => false,
})
.unwrap_or(false)
}
#[must_use]
pub fn audio(&self) -> Option<&types::Audio> {
match &self.kind {
@ -1131,6 +1205,8 @@ mod getters {
_ => None,
}
}
// FIXME: add more getters for other types of messages
}
}
@ -1584,6 +1660,8 @@ mod tests {
message_auto_delete_time: None,
photo: None,
pinned_message: None,
has_hidden_members: false,
has_aggressive_anti_spam_enabled: false,
};
assert!(message.from().unwrap().is_anonymous());

View file

@ -11,6 +11,7 @@ use crate::types::KeyboardButton;
/// [Introduction to bots]: https://core.telegram.org/bots#keyboards
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, Default)]
// FIXME: unoption bools?
pub struct KeyboardMarkup {
/// Array of button rows, each represented by an Array of
/// [`KeyboardButton`] objects
@ -18,6 +19,12 @@ pub struct KeyboardMarkup {
/// [`KeyboardButton`]: crate::types::KeyboardButton
pub keyboard: Vec<Vec<KeyboardButton>>,
/// Requests clients to always show the keyboard when the regular keyboard
/// is hidden. Defaults to `false`, in which case the custom keyboard
/// can be hidden and opened with a keyboard icon.
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub is_persistent: bool,
/// Requests clients to resize the keyboard vertically for optimal fit
/// (e.g., make the keyboard smaller if there are just two rows of
/// buttons). Defaults to `false`, in which case the custom keyboard is
@ -56,6 +63,7 @@ impl KeyboardMarkup {
{
Self {
keyboard: keyboard.into_iter().map(<_>::into_iter).map(<_>::collect).collect(),
is_persistent: false,
resize_keyboard: None,
one_time_keyboard: None,
input_field_placeholder: None,
@ -80,6 +88,14 @@ impl KeyboardMarkup {
self
}
/// Sets [`is_persistent`] to `true`.
///
/// [`is_persistent`]: KeyboardMarkup::is_persistent
pub fn persistent(mut self) -> Self {
self.is_persistent = true;
self
}
pub fn resize_keyboard<T>(mut self, val: T) -> Self
where
T: Into<Option<bool>>,

View file

@ -348,6 +348,8 @@ mod test {
photo: None,
pinned_message: None,
message_auto_delete_time: None,
has_hidden_members: false,
has_aggressive_anti_spam_enabled: false,
},
kind: MessageKind::Common(MessageCommon {
from: Some(User {

View file

@ -0,0 +1,9 @@
use serde::{Deserialize, Serialize};
/// This object represents a service message about a user allowing a bot added
/// to the attachment menu to write messages. Currently holds no information.
///
/// [The official docs](https://core.telegram.org/bots/api#writeaccessallowed).
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct WriteAccessAllowed;

View file

@ -260,6 +260,5 @@ fn custom_result() {
type Result = ();
#[derive(BotCommands, Debug, PartialEq)]
enum DefaultCommands {
}
enum DefaultCommands {}
}