Add UserId::{url, is_anonymous, is_channel, is_telegram} functions

This commit is contained in:
Maybe Waffle 2022-04-02 20:59:41 +04:00
parent 1746be2b7f
commit 705083c2d9
3 changed files with 57 additions and 19 deletions

View file

@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## unreleased ## unreleased
### Added
- `UserId::{url, is_anonymous, is_channel, is_telegram}` convenience functions ([#197][pr197])
[pr197]: https://github.com/teloxide/teloxide-core/pull/197
### Changed ### Changed
- `user.id` now uses `UserId` type, `ChatId` now represents only _chat id_, not channel username, all `chat_id` function parameters now accept `Recipient` [**BC**] - `user.id` now uses `UserId` type, `ChatId` now represents only _chat id_, not channel username, all `chat_id` function parameters now accept `Recipient` [**BC**]

View file

@ -46,65 +46,57 @@ impl User {
} }
/// Returns an URL that links to this user in the form of /// Returns an URL that links to this user in the form of
/// `tg://user/?id=<...>` /// `tg://user/?id=<...>`.
pub fn url(&self) -> reqwest::Url { pub fn url(&self) -> reqwest::Url {
reqwest::Url::parse(&format!("tg://user/?id={}", self.id)).unwrap() self.id.url()
} }
/// Returns `true` if this is special user used by telegram bot API to /// Returns `true` if this is the special user used by telegram bot API to
/// denote an anonymous user that sends messages on behalf of a group. /// denote an anonymous user that sends messages on behalf of a group.
pub fn is_anonymous(&self) -> bool { pub fn is_anonymous(&self) -> bool {
// https://github.com/tdlib/td/blob/4791fb6a2af0257f6cad8396e10424a79ee5f768/td/telegram/ContactsManager.cpp#L4941-L4943
const ANON_ID: UserId = UserId(1087968824);
// Sanity check // Sanity check
debug_assert!( debug_assert!(
(self.id != ANON_ID) !self.id.is_anonymous()
|| (self.is_bot || (self.is_bot
&& self.first_name == "Group" && self.first_name == "Group"
&& self.last_name.is_none() && self.last_name.is_none()
&& self.username.as_deref() == Some("GroupAnonymousBot")) && self.username.as_deref() == Some("GroupAnonymousBot"))
); );
self.id == ANON_ID self.id.is_anonymous()
} }
/// Returns `true` if this is special user used by telegram bot API to /// Returns `true` if this is the special user used by telegram bot API to
/// denote an anonymous user that sends messages on behalf of a channel. /// denote an anonymous user that sends messages on behalf of a channel.
pub fn is_channel(&self) -> bool { pub fn is_channel(&self) -> bool {
// https://github.com/tdlib/td/blob/4791fb6a2af0257f6cad8396e10424a79ee5f768/td/telegram/ContactsManager.cpp#L4945-L4947
const ANON_CHANNEL_ID: UserId = UserId(136817688);
// Sanity check // Sanity check
debug_assert!( debug_assert!(
(self.id != ANON_CHANNEL_ID) !self.id.is_channel()
|| (self.is_bot || (self.is_bot
&& self.first_name == "Group" && self.first_name == "Group"
&& self.last_name.is_none() && self.last_name.is_none()
&& self.username.as_deref() == Some("GroupAnonymousBot")) && self.username.as_deref() == Some("GroupAnonymousBot"))
); );
self.id == ANON_CHANNEL_ID self.id.is_channel()
} }
/// Returns `true` if this is special user used by telegram itself. /// Returns `true` if this is the special user used by telegram itself.
/// ///
/// It is sometimes also used as a fallback, for example when a channel post /// It is sometimes also used as a fallback, for example when a channel post
/// is automatically forwarded to a group, bots in a group will get a /// is automatically forwarded to a group, bots in a group will get a
/// message where `from` is the Telegram user. /// message where `from` is the Telegram user.
pub fn is_telegram(&self) -> bool { pub fn is_telegram(&self) -> bool {
const TELEGRAM_USER_ID: UserId = UserId(777000);
// Sanity check // Sanity check
debug_assert!( debug_assert!(
(self.id != TELEGRAM_USER_ID) !self.id.is_telegram()
|| (!self.is_bot || (!self.is_bot
&& self.first_name == "Telegram" && self.first_name == "Telegram"
&& self.last_name.is_none() && self.last_name.is_none()
&& self.username.is_none()) && self.username.is_none())
); );
self.id == TELEGRAM_USER_ID self.id.is_telegram()
} }
} }

View file

@ -8,6 +8,46 @@ use serde::{Deserialize, Serialize};
#[serde(transparent)] #[serde(transparent)]
pub struct UserId(pub u64); pub struct UserId(pub u64);
impl UserId {
/// Returns an URL that links to the user with this id in the form of
/// `tg://user/?id=<...>`.
pub fn url(self) -> reqwest::Url {
reqwest::Url::parse(&format!("tg://user/?id={}", self)).unwrap()
}
/// Returns `true` if this is the id of the special user used by telegram
/// bot API to denote an anonymous user that sends messages on behalf of
/// a group.
pub fn is_anonymous(self) -> bool {
// https://github.com/tdlib/td/blob/4791fb6a2af0257f6cad8396e10424a79ee5f768/td/telegram/ContactsManager.cpp#L4941-L4943
const ANON_ID: UserId = UserId(1087968824);
self == ANON_ID
}
/// Returns `true` if this is the id of the special user used by telegram
/// bot API to denote an anonymous user that sends messages on behalf of
/// a channel.
pub fn is_channel(self) -> bool {
// https://github.com/tdlib/td/blob/4791fb6a2af0257f6cad8396e10424a79ee5f768/td/telegram/ContactsManager.cpp#L4945-L4947
const ANON_CHANNEL_ID: UserId = UserId(136817688);
self == ANON_CHANNEL_ID
}
/// Returns `true` if this is the id of the special user used by telegram
/// itself.
///
/// It is sometimes also used as a fallback, for example when a channel post
/// is automatically forwarded to a group, bots in a group will get a
/// message where `from` is the Telegram user.
pub fn is_telegram(self) -> bool {
const TELEGRAM_USER_ID: UserId = UserId(777000);
self == TELEGRAM_USER_ID
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};