mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 14:35:36 +01:00
Add request chat and user
This commit is contained in:
parent
f52665dbd0
commit
dbf3e66a99
9 changed files with 441 additions and 58 deletions
|
@ -17,6 +17,7 @@ pub use chat_member::*;
|
|||
pub use chat_member_updated::*;
|
||||
pub use chat_permissions::*;
|
||||
pub use chat_photo::*;
|
||||
pub use chat_shared::*;
|
||||
pub use chat_type::*;
|
||||
pub use chosen_inline_result::*;
|
||||
pub use contact::*;
|
||||
|
@ -67,6 +68,8 @@ pub use input_sticker::*;
|
|||
pub use invoice::*;
|
||||
pub use keyboard_button::*;
|
||||
pub use keyboard_button_poll_type::*;
|
||||
pub use keyboard_button_request_chat::*;
|
||||
pub use keyboard_button_request_user::*;
|
||||
pub use label_price::*;
|
||||
pub use location::*;
|
||||
pub use login_url::*;
|
||||
|
@ -106,6 +109,7 @@ pub use unit_true::*;
|
|||
pub use update::*;
|
||||
pub use user::*;
|
||||
pub use user_profile_photos::*;
|
||||
pub use user_shared::*;
|
||||
pub use venue::*;
|
||||
pub use video::*;
|
||||
pub use video_chat_ended::*;
|
||||
|
@ -136,6 +140,7 @@ mod chat_member;
|
|||
mod chat_member_updated;
|
||||
mod chat_permissions;
|
||||
mod chat_photo;
|
||||
mod chat_shared;
|
||||
mod chat_type;
|
||||
mod chosen_inline_result;
|
||||
mod contact;
|
||||
|
@ -162,6 +167,8 @@ mod input_sticker;
|
|||
mod invoice;
|
||||
mod keyboard_button;
|
||||
mod keyboard_button_poll_type;
|
||||
mod keyboard_button_request_chat;
|
||||
mod keyboard_button_request_user;
|
||||
mod label_price;
|
||||
mod location;
|
||||
mod login_url;
|
||||
|
@ -198,6 +205,7 @@ mod unit_true;
|
|||
mod update;
|
||||
mod user;
|
||||
mod user_profile_photos;
|
||||
mod user_shared;
|
||||
mod venue;
|
||||
mod video;
|
||||
mod video_chat_ended;
|
||||
|
|
|
@ -632,15 +632,46 @@ impl ChatMemberKind {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the user is allowed to send audios, documents, photos,
|
||||
/// videos, video notes and voice notes.
|
||||
///
|
||||
/// I.e. returns **`false`** if the user
|
||||
/// - has left or has been banned in the chat
|
||||
/// - is restricted and doesn't have all send media right
|
||||
/// Returns `true` otherwise.
|
||||
#[must_use]
|
||||
pub fn can_send_media_messages(&self) -> bool {
|
||||
match &self {
|
||||
Self::Restricted(Restricted {
|
||||
can_send_audios,
|
||||
can_send_documents,
|
||||
can_send_photos,
|
||||
can_send_videos,
|
||||
can_send_video_notes,
|
||||
can_send_voice_notes,
|
||||
..
|
||||
}) => {
|
||||
*can_send_audios
|
||||
&& *can_send_documents
|
||||
&& *can_send_photos
|
||||
&& *can_send_videos
|
||||
&& *can_send_video_notes
|
||||
&& *can_send_voice_notes
|
||||
}
|
||||
Self::Owner(_) | Self::Administrator(_) | Self::Member => true,
|
||||
Self::Left | Self::Banned(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the user is allowed to send animations, games,
|
||||
/// stickers and use inline bots.
|
||||
///
|
||||
/// I.e. returns **`false`** if the user
|
||||
/// - has left or has been banned from the chat
|
||||
/// - is restricted and doesn't have the [`can_send_media_messages`] right
|
||||
/// - is restricted and has no [`can_send_other_messages`] right
|
||||
/// Returns `true` otherwise.
|
||||
///
|
||||
/// [`can_send_media_messages`]: Restricted::can_send_media_messages
|
||||
/// [`can_send_other_messages`]: Restricted::can_send_other_messages
|
||||
#[deprecated(
|
||||
since = "0.9.0",
|
||||
note = "Match manually and use `can_send_other_messages` field directly. Details: https://github.com/teloxide/teloxide/issues/781"
|
||||
|
@ -661,10 +692,10 @@ impl ChatMemberKind {
|
|||
///
|
||||
/// I.e. returns **`false`** if the user
|
||||
/// - has left or has been banned from the chat
|
||||
/// - is restricted and doesn't have the [`can_send_media_messages`] right
|
||||
/// - is restricted and has no [`can_add_web_page_previews`] right
|
||||
/// Returns `true` otherwise.
|
||||
///
|
||||
/// [`can_send_media_messages`]: Restricted::can_send_media_messages
|
||||
/// [`can_add_web_page_previews`]: Restricted::can_add_web_page_previews
|
||||
#[deprecated(
|
||||
since = "0.9.0",
|
||||
note = "Match manually and use `can_add_web_page_previews` field directly. Details: https://github.com/teloxide/teloxide/issues/781"
|
||||
|
@ -884,6 +915,7 @@ mod tests {
|
|||
"status":"restricted",
|
||||
"is_member": true,
|
||||
"can_send_messages": true,
|
||||
"can_send_media_messages": true,
|
||||
"can_send_audios": false,
|
||||
"can_send_documents": false,
|
||||
"can_send_photos": true,
|
||||
|
|
|
@ -51,59 +51,69 @@ bitflags::bitflags! {
|
|||
/// locations and venues.
|
||||
const SEND_MESSAGES = 1;
|
||||
|
||||
/// Set if the user is allowed to send audios.
|
||||
const SEND_AUDIOS = (1 << 1) | Self::SEND_MESSAGES.bits;
|
||||
|
||||
/// Set if the user is allowed to send documents.
|
||||
const SEND_DOCUMENTS = (1 << 2) | Self::SEND_MESSAGES.bits;
|
||||
|
||||
/// Set if the user is allowed to send photos.
|
||||
const SEND_PHOTOS = (1 << 3) | Self::SEND_MESSAGES.bits;
|
||||
|
||||
/// Set if the user is allowed to send videos.
|
||||
const SEND_VIDEOS = (1 << 4) | Self::SEND_MESSAGES.bits;
|
||||
|
||||
/// Set if the user is allowed to send video notes.
|
||||
const SEND_VIDEO_NOTES = (1 << 5) | Self::SEND_MESSAGES.bits;
|
||||
|
||||
/// Set if the user is allowed to send voice notes.
|
||||
const SEND_VOICE_NOTES = (1 << 6) | Self::SEND_MESSAGES.bits;
|
||||
|
||||
/// Set if the user is allowed to send polls, implies
|
||||
/// `SEND_MESSAGES`.
|
||||
const SEND_POLLS = (1 << 7) | Self::SEND_MESSAGES.bits;
|
||||
const SEND_POLLS = (1 << 2) | Self::SEND_MESSAGES.bits;
|
||||
|
||||
/// Set if the user is allowed to send animations, games, stickers and
|
||||
/// use inline bots, implies midia messages permissions.
|
||||
const SEND_OTHER_MESSAGES = (1 << 8) | Self::SEND_AUDIOS.bits
|
||||
| Self::SEND_DOCUMENTS.bits
|
||||
| Self::SEND_PHOTOS.bits
|
||||
| Self::SEND_VIDEOS.bits
|
||||
| Self::SEND_VIDEO_NOTES.bits
|
||||
| Self::SEND_VOICE_NOTES.bits;
|
||||
/// use inline bots, implies `SEND_MEDIA_MESSAGES`.
|
||||
const SEND_OTHER_MESSAGES = (1 << 3);
|
||||
|
||||
/// Set if the user is allowed to add web page previews to
|
||||
/// their messages, implies midia messages permissions.
|
||||
const ADD_WEB_PAGE_PREVIEWS = (1 << 9) | Self::SEND_AUDIOS.bits
|
||||
| Self::SEND_DOCUMENTS.bits
|
||||
| Self::SEND_PHOTOS.bits
|
||||
| Self::SEND_VIDEOS.bits
|
||||
| Self::SEND_VIDEO_NOTES.bits
|
||||
| Self::SEND_VOICE_NOTES.bits;
|
||||
/// their messages, implies `SEND_MEDIA_MESSAGES`.
|
||||
const ADD_WEB_PAGE_PREVIEWS = (1 << 4);
|
||||
|
||||
/// Set if the user is allowed to change the chat title, photo and
|
||||
/// other settings. Ignored in public supergroups.
|
||||
const CHANGE_INFO = (1 << 10);
|
||||
const CHANGE_INFO = (1 << 5);
|
||||
|
||||
/// Set if the user is allowed to invite new users to the chat.
|
||||
const INVITE_USERS = (1 << 11);
|
||||
const INVITE_USERS = (1 << 6);
|
||||
|
||||
/// Set if the user is allowed to pin messages. Ignored in public
|
||||
/// supergroups.
|
||||
const PIN_MESSAGES = (1 << 12);
|
||||
const PIN_MESSAGES = (1 << 7);
|
||||
|
||||
/// Set if the user is allowed to create, rename, close, and reopen forum topics.
|
||||
const MANAGE_TOPICS = (1 << 13);
|
||||
const MANAGE_TOPICS = (1 << 8);
|
||||
|
||||
/// Set if the user is allowed to send audios. implies
|
||||
/// `SEND_MESSAGES`.
|
||||
const SEND_AUDIOS = (1 << 9) | Self::SEND_MESSAGES.bits;
|
||||
|
||||
/// Set if the user is allowed to send documents. implies
|
||||
/// `SEND_MESSAGES`.
|
||||
const SEND_DOCUMENTS = (1 << 10) | Self::SEND_MESSAGES.bits;
|
||||
|
||||
/// Set if the user is allowed to send photos. implies
|
||||
/// `SEND_MESSAGES`.
|
||||
const SEND_PHOTOS = (1 << 11) | Self::SEND_MESSAGES.bits;
|
||||
|
||||
/// Set if the user is allowed to send videos. implies
|
||||
/// `SEND_MESSAGES`.
|
||||
const SEND_VIDEOS = (1 << 12) | Self::SEND_MESSAGES.bits;
|
||||
|
||||
/// Set if the user is allowed to send video notes. implies
|
||||
/// `SEND_MESSAGES`.
|
||||
const SEND_VIDEO_NOTES = (1 << 13) | Self::SEND_MESSAGES.bits;
|
||||
|
||||
/// Set if the user is allowed to send voice notes. implies
|
||||
/// `SEND_MESSAGES`.
|
||||
const SEND_VOICE_NOTES = (1 << 14) | Self::SEND_MESSAGES.bits;
|
||||
|
||||
/// Set if the user is allowed to send audios, documents,
|
||||
/// photos, videos, video notes and voice notes, implies
|
||||
/// `SEND_MESSAGES`, `SEND_AUDIOS`, `SEND_DOCUMENTS`,
|
||||
/// `SEND_PHOTOS`, `SEND_VIDEOS`, `SEND_VIDEO_NOTES` and `SEND_VOICE_NOTES`.
|
||||
/// Note: this is not a separate permission on it's own, this is just a alias for all the permissions mentioned.
|
||||
const SEND_MEDIA_MESSAGES = Self::SEND_MESSAGES.bits
|
||||
| Self::SEND_AUDIOS.bits
|
||||
| Self::SEND_DOCUMENTS.bits
|
||||
| Self::SEND_PHOTOS.bits
|
||||
| Self::SEND_VIDEOS.bits
|
||||
| Self::SEND_VIDEO_NOTES.bits
|
||||
| Self::SEND_VOICE_NOTES.bits;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,6 +167,13 @@ impl ChatPermissions {
|
|||
self.contains(ChatPermissions::SEND_VOICE_NOTES)
|
||||
}
|
||||
|
||||
/// Checks for [`SEND_MEDIA_MESSAGES`] permission.
|
||||
///
|
||||
/// [`SEND_MEDIA_MESSAGES`]: ChatPermissions::SEND_MEDIA_MESSAGES
|
||||
pub fn can_send_media_messages(&self) -> bool {
|
||||
self.contains(ChatPermissions::SEND_MEDIA_MESSAGES)
|
||||
}
|
||||
|
||||
/// Checks for [`SEND_POLLS`] permission.
|
||||
///
|
||||
/// [`SEND_POLLS`]: ChatPermissions::SEND_POLLS
|
||||
|
|
15
crates/teloxide-core/src/types/chat_shared.rs
Normal file
15
crates/teloxide-core/src/types/chat_shared.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::types::ChatId;
|
||||
|
||||
/// Information about the chat whose identifier was shared with the bot using a
|
||||
/// [`KeyboardButtonRequestChat`] button.
|
||||
///
|
||||
/// [`KeyboardButtonRequestChat`]: crate::types::KeyboardButtonRequestChat
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ChatShared {
|
||||
/// Identifier of the request.
|
||||
pub request_id: i32,
|
||||
/// Identifier of the shared chat.
|
||||
pub chat_id: ChatId,
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use crate::types::{KeyboardButtonPollType, True, WebAppInfo};
|
||||
use crate::types::{
|
||||
KeyboardButtonPollType, KeyboardButtonRequestChat, KeyboardButtonRequestUser, True, WebAppInfo,
|
||||
};
|
||||
|
||||
/// This object represents one button of the reply keyboard.
|
||||
///
|
||||
|
@ -59,6 +61,18 @@ pub enum ButtonRequest {
|
|||
/// 9 April, 2016. Older clients will display unsupported message.
|
||||
Contact,
|
||||
|
||||
/// If this variant is used, pressing the button will open a list of
|
||||
/// suitable chats. Tapping on a chat will send its identifier to the bot in
|
||||
/// a [`chat_shared`] service message.
|
||||
///
|
||||
/// [`chat_shared`]: crate::types::MessageKind::ChatShared
|
||||
RequestChat(KeyboardButtonRequestChat),
|
||||
|
||||
/// If this variant is used, pressing the button will open a list of
|
||||
/// suitable users. Tapping on any user will send their identifier to the
|
||||
/// bot in a “user_shared” service message.
|
||||
RequestUser(KeyboardButtonRequestUser),
|
||||
|
||||
/// If this variant is used, the user will be asked to create a poll and
|
||||
/// send it to the bot when the button is pressed.
|
||||
///
|
||||
|
@ -89,6 +103,18 @@ struct RawRequest {
|
|||
#[serde(rename = "request_location")]
|
||||
location: Option<True>,
|
||||
|
||||
/// If specified, pressing the button will open a list of suitable chats.
|
||||
/// Tapping on a chat will send its identifier to the bot in a “chat_shared”
|
||||
/// service message. Available in private chats only.
|
||||
#[serde(rename = "request_chat")]
|
||||
chat: Option<KeyboardButtonRequestChat>,
|
||||
|
||||
/// If specified, pressing the button will open a list of suitable users.
|
||||
/// Tapping on any user will send their identifier to the bot in a
|
||||
/// “user_shared” service message. Available in private chats only.
|
||||
#[serde(rename = "request_user")]
|
||||
user: Option<KeyboardButtonRequestUser>,
|
||||
|
||||
/// If specified, the user will be asked to create a poll and
|
||||
/// send it to the bot when the button is pressed. Available in private
|
||||
/// chats only.
|
||||
|
@ -108,25 +134,36 @@ impl<'de> Deserialize<'de> for ButtonRequest {
|
|||
{
|
||||
let raw = RawRequest::deserialize(deserializer)?;
|
||||
match raw {
|
||||
RawRequest { contact, location, poll, web_app }
|
||||
RawRequest { contact, location, chat, user, poll, web_app }
|
||||
if 1 < (contact.is_some() as u8
|
||||
+ location.is_some() as u8
|
||||
+ chat.is_some() as u8
|
||||
+ user.is_some() as u8
|
||||
+ poll.is_some() as u8
|
||||
+ web_app.is_some() as u8) =>
|
||||
{
|
||||
Err(D::Error::custom(
|
||||
"`request_contact`, `request_location`, `request_poll` and `web_app` fields \
|
||||
are mutually exclusive",
|
||||
"`request_contact`, `request_location`, `request_chat`, `request_user`, \
|
||||
`request_poll` and `web_app` fields are mutually exclusive",
|
||||
))
|
||||
}
|
||||
RawRequest { contact: Some(_), .. } => Ok(Self::Contact),
|
||||
RawRequest { location: Some(_), .. } => Ok(Self::Location),
|
||||
RawRequest { contact: Some(True), .. } => Ok(Self::Contact),
|
||||
RawRequest { location: Some(True), .. } => Ok(Self::Location),
|
||||
RawRequest { chat: Some(request_chat), .. } => Ok(Self::RequestChat(request_chat)),
|
||||
RawRequest { user: Some(request_user), .. } => Ok(Self::RequestUser(request_user)),
|
||||
RawRequest { poll: Some(poll_type), .. } => Ok(Self::Poll(poll_type)),
|
||||
RawRequest { web_app: Some(web_app), .. } => Ok(Self::WebApp(web_app)),
|
||||
|
||||
_ => Err(D::Error::custom(
|
||||
"Either one of `request_contact`, `request_location`, `request_poll` and \
|
||||
`web_app` fields is required",
|
||||
RawRequest {
|
||||
contact: None,
|
||||
location: None,
|
||||
chat: None,
|
||||
user: None,
|
||||
poll: None,
|
||||
web_app: None,
|
||||
} => Err(D::Error::custom(
|
||||
"Either one of `request_contact`, `request_chat`, `request_user`, \
|
||||
`request_location`, `request_poll` and `web_app` fields is required",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
@ -137,11 +174,20 @@ impl Serialize for ButtonRequest {
|
|||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut raw = RawRequest { contact: None, location: None, poll: None, web_app: None };
|
||||
let mut raw = RawRequest {
|
||||
contact: None,
|
||||
location: None,
|
||||
chat: None,
|
||||
user: None,
|
||||
poll: None,
|
||||
web_app: None,
|
||||
};
|
||||
|
||||
match self {
|
||||
Self::Contact => raw.contact = Some(True),
|
||||
Self::Location => raw.location = Some(True),
|
||||
Self::RequestChat(request_chat) => raw.chat = Some(request_chat.clone()),
|
||||
Self::RequestUser(request_user) => raw.user = Some(request_user.clone()),
|
||||
Self::Poll(poll_type) => raw.poll = Some(poll_type.clone()),
|
||||
Self::WebApp(web_app) => raw.web_app = Some(web_app.clone()),
|
||||
};
|
||||
|
@ -171,6 +217,17 @@ mod tests {
|
|||
assert_eq!(expected, actual);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_chat_request() {
|
||||
let button = KeyboardButton {
|
||||
text: String::from(""),
|
||||
request: Some(ButtonRequest::RequestChat(KeyboardButtonRequestChat::new(0, false))),
|
||||
};
|
||||
let expected = r#"{"text":"","request_chat":{"request_id":0,"chat_is_channel":false}}"#;
|
||||
let actual = serde_json::to_string(&button).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_no_request() {
|
||||
let json = r#"{"text":""}"#;
|
||||
|
|
114
crates/teloxide-core/src/types/keyboard_button_request_chat.rs
Normal file
114
crates/teloxide-core/src/types/keyboard_button_request_chat.rs
Normal file
|
@ -0,0 +1,114 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::types::ChatAdministratorRights;
|
||||
|
||||
/// This object defines the criteria used to request a suitable chat. The
|
||||
/// identifier of the selected chat will be shared with the bot when the
|
||||
/// corresponding button is pressed. [More about requesting chats »]
|
||||
///
|
||||
/// [More about requesting chats »]: https://core.telegram.org/bots/features#chat-and-user-selection
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct KeyboardButtonRequestChat {
|
||||
/// identifier of the request, which will be received back in the
|
||||
/// [`ChatShared`] object. Must be unique within the message.
|
||||
///
|
||||
/// [`ChatShared`]: crate::types::ChatShared
|
||||
pub request_id: i32,
|
||||
|
||||
/// Pass `true` to request a channel chat, pass `false` to request a group
|
||||
/// or a supergroup chat.
|
||||
pub chat_is_channel: bool,
|
||||
|
||||
/// Pass `true` to request a forum supergroup, pass `false` to request a
|
||||
/// non-forum chat. If not specified, no additional restrictions are
|
||||
/// applied.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub chat_is_forum: Option<bool>,
|
||||
|
||||
/// Pass `true` to request a supergroup or a channel with a username, pass
|
||||
/// `false` to request a chat without a username. If not specified, no
|
||||
/// additional restrictions are applied.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub chat_has_username: Option<bool>,
|
||||
|
||||
/// Pass `true` to request a chat owned by the user. Otherwise, no
|
||||
/// additional restrictions are applied.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub chat_is_created: Option<bool>,
|
||||
|
||||
/// Listing the required administrator rights of the user in the chat. The
|
||||
/// rights must be a superset of bot_administrator_rights. If not specified,
|
||||
/// no additional restrictions are applied.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub user_administrator_rights: Option<ChatAdministratorRights>,
|
||||
|
||||
/// Listing the required administrator rights of the bot in the chat. The
|
||||
/// rights must be a subset of user_administrator_rights. If not specified,
|
||||
/// no additional restrictions are applied.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub bot_administrator_rights: Option<ChatAdministratorRights>,
|
||||
|
||||
/// Pass `true` to request a chat with the bot as a member. Otherwise, no
|
||||
/// additional restrictions are applied.
|
||||
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
|
||||
pub bot_is_member: bool,
|
||||
}
|
||||
|
||||
impl KeyboardButtonRequestChat {
|
||||
/// Creates a new [`KeyboardButtonRequestChat`].
|
||||
pub fn new(request_id: i32, chat_is_channel: bool) -> Self {
|
||||
Self {
|
||||
request_id,
|
||||
chat_is_channel,
|
||||
chat_is_forum: None,
|
||||
chat_has_username: None,
|
||||
chat_is_created: None,
|
||||
user_administrator_rights: None,
|
||||
bot_administrator_rights: None,
|
||||
bot_is_member: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Setter for `chat_is_forum` field.
|
||||
#[must_use]
|
||||
pub fn chat_is_forum(mut self, value: bool) -> Self {
|
||||
self.chat_is_forum = Some(value);
|
||||
self
|
||||
}
|
||||
|
||||
/// Setter for `chat_has_username` field.
|
||||
#[must_use]
|
||||
pub fn chat_has_username(mut self, value: bool) -> Self {
|
||||
self.chat_has_username = Some(value);
|
||||
self
|
||||
}
|
||||
|
||||
/// Setter for `chat_is_created` field.
|
||||
#[must_use]
|
||||
pub fn chat_is_created(mut self, value: bool) -> Self {
|
||||
self.chat_is_created = Some(value);
|
||||
self
|
||||
}
|
||||
|
||||
/// Request a chat where the user has the specified administrator rights.
|
||||
#[must_use]
|
||||
pub fn user_administrator_rights(mut self, rights: ChatAdministratorRights) -> Self {
|
||||
self.user_administrator_rights = Some(rights);
|
||||
self
|
||||
}
|
||||
|
||||
/// Request a chat where the bot has the specified administrator rights.
|
||||
#[must_use]
|
||||
pub fn bot_administrator_rights(mut self, rights: ChatAdministratorRights) -> Self {
|
||||
self.bot_administrator_rights = Some(rights);
|
||||
self
|
||||
}
|
||||
|
||||
/// Setter for `bot_is_member` field.
|
||||
#[must_use]
|
||||
pub fn bot_is_member(mut self, value: bool) -> Self {
|
||||
self.bot_is_member = value;
|
||||
self
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// This object defines the criteria used to request a suitable user. The
|
||||
/// identifier of the selected user will be shared with the bot when the
|
||||
/// corresponding button is pressed. More about requesting users »
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct KeyboardButtonRequestUser {
|
||||
/// identifier of the request, which will be received back in the
|
||||
/// [`UserShared`] object. Must be unique within the message.
|
||||
///
|
||||
/// [`UserShared`]: crate::types::UserShared
|
||||
pub request_id: i32,
|
||||
|
||||
/// Pass `true` to request a bot, pass `false` to request a regular user. If
|
||||
/// not specified, no additional restrictions are applied.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub user_is_bot: Option<bool>,
|
||||
|
||||
/// Pass `true` to request a premium user, pass `false` to request a
|
||||
/// non-premium user. If not specified, no additional restrictions are
|
||||
/// applied.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub user_is_premium: Option<bool>,
|
||||
}
|
||||
|
||||
impl KeyboardButtonRequestUser {
|
||||
/// Creates a new [`KeyboardButtonRequestUser`].
|
||||
pub fn new(request_id: i32) -> Self {
|
||||
Self { request_id, user_is_bot: None, user_is_premium: None }
|
||||
}
|
||||
|
||||
/// Setter for `user_is_bot` field
|
||||
pub fn user_is_bot(mut self, value: bool) -> Self {
|
||||
self.user_is_bot = Some(value);
|
||||
self
|
||||
}
|
||||
|
||||
/// Setter for `user_is_premium` field
|
||||
pub fn user_is_premium(mut self, value: bool) -> Self {
|
||||
self.user_is_premium = Some(value);
|
||||
self
|
||||
}
|
||||
}
|
|
@ -5,12 +5,12 @@ use serde::{Deserialize, Serialize};
|
|||
use url::Url;
|
||||
|
||||
use crate::types::{
|
||||
Animation, Audio, BareChatId, Chat, ChatId, Contact, Dice, Document, ForumTopicClosed,
|
||||
ForumTopicCreated, ForumTopicEdited, ForumTopicReopened, Game, GeneralForumTopicHidden,
|
||||
GeneralForumTopicUnhidden, InlineKeyboardMarkup, Invoice, Location,
|
||||
Animation, Audio, BareChatId, Chat, ChatId, ChatShared, Contact, Dice, Document,
|
||||
ForumTopicClosed, ForumTopicCreated, ForumTopicEdited, ForumTopicReopened, Game,
|
||||
GeneralForumTopicHidden, GeneralForumTopicUnhidden, InlineKeyboardMarkup, Invoice, Location,
|
||||
MessageAutoDeleteTimerChanged, MessageEntity, MessageEntityRef, MessageId, PassportData,
|
||||
PhotoSize, Poll, ProximityAlertTriggered, Sticker, SuccessfulPayment, ThreadId, True, User,
|
||||
Venue, Video, VideoChatEnded, VideoChatParticipantsInvited, VideoChatScheduled,
|
||||
UserShared, Venue, Video, VideoChatEnded, VideoChatParticipantsInvited, VideoChatScheduled,
|
||||
VideoChatStarted, VideoNote, Voice, WebAppData, WriteAccessAllowed,
|
||||
};
|
||||
|
||||
|
@ -60,6 +60,8 @@ pub enum MessageKind {
|
|||
ChannelChatCreated(MessageChannelChatCreated),
|
||||
MessageAutoDeleteTimerChanged(MessageMessageAutoDeleteTimerChanged),
|
||||
Pinned(MessagePinned),
|
||||
ChatShared(MessageChatShared),
|
||||
UserShared(MessageUserShared),
|
||||
Invoice(MessageInvoice),
|
||||
SuccessfulPayment(MessageSuccessfulPayment),
|
||||
ConnectedWebsite(MessageConnectedWebsite),
|
||||
|
@ -247,6 +249,18 @@ pub struct MessagePinned {
|
|||
pub pinned: Box<Message>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct MessageChatShared {
|
||||
/// A chat was shared with the bot.
|
||||
pub chat_shared: ChatShared,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct MessageUserShared {
|
||||
/// A chat was shared with the bot.
|
||||
pub user_shared: UserShared,
|
||||
}
|
||||
|
||||
#[serde_with_macros::skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct MessageInvoice {
|
||||
|
@ -655,12 +669,13 @@ mod getters {
|
|||
self, message::MessageKind::*, Chat, ChatId, ChatMigration, Forward, ForwardedFrom,
|
||||
MediaAnimation, MediaAudio, MediaContact, MediaDocument, MediaGame, MediaKind,
|
||||
MediaLocation, MediaPhoto, MediaPoll, MediaSticker, MediaText, MediaVenue, MediaVideo,
|
||||
MediaVideoNote, MediaVoice, Message, MessageChannelChatCreated, MessageCommon,
|
||||
MessageConnectedWebsite, MessageDeleteChatPhoto, MessageDice, MessageEntity,
|
||||
MediaVideoNote, MediaVoice, Message, MessageChannelChatCreated, MessageChatShared,
|
||||
MessageCommon, MessageConnectedWebsite, MessageDeleteChatPhoto, MessageDice, MessageEntity,
|
||||
MessageGroupChatCreated, MessageId, MessageInvoice, MessageLeftChatMember,
|
||||
MessageNewChatMembers, MessageNewChatPhoto, MessageNewChatTitle, MessagePassportData,
|
||||
MessagePinned, MessageProximityAlertTriggered, MessageSuccessfulPayment,
|
||||
MessageSupergroupChatCreated, MessageVideoChatParticipantsInvited, PhotoSize, User,
|
||||
MessageSupergroupChatCreated, MessageUserShared, MessageVideoChatParticipantsInvited,
|
||||
PhotoSize, User,
|
||||
};
|
||||
|
||||
use super::{
|
||||
|
@ -1269,6 +1284,22 @@ mod getters {
|
|||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn shared_chat(&self) -> Option<&types::ChatShared> {
|
||||
match &self.kind {
|
||||
ChatShared(MessageChatShared { chat_shared }) => Some(chat_shared),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn shared_user(&self) -> Option<&types::UserShared> {
|
||||
match &self.kind {
|
||||
UserShared(MessageUserShared { user_shared }) => Some(user_shared),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn dice(&self) -> Option<&types::Dice> {
|
||||
match &self.kind {
|
||||
|
@ -1699,6 +1730,56 @@ mod tests {
|
|||
assert!(message.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn de_shared_chat() {
|
||||
let json = r#"{
|
||||
"message_id": 198283,
|
||||
"chat": {
|
||||
"id": 250918540,
|
||||
"first_name": "Андрей",
|
||||
"last_name": "Власов",
|
||||
"username": "aka_dude",
|
||||
"type": "private"
|
||||
},
|
||||
"date": 1567927221,
|
||||
"chat_shared": {
|
||||
"request_id": 348349,
|
||||
"chat_id": 384939
|
||||
}
|
||||
}"#;
|
||||
let message = from_str::<Message>(json);
|
||||
assert!(message.is_ok());
|
||||
assert_eq!(
|
||||
message.unwrap(),
|
||||
Message {
|
||||
id: MessageId(198283),
|
||||
thread_id: None,
|
||||
date: chrono::NaiveDateTime::from_timestamp_opt(1567927221, 0).unwrap().and_utc(),
|
||||
chat: Chat {
|
||||
id: ChatId(250918540),
|
||||
kind: ChatKind::Private(ChatPrivate {
|
||||
first_name: Some("Андрей".to_string()),
|
||||
last_name: Some("Власов".to_string()),
|
||||
username: Some("aka_dude".to_string()),
|
||||
bio: None,
|
||||
emoji_status_custom_emoji_id: None,
|
||||
has_private_forwards: None,
|
||||
has_restricted_voice_and_video_messages: None
|
||||
}),
|
||||
photo: None,
|
||||
has_aggressive_anti_spam_enabled: false,
|
||||
pinned_message: None,
|
||||
message_auto_delete_time: None,
|
||||
has_hidden_members: false
|
||||
},
|
||||
kind: MessageKind::ChatShared(MessageChatShared {
|
||||
chat_shared: ChatShared { request_id: 348349, chat_id: ChatId(384939) }
|
||||
}),
|
||||
via_bot: None
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn de_media_group_forwarded() {
|
||||
let json = r#"{
|
||||
|
|
15
crates/teloxide-core/src/types/user_shared.rs
Normal file
15
crates/teloxide-core/src/types/user_shared.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::types::UserId;
|
||||
|
||||
/// Information about the chat whose identifier was shared with the bot using a
|
||||
/// [`KeyboardButtonRequestUser`] button.
|
||||
///
|
||||
/// [`KeyboardButtonRequestUser`]: crate::types::KeyboardButtonRequestUser
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
pub struct UserShared {
|
||||
/// Identifier of the request.
|
||||
pub request_id: i32,
|
||||
/// Identifier of the shared user.
|
||||
pub user_id: UserId,
|
||||
}
|
Loading…
Reference in a new issue