Skip to main content

rustigram_types/
chat.rs

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