rustigram-types 0.12.0

Telegram Bot API type definitions for rustigram
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
use serde::{Deserialize, Serialize};

use crate::games::CallbackGame;
use crate::user::ChatAdministratorRights;

use crate::message::WebAppInfo;

/// An inline keyboard attached to a message.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct InlineKeyboardMarkup {
    /// Array of button rows, each represented by an array of
    /// [`InlineKeyboardButton`] objects.
    pub inline_keyboard: Vec<Vec<InlineKeyboardButton>>,
}

impl InlineKeyboardMarkup {
    /// Creates an empty inline keyboard.
    #[must_use]
    pub fn new() -> Self {
        Self::default()
    }

    /// Appends a row of buttons.
    #[must_use]
    pub fn row(mut self, row: Vec<InlineKeyboardButton>) -> Self {
        self.inline_keyboard.push(row);
        self
    }
}

/// One button in an inline keyboard.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InlineKeyboardButton {
    /// Label text on the button.
    pub text: String,
    /// Custom emoji identifier shown before the button text.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub icon_custom_emoji_id: Option<String>,
    /// Visual style of the button (`"danger"`, `"success"`, or `"primary"`).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub style: Option<ButtonStyle>,
    /// URL to open when the button is pressed.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub url: Option<String>,
    /// Data to be sent in a callback query (1–64 bytes).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub callback_data: Option<String>,
    /// Web App to launch when the button is pressed.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub web_app: Option<WebAppInfo>,
    /// Defines an authentication button.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub login_url: Option<LoginUrl>,
    /// Pressing the button prompts the user to select a chat and opens an inline query.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub switch_inline_query: Option<String>,
    /// Pressing the button opens an inline query in the current chat.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub switch_inline_query_current_chat: Option<String>,
    /// Prompts the user to select a specific type of chat for an inline query.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub switch_inline_query_chosen_chat: Option<SwitchInlineQueryChosenChat>,
    /// Describes a button that copies specified text to the clipboard.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub copy_text: Option<CopyTextButton>,
    /// Description of the game that will be launched when the user presses the button.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub callback_game: Option<CallbackGame>,
    /// Specify `true` to send a Pay button (invoices only).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub pay: Option<bool>,
}

impl InlineKeyboardButton {
    /// Creates a callback button.
    #[must_use]
    pub fn callback(text: impl Into<String>, data: impl Into<String>) -> Self {
        Self {
            text: text.into(),
            callback_data: Some(data.into()),
            icon_custom_emoji_id: None,
            style: None,
            url: None,
            web_app: None,
            login_url: None,
            switch_inline_query: None,
            switch_inline_query_current_chat: None,
            switch_inline_query_chosen_chat: None,
            copy_text: None,
            callback_game: None,
            pay: None,
        }
    }

    /// Creates a URL button.
    #[must_use]
    pub fn url(text: impl Into<String>, url: impl Into<String>) -> Self {
        Self {
            text: text.into(),
            url: Some(url.into()),
            icon_custom_emoji_id: None,
            style: None,
            callback_data: None,
            web_app: None,
            login_url: None,
            switch_inline_query: None,
            switch_inline_query_current_chat: None,
            switch_inline_query_chosen_chat: None,
            copy_text: None,
            callback_game: None,
            pay: None,
        }
    }

    /// Creates a Web App button.
    #[must_use]
    pub fn web_app(text: impl Into<String>, url: impl Into<String>) -> Self {
        Self {
            text: text.into(),
            web_app: Some(WebAppInfo { url: url.into() }),
            icon_custom_emoji_id: None,
            style: None,
            url: None,
            callback_data: None,
            login_url: None,
            switch_inline_query: None,
            switch_inline_query_current_chat: None,
            switch_inline_query_chosen_chat: None,
            copy_text: None,
            callback_game: None,
            pay: None,
        }
    }
}

/// The visual style applied to an inline or reply keyboard button.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ButtonStyle {
    /// Red destructive button style.
    Danger,
    /// Green positive button style.
    Success,
    /// Default blue button style.
    Primary,
}

/// Parameters for a Login URL button.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LoginUrl {
    /// HTTPS URL to forward the user to.
    pub url: String,
    /// New text of the button in forwarded messages.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub forward_text: Option<String>,
    /// Username of the bot to use for user authorization.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub bot_username: Option<String>,
    /// `true` to request permission for the bot to send messages to the user.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub request_write_access: Option<bool>,
}

/// Parameters for inline query routing to a specific type of chat.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct SwitchInlineQueryChosenChat {
    /// Default inline query to insert in the input field.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub query: Option<String>,
    /// `true` if private chats with users can be chosen.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub allow_user_chats: Option<bool>,
    /// `true` if private chats with bots can be chosen.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub allow_bot_chats: Option<bool>,
    /// `true` if group and supergroup chats can be chosen.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub allow_group_chats: Option<bool>,
    /// `true` if channel chats can be chosen.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub allow_channel_chats: Option<bool>,
}

/// Represents a button that copies text to clipboard.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CopyTextButton {
    /// Text to copy (1–256 characters).
    pub text: String,
}

/// Custom keyboard shown to the message recipient.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReplyKeyboardMarkup {
    /// Array of button rows.
    pub keyboard: Vec<Vec<KeyboardButton>>,
    /// Whether the keyboard is persistent.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub is_persistent: Option<bool>,
    /// Requests clients to resize the keyboard vertically.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub resize_keyboard: Option<bool>,
    /// Requests clients to hide the keyboard after a button is used.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub one_time_keyboard: Option<bool>,
    /// Placeholder text shown in the input field when the keyboard is active.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub input_field_placeholder: Option<String>,
    /// Show keyboard to specific users only.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub selective: Option<bool>,
}

/// One button in a reply keyboard.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeyboardButton {
    /// Label text on the button.
    pub text: String,
    /// Custom emoji identifier shown before the button text.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub icon_custom_emoji_id: Option<String>,
    /// Visual style of the button.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub style: Option<ButtonStyle>,
    /// Request to select and share one or more users.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub request_users: Option<KeyboardButtonRequestUsers>,
    /// Request to select and share a chat.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub request_chat: Option<KeyboardButtonRequestChat>,
    /// Request a managed bot from the user.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub request_managed_bot: Option<KeyboardButtonRequestManagedBot>,
    /// Requests the user's phone number.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub request_contact: Option<bool>,
    /// Requests the user's current location.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub request_location: Option<bool>,
    /// Requests the user to create a poll.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub request_poll: Option<KeyboardButtonPollType>,
    /// Web App to launch when the button is pressed.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub web_app: Option<WebAppInfo>,
}

impl KeyboardButton {
    /// Creates a simple text button.
    #[must_use]
    pub fn text(label: impl Into<String>) -> Self {
        Self {
            text: label.into(),
            icon_custom_emoji_id: None,
            style: None,
            request_users: None,
            request_chat: None,
            request_managed_bot: None,
            request_contact: None,
            request_location: None,
            request_poll: None,
            web_app: None,
        }
    }

    /// Creates a button that requests the user's phone number.
    #[must_use]
    pub fn request_contact(label: impl Into<String>) -> Self {
        Self {
            request_contact: Some(true),
            ..Self::text(label)
        }
    }

    /// Creates a button that requests the user's location.
    #[must_use]
    pub fn request_location(label: impl Into<String>) -> Self {
        Self {
            request_location: Some(true),
            ..Self::text(label)
        }
    }
}

/// Defines criteria for selecting users via a keyboard button.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeyboardButtonRequestUsers {
    /// Signed 32-bit identifier of the request.
    pub request_id: i32,
    /// `true` to request only bots.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub user_is_bot: Option<bool>,
    /// `true` to request only premium users.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub user_is_premium: Option<bool>,
    /// Maximum number of users to be selected (1–10, default 1).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub max_quantity: Option<u8>,
    /// `true` to request the user's name.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub request_name: Option<bool>,
    /// `true` to request the user's username.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub request_username: Option<bool>,
    /// `true` to request the user's profile photo.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub request_photo: Option<bool>,
}

/// Defines criteria for selecting a chat via a keyboard button.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeyboardButtonRequestChat {
    /// Signed 32-bit identifier of the request.
    pub request_id: i32,
    /// `true` to request a channel chat; `false` for group or supergroup.
    pub chat_is_channel: bool,
    /// `true` to request a forum supergroup.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub chat_is_forum: Option<bool>,
    /// `true` to request a chat with a username.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub chat_has_username: Option<bool>,
    /// `true` to request a chat owned by the user.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub chat_is_created: Option<bool>,
    /// Required administrator rights of the user in the chat.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub user_administrator_rights: Option<ChatAdministratorRights>,
    /// Required administrator rights of the bot in the chat.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub bot_administrator_rights: Option<ChatAdministratorRights>,
    /// `true` to request a chat where the bot is a member.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub bot_is_member: Option<bool>,
    /// `true` to request the chat title.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub request_title: Option<bool>,
    /// `true` to request the chat username.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub request_username: Option<bool>,
    /// `true` to request the chat photo.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub request_photo: Option<bool>,
}

/// Defines parameters for requesting the creation of a managed bot.
///
/// Bot API 9.6 — available for bots that have enabled managed bot creation in @BotFather.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct KeyboardButtonRequestManagedBot {
    /// Signed 32-bit identifier of the request; must be unique within the message.
    pub request_id: i32,
    /// Suggested name for the new bot.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub suggested_name: Option<String>,
    /// Suggested username for the new bot.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub suggested_username: Option<String>,
}

/// The type of poll requested via a keyboard button.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeyboardButtonPollType {
    /// `"quiz"`, `"regular"`, or absent (any type).
    #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
    pub kind: Option<String>,
}

/// Instructs clients to remove the reply keyboard.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReplyKeyboardRemove {
    /// Must be `true`.
    pub remove_keyboard: bool,
    /// Show the remove keyboard to specific users only.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub selective: Option<bool>,
}

/// Forces a reply from the user.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ForceReply {
    /// Must be `true`.
    pub force_reply: bool,
    /// Placeholder text in the input field when the reply is active (1–64 characters).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub input_field_placeholder: Option<String>,
    /// Show the force reply to specific users only.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub selective: Option<bool>,
}

/// All reply markup variants.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ReplyMarkup {
    /// An inline keyboard attached to the message.
    InlineKeyboard(InlineKeyboardMarkup),
    /// A custom reply keyboard shown to the user.
    ReplyKeyboard(ReplyKeyboardMarkup),
    /// Removes the reply keyboard.
    Remove(ReplyKeyboardRemove),
    /// Forces the user to reply to the message.
    ForceReply(ForceReply),
}

/// Menu button configuration.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum MenuButton {
    /// Shows the list of bot commands.
    Commands,
    /// Launches a Web App.
    WebApp {
        /// Button label text.
        text: String,
        /// Web App to launch.
        web_app: WebAppInfo,
    },
    /// No action — uses the default behavior.
    Default,
}

/// A keyboard button prepared for use by a Mini App.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[non_exhaustive]
pub struct PreparedKeyboardButton {
    /// Unique identifier of the prepared button.
    pub id: String,
}