Skip to main content

rustigram_types/
chat.rs

1use serde::{Deserialize, Serialize};
2
3use crate::message::Message;
4use crate::user::User;
5
6#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
7/// Type of a Telegram chat.
8#[serde(rename_all = "snake_case")]
9pub enum ChatType {
10    /// One-on-one conversation.
11    Private,
12    /// Group chat.
13    Group,
14    /// Supergroup.
15    Supergroup,
16    /// Broadcast channel.
17    Channel,
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
21/// Minimal chat descriptor — used in messages and updates.
22pub struct Chat {
23    /// Unique identifier for this chat.
24    pub id: i64,
25
26    /// Type of chat.
27    #[serde(rename = "type")]
28    pub kind: ChatType,
29
30    /// Title, for supergroups, channels and group chats.
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub title: Option<String>,
33
34    /// Username, for private chats, supergroups and channels.
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub username: Option<String>,
37
38    /// First name of the other party in a private chat.
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub first_name: Option<String>,
41
42    /// Last name of the other party in a private chat.
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub last_name: Option<String>,
45
46    /// `true` if the supergroup chat is a forum (has topics enabled).
47    #[serde(skip_serializing_if = "Option::is_none")]
48    pub is_forum: Option<bool>,
49    /// `true` if the chat is the direct messages chat of a channel.
50    #[serde(skip_serializing_if = "Option::is_none")]
51    pub is_direct_messages: Option<bool>,
52    /// The bot that processes join request queries in the chat.
53    ///
54    /// Only available to chat administrators.
55    #[serde(skip_serializing_if = "Option::is_none")]
56    pub guard_bot: Option<User>,
57}
58
59impl Chat {
60    /// Returns the chat's display name.
61    #[must_use]
62    pub fn display_name(&self) -> String {
63        self.title
64            .clone()
65            .or_else(|| {
66                self.first_name.as_ref().map(|f| {
67                    self.last_name
68                        .as_ref()
69                        .map_or(f.clone(), |l| format!("{f} {l}"))
70                })
71            })
72            .or_else(|| self.username.clone())
73            .unwrap_or_else(|| self.id.to_string())
74    }
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize)]
78/// Full chat information — returned by `getChat`.
79pub struct ChatFullInfo {
80    /// Unique identifier for this chat.
81    pub id: i64,
82
83    /// Type of chat.
84    #[serde(rename = "type")]
85    pub kind: ChatType,
86
87    /// Title of the chat (groups, supergroups, and channels).
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub title: Option<String>,
90
91    /// Username of the chat.
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub username: Option<String>,
94
95    /// First name of the other party in a private chat.
96    #[serde(skip_serializing_if = "Option::is_none")]
97    pub first_name: Option<String>,
98
99    /// Last name of the other party in a private chat.
100    #[serde(skip_serializing_if = "Option::is_none")]
101    pub last_name: Option<String>,
102
103    /// `true` if the supergroup chat is a forum (has topics enabled).
104    #[serde(skip_serializing_if = "Option::is_none")]
105    pub is_forum: Option<bool>,
106    /// `true` if the chat is the direct messages chat of a channel.
107    #[serde(skip_serializing_if = "Option::is_none")]
108    pub is_direct_messages: Option<bool>,
109    /// Identifier of the accent color for the chat name and backgrounds.
110    #[serde(skip_serializing_if = "Option::is_none")]
111    pub accent_color_id: Option<u32>,
112
113    /// Maximum number of reactions that can be set on a message.
114    #[serde(skip_serializing_if = "Option::is_none")]
115    pub max_reaction_count: Option<u32>,
116
117    /// Chat photo.
118    #[serde(skip_serializing_if = "Option::is_none")]
119    pub photo: Option<ChatPhoto>,
120
121    /// Active usernames of a channel, supergroup, or user.
122    #[serde(skip_serializing_if = "Option::is_none")]
123    pub active_usernames: Option<Vec<String>>,
124
125    /// Bio of the other party in a private chat.
126    #[serde(skip_serializing_if = "Option::is_none")]
127    pub bio: Option<String>,
128
129    /// `true` if privacy settings prevent viewing the other party's bio.
130    #[serde(skip_serializing_if = "Option::is_none")]
131    pub has_private_forwards: Option<bool>,
132
133    /// `true` if the privacy settings prevent sending voice and video note messages.
134    #[serde(skip_serializing_if = "Option::is_none")]
135    pub has_restricted_voice_and_video_messages: Option<bool>,
136
137    /// `true` if users need to join in order to send messages.
138    #[serde(skip_serializing_if = "Option::is_none")]
139    pub join_to_send_messages: Option<bool>,
140
141    /// `true` if all users directly joining the supergroup need to be approved.
142    #[serde(skip_serializing_if = "Option::is_none")]
143    pub join_by_request: Option<bool>,
144
145    /// Description, for groups, supergroups and channel chats.
146    #[serde(skip_serializing_if = "Option::is_none")]
147    pub description: Option<String>,
148
149    /// Primary invite link for the chat.
150    #[serde(skip_serializing_if = "Option::is_none")]
151    pub invite_link: Option<String>,
152
153    /// Latest pinned message.
154    #[serde(skip_serializing_if = "Option::is_none")]
155    pub pinned_message: Option<Box<Message>>,
156
157    /// Default chat member permissions, for groups and supergroups.
158    #[serde(skip_serializing_if = "Option::is_none")]
159    pub permissions: Option<ChatPermissions>,
160
161    /// `true` if paid media messages can be sent or forwarded to the channel chat.
162    #[serde(skip_serializing_if = "Option::is_none")]
163    pub can_send_paid_media: Option<bool>,
164
165    /// Delay in seconds between consecutive messages from a non-administrator.
166    #[serde(skip_serializing_if = "Option::is_none")]
167    pub slow_mode_delay: Option<u32>,
168
169    /// Delay in seconds after which all messages sent by the user will be automatically
170    /// deleted.
171    #[serde(skip_serializing_if = "Option::is_none")]
172    pub unrestrict_boost_count: Option<u32>,
173
174    /// Message auto-delete timer setting for new messages.
175    #[serde(skip_serializing_if = "Option::is_none")]
176    pub message_auto_delete_time: Option<u32>,
177
178    /// `true` if aggressive anti-spam checks are enabled in the supergroup.
179    #[serde(skip_serializing_if = "Option::is_none")]
180    pub has_aggressive_anti_spam_enabled: Option<bool>,
181
182    /// `true` if non-administrators can only get the list of bots and administrators.
183    #[serde(skip_serializing_if = "Option::is_none")]
184    pub has_hidden_members: Option<bool>,
185
186    /// `true` if messages from the chat can't be forwarded to other chats.
187    #[serde(skip_serializing_if = "Option::is_none")]
188    pub has_protected_content: Option<bool>,
189
190    /// `true` if new chat members will have access to old messages.
191    #[serde(skip_serializing_if = "Option::is_none")]
192    pub has_visible_history: Option<bool>,
193
194    /// Name of the group sticker set.
195    #[serde(skip_serializing_if = "Option::is_none")]
196    pub sticker_set_name: Option<String>,
197
198    /// `true` if the bot can change the group sticker set.
199    #[serde(skip_serializing_if = "Option::is_none")]
200    pub can_set_sticker_set: Option<bool>,
201
202    /// Custom emoji identifier of the emoji chosen by the chat for the reply header.
203    #[serde(skip_serializing_if = "Option::is_none")]
204    pub custom_emoji_sticker_set_name: Option<String>,
205
206    /// Unique identifier for the linked chat.
207    #[serde(skip_serializing_if = "Option::is_none")]
208    pub linked_chat_id: Option<i64>,
209
210    /// The location to which the supergroup is connected.
211    #[serde(skip_serializing_if = "Option::is_none")]
212    pub location: Option<ChatLocation>,
213}
214
215#[derive(Debug, Clone, Serialize, Deserialize)]
216/// Chat photo information.
217pub struct ChatPhoto {
218    /// File identifier of small (160x160) chat photo.
219    pub small_file_id: String,
220    /// Unique file identifier of small chat photo.
221    pub small_file_unique_id: String,
222    /// File identifier of big (640x640) chat photo.
223    pub big_file_id: String,
224    /// Unique file identifier of big chat photo.
225    pub big_file_unique_id: String,
226}
227
228#[derive(Debug, Clone, Default, Serialize, Deserialize)]
229/// Defines chat permissions for regular members.
230pub struct ChatPermissions {
231    /// `true` if the user is allowed to send text messages, rich messages, contacts,
232    /// giveaways, giveaway winners, invoices, locations, and venues.
233    #[serde(skip_serializing_if = "Option::is_none")]
234    pub can_send_messages: Option<bool>,
235    /// Allows sending audio files.
236    #[serde(skip_serializing_if = "Option::is_none")]
237    pub can_send_audios: Option<bool>,
238    /// Allows sending documents.
239    #[serde(skip_serializing_if = "Option::is_none")]
240    pub can_send_documents: Option<bool>,
241    /// Allows sending photos.
242    #[serde(skip_serializing_if = "Option::is_none")]
243    pub can_send_photos: Option<bool>,
244    /// Allows sending videos.
245    #[serde(skip_serializing_if = "Option::is_none")]
246    pub can_send_videos: Option<bool>,
247    /// Allows sending video notes.
248    #[serde(skip_serializing_if = "Option::is_none")]
249    pub can_send_video_notes: Option<bool>,
250    /// Allows sending voice notes.
251    #[serde(skip_serializing_if = "Option::is_none")]
252    pub can_send_voice_notes: Option<bool>,
253    /// Allows sending polls.
254    #[serde(skip_serializing_if = "Option::is_none")]
255    pub can_send_polls: Option<bool>,
256    /// Allows sending other types of messages (stickers, GIFs, games, etc.).
257    #[serde(skip_serializing_if = "Option::is_none")]
258    pub can_send_other_messages: Option<bool>,
259    /// Allows adding web page previews to messages.
260    #[serde(skip_serializing_if = "Option::is_none")]
261    pub can_add_web_page_previews: Option<bool>,
262    /// Allows changing the chat title, photo, and other settings.
263    #[serde(skip_serializing_if = "Option::is_none")]
264    pub can_change_info: Option<bool>,
265    /// Allows inviting new users to the chat.
266    #[serde(skip_serializing_if = "Option::is_none")]
267    pub can_invite_users: Option<bool>,
268    /// Allows pinning messages.
269    #[serde(skip_serializing_if = "Option::is_none")]
270    pub can_pin_messages: Option<bool>,
271    /// Allows managing forum topics (supergroups only).
272    #[serde(skip_serializing_if = "Option::is_none")]
273    pub can_manage_topics: Option<bool>,
274    /// Allows editing the chat tag (supergroups only).
275    #[serde(skip_serializing_if = "Option::is_none")]
276    pub can_edit_tag: Option<bool>,
277    /// Allows reacting to messages.
278    ///
279    /// If omitted, defaults to the value of `can_send_messages`.
280    #[serde(skip_serializing_if = "Option::is_none")]
281    pub can_react_to_messages: Option<bool>,
282}
283
284/// Location to which the supergroup is connected.
285#[derive(Debug, Clone, Serialize, Deserialize)]
286pub struct ChatLocation {
287    /// The location to which the supergroup is connected.
288    pub location: Location,
289    /// Location address; 1-64 characters.
290    pub address: String,
291}
292
293/// Geographic point on the map.
294#[derive(Debug, Clone, Serialize, Deserialize)]
295pub struct Location {
296    /// Latitude as defined by the sender.
297    pub latitude: f64,
298    /// Longitude as defined by the sender.
299    pub longitude: f64,
300    /// Radius of uncertainty for the location, in metres (0–1500).
301    #[serde(skip_serializing_if = "Option::is_none")]
302    pub horizontal_accuracy: Option<f64>,
303    /// Time relative to the message sending date, during which the location can
304    /// be updated; in seconds.
305    #[serde(skip_serializing_if = "Option::is_none")]
306    pub live_period: Option<u32>,
307    /// Direction of movement in degrees (1–360).
308    #[serde(skip_serializing_if = "Option::is_none")]
309    pub heading: Option<u16>,
310    /// Maximum distance in metres for proximity alerts.
311    #[serde(skip_serializing_if = "Option::is_none")]
312    pub proximity_alert_radius: Option<u32>,
313}
314
315/// Represents a venue.
316#[derive(Debug, Clone, Serialize, Deserialize)]
317pub struct Venue {
318    /// Venue location.
319    pub location: Location,
320    /// Name of the venue.
321    pub title: String,
322    /// Address of the venue.
323    pub address: String,
324    /// Foursquare identifier of the venue.
325    #[serde(skip_serializing_if = "Option::is_none")]
326    pub foursquare_id: Option<String>,
327    /// Foursquare type of the venue.
328    #[serde(skip_serializing_if = "Option::is_none")]
329    pub foursquare_type: Option<String>,
330    /// Google Places identifier of the venue.
331    #[serde(skip_serializing_if = "Option::is_none")]
332    pub google_place_id: Option<String>,
333    /// Google Places type of the venue.
334    #[serde(skip_serializing_if = "Option::is_none")]
335    pub google_place_type: Option<String>,
336}
337
338#[derive(Debug, Clone, Serialize, Deserialize)]
339/// Invite link for a chat.
340pub struct ChatInviteLink {
341    /// The invite link.
342    pub invite_link: String,
343    /// Creator of the link.
344    pub creator: User,
345    /// `true` if users joining the chat via the link need to be approved by chat admins.
346    pub creates_join_request: bool,
347    /// `true` if the link is primary.
348    pub is_primary: bool,
349    /// `true` if the link is revoked.
350    pub is_revoked: bool,
351    /// Invite link name.
352    #[serde(skip_serializing_if = "Option::is_none")]
353    pub name: Option<String>,
354    /// Point in time (Unix) when the link will expire or has been expired.
355    #[serde(skip_serializing_if = "Option::is_none")]
356    pub expire_date: Option<i64>,
357    /// Maximum number of users that can be members of the chat simultaneously.
358    #[serde(skip_serializing_if = "Option::is_none")]
359    pub member_limit: Option<u32>,
360    /// Number of pending join requests created using this link.
361    #[serde(skip_serializing_if = "Option::is_none")]
362    pub pending_join_request_count: Option<u32>,
363    /// Number of seconds the subscription created by this link will be active.
364    #[serde(skip_serializing_if = "Option::is_none")]
365    pub subscription_period: Option<u32>,
366    /// Number of Telegram Stars a user must pay for a subscription.
367    #[serde(skip_serializing_if = "Option::is_none")]
368    pub subscription_price: Option<u32>,
369}
370
371#[derive(Debug, Clone, Serialize, Deserialize)]
372/// Represents a join request sent to a chat.
373pub struct ChatJoinRequest {
374    /// The chat the join request was sent to.
375    pub chat: Chat,
376    /// The user that sent the join request.
377    pub from: User,
378    /// Identifier of a private chat with the user.
379    pub user_chat_id: i64,
380    /// Date the request was sent as Unix time.
381    pub date: i64,
382    /// Bio of the user, if available.
383    #[serde(skip_serializing_if = "Option::is_none")]
384    pub bio: Option<String>,
385    /// The invite link used to send the request, if any.
386    #[serde(skip_serializing_if = "Option::is_none")]
387    pub invite_link: Option<ChatInviteLink>,
388    /// Identifier of the join request query.
389    ///
390    /// When present, the bot must call `answerChatJoinRequestQuery` or
391    /// `sendChatJoinRequestWebApp` within 10 seconds.
392    #[serde(skip_serializing_if = "Option::is_none")]
393    pub query_id: Option<String>,
394}
395
396// ─── Link & InputMediaLink ────────────────────────────────────────────────────
397
398/// Represents an HTTP link.
399#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
400pub struct Link {
401    /// The HTTP(S) URL.
402    pub url: String,
403}
404
405/// An HTTP link to be used as [`InputPollOptionMedia`](crate::poll::InputPollOptionMedia).
406#[derive(Debug, Clone, Serialize, Deserialize)]
407pub struct InputMediaLink {
408    /// Always `"link"`.
409    #[serde(rename = "type")]
410    pub kind: String,
411    /// The HTTP(S) URL of the link.
412    pub url: String,
413}
414
415impl InputMediaLink {
416    /// Creates a new `InputMediaLink` from a URL.
417    pub fn new(url: impl Into<String>) -> Self {
418        Self {
419            kind: "link".to_owned(),
420            url: url.into(),
421        }
422    }
423}