diff --git a/README.md b/README.md
index f5c23baf..391f9345 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@
-
+
diff --git a/crates/teloxide-core/CHANGELOG.md b/crates/teloxide-core/CHANGELOG.md
index ae3f911e..20a730fc 100644
--- a/crates/teloxide-core/CHANGELOG.md
+++ b/crates/teloxide-core/CHANGELOG.md
@@ -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
diff --git a/crates/teloxide-core/README.md b/crates/teloxide-core/README.md
index d4c80ba5..c06d2c43 100644
--- a/crates/teloxide-core/README.md
+++ b/crates/teloxide-core/README.md
@@ -12,7 +12,7 @@
-
+
diff --git a/crates/teloxide-core/schema.ron b/crates/teloxide-core/schema.ron
index d814072e..8d209588 100644
--- a/crates/teloxide-core/schema.ron
+++ b/crates/teloxide-core/schema.ron
@@ -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,
diff --git a/crates/teloxide-core/src/adaptors/auto_send.rs b/crates/teloxide-core/src/adaptors/auto_send.rs
index 2bd9c075..a613d486 100644
--- a/crates/teloxide-core/src/adaptors/auto_send.rs
+++ b/crates/teloxide-core/src/adaptors/auto_send.rs
@@ -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,
diff --git a/crates/teloxide-core/src/adaptors/cache_me.rs b/crates/teloxide-core/src/adaptors/cache_me.rs
index c2b3537f..ae940f37 100644
--- a/crates/teloxide-core/src/adaptors/cache_me.rs
+++ b/crates/teloxide-core/src/adaptors/cache_me.rs
@@ -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,
diff --git a/crates/teloxide-core/src/adaptors/erased.rs b/crates/teloxide-core/src/adaptors/erased.rs
index 2041d22c..4d06a22e 100644
--- a/crates/teloxide-core/src/adaptors/erased.rs
+++ b/crates/teloxide-core/src/adaptors/erased.rs
@@ -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,
diff --git a/crates/teloxide-core/src/adaptors/parse_mode.rs b/crates/teloxide-core/src/adaptors/parse_mode.rs
index d69c275b..1d915c9a 100644
--- a/crates/teloxide-core/src/adaptors/parse_mode.rs
+++ b/crates/teloxide-core/src/adaptors/parse_mode.rs
@@ -149,6 +149,11 @@ impl Requester for DefaultParseMode {
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,
diff --git a/crates/teloxide-core/src/adaptors/throttle/requester_impl.rs b/crates/teloxide-core/src/adaptors/throttle/requester_impl.rs
index a0d5965c..02b747e7 100644
--- a/crates/teloxide-core/src/adaptors/throttle/requester_impl.rs
+++ b/crates/teloxide-core/src/adaptors/throttle/requester_impl.rs
@@ -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,
diff --git a/crates/teloxide-core/src/adaptors/trace.rs b/crates/teloxide-core/src/adaptors/trace.rs
index 189e1c96..4dca2bc5 100644
--- a/crates/teloxide-core/src/adaptors/trace.rs
+++ b/crates/teloxide-core/src/adaptors/trace.rs
@@ -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,
diff --git a/crates/teloxide-core/src/bot/api.rs b/crates/teloxide-core/src/bot/api.rs
index 8a4b8140..7f1b4d32 100644
--- a/crates/teloxide-core/src/bot/api.rs
+++ b/crates/teloxide-core/src/bot/api.rs
@@ -675,21 +675,13 @@ impl Requester for Bot {
type EditForumTopic = JsonRequest;
- fn edit_forum_topic(
- &self,
- chat_id: C,
- message_thread_id: i32,
- name: N,
- icon_custom_emoji_id: I,
- ) -> Self::EditForumTopic
+ fn edit_forum_topic(&self, chat_id: C, message_thread_id: i32) -> Self::EditForumTopic
where
C: Into,
- N: Into,
- I: Into,
{
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;
+
+ fn edit_general_forum_topic(&self, chat_id: C, name: N) -> Self::EditGeneralForumTopic
+ where
+ C: Into,
+ N: Into,
+ {
+ Self::EditGeneralForumTopic::new(
+ self.clone(),
+ payloads::EditGeneralForumTopic::new(chat_id, name),
+ )
+ }
+
+ type CloseGeneralForumTopic = JsonRequest;
+
+ fn close_general_forum_topic(&self, chat_id: C) -> Self::CloseGeneralForumTopic
+ where
+ C: Into,
+ {
+ Self::CloseGeneralForumTopic::new(
+ self.clone(),
+ payloads::CloseGeneralForumTopic::new(chat_id),
+ )
+ }
+
+ type ReopenGeneralForumTopic = JsonRequest;
+
+ fn reopen_general_forum_topic(&self, chat_id: C) -> Self::ReopenGeneralForumTopic
+ where
+ C: Into,
+ {
+ Self::ReopenGeneralForumTopic::new(
+ self.clone(),
+ payloads::ReopenGeneralForumTopic::new(chat_id),
+ )
+ }
+
+ type HideGeneralForumTopic = JsonRequest;
+
+ fn hide_general_forum_topic(&self, chat_id: C) -> Self::HideGeneralForumTopic
+ where
+ C: Into,
+ {
+ Self::HideGeneralForumTopic::new(
+ self.clone(),
+ payloads::HideGeneralForumTopic::new(chat_id),
+ )
+ }
+
+ type UnhideGeneralForumTopic = JsonRequest;
+
+ fn unhide_general_forum_topic(&self, chat_id: C) -> Self::UnhideGeneralForumTopic
+ where
+ C: Into,
+ {
+ Self::UnhideGeneralForumTopic::new(
+ self.clone(),
+ payloads::UnhideGeneralForumTopic::new(chat_id),
+ )
+ }
+
type AnswerCallbackQuery = JsonRequest;
fn answer_callback_query(&self, callback_query_id: C) -> Self::AnswerCallbackQuery
diff --git a/crates/teloxide-core/src/codegen.rs b/crates/teloxide-core/src/codegen.rs
index 5e90823e..fe956bce 100644
--- a/crates/teloxide-core/src/codegen.rs
+++ b/crates/teloxide-core/src/codegen.rs
@@ -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;
diff --git a/crates/teloxide-core/src/lib.rs b/crates/teloxide-core/src/lib.rs
index 7ac35e29..d76dac3b 100644
--- a/crates/teloxide-core/src/lib.rs
+++ b/crates/teloxide-core/src/lib.rs
@@ -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
diff --git a/crates/teloxide-core/src/local_macros.rs b/crates/teloxide-core/src/local_macros.rs
index 15884d21..95b31eb0 100644
--- a/crates/teloxide-core/src/local_macros.rs
+++ b/crates/teloxide-core/src/local_macros.rs
@@ -931,11 +931,9 @@ macro_rules! requester_forward {
(@method edit_forum_topic $body:ident $ty:ident) => {
type EditForumTopic = $ty![EditForumTopic];
- fn edit_forum_topic(&self, chat_id: C, message_thread_id: i32, name: N, icon_custom_emoji_id: I) -> Self::EditForumTopic where C: Into,
- N: Into,
- I: Into {
+ fn edit_forum_topic(&self, chat_id: C, message_thread_id: i32) -> Self::EditForumTopic where C: Into {
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(&self, chat_id: C, name: N) -> Self::EditGeneralForumTopic where C: Into,
+ N: Into {
+ 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(&self, chat_id: C) -> Self::CloseGeneralForumTopic where C: Into {
+ 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(&self, chat_id: C) -> Self::ReopenGeneralForumTopic where C: Into {
+ 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(&self, chat_id: C) -> Self::HideGeneralForumTopic where C: Into {
+ 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(&self, chat_id: C) -> Self::UnhideGeneralForumTopic where C: Into {
+ let this = self;
+ $body!(unhide_general_forum_topic this (chat_id: C))
+ }
+ };
(@method answer_callback_query $body:ident $ty:ident) => {
type AnswerCallbackQuery = $ty![AnswerCallbackQuery];
diff --git a/crates/teloxide-core/src/payloads.rs b/crates/teloxide-core/src/payloads.rs
index b74b1fb4..2f4d7e08 100644
--- a/crates/teloxide-core/src/payloads.rs
+++ b/crates/teloxide-core/src/payloads.rs
@@ -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,
diff --git a/crates/teloxide-core/src/payloads/close_general_forum_topic.rs b/crates/teloxide-core/src/payloads/close_general_forum_topic.rs
new file mode 100644
index 00000000..d211f0d8
--- /dev/null
+++ b/crates/teloxide-core/src/payloads/close_general_forum_topic.rs
@@ -0,0 +1,16 @@
+//! Generated by `codegen_payloads`, do not edit by hand.
+
+use serde::Serialize;
+
+use crate::types::{Recipient, True};
+
+impl_payload! {
+ /// Use this method to 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],
+ }
+ }
+}
diff --git a/crates/teloxide-core/src/payloads/edit_forum_topic.rs b/crates/teloxide-core/src/payloads/edit_forum_topic.rs
index 8cbcf916..dd311dea 100644
--- a/crates/teloxide-core/src/payloads/edit_forum_topic.rs
+++ b/crates/teloxide-core/src/payloads/edit_forum_topic.rs
@@ -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],
}
}
diff --git a/crates/teloxide-core/src/payloads/edit_general_forum_topic.rs b/crates/teloxide-core/src/payloads/edit_general_forum_topic.rs
new file mode 100644
index 00000000..3f593e7c
--- /dev/null
+++ b/crates/teloxide-core/src/payloads/edit_general_forum_topic.rs
@@ -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],
+ }
+ }
+}
diff --git a/crates/teloxide-core/src/payloads/hide_general_forum_topic.rs b/crates/teloxide-core/src/payloads/hide_general_forum_topic.rs
new file mode 100644
index 00000000..014061a7
--- /dev/null
+++ b/crates/teloxide-core/src/payloads/hide_general_forum_topic.rs
@@ -0,0 +1,16 @@
+//! Generated by `codegen_payloads`, do not edit by hand.
+
+use serde::Serialize;
+
+use crate::types::{Recipient, True};
+
+impl_payload! {
+ /// Use this method to 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],
+ }
+ }
+}
diff --git a/crates/teloxide-core/src/payloads/reopen_general_forum_topic.rs b/crates/teloxide-core/src/payloads/reopen_general_forum_topic.rs
new file mode 100644
index 00000000..09fe1f2b
--- /dev/null
+++ b/crates/teloxide-core/src/payloads/reopen_general_forum_topic.rs
@@ -0,0 +1,16 @@
+//! Generated by `codegen_payloads`, do not edit by hand.
+
+use serde::Serialize;
+
+use crate::types::{Recipient, True};
+
+impl_payload! {
+ /// Use this method to 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],
+ }
+ }
+}
diff --git a/crates/teloxide-core/src/payloads/send_animation.rs b/crates/teloxide-core/src/payloads/send_animation.rs
index b6bc5b7f..3c4e487d 100644
--- a/crates/teloxide-core/src/payloads/send_animation.rs
+++ b/crates/teloxide-core/src/payloads/send_animation.rs
@@ -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 [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
diff --git a/crates/teloxide-core/src/payloads/send_chat_action.rs b/crates/teloxide-core/src/payloads/send_chat_action.rs
index a3acd43e..50b4c3db 100644
--- a/crates/teloxide-core/src/payloads/send_chat_action.rs
+++ b/crates/teloxide-core/src/payloads/send_chat_action.rs
@@ -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,
+ }
}
}
diff --git a/crates/teloxide-core/src/payloads/send_photo.rs b/crates/teloxide-core/src/payloads/send_photo.rs
index 77399f1c..70e97bea 100644
--- a/crates/teloxide-core/src/payloads/send_photo.rs
+++ b/crates/teloxide-core/src/payloads/send_photo.rs
@@ -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 [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
diff --git a/crates/teloxide-core/src/payloads/send_video.rs b/crates/teloxide-core/src/payloads/send_video.rs
index 9eb0f307..2723e6e4 100644
--- a/crates/teloxide-core/src/payloads/send_video.rs
+++ b/crates/teloxide-core/src/payloads/send_video.rs
@@ -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 [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.
diff --git a/crates/teloxide-core/src/payloads/setters.rs b/crates/teloxide-core/src/payloads/setters.rs
index d111970f..ac2a626f 100644
--- a/crates/teloxide-core/src/payloads/setters.rs
+++ b/crates/teloxide-core/src/payloads/setters.rs
@@ -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 _,
};
diff --git a/crates/teloxide-core/src/payloads/unhide_general_forum_topic.rs b/crates/teloxide-core/src/payloads/unhide_general_forum_topic.rs
new file mode 100644
index 00000000..640e4737
--- /dev/null
+++ b/crates/teloxide-core/src/payloads/unhide_general_forum_topic.rs
@@ -0,0 +1,16 @@
+//! Generated by `codegen_payloads`, do not edit by hand.
+
+use serde::Serialize;
+
+use crate::types::{Recipient, True};
+
+impl_payload! {
+ /// Use this method to 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],
+ }
+ }
+}
diff --git a/crates/teloxide-core/src/requests/requester.rs b/crates/teloxide-core/src/requests/requester.rs
index 974c4f66..5c0c64d5 100644
--- a/crates/teloxide-core/src/requests/requester.rs
+++ b/crates/teloxide-core/src/requests/requester.rs
@@ -682,17 +682,9 @@ pub trait Requester {
type EditForumTopic: Request;
/// For Telegram documentation see [`EditForumTopic`].
- fn edit_forum_topic(
- &self,
- chat_id: C,
- message_thread_id: i32,
- name: N,
- icon_custom_emoji_id: I,
- ) -> Self::EditForumTopic
+ fn edit_forum_topic(&self, chat_id: C, message_thread_id: i32) -> Self::EditForumTopic
where
- C: Into,
- N: Into,
- I: Into;
+ C: Into;
type CloseForumTopic: Request;
@@ -726,6 +718,42 @@ pub trait Requester {
where
C: Into;
+ type EditGeneralForumTopic: Request;
+
+ /// For Telegram documentation see [`EditGeneralForumTopic`].
+ fn edit_general_forum_topic(&self, chat_id: C, name: N) -> Self::EditGeneralForumTopic
+ where
+ C: Into,
+ N: Into;
+
+ type CloseGeneralForumTopic: Request;
+
+ /// For Telegram documentation see [`CloseGeneralForumTopic`].
+ fn close_general_forum_topic(&self, chat_id: C) -> Self::CloseGeneralForumTopic
+ where
+ C: Into;
+
+ type ReopenGeneralForumTopic: Request;
+
+ /// For Telegram documentation see [`ReopenGeneralForumTopic`].
+ fn reopen_general_forum_topic(&self, chat_id: C) -> Self::ReopenGeneralForumTopic
+ where
+ C: Into;
+
+ type HideGeneralForumTopic: Request;
+
+ /// For Telegram documentation see [`HideGeneralForumTopic`].
+ fn hide_general_forum_topic(&self, chat_id: C) -> Self::HideGeneralForumTopic
+ where
+ C: Into;
+
+ type UnhideGeneralForumTopic: Request;
+
+ /// For Telegram documentation see [`UnhideGeneralForumTopic`].
+ fn unhide_general_forum_topic(&self, chat_id: C) -> Self::UnhideGeneralForumTopic
+ where
+ C: Into;
+
type AnswerCallbackQuery: Request;
/// 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,
diff --git a/crates/teloxide-core/src/types.rs b/crates/teloxide-core/src/types.rs
index 533f7afc..420e8fee 100644
--- a/crates/teloxide-core/src/types.rs
+++ b/crates/teloxide-core/src/types.rs
@@ -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;
diff --git a/crates/teloxide-core/src/types/chat.rs b/crates/teloxide-core/src/types/chat.rs
index 9c9e31e6..38da326b 100644
--- a/crates/teloxide-core/src/types/chat.rs
+++ b/crates/teloxide-core/src/types/chat.rs
@@ -30,6 +30,21 @@ pub struct Chat {
///
/// [`GetChat`]: crate::payloads::GetChat
pub message_auto_delete_time: Option,
+
+ /// `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();
diff --git a/crates/teloxide-core/src/types/forum_topic_closed.rs b/crates/teloxide-core/src/types/forum_topic_closed.rs
index b3d45cf5..f3a57eb2 100644
--- a/crates/teloxide-core/src/types/forum_topic_closed.rs
+++ b/crates/teloxide-core/src/types/forum_topic_closed.rs
@@ -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;
diff --git a/crates/teloxide-core/src/types/forum_topic_edited.rs b/crates/teloxide-core/src/types/forum_topic_edited.rs
new file mode 100644
index 00000000..b6df3cf1
--- /dev/null
+++ b/crates/teloxide-core/src/types/forum_topic_edited.rs
@@ -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,
+
+ /// 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,
+}
diff --git a/crates/teloxide-core/src/types/forum_topic_reopened.rs b/crates/teloxide-core/src/types/forum_topic_reopened.rs
index 88107186..faae4bd6 100644
--- a/crates/teloxide-core/src/types/forum_topic_reopened.rs
+++ b/crates/teloxide-core/src/types/forum_topic_reopened.rs
@@ -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;
diff --git a/crates/teloxide-core/src/types/general_forum_topic_hidden.rs b/crates/teloxide-core/src/types/general_forum_topic_hidden.rs
new file mode 100644
index 00000000..c1863688
--- /dev/null
+++ b/crates/teloxide-core/src/types/general_forum_topic_hidden.rs
@@ -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;
diff --git a/crates/teloxide-core/src/types/general_forum_topic_unhidden.rs b/crates/teloxide-core/src/types/general_forum_topic_unhidden.rs
new file mode 100644
index 00000000..ce85bfde
--- /dev/null
+++ b/crates/teloxide-core/src/types/general_forum_topic_unhidden.rs
@@ -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;
diff --git a/crates/teloxide-core/src/types/input_media.rs b/crates/teloxide-core/src/types/input_media.rs
index f9953db7..9b9effcc 100644
--- a/crates/teloxide-core/src/types/input_media.rs
+++ b/crates/teloxide-core/src/types/input_media.rs
@@ -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>,
+
+ /// 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,
+
+ /// 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,
+
+ /// 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();
diff --git a/crates/teloxide-core/src/types/message.rs b/crates/teloxide-core/src/types/message.rs
index 00927091..e121ee1f 100644
--- a/crates/teloxide-core/src/types/message.rs
+++ b/crates/teloxide-core/src/types/message.rs
@@ -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,
+
+ /// `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,
+ /// `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,
@@ -458,6 +474,10 @@ pub struct MediaVideo {
#[serde(default = "Vec::new")]
pub caption_entities: Vec,
+ /// `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,
@@ -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());
diff --git a/crates/teloxide-core/src/types/reply_keyboard_markup.rs b/crates/teloxide-core/src/types/reply_keyboard_markup.rs
index 649d9ee2..37ba29bb 100644
--- a/crates/teloxide-core/src/types/reply_keyboard_markup.rs
+++ b/crates/teloxide-core/src/types/reply_keyboard_markup.rs
@@ -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>,
+ /// 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(mut self, val: T) -> Self
where
T: Into