Skip to main content

grammers_client/message/
button.rs

1// Copyright 2020 - developers of the `grammers` project.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Custom keyboards and inline buttons used by messages.
10
11use grammers_tl_types as tl;
12
13/// Inline button to be used as the reply markup underneath a message.
14pub struct Button {
15    pub raw: tl::enums::KeyboardButton,
16}
17
18/// Key to be used as the reply markup of an alternate virtual keyboard.
19pub struct Key {
20    pub raw: tl::enums::KeyboardButton,
21}
22
23impl Button {
24    /// Creates a button that will trigger a [`crate::update::CallbackQuery`] when clicked.
25    ///
26    /// Although any combination of bytes can be used (including null, and not just UTF-8), [there is
27    /// a limit](https://core.telegram.org/bots/api#inlinekeyboardbutton) to how long the payload data
28    /// can be (see the description for the `callback_data` field for an up-to-date value). If you
29    /// need to store more data than that, consider storing the real data in some form of database,
30    /// and a reference to that data's row in the button's payload.
31    ///
32    /// Both the text and bytes data must be non-empty.
33    pub fn data<T: Into<String>, B: Into<Vec<u8>>>(text: T, bytes: B) -> Button {
34        Button {
35            raw: tl::types::KeyboardButtonCallback {
36                text: text.into(),
37                data: bytes.into(),
38                requires_password: false,
39                style: None,
40            }
41            .into(),
42        }
43    }
44
45    /// Creates a button to force the user to switch to inline mode (perform inline queries).
46    ///
47    /// Pressing the button will insert the bot's username and the specified inline query in the input
48    /// field.
49    pub fn switch<T: Into<String>, Q: Into<String>>(text: T, query: Q) -> Button {
50        Button {
51            raw: tl::types::KeyboardButtonSwitchInline {
52                text: text.into(),
53                query: query.into(),
54                same_peer: true,
55                style: None,
56                peer_types: None,
57            }
58            .into(),
59        }
60    }
61    /// Creates a button identical to [`Self::switch`], except the user will be prompted to select a
62    /// different peer.
63    ///
64    /// Pressing the button will prompt the user to select one of their peers, open that peer and
65    /// insert the bot's username and the specified inline query in the input field.
66    pub fn switch_elsewhere<T: Into<String>, Q: Into<String>>(text: T, query: Q) -> Button {
67        Button {
68            raw: tl::types::KeyboardButtonSwitchInline {
69                text: text.into(),
70                query: query.into(),
71                same_peer: false,
72                style: None,
73                peer_types: None,
74            }
75            .into(),
76        }
77    }
78
79    /// Creates a button that when clicked will ask the user if they want to open the specified URL.
80    ///
81    /// The URL will be visible to the user before it's opened unless it's trusted (such as Telegram's
82    /// domain).
83    pub fn url<T: Into<String>, U: Into<String>>(text: T, url: U) -> Button {
84        Button {
85            raw: tl::types::KeyboardButtonUrl {
86                style: None,
87                text: text.into(),
88                url: url.into(),
89            }
90            .into(),
91        }
92    }
93
94    /// Creates a button that when clicked will open the specified URL in an in-app browser.
95    pub fn webview<T: Into<String>, U: Into<String>>(text: T, url: U) -> Button {
96        Button {
97            raw: tl::types::KeyboardButtonWebView {
98                style: None,
99                text: text.into(),
100                url: url.into(),
101            }
102            .into(),
103        }
104    }
105}
106
107impl Key {
108    /// Creates a simple keyboard key.
109    ///
110    /// When pressed, the button's text will be sent as a normal message, as if the user had typed it.
111    pub fn text<T: Into<String>>(text: T) -> Key {
112        Key {
113            raw: tl::types::KeyboardButton {
114                style: None,
115                text: text.into(),
116            }
117            .into(),
118        }
119    }
120
121    /// Creates a keyboard key to request the user's contact information (including the phone).
122    pub fn request_phone<T: Into<String>>(text: T) -> Key {
123        Key {
124            raw: tl::types::KeyboardButtonRequestPhone {
125                style: None,
126                text: text.into(),
127            }
128            .into(),
129        }
130    }
131
132    /// Creates a keyboard key to request the user's current geo-location.
133    pub fn request_geo<T: Into<String>>(text: T) -> Key {
134        Key {
135            raw: tl::types::KeyboardButtonRequestGeoLocation {
136                style: None,
137                text: text.into(),
138            }
139            .into(),
140        }
141    }
142
143    /// Creates a keyboard key that will direct the user to create and send a poll when pressed.
144    ///
145    /// This is only available in direct conversations with the user.
146    pub fn request_poll<T: Into<String>>(text: T) -> Key {
147        Key {
148            raw: tl::types::KeyboardButtonRequestPoll {
149                style: None,
150                text: text.into(),
151                quiz: None,
152            }
153            .into(),
154        }
155    }
156
157    /// Creates a keyboard key identical to [`Self::request_poll`], except the poll requested must be a quiz.
158    ///
159    /// This is only available in direct conversations with the user.
160    pub fn request_quiz<T: Into<String>>(text: T) -> Key {
161        Key {
162            raw: tl::types::KeyboardButtonRequestPoll {
163                style: None,
164                text: text.into(),
165                quiz: Some(true),
166            }
167            .into(),
168        }
169    }
170}
171
172/*
173TODO implement other buttons
174(with password) keyboardButtonCallback#35bbdb6b flags:# requires_password:flags.0?true text:string data:bytes = KeyboardButton;
175keyboardButtonUrlAuth#10b78d29 flags:# text:string fwd_text:flags.0?string url:string button_id:int = KeyboardButton;
176keyboardButtonGame#50f41ccf text:string = KeyboardButton;
177keyboardButtonBuy#afd93fbb text:string = KeyboardButton;
178inputKeyboardButtonUrlAuth#d02e7fd4 flags:# request_write_access:flags.0?true text:string fwd_text:flags.1?string url:string bot:InputUser = KeyboardButton;
179*/