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*/