botx_api/api/utils/
url.rs

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}