1use sha2::Sha256;
2use hmac::{Hmac, Mac};
3use uuid::Uuid;
4
5type HmacSha256 = Hmac<Sha256>;
6
7pub struct ApiEndpoints {
8 #[cfg(feature = "token")]
9 pub token_api_builder: Box<dyn Fn(&String, &String, &String) -> String + Sync + Send>,
10
11 #[cfg(feature = "notifications-direct")]
12 pub direct_notification_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
13
14 #[cfg(feature = "notifications-internal")]
15 pub internal_notification_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
16
17 #[cfg(feature = "events-edit_event")]
18 pub edit_event_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
19
20 #[cfg(feature = "events-reply_event")]
21 pub reply_event_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
22
23 #[cfg(feature = "events-status")]
24 pub event_status_api_builder: Box<dyn Fn(&String, &Uuid) -> String + Sync + Send>,
25
26 #[cfg(feature = "events-typing")]
27 pub typing_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
28
29 #[cfg(feature = "events-stop_typing")]
30 pub stop_typing_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
31
32 #[cfg(feature = "files-upload")]
33 pub upload_file_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
34
35 #[cfg(feature = "files-download")]
36 pub download_file_api_builder: Box<dyn Fn(&String, &Uuid, &Uuid, &bool) -> String + Sync + Send>,
37
38 #[cfg(feature = "stickers-new_sticker_pack")]
39 pub new_sticker_pack_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
40
41 #[cfg(feature = "stickers-sticker_packs_list")]
42 pub sticker_packs_list_api_builder: Box<dyn Fn(&String, &Option<Uuid>, &Option<u32>, &Option<String>) -> String + Sync + Send>,
43
44 #[cfg(feature = "stickers-add_sticker")]
45 pub add_sticker_api_builder: Box<dyn Fn(&String, &Uuid) -> String + Sync + Send>,
46
47 #[cfg(feature = "stickers-get_sticker_pack")]
48 pub get_sticker_pack_api_builder: Box<dyn Fn(&String, &Uuid) -> String + Sync + Send>,
49
50 #[cfg(feature = "stickers-get_sticker")]
51 pub get_sticker_api_builder: Box<dyn Fn(&String, &Uuid, &Uuid) -> String + Sync + Send>,
52
53 #[cfg(feature = "stickers-update_sticker_pack")]
54 pub update_sticker_pack_api_builder: Box<dyn Fn(&String, &Uuid) -> String + Sync + Send>,
55
56 #[cfg(feature = "stickers-delete_sticker_pack")]
57 pub delete_sticker_pack_api_builder: Box<dyn Fn(&String, &Uuid) -> String + Sync + Send>,
58
59 #[cfg(feature = "stickers-delete_sticker")]
60 pub delete_sticker_api_builder: Box<dyn Fn(&String, &Uuid, &Uuid) -> String + Sync + Send>,
61
62 #[cfg(feature = "chats-list")]
63 pub get_chats_list_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
64
65 #[cfg(feature = "chats-info")]
66 pub get_chat_info_api_builder: Box<dyn Fn(&String, &Uuid) -> String + Sync + Send>,
67
68 #[cfg(feature = "chats-add_user")]
69 pub add_user_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
70
71 #[cfg(feature = "chats-remove_user")]
72 pub remove_user_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
73
74 #[cfg(feature = "chats-add_admin")]
75 pub add_admin_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
76
77 #[cfg(feature = "chats-set_stealth")]
78 pub set_stealth_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
79
80 #[cfg(feature = "chats-disable_stealth")]
81 pub disable_stealth_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
82
83 #[cfg(feature = "chats-create")]
84 pub create_chat_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
85
86 #[cfg(feature = "chats-pin_message")]
87 pub pin_message_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
88
89 #[cfg(feature = "chats-unpin_message")]
90 pub unpin_message_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
91
92 #[cfg(feature = "users-by_email")]
93 pub get_users_by_email_api_builder: Box<dyn Fn(&String) -> String + Sync + Send>,
94
95 #[cfg(feature = "users-by_huid")]
96 pub get_user_by_huid_api_builder: Box<dyn Fn(&String, &Uuid) -> String + Sync + Send>,
97
98 #[cfg(feature = "users-by_login")]
99 pub get_user_by_login_api_builder: Box<dyn Fn(&String, &String, &String) -> String + Sync + Send>,
100
101 #[cfg(feature = "users-by_other_id")]
102 pub get_user_by_other_id_api_builder: Box<dyn Fn(&String, &String) -> String + Sync + Send>,
103
104 #[cfg(feature = "users-users_as_csv")]
105 pub get_users_as_csv_api_builder: Box<dyn Fn(&String, bool, bool, bool) -> String + Sync + Send>,
106}
107
108impl Default for ApiEndpoints {
109 fn default() -> Self { Self::new() }
110}
111
112impl ApiEndpoints {
113 pub fn new() -> Self {
114 Self {
115 #[cfg(feature = "token")]
116 token_api_builder: Self::get_token_api_builder(),
117 #[cfg(feature = "notifications-direct")]
118 direct_notification_api_builder: Self::get_direct_notification_api_builder(),
119 #[cfg(feature = "notifications-internal")]
120 internal_notification_api_builder: Self::get_internal_notification_api_builder(),
121 #[cfg(feature = "events-edit_event")]
122 edit_event_api_builder: Self::get_edit_event_api_builder(),
123 #[cfg(feature = "events-reply_event")]
124 reply_event_api_builder: Self::get_reply_event_api_builder(),
125 #[cfg(feature = "events-status")]
126 event_status_api_builder: Self::get_event_status_api_builder(),
127 #[cfg(feature = "events-typing")]
128 typing_api_builder: Self::get_typing_api_builder(),
129 #[cfg(feature = "events-stop_typing")]
130 stop_typing_api_builder: Self::get_stop_typing_api_builder(),
131 #[cfg(feature = "files-upload")]
132 upload_file_api_builder: Self::get_upload_file_api_builder(),
133 #[cfg(feature = "files-download")]
134 download_file_api_builder: Self::get_download_file_api_builder(),
135 #[cfg(feature = "stickers-new_sticker_pack")]
136 new_sticker_pack_api_builder: Self::get_new_sticker_pack_api_builder(),
137 #[cfg(feature = "stickers-sticker_packs_list")]
138 sticker_packs_list_api_builder: Self::get_sticker_packs_list_api_builder(),
139 #[cfg(feature = "stickers-add_sticker")]
140 add_sticker_api_builder: Self::get_add_sticker_api_builder(),
141 #[cfg(feature = "stickers-get_sticker_pack")]
142 get_sticker_pack_api_builder: Self::get_get_sticker_pack_api_builder(),
143 #[cfg(feature = "stickers-get_sticker")]
144 get_sticker_api_builder: Self::get_get_sticker_api_builder(),
145 #[cfg(feature = "stickers-update_sticker_pack")]
146 update_sticker_pack_api_builder: Self::get_update_sticker_pack_api_builder(),
147 #[cfg(feature = "stickers-delete_sticker_pack")]
148 delete_sticker_pack_api_builder: Self::get_delete_sticker_pack_api_builder(),
149 #[cfg(feature = "stickers-delete_sticker")]
150 delete_sticker_api_builder: Self::get_delete_sticker_api_builder(),
151 #[cfg(feature = "chats-list")]
152 get_chats_list_api_builder: Self::get_get_chats_list_api_builder(),
153 #[cfg(feature = "chats-info")]
154 get_chat_info_api_builder: Self::get_get_chat_info_api_builder(),
155 #[cfg(feature = "chats-add_user")]
156 add_user_api_builder: Self::get_add_user_api_builder(),
157 #[cfg(feature = "chats-remove_user")]
158 remove_user_api_builder: Self::get_remove_user_api_builder(),
159 #[cfg(feature = "chats-add_admin")]
160 add_admin_api_builder: Self::get_add_admin_api_builder(),
161 #[cfg(feature = "chats-set_stealth")]
162 set_stealth_api_builder: Self::get_set_stealth_api_builder(),
163 #[cfg(feature = "chats-disable_stealth")]
164 disable_stealth_api_builder: Self::get_disable_stealth_api_builder(),
165 #[cfg(feature = "chats-create")]
166 create_chat_api_builder: Self::get_create_chat_api_builder(),
167 #[cfg(feature = "chats-pin_message")]
168 pin_message_api_builder: Self::get_pin_message_api_builder(),
169 #[cfg(feature = "chats-unpin_message")]
170 unpin_message_api_builder: Self::get_unpin_message_api_builder(),
171 #[cfg(feature = "users-by_email")]
172 get_users_by_email_api_builder: Self::get_get_users_by_email_api_builder(),
173 #[cfg(feature = "users-by_huid")]
174 get_user_by_huid_api_builder: Self::get_get_user_by_huid_api_builder(),
175 #[cfg(feature = "users-by_login")]
176 get_user_by_login_api_builder: Self::get_get_user_by_login_api_builder(),
177 #[cfg(feature = "users-by_other_id")]
178 get_user_by_other_id_api_builder: Self::get_get_user_by_other_id_api_builder(),
179 #[cfg(feature = "users-users_as_csv")]
180 get_users_as_csv_api_builder: Self::get_get_users_as_csv_api_builder(),
181 }
182 }
183
184 #[cfg(feature = "token")]
185 fn get_token_api_builder() -> Box<dyn Fn(&String, &String, &String) -> String + Sync + Send> {
186 Box::new(|cts_url: &String, bot_id: &String, secret_key: &String| {
187 let mut mac = HmacSha256::new_from_slice(secret_key.as_bytes())
188 .expect("invalid secret key");
189
190 mac.update(bot_id.as_bytes());
191
192 let result = mac.finalize();
193
194 format!("{}/api/v2/botx/bots/{}/token?signature={:02X}", cts_url, bot_id, result.into_bytes())
195 })
196 }
197
198 #[cfg(feature = "notifications-direct")]
199 fn get_direct_notification_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
200 Box::new(|cts_url| {
201 format!("{cts_url}/api/v4/botx/notifications/direct")
202 })
203 }
204
205 #[cfg(feature = "notifications-internal")]
206 fn get_internal_notification_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
207 Box::new(|cts_url| {
208 format!("{cts_url}/api/v4/botx/notifications/internal")
209 })
210 }
211
212 #[cfg(feature = "events-edit_event")]
213 fn get_edit_event_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
214 Box::new(|cts_url| {
215 format!("{cts_url}/api/v3/botx/events/edit_event")
216 })
217 }
218
219 #[cfg(feature = "events-reply_event")]
220 fn get_reply_event_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
221 Box::new(|cts_url| {
222 format!("{cts_url}/api/v3/botx/events/reply_event")
223 })
224 }
225
226 #[cfg(feature = "events-status")]
227 fn get_event_status_api_builder() -> Box<dyn Fn(&String, &Uuid) -> String + Sync + Send> {
228 Box::new(|cts_url, sync_id| {
229 format!("{cts_url}/api/v3/botx/events/{sync_id}/status")
230 })
231 }
232
233 #[cfg(feature = "events-typing")]
234 fn get_typing_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
235 Box::new(|cts_url| {
236 format!("{cts_url}/api/v3/botx/events/typing")
237 })
238 }
239
240 #[cfg(feature = "events-stop_typing")]
241 fn get_stop_typing_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
242 Box::new(|cts_url| {
243 format!("{cts_url}/api/v3/botx/events/stop_typing")
244 })
245 }
246
247 #[cfg(feature = "files-upload")]
248 fn get_upload_file_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
249 Box::new(|cts_url| {
250 format!("{cts_url}/api/v3/botx/files/upload")
251 })
252 }
253
254 #[cfg(feature = "files-download")]
255 fn get_download_file_api_builder() -> Box<dyn Fn(&String, &Uuid, &Uuid, &bool) -> String + Sync + Send> {
256 Box::new(|cts_url, group_chat_id, file_id, is_preview| {
257 format!("{cts_url}/api/v3/botx/files/download?group_chat_id={group_chat_id}&file_id={file_id}&is_preview={is_preview}")
258 })
259 }
260
261 #[cfg(feature = "stickers-new_sticker_pack")]
262 fn get_new_sticker_pack_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
263 Box::new(|cts_url| {
264 format!("{cts_url}/api/v3/botx/stickers/packs")
265 })
266 }
267
268 #[cfg(feature = "stickers-sticker_packs_list")]
269 fn get_sticker_packs_list_api_builder() -> Box<dyn Fn(&String, &Option<Uuid>, &Option<u32>, &Option<String>) -> String + Sync + Send> {
270 Box::new(|cts_url, user_huid, limit, after| {
271 let has_any_param = user_huid.is_some() || limit.is_some() || after.is_some();
272
273 let params = vec![
274 user_huid.as_ref().map(|x| format!("user_huid={x}")),
275 limit.as_ref().map(|x| format!("limit={x}")),
276 after.as_ref().map(|x| format!("after={x}")),
277 ]
278 .into_iter()
279 .filter_map(|x| x)
280 .collect::<Vec<String>>()
281 .join("&");
282
283 format!("{}/api/v3/botx/stickers/packs{}{}",
284 cts_url,
285 if has_any_param { "?" } else { "" },
286 params)
287 })
288 }
289
290 #[cfg(feature = "stickers-add_sticker")]
291 fn get_add_sticker_api_builder() -> Box<dyn Fn(&String, &Uuid) -> String + Sync + Send> {
292 Box::new(|cts_url, pack_id| {
293 format!("{cts_url}/api/v3/botx/stickers/packs/{pack_id}/stickers")
294 })
295 }
296
297 #[cfg(feature = "stickers-get_sticker_pack")]
298 fn get_get_sticker_pack_api_builder() -> Box<dyn Fn(&String, &Uuid) -> String + Sync + Send> {
299 Box::new(|cts_url, pack_id| {
300 format!("{cts_url}/api/v3/botx/stickers/packs/{pack_id}")
301 })
302 }
303
304 #[cfg(feature = "stickers-get_sticker")]
305 fn get_get_sticker_api_builder() -> Box<dyn Fn(&String, &Uuid, &Uuid) -> String + Sync + Send> {
306 Box::new(|cts_url, pack_id, sticker_id| {
307 format!("{cts_url}/api/v3/botx/stickers/packs/{pack_id}/stickers/{sticker_id}")
308 })
309 }
310
311 #[cfg(feature = "stickers-update_sticker_pack")]
312 fn get_update_sticker_pack_api_builder() -> Box<dyn Fn(&String, &Uuid) -> String + Sync + Send> {
313 Box::new(|cts_url, pack_id| {
314 format!("{cts_url}/api/v3/botx/stickers/packs/{pack_id}/")
315 })
316 }
317
318 #[cfg(feature = "stickers-delete_sticker_pack")]
319 fn get_delete_sticker_pack_api_builder() -> Box<dyn Fn(&String, &Uuid) -> String + Sync + Send> {
320 Box::new(|cts_url, pack_id| {
321 format!("{cts_url}/api/v3/botx/stickers/packs/{pack_id}")
322 })
323 }
324
325 #[cfg(feature = "stickers-delete_sticker")]
326 fn get_delete_sticker_api_builder() -> Box<dyn Fn(&String, &Uuid, &Uuid) -> String + Sync + Send> {
327 Box::new(|cts_url, pack_id, sticker_id| {
328 format!("{cts_url}/api/v3/botx/stickers/packs/{pack_id}/stickers/{sticker_id}")
329 })
330 }
331
332 #[cfg(feature = "chats-list")]
333 fn get_get_chats_list_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
334 Box::new(|cts_url| {
335 format!("{cts_url}/api/v3/botx/chats/list")
336 })
337 }
338
339 #[cfg(feature = "chats-info")]
340 fn get_get_chat_info_api_builder() -> Box<dyn Fn(&String, &Uuid) -> String + Sync + Send> {
341 Box::new(|cts_url, group_chat_id| {
342 format!("{cts_url}/api/v3/botx/chats/info?group_chat_id={group_chat_id}")
343 })
344 }
345
346 #[cfg(feature = "chats-add_user")]
347 fn get_add_user_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
348 Box::new(|cts_url| {
349 format!("{cts_url}/api/v3/botx/chats/add_user")
350 })
351 }
352
353 #[cfg(feature = "chats-remove_user")]
354 fn get_remove_user_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
355 Box::new(|cts_url| {
356 format!("{cts_url}/api/v3/botx/chats/remove_user")
357 })
358 }
359
360 #[cfg(feature = "chats-add_admin")]
361 fn get_add_admin_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
362 Box::new(|cts_url| {
363 format!("{cts_url}/api/v3/botx/chats/add_admin")
364 })
365 }
366
367 #[cfg(feature = "chats-set_stealth")]
368 fn get_set_stealth_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
369 Box::new(|cts_url| {
370 format!("{cts_url}/api/v3/botx/chats/stealth_set")
371 })
372 }
373
374 #[cfg(feature = "chats-disable_stealth")]
375 fn get_disable_stealth_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
376 Box::new(|cts_url| {
377 format!("{cts_url}/api/v3/botx/chats/stealth_disable")
378 })
379 }
380
381 #[cfg(feature = "chats-create")]
382 fn get_create_chat_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
383 Box::new(|cts_url| {
384 format!("{cts_url}/api/v3/botx/chats/create")
385 })
386 }
387
388 #[cfg(feature = "chats-pin_message")]
389 fn get_pin_message_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
390 Box::new(|cts_url| {
391 format!("{cts_url}/api/v3/botx/chats/pin_message")
392 })
393 }
394
395 #[cfg(feature = "chats-unpin_message")]
396 fn get_unpin_message_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
397 Box::new(|cts_url| {
398 format!("{cts_url}/api/v3/botx/chats/unpin_message")
399 })
400 }
401
402 #[cfg(feature = "users-by_email")]
403 fn get_get_users_by_email_api_builder() -> Box<dyn Fn(&String) -> String + Sync + Send> {
404 Box::new(|cts_url| {
405 format!("{cts_url}/api/v3/botx/users/by_email")
406 })
407 }
408
409 #[cfg(feature = "users-by_huid")]
410 fn get_get_user_by_huid_api_builder() -> Box<dyn Fn(&String, &Uuid) -> String + Sync + Send> {
411 Box::new(|cts_url, user_huid| {
412 format!("{cts_url}/api/v3/botx/users/by_huid?user_huid={user_huid}")
413 })
414 }
415
416 #[cfg(feature = "users-by_login")]
417 fn get_get_user_by_login_api_builder() -> Box<dyn Fn(&String, &String, &String) -> String + Sync + Send> {
418 Box::new(|cts_url, ad_login, ad_domain| {
419 format!("{cts_url}/api/v3/botx/users/by_login?ad_login={ad_login}&ad_domain={ad_domain}")
420 })
421 }
422
423 #[cfg(feature = "users-by_other_id")]
424 fn get_get_user_by_other_id_api_builder() -> Box<dyn Fn(&String, &String) -> String + Sync + Send> {
425 Box::new(|cts_url, other_id| {
426 format!("{cts_url}/api/v3/botx/users/by_other_id?other_id={other_id}")
427 })
428 }
429
430 #[cfg(feature = "users-users_as_csv")]
431 fn get_get_users_as_csv_api_builder() -> Box<dyn Fn(&String, bool, bool, bool) -> String + Sync + Send> {
432 Box::new(|cts_url, cts_user, unregistered, botx| {
433 format!("{cts_url}/api/v3/botx/users/users_as_csv?cts_user={cts_user}&unregistered={unregistered}&botx={botx}")
434 })
435 }
436}