use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc, TimeZone};
fn ms_to_datetime(ms: i64) -> DateTime<Utc> {
Utc.timestamp_millis_opt(ms).unwrap()
}
fn format_datetime(dt: DateTime<Utc>) -> String {
dt.format("%d.%m.%Y %H:%M:%S").to_string()
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User {
pub user_id: i64,
pub first_name: String,
pub last_name: Option<String>,
pub username: Option<String>,
pub is_bot: bool,
pub last_activity_time: Option<i64>,
}
impl User {
pub fn last_activity_datetime(&self) -> Option<DateTime<Utc>> {
self.last_activity_time.map(ms_to_datetime)
}
pub fn last_activity_time_formatted(&self) -> Option<String> {
self.last_activity_datetime().map(format_datetime)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BotInfo {
#[serde(flatten)]
pub user: User,
pub description: Option<String>,
pub avatar_url: Option<String>,
pub full_avatar_url: Option<String>,
#[serde(default)]
pub commands: Vec<BotCommand>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BotCommand {
pub name: String,
pub description: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ChatTypeKind {
Chat,
Dialog,
Unknown(String),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ChatStatusKind {
Active,
Removed,
Left,
Closed,
Unknown(String),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ChatAdminPermissionKind {
ReadAllMessages,
AddRemoveMembers,
AddAdmins,
ChangeChatInfo,
PinMessage,
Write,
CanCall,
EditLink,
PostEditDeleteMessage,
EditMessage,
DeleteMessage,
ViewStats,
Delete,
Edit,
Unknown(String),
}
impl ChatTypeKind {
pub fn from_str(s: &str) -> Self {
match s {
"chat" => ChatTypeKind::Chat,
"dialog" => ChatTypeKind::Dialog,
other => ChatTypeKind::Unknown(other.to_string()),
}
}
pub fn as_str(&self) -> &str {
match self {
ChatTypeKind::Chat => "chat",
ChatTypeKind::Dialog => "dialog",
ChatTypeKind::Unknown(s) => s.as_str(),
}
}
}
impl ChatStatusKind {
pub fn from_str(s: &str) -> Self {
match s {
"active" => ChatStatusKind::Active,
"removed" => ChatStatusKind::Removed,
"left" => ChatStatusKind::Left,
"closed" => ChatStatusKind::Closed,
other => ChatStatusKind::Unknown(other.to_string()),
}
}
pub fn as_str(&self) -> &str {
match self {
ChatStatusKind::Active => "active",
ChatStatusKind::Removed => "removed",
ChatStatusKind::Left => "left",
ChatStatusKind::Closed => "closed",
ChatStatusKind::Unknown(s) => s.as_str(),
}
}
}
impl ChatAdminPermissionKind {
pub fn from_str(s: &str) -> Self {
match s {
"read_all_messages" => ChatAdminPermissionKind::ReadAllMessages,
"add_remove_members" => ChatAdminPermissionKind::AddRemoveMembers,
"add_admins" => ChatAdminPermissionKind::AddAdmins,
"change_chat_info" => ChatAdminPermissionKind::ChangeChatInfo,
"pin_message" => ChatAdminPermissionKind::PinMessage,
"write" => ChatAdminPermissionKind::Write,
"can_call" => ChatAdminPermissionKind::CanCall,
"edit_link" => ChatAdminPermissionKind::EditLink,
"post_edit_delete_message" => ChatAdminPermissionKind::PostEditDeleteMessage,
"edit_message" => ChatAdminPermissionKind::EditMessage,
"delete_message" => ChatAdminPermissionKind::DeleteMessage,
"view_stats" => ChatAdminPermissionKind::ViewStats,
"delete" => ChatAdminPermissionKind::Delete,
"edit" => ChatAdminPermissionKind::Edit,
other => ChatAdminPermissionKind::Unknown(other.to_string()),
}
}
pub fn as_str(&self) -> &str {
match self {
ChatAdminPermissionKind::ReadAllMessages => "read_all_messages",
ChatAdminPermissionKind::AddRemoveMembers => "add_remove_members",
ChatAdminPermissionKind::AddAdmins => "add_admins",
ChatAdminPermissionKind::ChangeChatInfo => "change_chat_info",
ChatAdminPermissionKind::PinMessage => "pin_message",
ChatAdminPermissionKind::Write => "write",
ChatAdminPermissionKind::CanCall => "can_call",
ChatAdminPermissionKind::EditLink => "edit_link",
ChatAdminPermissionKind::PostEditDeleteMessage => "post_edit_delete_message",
ChatAdminPermissionKind::EditMessage => "edit_message",
ChatAdminPermissionKind::DeleteMessage => "delete_message",
ChatAdminPermissionKind::ViewStats => "view_stats",
ChatAdminPermissionKind::Delete => "delete",
ChatAdminPermissionKind::Edit => "edit",
ChatAdminPermissionKind::Unknown(s) => s.as_str(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Chat {
pub chat_id: i64,
pub r#type: String,
pub status: String,
pub title: Option<String>,
pub icon: Option<Image>,
pub last_event_time: i64,
pub participants_count: i32,
pub owner_id: Option<i64>,
pub is_public: bool,
pub link: Option<String>,
pub description: Option<String>,
pub dialog_with_user: Option<User>,
pub chat_message_id: Option<String>,
pub pinned_message: Option<serde_json::Value>,
}
impl Chat {
pub fn type_kind(&self) -> ChatTypeKind {
ChatTypeKind::from_str(&self.r#type)
}
pub fn status_kind(&self) -> ChatStatusKind {
ChatStatusKind::from_str(&self.status)
}
pub fn last_event_datetime(&self) -> DateTime<Utc> {
ms_to_datetime(self.last_event_time)
}
pub fn last_event_time_formatted(&self) -> String {
format_datetime(self.last_event_datetime())
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Image {
pub url: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChatMember {
#[serde(flatten)]
pub user: User,
pub description: Option<String>,
pub avatar_url: Option<String>,
pub full_avatar_url: Option<String>,
pub last_access_time: i64,
pub is_owner: bool,
pub is_admin: bool,
pub join_time: i64,
#[serde(default)]
pub permissions: Vec<String>,
pub alias: Option<String>,
}
impl ChatMember {
pub fn permission_kinds(&self) -> Vec<ChatAdminPermissionKind> {
self.permissions.iter().map(|s| ChatAdminPermissionKind::from_str(s)).collect()
}
pub fn last_access_datetime(&self) -> DateTime<Utc> {
ms_to_datetime(self.last_access_time)
}
pub fn last_access_time_formatted(&self) -> String {
format_datetime(self.last_access_datetime())
}
pub fn join_datetime(&self) -> DateTime<Utc> {
ms_to_datetime(self.join_time)
}
pub fn join_time_formatted(&self) -> String {
format_datetime(self.join_datetime())
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Message {
pub sender: Option<User>,
pub recipient: Recipient,
pub timestamp: i64,
pub body: Option<MessageBody>,
pub url: Option<String>,
}
impl Message {
pub fn timestamp_datetime(&self) -> DateTime<Utc> {
ms_to_datetime(self.timestamp)
}
pub fn timestamp_formatted(&self) -> String {
format_datetime(self.timestamp_datetime())
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Recipient {
pub chat_id: Option<i64>,
pub user_id: Option<i64>,
pub chat_type: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MessageBody {
pub mid: String,
pub seq: i64,
pub text: Option<String>,
pub contact: Option<Contact>,
pub location: Option<Location>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Contact {
pub name: String,
pub phone: String,
pub vcf_info: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Location {
pub latitude: f64,
pub longitude: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Update {
pub update_type: UpdateType,
pub timestamp: i64,
pub user_locale: String,
pub message: Option<Message>,
pub callback: Option<CallbackQuery>,
}
impl Update {
pub fn timestamp_datetime(&self) -> DateTime<Utc> {
ms_to_datetime(self.timestamp)
}
pub fn timestamp_formatted(&self) -> String {
format_datetime(self.timestamp_datetime())
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum UpdateType {
MessageCreated,
MessageCallback,
#[serde(other)]
Unknown,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CallbackQuery {
pub callback_id: String,
pub timestamp: i64,
pub user: User,
pub payload: String,
}
impl CallbackQuery {
pub fn timestamp_datetime(&self) -> DateTime<Utc> {
ms_to_datetime(self.timestamp)
}
pub fn timestamp_formatted(&self) -> String {
format_datetime(self.timestamp_datetime())
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Subscription {
pub url: String,
pub time: i64,
pub update_types: Vec<String>,
}
impl Subscription {
pub fn time_datetime(&self) -> DateTime<Utc> {
ms_to_datetime(self.time)
}
pub fn time_formatted(&self) -> String {
format_datetime(self.time_datetime())
}
}
#[derive(Debug, Clone, Default)]
pub struct UpdateChatInfo {
pub title: Option<String>,
pub description: Option<String>,
pub icon_token: Option<String>,
pub icon_url: Option<String>,
pub link: Option<String>,
pub is_public: Option<bool>,
pub pin: Option<String>,
pub notify: Option<bool>,
}