mobot/api/
query.rs

1use mobot_derive::BotRequest;
2use serde::{Deserialize, Serialize};
3
4use super::{user::User, API};
5
6#[derive(Default, Debug, Clone, Deserialize, Serialize)]
7pub struct CallbackQuery {
8    /// Unique identifier for this query
9    pub id: String,
10
11    /// Sender of the query
12    pub from: User,
13
14    /// Message with the callback button that originated the query. Note that
15    /// message content and message date will not be available if the message
16    /// is too old.
17    pub message: Option<super::Message>,
18
19    /// Identifier of the message sent via the bot in inline mode, that
20    /// originated the query.
21    pub inline_message_id: Option<String>,
22
23    /// Data associated with the callback button. Be aware that a bad client
24    /// can send arbitrary data in this field.
25    pub data: Option<String>,
26}
27
28#[derive(Debug, Clone, Deserialize, Serialize)]
29pub struct InlineQuery {
30    /// Unique identifier for this query
31    pub id: String,
32
33    /// Sender
34    pub from: User,
35
36    /// Text of the query (up to 512 characters)
37    pub query: String,
38
39    /// Offset of the results to be returned, can be controlled by the bot
40    pub offset: String,
41}
42
43#[derive(Debug, Serialize, Clone, Default, BotRequest)]
44pub struct AnswerInlineQuery {
45    /// Unique identifier for the answered query
46    pub inline_query_id: String,
47
48    /// A JSON-serialized array of results for the inline query
49    pub results: Vec<InlineQueryResultArticle>,
50
51    /// The maximum amount of time in seconds that the result of the inline query
52    /// may be cached on the server. Defaults to 300.
53    #[serde(skip_serializing_if = "Option::is_none")]
54    pub cache_time: Option<i64>,
55
56    /// Pass True, if results may be cached on the server side only for the user
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub is_personal: Option<bool>,
59
60    /// Pass the offset that a client should send in the next query with the same
61    #[serde(skip_serializing_if = "Option::is_none")]
62    pub next_offset: Option<String>,
63}
64
65impl AnswerInlineQuery {
66    pub fn new(inline_query_id: String) -> Self {
67        Self {
68            inline_query_id,
69            ..Default::default()
70        }
71    }
72
73    pub fn with_article_text(self, title: impl Into<String>, text: impl Into<String>) -> Self {
74        Self {
75            inline_query_id: self.inline_query_id,
76            results: vec![InlineQueryResultArticle {
77                id: "0".to_string(),
78                result_type: "article".to_string(),
79                title: title.into(),
80                input_message_content: InputMessageContent {
81                    message_text: text.into(),
82                },
83            }],
84            ..Default::default()
85        }
86    }
87}
88
89#[derive(Debug, Serialize, Clone, Default)]
90pub struct InlineQueryResultArticle {
91    /// Unique identifier for this result, 1-64 Bytes
92    pub id: String,
93
94    /// Type of the result
95    #[serde(rename = "type")]
96    pub result_type: String,
97
98    /// Title of the result
99    pub title: String,
100
101    /// Content of the message to be sent
102    pub input_message_content: InputMessageContent,
103}
104
105#[derive(Debug, Serialize, Clone, Default)]
106pub struct InputMessageContent {
107    /// Text of the message to be sent, 1-4096 characters
108    pub message_text: String,
109}
110
111#[derive(Debug, Clone, Deserialize, Serialize, Default, BotRequest)]
112pub struct AnswerCallbackQueryRequest {
113    /// Unique identifier for the query to be answered
114    pub callback_query_id: String,
115
116    /// Text of the notification. If not specified, nothing will be shown to the user, 0-200 characters
117    #[serde(skip_serializing_if = "Option::is_none")]
118    pub text: Option<String>,
119
120    /// If true, an alert will be shown by the client instead of a notification at the top of the chat screen.
121    #[serde(skip_serializing_if = "Option::is_none")]
122    pub show_alert: Option<bool>,
123
124    /// URL that will be opened by the user's client. If you have created a Game and accepted the conditions via @Botfather,
125    /// specify the URL that opens your game – note that this will only work if the query comes from a callback_game button.
126    /// Otherwise, you may use links like telegram.me/your_bot?start=XXXX that open your bot with a parameter.
127    #[serde(skip_serializing_if = "Option::is_none")]
128    pub url: Option<String>,
129
130    /// The maximum amount of time in seconds that the result of the callback query may be cached client-side.
131    /// Telegram apps will support caching starting in version 3.14. Defaults to 0.
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub cache_time: Option<i64>,
134}
135
136impl AnswerCallbackQueryRequest {
137    pub fn new(callback_query_id: String) -> Self {
138        Self {
139            callback_query_id,
140            ..Default::default()
141        }
142    }
143
144    pub fn with_text(self, text: impl Into<String>) -> Self {
145        Self {
146            callback_query_id: self.callback_query_id,
147            text: Some(text.into()),
148            ..Default::default()
149        }
150    }
151
152    pub fn with_show_alert(self, show_alert: bool) -> Self {
153        Self {
154            callback_query_id: self.callback_query_id,
155            show_alert: Some(show_alert),
156            ..Default::default()
157        }
158    }
159}
160
161impl API {
162    pub async fn answer_inline_query(&self, req: &AnswerInlineQuery) -> anyhow::Result<bool> {
163        self.client.post("answerInlineQuery", req).await
164    }
165
166    pub async fn answer_callback_query(
167        &self,
168        req: &AnswerCallbackQueryRequest,
169    ) -> anyhow::Result<bool> {
170        self.client.post("answerCallbackQuery", req).await
171    }
172}