Merge pull request #1086 from syrtcevvi/feature/support-tba-6.7

Add support TBA 6.7
This commit is contained in:
Waffle Maybe 2024-07-08 19:46:11 +00:00 committed by GitHub
commit 617197a1c7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 275 additions and 33 deletions

View file

@ -69,12 +69,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add new type `StickerFormatFlags` with fields `is_animated` and `is_video`
- Add new method `Sticker::format` which returns the format of the sticker, the format is determined by the `StickerFormatFlags` of the `Sticker`
- Add missing fields `{InlineQueryResultGif, InlineQueryResultMpeg4Gif}::thumbnail_mime_type`
- Support for TBA 6.7 ([#1086](pr1086))
- Add support for launching [Web Apps](https://core.telegram.org/bots/webapps) from inline query results by replacing the parameters `switch_pm_text` and `switch_pm_parameter` of the method `answer_inline_query` with the parameter `button` of type `InlineQueryResultsButton`
- Add new fields:
- `web_app_name` to `WriteAccessAllowed`
- `switch_inline_query_chosen_chat` of the type `SwitchInlineQueryChosenChat` to `InlineKeyboardButton`
- `via_chat_folder_invite_link` to `ChatMemberUpdated`
- Add methods for working with bot's name:
- `set_my_name`
- `get_my_name`
- Add the ability to specify custom emoji entities using `HTML` and `MarkdownV2` formatting options for bots that purchased additional usernames on [Fragment](https://fragment.com/)
[pr851]: https://github.com/teloxide/teloxide/pull/851
[pr887]: https://github.com/teloxide/teloxide/pull/887
[pr905]: https://github.com/teloxide/teloxide/pull/905
[pr982]: https://github.com/teloxide/teloxide/pull/982
[pr1040]: https://github.com/teloxide/teloxide/pull/1040
[pr1086]: https://github.com/teloxide/teloxide/pull/1086
### Fixed

View file

@ -39,7 +39,7 @@
//! [github]: https://github.com/WaffleLapkin/tg-methods-schema
Schema(
api_version: ApiVersion(ver: "6.6", date: "March 9, 2023"),
api_version: ApiVersion(ver: "6.7", date: "April 21, 2023"),
methods: [
Method(
names: ("getUpdates", "GetUpdates", "get_updates"),
@ -2894,6 +2894,42 @@ Schema(
),
],
),
Method(
names: ("setMyName", "SetMyName", "set_my_name"),
return_ty: True,
doc: Doc(md: "Use this method to change the bot's name. Returns True on success."),
tg_doc: "https://core.telegram.org/bots/api#setmyname",
tg_category: "Available methods",
params: [
Param(
name: "name",
ty: Option(String),
descr: Doc(md: "New bot name; 0-64 characters. Pass an empty string to remove the dedicated name for the given language.")
),
Param(
name: "language_code",
ty: Option(String),
descr: Doc(md: "A two-letter ISO 639-1 language code. If empty, the name will be shown to all users for whose language there is no dedicated name.")
),
],
),
Method(
names: ("getMyName", "GetMyName", "get_my_name"),
return_ty: RawTy("BotName"),
doc: Doc(
md: "Use this method to get the current bot name for the given user language. Returns [BotName] on success.",
md_links: {"BotName": "https://core.telegram.org/bots/api#botname"},
),
tg_doc: "https://core.telegram.org/bots/api#getmyname",
tg_category: "Available methods",
params: [
Param(
name: "language_code",
ty: Option(String),
descr: Doc(md: "A two-letter ISO 639-1 language code or an empty string")
),
],
),
Method(
names: ("setMyDescription", "SetMyDescription", "set_my_description"),
return_ty: True,
@ -3087,21 +3123,10 @@ Schema(
descr: Doc(md: "Pass the offset that a client should send in the next query with the same text to receive more results. Pass an empty string if there are no more results or if you don't support pagination. Offset length can't exceed 64 bytes.")
),
Param(
name: "switch_pm_text",
ty: Option(String),
descr: Doc(md: "If passed, clients will display a button with specified text that switches the user to a private chat with the bot and sends the bot a start message with the parameter switch_pm_parameter")
),
Param(
name: "switch_pm_parameter",
ty: Option(String),
descr: Doc(
md: "[Deep-linking] parameter for the /start message sent to the bot when user presses the switch button. 1-64 characters, only `A-Z`, `a-z`, `0-9`, `_` and `-` are allowed.\n\n_Example_: An inline bot that sends YouTube videos can ask the user to connect the bot to their YouTube account to adapt search results accordingly. To do this, it displays a 'Connect your YouTube account' button above the results, or even before showing any. The user presses the button, switches to a private chat with the bot and, in doing so, passes a start parameter that instructs the bot to return an oauth link. Once done, the bot can offer a [switch_inline] button so that the user can easily return to the chat where they wanted to use the bot's inline capabilities.",
md_links: {
"Deep-linking": "https://core.telegram.org/bots#deep-linking",
"switch_inline": "https://core.telegram.org/bots/api#inlinekeyboardmarkup",
},
),
),
name: "button",
ty: Option(RawTy("InlineQueryResultsButton")),
descr: Doc(md: "A JSON-serialized object describing a button to be shown above inline query results")
)
],
),
Method(

View file

@ -159,6 +159,8 @@ where
answer_callback_query,
set_my_commands,
get_my_commands,
set_my_name,
get_my_name,
set_my_description,
get_my_description,
set_my_short_description,

View file

@ -254,6 +254,8 @@ where
answer_callback_query,
set_my_commands,
get_my_commands,
set_my_name,
get_my_name,
set_my_description,
get_my_description,
set_my_short_description,
@ -709,6 +711,10 @@ trait ErasableRequester<'a> {
fn get_my_commands(&self) -> ErasedRequest<'a, GetMyCommands, Self::Err>;
fn set_my_name(&self) -> ErasedRequest<'a, SetMyName, Self::Err>;
fn get_my_name(&self) -> ErasedRequest<'a, GetMyName, Self::Err>;
fn set_my_description(&self) -> ErasedRequest<'a, SetMyDescription, Self::Err>;
fn get_my_description(&self) -> ErasedRequest<'a, GetMyDescription, Self::Err>;
@ -1512,6 +1518,14 @@ where
Requester::get_my_commands(self).erase()
}
fn set_my_name(&self) -> ErasedRequest<'a, SetMyName, Self::Err> {
Requester::set_my_name(self).erase()
}
fn get_my_name(&self) -> ErasedRequest<'a, GetMyName, Self::Err> {
Requester::get_my_name(self).erase()
}
fn set_my_description(&self) -> ErasedRequest<'a, SetMyDescription, Self::Err> {
Requester::set_my_description(self).erase()
}

View file

@ -240,6 +240,8 @@ where
answer_callback_query,
set_my_commands,
get_my_commands,
set_my_name,
get_my_name,
set_my_description,
get_my_description,
set_my_short_description,

View file

@ -142,6 +142,8 @@ where
answer_callback_query,
set_my_commands,
get_my_commands,
set_my_name,
get_my_name,
set_my_description,
get_my_description,
set_my_short_description,

View file

@ -188,6 +188,8 @@ where
answer_callback_query,
set_my_commands,
get_my_commands,
set_my_name,
get_my_name,
set_my_description,
get_my_description,
set_my_short_description,

View file

@ -829,6 +829,18 @@ impl Requester for Bot {
Self::GetMyCommands::new(self.clone(), payloads::GetMyCommands::new())
}
type SetMyName = JsonRequest<payloads::SetMyName>;
fn set_my_name(&self) -> Self::SetMyName {
Self::SetMyName::new(self.clone(), payloads::SetMyName::new())
}
type GetMyName = JsonRequest<payloads::GetMyName>;
fn get_my_name(&self) -> Self::GetMyName {
Self::GetMyName::new(self.clone(), payloads::GetMyName::new())
}
type SetMyDescription = JsonRequest<payloads::SetMyDescription>;
fn set_my_description(&self) -> Self::SetMyDescription {

View file

@ -1033,6 +1033,22 @@ macro_rules! requester_forward {
$body!(get_my_commands this ())
}
};
(@method set_my_name $body:ident $ty:ident) => {
type SetMyName = $ty![SetMyName];
fn set_my_name(&self, ) -> Self::SetMyName {
let this = self;
$body!(set_my_name this ())
}
};
(@method get_my_name $body:ident $ty:ident) => {
type GetMyName = $ty![GetMyName];
fn get_my_name(&self, ) -> Self::GetMyName {
let this = self;
$body!(get_my_name this ())
}
};
(@method set_my_description $body:ident $ty:ident) => {
type SetMyDescription = $ty![SetMyDescription];

View file

@ -70,6 +70,7 @@ mod get_me;
mod get_my_commands;
mod get_my_default_administrator_rights;
mod get_my_description;
mod get_my_name;
mod get_my_short_description;
mod get_sticker_set;
mod get_updates;
@ -116,6 +117,7 @@ mod set_game_score_inline;
mod set_my_commands;
mod set_my_default_administrator_rights;
mod set_my_description;
mod set_my_name;
mod set_my_short_description;
mod set_passport_data_errors;
mod set_sticker_emoji_list;
@ -199,6 +201,7 @@ pub use get_my_default_administrator_rights::{
GetMyDefaultAdministratorRights, GetMyDefaultAdministratorRightsSetters,
};
pub use get_my_description::{GetMyDescription, GetMyDescriptionSetters};
pub use get_my_name::{GetMyName, GetMyNameSetters};
pub use get_my_short_description::{GetMyShortDescription, GetMyShortDescriptionSetters};
pub use get_sticker_set::{GetStickerSet, GetStickerSetSetters};
pub use get_updates::{GetUpdates, GetUpdatesSetters};
@ -251,6 +254,7 @@ pub use set_my_default_administrator_rights::{
SetMyDefaultAdministratorRights, SetMyDefaultAdministratorRightsSetters,
};
pub use set_my_description::{SetMyDescription, SetMyDescriptionSetters};
pub use set_my_name::{SetMyName, SetMyNameSetters};
pub use set_my_short_description::{SetMyShortDescription, SetMyShortDescriptionSetters};
pub use set_passport_data_errors::{SetPassportDataErrors, SetPassportDataErrorsSetters};
pub use set_sticker_emoji_list::{SetStickerEmojiList, SetStickerEmojiListSetters};

View file

@ -2,7 +2,7 @@
use serde::Serialize;
use crate::types::{InlineQueryResult, True};
use crate::types::{InlineQueryResult, InlineQueryResultsButton, True};
impl_payload! {
/// Use this method to send answers to an inline query. On success, _True_ is returned. No more than **50** results per query are allowed.
@ -21,15 +21,8 @@ impl_payload! {
pub is_personal: bool,
/// Pass the offset that a client should send in the next query with the same text to receive more results. Pass an empty string if there are no more results or if you don't support pagination. Offset length can't exceed 64 bytes.
pub next_offset: String [into],
/// If passed, clients will display a button with specified text that switches the user to a private chat with the bot and sends the bot a start message with the parameter switch_pm_parameter
pub switch_pm_text: String [into],
/// [Deep-linking] parameter for the /start message sent to the bot when user presses the switch button. 1-64 characters, only `A-Z`, `a-z`, `0-9`, `_` and `-` are allowed.
///
/// _Example_: An inline bot that sends YouTube videos can ask the user to connect the bot to their YouTube account to adapt search results accordingly. To do this, it displays a 'Connect your YouTube account' button above the results, or even before showing any. The user presses the button, switches to a private chat with the bot and, in doing so, passes a start parameter that instructs the bot to return an oauth link. Once done, the bot can offer a [switch_inline] button so that the user can easily return to the chat where they wanted to use the bot's inline capabilities.
///
/// [Deep-linking]: https://core.telegram.org/bots#deep-linking
/// [switch_inline]: https://core.telegram.org/bots/api#inlinekeyboardmarkup
pub switch_pm_parameter: String [into],
/// A JSON-serialized object describing a button to be shown above inline query results
pub button: InlineQueryResultsButton,
}
}
}

View file

@ -0,0 +1,18 @@
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::BotName;
impl_payload! {
/// Use this method to get the current bot name for the given user language. Returns [`BotName`] on success.
///
/// [`BotName`]: crate::types::BotName
#[derive(Debug, PartialEq, Eq, Hash, Default, Clone, Serialize)]
pub GetMyName (GetMyNameSetters) => BotName {
optional {
/// A two-letter ISO 639-1 language code or an empty string
pub language_code: String [into],
}
}
}

View file

@ -0,0 +1,18 @@
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::True;
impl_payload! {
/// Use this method to change the bot's name. Returns True on success.
#[derive(Debug, PartialEq, Eq, Hash, Default, Clone, Serialize)]
pub SetMyName (SetMyNameSetters) => True {
optional {
/// New bot name; 0-64 characters. Pass an empty string to remove the dedicated name for the given language.
pub name: String [into],
/// A two-letter ISO 639-1 language code. If empty, the name will be shown to all users for whose language there is no dedicated name.
pub language_code: String [into],
}
}
}

View file

@ -23,8 +23,8 @@ pub use crate::payloads::{
GetCustomEmojiStickersSetters as _, GetFileSetters as _, GetForumTopicIconStickersSetters as _,
GetGameHighScoresSetters as _, GetMeSetters as _, GetMyCommandsSetters as _,
GetMyDefaultAdministratorRightsSetters as _, GetMyDescriptionSetters as _,
GetMyShortDescriptionSetters as _, GetStickerSetSetters as _, GetUpdatesSetters as _,
GetUserProfilePhotosSetters as _, GetWebhookInfoSetters as _,
GetMyNameSetters as _, GetMyShortDescriptionSetters as _, GetStickerSetSetters as _,
GetUpdatesSetters as _, GetUserProfilePhotosSetters as _, GetWebhookInfoSetters as _,
HideGeneralForumTopicSetters as _, KickChatMemberSetters as _, LeaveChatSetters as _,
LogOutSetters as _, PinChatMessageSetters as _, PromoteChatMemberSetters as _,
ReopenForumTopicSetters as _, ReopenGeneralForumTopicSetters as _,
@ -40,7 +40,7 @@ pub use crate::payloads::{
SetCustomEmojiStickerSetThumbnailSetters as _, SetGameScoreInlineSetters as _,
SetGameScoreSetters as _, SetMyCommandsSetters as _,
SetMyDefaultAdministratorRightsSetters as _, SetMyDescriptionSetters as _,
SetMyShortDescriptionSetters as _, SetPassportDataErrorsSetters as _,
SetMyNameSetters as _, SetMyShortDescriptionSetters as _, SetPassportDataErrorsSetters as _,
SetStickerEmojiListSetters as _, SetStickerKeywordsSetters as _,
SetStickerMaskPositionSetters as _, SetStickerPositionInSetSetters as _,
SetStickerSetThumbnailSetters as _, SetStickerSetTitleSetters as _, SetWebhookSetters as _,

View file

@ -777,6 +777,16 @@ pub trait Requester {
/// For Telegram documentation see [`GetMyCommands`].
fn get_my_commands(&self) -> Self::GetMyCommands;
type SetMyName: Request<Payload = SetMyName, Err = Self::Err>;
/// For Telegram documentation see [`SetMyName`].
fn set_my_name(&self) -> Self::SetMyName;
type GetMyName: Request<Payload = GetMyName, Err = Self::Err>;
/// For Telegram documentation see [`GetMyName`].
fn get_my_name(&self) -> Self::GetMyName;
type SetMyDescription: Request<Payload = SetMyDescription, Err = Self::Err>;
/// For Telegram documentation see [`SetMyDescription`].
@ -1290,6 +1300,8 @@ macro_rules! forward_all {
answer_callback_query,
set_my_commands,
get_my_commands,
set_my_name,
get_my_name,
set_my_description,
get_my_description,
set_my_short_description,

View file

@ -6,6 +6,7 @@ pub use audio::*;
pub use bot_command::*;
pub use bot_command_scope::*;
pub use bot_description::*;
pub use bot_name::*;
pub use bot_short_description::*;
pub use callback_game::*;
pub use callback_query::*;
@ -63,6 +64,7 @@ pub use inline_query_result_photo::*;
pub use inline_query_result_venue::*;
pub use inline_query_result_video::*;
pub use inline_query_result_voice::*;
pub use inline_query_results_button::*;
pub use input_file::*;
pub use input_media::*;
pub use input_message_content::*;
@ -104,6 +106,7 @@ pub use shipping_query::*;
pub use sticker::*;
pub use sticker_set::*;
pub use successful_payment::*;
pub use switch_inline_query_chosen_chat::*;
pub use target_message::*;
pub use thread_id::*;
pub use unit_false::*;
@ -131,6 +134,7 @@ mod audio;
mod bot_command;
mod bot_command_scope;
mod bot_description;
mod bot_name;
mod bot_short_description;
mod callback_game;
mod callback_query;
@ -164,6 +168,7 @@ mod general_forum_topic_hidden;
mod general_forum_topic_unhidden;
mod inline_keyboard_button;
mod inline_keyboard_markup;
mod inline_query_results_button;
mod input_file;
mod input_media;
mod input_message_content;
@ -202,6 +207,7 @@ mod shipping_query;
mod sticker;
mod sticker_set;
mod successful_payment;
mod switch_inline_query_chosen_chat;
mod target_message;
mod thread_id;
mod unit_false;

View file

@ -0,0 +1,7 @@
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct BotName {
/// The bot's name
pub name: String,
}

View file

@ -3,6 +3,9 @@ use serde::{Deserialize, Serialize};
use crate::types::{Chat, ChatInviteLink, ChatMember, User};
/// This object represents changes in the status of a chat member.
///
/// [The official docs](https://core.telegram.org/bots/api#chatmemberupdated).
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ChatMemberUpdated {
@ -20,6 +23,9 @@ pub struct ChatMemberUpdated {
/// Chat invite link, which was used by the user to join the chat; for
/// joining by invite link events only.
pub invite_link: Option<ChatInviteLink>,
#[serde(default)]
/// True, if the user joined the chat via a chat folder invite link
pub via_chat_folder_invite_link: bool,
}
impl ChatMemberUpdated {

View file

@ -1,4 +1,4 @@
use crate::types::{CallbackGame, LoginUrl, True, WebAppInfo};
use crate::types::{CallbackGame, LoginUrl, SwitchInlineQueryChosenChat, True, WebAppInfo};
use serde::{Deserialize, Serialize};
/// This object represents one button of an inline keyboard.
@ -71,6 +71,11 @@ pub enum InlineKeyboardButtonKind {
/// the same chat good for selecting something from multiple options.
SwitchInlineQueryCurrentChat(String),
/// If set, pressing the button will prompt the user to select one of their
/// chats of the specified type, open that chat and insert the bot's
/// username and the specified inline query in the input field
SwitchInlineQueryChosenChat(SwitchInlineQueryChosenChat),
/// Description of the game that will be launched when the user presses the
/// button.
///

View file

@ -0,0 +1,46 @@
use serde::{Deserialize, Serialize};
use crate::types::WebAppInfo;
/// This object represents a button to be shown above inline query results. You
/// must use exactly one of the optional fields.
///
/// [The official docs](https://core.telegram.org/bots/api#inlinequeryresultsbutton)
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct InlineQueryResultsButton {
/// Label text on the button
pub text: String,
#[serde(flatten)]
pub kind: InlineQueryResultsButtonKind,
}
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum InlineQueryResultsButtonKind {
/// Description of the [Web App] that will be launched when the user presses
/// the button. The Web App will be able to switch back to the inline mode
/// using the method [switchInlineQuery] inside the Web App.
///
/// [Web App]: https://core.telegram.org/bots/webapps
/// [switchInlineQuery]: https://core.telegram.org/bots/webapps#initializing-mini-apps
WebApp(WebAppInfo),
/// [Deep-linking] parameter for the /start message sent to the bot when a
/// user presses the button. 1-64 characters, only `A-Z`, `a-z`, `0-9`, `_`
/// and `-` are allowed.
///
/// Example: An inline bot that sends YouTube videos can
/// ask the user to connect the bot to their YouTube account to adapt search
/// results accordingly. To do this, it displays a 'Connect your YouTube
/// account' button above the results, or even before showing any. The user
/// presses the button, switches to a private chat with the bot and, in
/// doing so, passes a start parameter that instructs the bot to return an
/// OAuth link. Once done, the bot can offer a [switch_inline] button so
/// that the user can easily return to the chat where they wanted to use
/// the bot's inline capabilities.
///
/// [Deep-linking]: https://core.telegram.org/bots/features#deep-linking
/// [switch_inline]: https://core.telegram.org/bots/api#inlinekeyboardmarkup
StartParameter(String),
}

View file

@ -47,6 +47,7 @@ use serde::{Deserialize, Serialize};
/// *bold _italic bold ~italic bold strikethrough ||italic bold strikethrough spoiler||~ __underline italic bold___ bold*
/// [inline URL](http://www.example.com/)
/// [inline mention of a user](tg://user?id=123456789)
/// ![👍](tg://emoji?id=5368324170671202286)
/// `inline fixed-width code`
/// ```
/// pre-formatted fixed-width code block
@ -72,6 +73,12 @@ use serde::{Deserialize, Serialize};
/// `underline` entity, so instead of `___italic underline___` use `___italic
/// underline_\r__`, where `\r` is a character with code `13`, which will be
/// ignored.
/// - A valid emoji must be provided as an alternative value for the custom
/// emoji. The emoji will be shown instead of the custom emoji in places where
/// a custom emoji cannot be displayed (e.g., system notifications) or if the
/// message is forwarded by a non-premium user. It is recommended to use the
/// emoji from the emoji field of the custom emoji [sticker](https://core.telegram.org/bots/api#sticker).
/// - Custom emoji entities can only be used by bots that purchased additional usernames on [Fragment](https://fragment.com/).
///
/// ## HTML style
///
@ -86,6 +93,7 @@ use serde::{Deserialize, Serialize};
/// <b>bold <i>italic bold <s>italic bold strikethrough <span class="tg-spoiler">italic bold strikethrough spoiler</span></s> <u>underline italic bold</u></i> bold</b>
/// <a href="http://www.example.com/">inline URL</a>
/// <a href="tg://user?id=123456789">inline mention of a user</a>
/// <tg-emoji emoji-id="5368324170671202286">👍</tg-emoji>
/// <code>inline fixed-width code</code>
/// <pre>pre-formatted fixed-width code block</pre>
#[doc = "<pre><code class=\"language-rust\">pre-formatted fixed-width code block written in the \
@ -104,6 +112,8 @@ use serde::{Deserialize, Serialize};
/// - Use nested `pre` and `code` tags, to define programming language for `pre`
/// entity.
/// - Programming language can't be specified for standalone `code` tags.
/// - A valid emoji must be used as the content of the `tg-emoji` tag. The emoji will be shown instead of the custom emoji in places where a custom emoji cannot be displayed (e.g., system notifications) or if the message is forwarded by a non-premium user. It is recommended to use the emoji from the emoji field of the custom emoji [sticker](https://core.telegram.org/bots/api#sticker).
/// - Custom emoji entities can only be used by bots that purchased additional usernames on [Fragment](https://fragment.com/).
///
/// ## Markdown style
///

View file

@ -0,0 +1,26 @@
use serde::{Deserialize, Serialize};
/// This object represents an inline button that switches the current user to
/// inline mode in a chosen chat, with an optional default inline query.
///
/// [The official docs](https://core.telegram.org/bots/api#switchinlinequerychosenchat)
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub struct SwitchInlineQueryChosenChat {
/// The default inline query to be inserted in the input field. If left
/// empty, only the bot's username will be inserted
pub query: Option<String>,
/// True, if private chats with users can be chosen
#[serde(default)]
pub allow_user_chats: bool,
/// True, if private chats with bots can be chosen
#[serde(default)]
pub allow_bot_chats: bool,
/// True, if group and supergroup chats can be chosen
#[serde(default)]
pub allow_group_chats: bool,
/// True, if channel chats can be chosen
#[serde(default)]
pub allow_channel_chats: bool,
}

View file

@ -1,9 +1,13 @@
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.
/// This object represents a service message about a user allowing a bot to
/// write messages after adding the bot to the attachment menu or launching a
/// Web App from a link.
///
/// [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 {}
pub struct WriteAccessAllowed {
/// Name of the Web App which was launched from a link
pub web_app_name: Option<String>,
}