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"> <img src="https://img.shields.io/crates/v/teloxide.svg">
</a> </a>
<a href="https://core.telegram.org/bots/api"> <a href="https://core.telegram.org/bots/api">
<img src="https://img.shields.io/badge/API%20coverage-Up%20to%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>
<a href="https://t.me/teloxide"> <a href="https://t.me/teloxide">
<img src="https://img.shields.io/badge/support-t.me%2Fteloxide-blueviolet"> <img src="https://img.shields.io/badge/support-t.me%2Fteloxide-blueviolet">

View file

@ -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]) - `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]) - `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/764
[pr764]: https://github.com/teloxide/teloxide/pull/789
[pr800]: https://github.com/teloxide/teloxide/pull/800 [pr800]: https://github.com/teloxide/teloxide/pull/800
[pr809]: https://github.com/teloxide/teloxide/pull/809
### Deprecated ### Deprecated

View file

@ -12,7 +12,7 @@
<img src="https://img.shields.io/badge/license-MIT-blue.svg"> <img src="https://img.shields.io/badge/license-MIT-blue.svg">
</a> </a>
<a href="https://core.telegram.org/bots/api"> <a href="https://core.telegram.org/bots/api">
<img src="https://img.shields.io/badge/API%20coverage-Up%20to%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>
<a href="https://crates.io/crates/teloxide_core"> <a href="https://crates.io/crates/teloxide_core">
<img src="https://img.shields.io/crates/v/teloxide_core.svg"> <img src="https://img.shields.io/crates/v/teloxide_core.svg">

View file

@ -468,6 +468,11 @@ Schema(
name: "caption_entities", name: "caption_entities",
ty: Option(ArrayOf(RawTy("MessageEntity"))), 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_"), 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( Param(
name: "disable_notification", name: "disable_notification",
@ -780,6 +785,11 @@ Schema(
ty: Option(ArrayOf(RawTy("MessageEntity"))), 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_"), 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( Param(
name: "supports_streaming", name: "supports_streaming",
ty: Option(bool), ty: Option(bool),
@ -891,6 +901,11 @@ Schema(
ty: Option(ArrayOf(RawTy("MessageEntity"))), 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_"), 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( Param(
name: "disable_notification", name: "disable_notification",
ty: Option(bool), ty: Option(bool),
@ -1809,7 +1824,7 @@ Schema(
name: "chat_id", name: "chat_id",
ty: RawTy("Recipient"), ty: RawTy("Recipient"),
descr: Doc(md: "Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)") descr: Doc(md: "Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)")
), ),
Param( Param(
name: "action", name: "action",
ty: RawTy("ChatAction"), 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( Method(
@ -2631,13 +2651,13 @@ Schema(
), ),
Param( Param(
name: "name", name: "name",
ty: String, ty: Option(String),
descr: Doc(md: "Topic name, 1-128 characters") descr: Doc(md: "Topic name, 0-128 characters. If not specified or empty, the current name of the topic will be kept")
), ),
Param( Param(
name: "icon_custom_emoji_id", name: "icon_custom_emoji_id",
ty: String, 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.") 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"), names: ("unpinAllForumTopicMessages", "UnpinAllForumTopicMessages", "unpin_all_forum_topic_messages"),
return_ty: True, 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."), 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", tg_category: "Available methods",
params: [ params: [
Param( 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( Method(
names: ("answerCallbackQuery", "AnswerCallbackQuery", "answer_callback_query"), names: ("answerCallbackQuery", "AnswerCallbackQuery", "answer_callback_query"),
return_ty: True, return_ty: True,

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -675,21 +675,13 @@ impl Requester for Bot {
type EditForumTopic = JsonRequest<payloads::EditForumTopic>; type EditForumTopic = JsonRequest<payloads::EditForumTopic>;
fn edit_forum_topic<C, N, I>( fn edit_forum_topic<C>(&self, chat_id: C, message_thread_id: i32) -> Self::EditForumTopic
&self,
chat_id: C,
message_thread_id: i32,
name: N,
icon_custom_emoji_id: I,
) -> Self::EditForumTopic
where where
C: Into<Recipient>, C: Into<Recipient>,
N: Into<String>,
I: Into<String>,
{ {
Self::EditForumTopic::new( Self::EditForumTopic::new(
self.clone(), 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>; type AnswerCallbackQuery = JsonRequest<payloads::AnswerCallbackQuery>;
fn answer_callback_query<C>(&self, callback_query_id: C) -> Self::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; let mut err_count = 0;
for (path, contents) in files_and_contents { 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) { if normalize_newlines(&old_contents) == normalize_newlines(contents) {
// File is already up to date. // File is already up to date.
continue; continue;
}
} }
err_count += 1; err_count += 1;

View file

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

View file

@ -931,11 +931,9 @@ macro_rules! requester_forward {
(@method edit_forum_topic $body:ident $ty:ident) => { (@method edit_forum_topic $body:ident $ty:ident) => {
type EditForumTopic = $ty![EditForumTopic]; 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>, 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> {
let this = self; 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) => { (@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)) $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) => { (@method answer_callback_query $body:ident $ty:ident) => {
type AnswerCallbackQuery = $ty![AnswerCallbackQuery]; type AnswerCallbackQuery = $ty![AnswerCallbackQuery];

View file

@ -26,6 +26,7 @@ mod ban_chat_member;
mod ban_chat_sender_chat; mod ban_chat_sender_chat;
mod close; mod close;
mod close_forum_topic; mod close_forum_topic;
mod close_general_forum_topic;
mod copy_message; mod copy_message;
mod create_chat_invite_link; mod create_chat_invite_link;
mod create_forum_topic; mod create_forum_topic;
@ -41,6 +42,7 @@ mod delete_sticker_from_set;
mod delete_webhook; mod delete_webhook;
mod edit_chat_invite_link; mod edit_chat_invite_link;
mod edit_forum_topic; mod edit_forum_topic;
mod edit_general_forum_topic;
mod edit_message_caption; mod edit_message_caption;
mod edit_message_caption_inline; mod edit_message_caption_inline;
mod edit_message_live_location; mod edit_message_live_location;
@ -70,12 +72,14 @@ mod get_sticker_set;
mod get_updates; mod get_updates;
mod get_user_profile_photos; mod get_user_profile_photos;
mod get_webhook_info; mod get_webhook_info;
mod hide_general_forum_topic;
mod kick_chat_member; mod kick_chat_member;
mod leave_chat; mod leave_chat;
mod log_out; mod log_out;
mod pin_chat_message; mod pin_chat_message;
mod promote_chat_member; mod promote_chat_member;
mod reopen_forum_topic; mod reopen_forum_topic;
mod reopen_general_forum_topic;
mod restrict_chat_member; mod restrict_chat_member;
mod revoke_chat_invite_link; mod revoke_chat_invite_link;
mod send_animation; mod send_animation;
@ -116,6 +120,7 @@ mod stop_message_live_location_inline;
mod stop_poll; mod stop_poll;
mod unban_chat_member; mod unban_chat_member;
mod unban_chat_sender_chat; mod unban_chat_sender_chat;
mod unhide_general_forum_topic;
mod unpin_all_chat_messages; mod unpin_all_chat_messages;
mod unpin_all_forum_topic_messages; mod unpin_all_forum_topic_messages;
mod unpin_chat_message; 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 ban_chat_sender_chat::{BanChatSenderChat, BanChatSenderChatSetters};
pub use close::{Close, CloseSetters}; pub use close::{Close, CloseSetters};
pub use close_forum_topic::{CloseForumTopic, CloseForumTopicSetters}; pub use close_forum_topic::{CloseForumTopic, CloseForumTopicSetters};
pub use close_general_forum_topic::{CloseGeneralForumTopic, CloseGeneralForumTopicSetters};
pub use copy_message::{CopyMessage, CopyMessageSetters}; pub use copy_message::{CopyMessage, CopyMessageSetters};
pub use create_chat_invite_link::{CreateChatInviteLink, CreateChatInviteLinkSetters}; pub use create_chat_invite_link::{CreateChatInviteLink, CreateChatInviteLinkSetters};
pub use create_forum_topic::{CreateForumTopic, CreateForumTopicSetters}; 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 delete_webhook::{DeleteWebhook, DeleteWebhookSetters};
pub use edit_chat_invite_link::{EditChatInviteLink, EditChatInviteLinkSetters}; pub use edit_chat_invite_link::{EditChatInviteLink, EditChatInviteLinkSetters};
pub use edit_forum_topic::{EditForumTopic, EditForumTopicSetters}; 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::{EditMessageCaption, EditMessageCaptionSetters};
pub use edit_message_caption_inline::{EditMessageCaptionInline, EditMessageCaptionInlineSetters}; pub use edit_message_caption_inline::{EditMessageCaptionInline, EditMessageCaptionInlineSetters};
pub use edit_message_live_location::{EditMessageLiveLocation, EditMessageLiveLocationSetters}; 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_updates::{GetUpdates, GetUpdatesSetters};
pub use get_user_profile_photos::{GetUserProfilePhotos, GetUserProfilePhotosSetters}; pub use get_user_profile_photos::{GetUserProfilePhotos, GetUserProfilePhotosSetters};
pub use get_webhook_info::{GetWebhookInfo, GetWebhookInfoSetters}; pub use get_webhook_info::{GetWebhookInfo, GetWebhookInfoSetters};
pub use hide_general_forum_topic::{HideGeneralForumTopic, HideGeneralForumTopicSetters};
pub use kick_chat_member::{KickChatMember, KickChatMemberSetters}; pub use kick_chat_member::{KickChatMember, KickChatMemberSetters};
pub use leave_chat::{LeaveChat, LeaveChatSetters}; pub use leave_chat::{LeaveChat, LeaveChatSetters};
pub use log_out::{LogOut, LogOutSetters}; pub use log_out::{LogOut, LogOutSetters};
pub use pin_chat_message::{PinChatMessage, PinChatMessageSetters}; pub use pin_chat_message::{PinChatMessage, PinChatMessageSetters};
pub use promote_chat_member::{PromoteChatMember, PromoteChatMemberSetters}; pub use promote_chat_member::{PromoteChatMember, PromoteChatMemberSetters};
pub use reopen_forum_topic::{ReopenForumTopic, ReopenForumTopicSetters}; pub use reopen_forum_topic::{ReopenForumTopic, ReopenForumTopicSetters};
pub use reopen_general_forum_topic::{ReopenGeneralForumTopic, ReopenGeneralForumTopicSetters};
pub use restrict_chat_member::{RestrictChatMember, RestrictChatMemberSetters}; pub use restrict_chat_member::{RestrictChatMember, RestrictChatMemberSetters};
pub use revoke_chat_invite_link::{RevokeChatInviteLink, RevokeChatInviteLinkSetters}; pub use revoke_chat_invite_link::{RevokeChatInviteLink, RevokeChatInviteLinkSetters};
pub use send_animation::{SendAnimation, SendAnimationSetters}; 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 stop_poll::{StopPoll, StopPollSetters};
pub use unban_chat_member::{UnbanChatMember, UnbanChatMemberSetters}; pub use unban_chat_member::{UnbanChatMember, UnbanChatMemberSetters};
pub use unban_chat_sender_chat::{UnbanChatSenderChat, UnbanChatSenderChatSetters}; 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_chat_messages::{UnpinAllChatMessages, UnpinAllChatMessagesSetters};
pub use unpin_all_forum_topic_messages::{ pub use unpin_all_forum_topic_messages::{
UnpinAllForumTopicMessages, UnpinAllForumTopicMessagesSetters, 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], pub chat_id: Recipient [into],
/// Unique identifier for the target message thread of the forum topic /// Unique identifier for the target message thread of the forum topic
pub message_thread_id: i32, 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], 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], 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, pub parse_mode: ParseMode,
/// List of special entities that appear in the photo caption, which can be specified instead of _parse\_mode_ /// List of special entities that appear in the photo caption, which can be specified instead of _parse\_mode_
pub caption_entities: Vec<MessageEntity> [collect], 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. /// Sends the message [silently]. Users will receive a notification with no sound.
/// ///
/// [silently]: https://telegram.org/blog/channels-2-0#silent-messages /// [silently]: https://telegram.org/blog/channels-2-0#silent-messages

View file

@ -29,5 +29,9 @@ impl_payload! {
/// [video notes]: crate::payloads::SendVideoNote /// [video notes]: crate::payloads::SendVideoNote
pub action: ChatAction, 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, pub parse_mode: ParseMode,
/// List of special entities that appear in the photo caption, which can be specified instead of _parse\_mode_ /// List of special entities that appear in the photo caption, which can be specified instead of _parse\_mode_
pub caption_entities: Vec<MessageEntity> [collect], 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. /// Sends the message [silently]. Users will receive a notification with no sound.
/// ///
/// [silently]: https://telegram.org/blog/channels-2-0#silent-messages /// [silently]: https://telegram.org/blog/channels-2-0#silent-messages

View file

@ -43,6 +43,8 @@ impl_payload! {
pub parse_mode: ParseMode, pub parse_mode: ParseMode,
/// List of special entities that appear in the caption, which can be specified instead of _parse\_mode_ /// List of special entities that appear in the caption, which can be specified instead of _parse\_mode_
pub caption_entities: Vec<MessageEntity> [collect], 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 /// Pass _True_, if the uploaded video is suitable for streaming
pub supports_streaming: bool, pub supports_streaming: bool,
/// Sends the message [silently]. Users will receive a notification with no sound. /// 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 _, AddStickerToSetSetters as _, AnswerCallbackQuerySetters as _, AnswerInlineQuerySetters as _,
AnswerPreCheckoutQuerySetters as _, AnswerShippingQuerySetters as _, AnswerPreCheckoutQuerySetters as _, AnswerShippingQuerySetters as _,
AnswerWebAppQuerySetters as _, ApproveChatJoinRequestSetters as _, BanChatMemberSetters as _, AnswerWebAppQuerySetters as _, ApproveChatJoinRequestSetters as _, BanChatMemberSetters as _,
BanChatSenderChatSetters as _, CloseForumTopicSetters as _, CloseSetters as _, BanChatSenderChatSetters as _, CloseForumTopicSetters as _, CloseGeneralForumTopicSetters as _,
CopyMessageSetters as _, CreateChatInviteLinkSetters as _, CreateForumTopicSetters as _, CloseSetters as _, CopyMessageSetters as _, CreateChatInviteLinkSetters as _,
CreateInvoiceLinkSetters as _, CreateNewStickerSetSetters as _, CreateForumTopicSetters as _, CreateInvoiceLinkSetters as _, CreateNewStickerSetSetters as _,
DeclineChatJoinRequestSetters as _, DeleteChatPhotoSetters as _, DeclineChatJoinRequestSetters as _, DeleteChatPhotoSetters as _,
DeleteChatStickerSetSetters as _, DeleteForumTopicSetters as _, DeleteMessageSetters as _, DeleteChatStickerSetSetters as _, DeleteForumTopicSetters as _, DeleteMessageSetters as _,
DeleteMyCommandsSetters as _, DeleteStickerFromSetSetters as _, DeleteWebhookSetters as _, DeleteMyCommandsSetters as _, DeleteStickerFromSetSetters as _, DeleteWebhookSetters as _,
EditChatInviteLinkSetters as _, EditForumTopicSetters as _, EditChatInviteLinkSetters as _, EditForumTopicSetters as _, EditGeneralForumTopicSetters as _,
EditMessageCaptionInlineSetters as _, EditMessageCaptionSetters as _, EditMessageCaptionInlineSetters as _, EditMessageCaptionSetters as _,
EditMessageLiveLocationInlineSetters as _, EditMessageLiveLocationSetters as _, EditMessageLiveLocationInlineSetters as _, EditMessageLiveLocationSetters as _,
EditMessageMediaInlineSetters as _, EditMessageMediaSetters as _, EditMessageMediaInlineSetters as _, EditMessageMediaSetters as _,
@ -23,12 +23,13 @@ pub use crate::payloads::{
GetCustomEmojiStickersSetters as _, GetFileSetters as _, GetForumTopicIconStickersSetters as _, GetCustomEmojiStickersSetters as _, GetFileSetters as _, GetForumTopicIconStickersSetters as _,
GetGameHighScoresSetters as _, GetMeSetters as _, GetMyCommandsSetters as _, GetGameHighScoresSetters as _, GetMeSetters as _, GetMyCommandsSetters as _,
GetMyDefaultAdministratorRightsSetters as _, GetStickerSetSetters as _, GetUpdatesSetters as _, GetMyDefaultAdministratorRightsSetters as _, GetStickerSetSetters as _, GetUpdatesSetters as _,
GetUserProfilePhotosSetters as _, GetWebhookInfoSetters as _, KickChatMemberSetters as _, GetUserProfilePhotosSetters as _, GetWebhookInfoSetters as _,
LeaveChatSetters as _, LogOutSetters as _, PinChatMessageSetters as _, HideGeneralForumTopicSetters as _, KickChatMemberSetters as _, LeaveChatSetters as _,
PromoteChatMemberSetters as _, ReopenForumTopicSetters as _, RestrictChatMemberSetters as _, LogOutSetters as _, PinChatMessageSetters as _, PromoteChatMemberSetters as _,
RevokeChatInviteLinkSetters as _, SendAnimationSetters as _, SendAudioSetters as _, ReopenForumTopicSetters as _, ReopenGeneralForumTopicSetters as _,
SendChatActionSetters as _, SendContactSetters as _, SendDiceSetters as _, RestrictChatMemberSetters as _, RevokeChatInviteLinkSetters as _, SendAnimationSetters as _,
SendDocumentSetters as _, SendGameSetters as _, SendInvoiceSetters as _, SendAudioSetters as _, SendChatActionSetters as _, SendContactSetters as _,
SendDiceSetters as _, SendDocumentSetters as _, SendGameSetters as _, SendInvoiceSetters as _,
SendLocationSetters as _, SendMediaGroupSetters as _, SendMessageSetters as _, SendLocationSetters as _, SendMediaGroupSetters as _, SendMessageSetters as _,
SendPhotoSetters as _, SendPollSetters as _, SendStickerSetters as _, SendVenueSetters as _, SendPhotoSetters as _, SendPollSetters as _, SendStickerSetters as _, SendVenueSetters as _,
SendVideoNoteSetters as _, SendVideoSetters as _, SendVoiceSetters as _, SendVideoNoteSetters as _, SendVideoSetters as _, SendVoiceSetters as _,
@ -40,6 +41,7 @@ pub use crate::payloads::{
SetStickerPositionInSetSetters as _, SetStickerSetThumbSetters as _, SetWebhookSetters as _, SetStickerPositionInSetSetters as _, SetStickerSetThumbSetters as _, SetWebhookSetters as _,
StopMessageLiveLocationInlineSetters as _, StopMessageLiveLocationSetters as _, StopMessageLiveLocationInlineSetters as _, StopMessageLiveLocationSetters as _,
StopPollSetters as _, UnbanChatMemberSetters as _, UnbanChatSenderChatSetters as _, StopPollSetters as _, UnbanChatMemberSetters as _, UnbanChatSenderChatSetters as _,
UnpinAllChatMessagesSetters as _, UnpinAllForumTopicMessagesSetters as _, UnhideGeneralForumTopicSetters as _, UnpinAllChatMessagesSetters as _,
UnpinChatMessageSetters as _, UploadStickerFileSetters 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>; type EditForumTopic: Request<Payload = EditForumTopic, Err = Self::Err>;
/// For Telegram documentation see [`EditForumTopic`]. /// For Telegram documentation see [`EditForumTopic`].
fn edit_forum_topic<C, N, I>( fn edit_forum_topic<C>(&self, chat_id: C, message_thread_id: i32) -> Self::EditForumTopic
&self,
chat_id: C,
message_thread_id: i32,
name: N,
icon_custom_emoji_id: I,
) -> Self::EditForumTopic
where where
C: Into<Recipient>, C: Into<Recipient>;
N: Into<String>,
I: Into<String>;
type CloseForumTopic: Request<Payload = CloseForumTopic, Err = Self::Err>; type CloseForumTopic: Request<Payload = CloseForumTopic, Err = Self::Err>;
@ -726,6 +718,42 @@ pub trait Requester {
where where
C: Into<Recipient>; 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>; type AnswerCallbackQuery: Request<Payload = AnswerCallbackQuery, Err = Self::Err>;
/// For Telegram documentation see [`AnswerCallbackQuery`]. /// For Telegram documentation see [`AnswerCallbackQuery`].
@ -1177,6 +1205,11 @@ macro_rules! forward_all {
reopen_forum_topic, reopen_forum_topic,
delete_forum_topic, delete_forum_topic,
unpin_all_forum_topic_messages, 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, answer_callback_query,
set_my_commands, set_my_commands,
get_my_commands, get_my_commands,

View file

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

View file

@ -30,6 +30,21 @@ pub struct Chat {
/// ///
/// [`GetChat`]: crate::payloads::GetChat /// [`GetChat`]: crate::payloads::GetChat
pub message_auto_delete_time: Option<u32>, 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] #[serde_with_macros::skip_serializing_none]
@ -579,6 +594,8 @@ mod tests {
photo: None, photo: None,
pinned_message: None, pinned_message: None,
message_auto_delete_time: 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(); let actual = from_str(r#"{"id":-1,"type":"channel","username":"channel_name"}"#).unwrap();
assert_eq!(expected, actual); assert_eq!(expected, actual);
@ -601,6 +618,8 @@ mod tests {
photo: None, photo: None,
pinned_message: None, pinned_message: None,
message_auto_delete_time: 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"}"#) from_str(r#"{"id":0,"type":"private","username":"username","first_name":"Anon"}"#)
.unwrap() .unwrap()
@ -623,6 +642,8 @@ mod tests {
photo: None, photo: None,
pinned_message: None, pinned_message: None,
message_auto_delete_time: None, message_auto_delete_time: None,
has_hidden_members: false,
has_aggressive_anti_spam_enabled: false,
}; };
let json = to_string(&chat).unwrap(); 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 /// This object represents a service message about a forum topic closed in the
/// chat. Currently holds no information. /// 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] #[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ForumTopicClosed; 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 /// This object represents a service message about a forum topic reopened in the
/// chat. Currently holds no information. /// 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] #[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ForumTopicReopened; 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 /// List of special entities that appear in the caption, which can be
/// specified instead of `parse_mode`. /// specified instead of `parse_mode`.
pub caption_entities: Option<Vec<MessageEntity>>, 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 { impl InputMediaPhoto {
pub const fn new(media: InputFile) -> Self { 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 { pub fn media(mut self, val: InputFile) -> Self {
@ -73,6 +77,14 @@ impl InputMediaPhoto {
self.caption_entities = Some(val.into_iter().collect()); self.caption_entities = Some(val.into_iter().collect());
self 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. /// Represents a video to be sent.
@ -117,6 +129,10 @@ pub struct InputMediaVideo {
/// Pass `true`, if the uploaded video is suitable for streaming. /// Pass `true`, if the uploaded video is suitable for streaming.
pub supports_streaming: Option<bool>, 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 { impl InputMediaVideo {
@ -131,6 +147,7 @@ impl InputMediaVideo {
height: None, height: None,
duration: None, duration: None,
supports_streaming: None, supports_streaming: None,
has_spoiler: false,
} }
} }
@ -184,6 +201,14 @@ impl InputMediaVideo {
self.supports_streaming = Some(val); self.supports_streaming = Some(val);
self 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 /// Represents an animation file (GIF or H.264/MPEG-4 AVC video without
@ -226,6 +251,11 @@ pub struct InputMediaAnimation {
/// Animation duration. /// Animation duration.
pub duration: Option<u16>, 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 { impl InputMediaAnimation {
@ -239,6 +269,7 @@ impl InputMediaAnimation {
height: None, height: None,
duration: None, duration: None,
caption_entities: None, caption_entities: None,
has_spoiler: false,
} }
} }
@ -287,6 +318,14 @@ impl InputMediaAnimation {
self.duration = Some(val); self.duration = Some(val);
self 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. /// Represents an audio file to be treated as music to be sent.
@ -534,6 +573,7 @@ mod tests {
caption: None, caption: None,
parse_mode: None, parse_mode: None,
caption_entities: None, caption_entities: None,
has_spoiler: false,
}); });
let actual_json = serde_json::to_string(&photo).unwrap(); let actual_json = serde_json::to_string(&photo).unwrap();
@ -553,6 +593,7 @@ mod tests {
duration: None, duration: None,
supports_streaming: None, supports_streaming: None,
caption_entities: None, caption_entities: None,
has_spoiler: false,
}); });
let actual_json = serde_json::to_string(&video).unwrap(); let actual_json = serde_json::to_string(&video).unwrap();
@ -571,6 +612,7 @@ mod tests {
height: None, height: None,
duration: None, duration: None,
caption_entities: None, caption_entities: None,
has_spoiler: false,
}); });
let actual_json = serde_json::to_string(&video).unwrap(); let actual_json = serde_json::to_string(&video).unwrap();

View file

@ -6,11 +6,12 @@ use url::Url;
use crate::types::{ use crate::types::{
Animation, Audio, BareChatId, Chat, ChatId, Contact, Dice, Document, ForumTopicClosed, 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, MessageAutoDeleteTimerChanged, MessageEntity, MessageEntityRef, MessageId, PassportData,
PhotoSize, Poll, ProximityAlertTriggered, Sticker, SuccessfulPayment, True, User, Venue, Video, PhotoSize, Poll, ProximityAlertTriggered, Sticker, SuccessfulPayment, True, User, Venue, Video,
VideoChatEnded, VideoChatParticipantsInvited, VideoChatScheduled, VideoChatStarted, VideoNote, VideoChatEnded, VideoChatParticipantsInvited, VideoChatScheduled, VideoChatStarted, VideoNote,
Voice, WebAppData, Voice, WebAppData, WriteAccessAllowed,
}; };
/// This object represents a message. /// This object represents a message.
@ -41,6 +42,9 @@ pub struct Message {
pub kind: MessageKind, 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)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)] #[serde(untagged)]
pub enum MessageKind { pub enum MessageKind {
@ -58,12 +62,16 @@ pub enum MessageKind {
Invoice(MessageInvoice), Invoice(MessageInvoice),
SuccessfulPayment(MessageSuccessfulPayment), SuccessfulPayment(MessageSuccessfulPayment),
ConnectedWebsite(MessageConnectedWebsite), ConnectedWebsite(MessageConnectedWebsite),
WriteAccessAllowed(MessageWriteAccessAllowed),
PassportData(MessagePassportData), PassportData(MessagePassportData),
Dice(MessageDice), Dice(MessageDice),
ProximityAlertTriggered(MessageProximityAlertTriggered), ProximityAlertTriggered(MessageProximityAlertTriggered),
ForumTopicCreated(ForumTopicCreated), ForumTopicCreated(MessageForumTopicCreated),
ForumTopicClosed(ForumTopicClosed), ForumTopicEdited(MessageForumTopicEdited),
ForumTopicReopened(ForumTopicReopened), ForumTopicClosed(MessageForumTopicClosed),
ForumTopicReopened(MessageForumTopicReopened),
GeneralForumTopicHidden(MessageGeneralForumTopicHidden),
GeneralForumTopicUnhidden(MessageGeneralForumTopicUnhidden),
VideoChatScheduled(MessageVideoChatScheduled), VideoChatScheduled(MessageVideoChatScheduled),
VideoChatStarted(MessageVideoChatStarted), VideoChatStarted(MessageVideoChatStarted),
VideoChatEnded(MessageVideoChatEnded), VideoChatEnded(MessageVideoChatEnded),
@ -339,6 +347,10 @@ pub struct MediaAnimation {
/// bot commands, etc. that appear in the caption. /// bot commands, etc. that appear in the caption.
#[serde(default = "Vec::new")] #[serde(default = "Vec::new")]
pub caption_entities: Vec<MessageEntity>, 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 // Note: for backward compatibility telegram also sends `document` field, but we ignore it
} }
@ -415,6 +427,10 @@ pub struct MediaPhoto {
#[serde(default = "Vec::new")] #[serde(default = "Vec::new")]
pub caption_entities: Vec<MessageEntity>, 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 /// The unique identifier of a media message group this message belongs
/// to. /// to.
pub media_group_id: Option<String>, pub media_group_id: Option<String>,
@ -458,6 +474,10 @@ pub struct MediaVideo {
#[serde(default = "Vec::new")] #[serde(default = "Vec::new")]
pub caption_entities: Vec<MessageEntity>, 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 /// The unique identifier of a media message group this message belongs
/// to. /// to.
pub media_group_id: Option<String>, pub media_group_id: Option<String>,
@ -506,12 +526,25 @@ pub struct MessageProximityAlertTriggered {
pub proximity_alert_triggered: ProximityAlertTriggered, 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)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct MessageForumTopicCreated { pub struct MessageForumTopicCreated {
/// Service message: forum topic created. /// Service message: forum topic created.
pub forum_topic_created: ForumTopicCreated, 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)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct MessageForumTopicClosed { pub struct MessageForumTopicClosed {
/// Service message: forum topic closed. /// Service message: forum topic closed.
@ -524,6 +557,18 @@ pub struct MessageForumTopicReopened {
pub forum_topic_reopened: ForumTopicReopened, 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)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct MessageVideoChatScheduled { pub struct MessageVideoChatScheduled {
/// Service message: video chat scheduled /// 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] #[must_use]
pub fn audio(&self) -> Option<&types::Audio> { pub fn audio(&self) -> Option<&types::Audio> {
match &self.kind { match &self.kind {
@ -1131,6 +1205,8 @@ mod getters {
_ => None, _ => None,
} }
} }
// FIXME: add more getters for other types of messages
} }
} }
@ -1584,6 +1660,8 @@ mod tests {
message_auto_delete_time: None, message_auto_delete_time: None,
photo: None, photo: None,
pinned_message: None, pinned_message: None,
has_hidden_members: false,
has_aggressive_anti_spam_enabled: false,
}; };
assert!(message.from().unwrap().is_anonymous()); 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 /// [Introduction to bots]: https://core.telegram.org/bots#keyboards
#[serde_with_macros::skip_serializing_none] #[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, Default)] #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, Default)]
// FIXME: unoption bools?
pub struct KeyboardMarkup { pub struct KeyboardMarkup {
/// Array of button rows, each represented by an Array of /// Array of button rows, each represented by an Array of
/// [`KeyboardButton`] objects /// [`KeyboardButton`] objects
@ -18,6 +19,12 @@ pub struct KeyboardMarkup {
/// [`KeyboardButton`]: crate::types::KeyboardButton /// [`KeyboardButton`]: crate::types::KeyboardButton
pub keyboard: Vec<Vec<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 /// Requests clients to resize the keyboard vertically for optimal fit
/// (e.g., make the keyboard smaller if there are just two rows of /// (e.g., make the keyboard smaller if there are just two rows of
/// buttons). Defaults to `false`, in which case the custom keyboard is /// buttons). Defaults to `false`, in which case the custom keyboard is
@ -56,6 +63,7 @@ impl KeyboardMarkup {
{ {
Self { Self {
keyboard: keyboard.into_iter().map(<_>::into_iter).map(<_>::collect).collect(), keyboard: keyboard.into_iter().map(<_>::into_iter).map(<_>::collect).collect(),
is_persistent: false,
resize_keyboard: None, resize_keyboard: None,
one_time_keyboard: None, one_time_keyboard: None,
input_field_placeholder: None, input_field_placeholder: None,
@ -80,6 +88,14 @@ impl KeyboardMarkup {
self 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 pub fn resize_keyboard<T>(mut self, val: T) -> Self
where where
T: Into<Option<bool>>, T: Into<Option<bool>>,

View file

@ -348,6 +348,8 @@ mod test {
photo: None, photo: None,
pinned_message: None, pinned_message: None,
message_auto_delete_time: None, message_auto_delete_time: None,
has_hidden_members: false,
has_aggressive_anti_spam_enabled: false,
}, },
kind: MessageKind::Common(MessageCommon { kind: MessageKind::Common(MessageCommon {
from: Some(User { 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 = (); type Result = ();
#[derive(BotCommands, Debug, PartialEq)] #[derive(BotCommands, Debug, PartialEq)]
enum DefaultCommands { enum DefaultCommands {}
}
} }