simploxide_api_types/
client_api.rs

1use crate::{commands::*, responses::*, utils::CommandSyntax, *};
2use std::future::Future;
3use std::sync::Arc;
4
5pub trait ClientApiError: From<BadResponseError> + std::error::Error {
6    /// If current error is a bad response error return a mut reference to it!
7    ///
8    /// Required for [`AllowUndocumentedResponses`] impl.
9    fn bad_response_mut(&mut self) -> Option<&mut BadResponseError>;
10}
11
12pub trait ClientApi: Sync {
13    type Error: ClientApiError;
14
15    fn send_raw(
16        &self,
17        command: String,
18    ) -> impl Future<Output = Result<JsonObject, Self::Error>> + Send;
19
20    /// ### Address commands
21    ///
22    /// Bots can use these commands to automatically check and create address when initialized
23    ///
24    /// ----
25    ///
26    /// Create bot address.
27    ///
28    /// *Network usage*: interactive.
29    ///
30    /// *Syntax:*
31    ///
32    /// ```
33    /// /_address <userId>
34    /// ```
35    fn api_create_my_address(
36        &self,
37        user_id: i64,
38    ) -> impl Future<Output = Result<Arc<UserContactLinkCreatedResponse>, Self::Error>> + Send {
39        async move {
40            let command = ApiCreateMyAddress { user_id };
41            let json = self.send_raw(command.interpret()).await?;
42            // Safe to unwrap because unrecognized JSON goes to undocumented variant
43            let response = serde_json::from_value(json).unwrap();
44            match response {
45                ApiCreateMyAddressResponse::UserContactLinkCreated(resp) => Ok(Arc::new(resp)),
46                ApiCreateMyAddressResponse::ChatCmdError(resp) => {
47                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
48                }
49                ApiCreateMyAddressResponse::Undocumented(resp) => {
50                    Err(BadResponseError::Undocumented(resp).into())
51                }
52            }
53        }
54    }
55
56    /// ### Address commands
57    ///
58    /// Bots can use these commands to automatically check and create address when initialized
59    ///
60    /// ----
61    ///
62    /// Delete bot address.
63    ///
64    /// *Network usage*: background.
65    ///
66    /// *Syntax:*
67    ///
68    /// ```
69    /// /_delete_address <userId>
70    /// ```
71    fn api_delete_my_address(
72        &self,
73        user_id: i64,
74    ) -> impl Future<Output = Result<Arc<UserContactLinkDeletedResponse>, Self::Error>> + Send {
75        async move {
76            let command = ApiDeleteMyAddress { user_id };
77            let json = self.send_raw(command.interpret()).await?;
78            // Safe to unwrap because unrecognized JSON goes to undocumented variant
79            let response = serde_json::from_value(json).unwrap();
80            match response {
81                ApiDeleteMyAddressResponse::UserContactLinkDeleted(resp) => Ok(Arc::new(resp)),
82                ApiDeleteMyAddressResponse::ChatCmdError(resp) => {
83                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
84                }
85                ApiDeleteMyAddressResponse::Undocumented(resp) => {
86                    Err(BadResponseError::Undocumented(resp).into())
87                }
88            }
89        }
90    }
91
92    /// ### Address commands
93    ///
94    /// Bots can use these commands to automatically check and create address when initialized
95    ///
96    /// ----
97    ///
98    /// Get bot address and settings.
99    ///
100    /// *Network usage*: no.
101    ///
102    /// *Syntax:*
103    ///
104    /// ```
105    /// /_show_address <userId>
106    /// ```
107    fn api_show_my_address(
108        &self,
109        user_id: i64,
110    ) -> impl Future<Output = Result<Arc<UserContactLinkResponse>, Self::Error>> + Send {
111        async move {
112            let command = ApiShowMyAddress { user_id };
113            let json = self.send_raw(command.interpret()).await?;
114            // Safe to unwrap because unrecognized JSON goes to undocumented variant
115            let response = serde_json::from_value(json).unwrap();
116            match response {
117                ApiShowMyAddressResponse::UserContactLink(resp) => Ok(Arc::new(resp)),
118                ApiShowMyAddressResponse::ChatCmdError(resp) => {
119                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
120                }
121                ApiShowMyAddressResponse::Undocumented(resp) => {
122                    Err(BadResponseError::Undocumented(resp).into())
123                }
124            }
125        }
126    }
127
128    /// ### Address commands
129    ///
130    /// Bots can use these commands to automatically check and create address when initialized
131    ///
132    /// ----
133    ///
134    /// Add address to bot profile.
135    ///
136    /// *Network usage*: interactive.
137    ///
138    /// *Syntax:*
139    ///
140    /// ```
141    /// /_profile_address <userId> on|off
142    /// ```
143    fn api_set_profile_address(
144        &self,
145        command: ApiSetProfileAddress,
146    ) -> impl Future<Output = Result<Arc<UserProfileUpdatedResponse>, Self::Error>> + Send {
147        async move {
148            let json = self.send_raw(command.interpret()).await?;
149            // Safe to unwrap because unrecognized JSON goes to undocumented variant
150            let response = serde_json::from_value(json).unwrap();
151            match response {
152                ApiSetProfileAddressResponse::UserProfileUpdated(resp) => Ok(Arc::new(resp)),
153                ApiSetProfileAddressResponse::ChatCmdError(resp) => {
154                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
155                }
156                ApiSetProfileAddressResponse::Undocumented(resp) => {
157                    Err(BadResponseError::Undocumented(resp).into())
158                }
159            }
160        }
161    }
162
163    /// ### Address commands
164    ///
165    /// Bots can use these commands to automatically check and create address when initialized
166    ///
167    /// ----
168    ///
169    /// Set bot address settings.
170    ///
171    /// *Network usage*: interactive.
172    ///
173    /// *Syntax:*
174    ///
175    /// ```
176    /// /_address_settings <userId> <json(settings)>
177    /// ```
178    fn api_set_address_settings(
179        &self,
180        user_id: i64,
181        settings: AddressSettings,
182    ) -> impl Future<Output = Result<Arc<UserContactLinkUpdatedResponse>, Self::Error>> + Send {
183        async move {
184            let command = ApiSetAddressSettings { user_id, settings };
185            let json = self.send_raw(command.interpret()).await?;
186            // Safe to unwrap because unrecognized JSON goes to undocumented variant
187            let response = serde_json::from_value(json).unwrap();
188            match response {
189                ApiSetAddressSettingsResponse::UserContactLinkUpdated(resp) => Ok(Arc::new(resp)),
190                ApiSetAddressSettingsResponse::ChatCmdError(resp) => {
191                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
192                }
193                ApiSetAddressSettingsResponse::Undocumented(resp) => {
194                    Err(BadResponseError::Undocumented(resp).into())
195                }
196            }
197        }
198    }
199
200    /// ### Message commands
201    ///
202    /// Commands to send, update, delete, moderate messages and set message reactions
203    ///
204    /// ----
205    ///
206    /// Send messages.
207    ///
208    /// *Network usage*: background.
209    ///
210    /// *Syntax:*
211    ///
212    /// ```
213    /// /_send <str(sendRef)>[ live=on][ ttl=<ttl>] json <json(composedMessages)>
214    /// ```
215    fn api_send_messages(
216        &self,
217        command: ApiSendMessages,
218    ) -> impl Future<Output = Result<Arc<NewChatItemsResponse>, Self::Error>> + Send {
219        async move {
220            let json = self.send_raw(command.interpret()).await?;
221            // Safe to unwrap because unrecognized JSON goes to undocumented variant
222            let response = serde_json::from_value(json).unwrap();
223            match response {
224                ApiSendMessagesResponse::NewChatItems(resp) => Ok(Arc::new(resp)),
225                ApiSendMessagesResponse::ChatCmdError(resp) => {
226                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
227                }
228                ApiSendMessagesResponse::Undocumented(resp) => {
229                    Err(BadResponseError::Undocumented(resp).into())
230                }
231            }
232        }
233    }
234
235    /// ### Message commands
236    ///
237    /// Commands to send, update, delete, moderate messages and set message reactions
238    ///
239    /// ----
240    ///
241    /// Update message.
242    ///
243    /// *Network usage*: background.
244    ///
245    /// *Syntax:*
246    ///
247    /// ```
248    /// /_update item <str(chatRef)> <chatItemId>[ live=on] json <json(updatedMessage)>
249    /// ```
250    fn api_update_chat_item(
251        &self,
252        command: ApiUpdateChatItem,
253    ) -> impl Future<Output = Result<ApiUpdateChatItemResponses, Self::Error>> + Send {
254        async move {
255            let json = self.send_raw(command.interpret()).await?;
256            // Safe to unwrap because unrecognized JSON goes to undocumented variant
257            let response = serde_json::from_value(json).unwrap();
258            match response {
259                ApiUpdateChatItemResponse::ChatItemUpdated(resp) => {
260                    Ok(ApiUpdateChatItemResponses::ChatItemUpdated(Arc::new(resp)))
261                }
262                ApiUpdateChatItemResponse::ChatItemNotChanged(resp) => Ok(
263                    ApiUpdateChatItemResponses::ChatItemNotChanged(Arc::new(resp)),
264                ),
265                ApiUpdateChatItemResponse::ChatCmdError(resp) => {
266                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
267                }
268                ApiUpdateChatItemResponse::Undocumented(resp) => {
269                    Err(BadResponseError::Undocumented(resp).into())
270                }
271            }
272        }
273    }
274
275    /// ### Message commands
276    ///
277    /// Commands to send, update, delete, moderate messages and set message reactions
278    ///
279    /// ----
280    ///
281    /// Delete message.
282    ///
283    /// *Network usage*: background.
284    ///
285    /// *Syntax:*
286    ///
287    /// ```
288    /// /_delete item <str(chatRef)> <chatItemIds[0]>[,<chatItemIds[1]>...] broadcast|internal|internalMark
289    /// ```
290    fn api_delete_chat_item(
291        &self,
292        chat_ref: ChatRef,
293        chat_item_ids: Vec<i64>,
294        delete_mode: CIDeleteMode,
295    ) -> impl Future<Output = Result<Arc<ChatItemsDeletedResponse>, Self::Error>> + Send {
296        async move {
297            let command = ApiDeleteChatItem {
298                chat_ref,
299                chat_item_ids,
300                delete_mode,
301            };
302            let json = self.send_raw(command.interpret()).await?;
303            // Safe to unwrap because unrecognized JSON goes to undocumented variant
304            let response = serde_json::from_value(json).unwrap();
305            match response {
306                ApiDeleteChatItemResponse::ChatItemsDeleted(resp) => Ok(Arc::new(resp)),
307                ApiDeleteChatItemResponse::ChatCmdError(resp) => {
308                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
309                }
310                ApiDeleteChatItemResponse::Undocumented(resp) => {
311                    Err(BadResponseError::Undocumented(resp).into())
312                }
313            }
314        }
315    }
316
317    /// ### Message commands
318    ///
319    /// Commands to send, update, delete, moderate messages and set message reactions
320    ///
321    /// ----
322    ///
323    /// Moderate message. Requires Moderator role (and higher than message author's).
324    ///
325    /// *Network usage*: background.
326    ///
327    /// *Syntax:*
328    ///
329    /// ```
330    /// /_delete member item #<groupId> <chatItemIds[0]>[,<chatItemIds[1]>...]
331    /// ```
332    fn api_delete_member_chat_item(
333        &self,
334        group_id: i64,
335        chat_item_ids: Vec<i64>,
336    ) -> impl Future<Output = Result<Arc<ChatItemsDeletedResponse>, Self::Error>> + Send {
337        async move {
338            let command = ApiDeleteMemberChatItem {
339                group_id,
340                chat_item_ids,
341            };
342            let json = self.send_raw(command.interpret()).await?;
343            // Safe to unwrap because unrecognized JSON goes to undocumented variant
344            let response = serde_json::from_value(json).unwrap();
345            match response {
346                ApiDeleteMemberChatItemResponse::ChatItemsDeleted(resp) => Ok(Arc::new(resp)),
347                ApiDeleteMemberChatItemResponse::ChatCmdError(resp) => {
348                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
349                }
350                ApiDeleteMemberChatItemResponse::Undocumented(resp) => {
351                    Err(BadResponseError::Undocumented(resp).into())
352                }
353            }
354        }
355    }
356
357    /// ### Message commands
358    ///
359    /// Commands to send, update, delete, moderate messages and set message reactions
360    ///
361    /// ----
362    ///
363    /// Add/remove message reaction.
364    ///
365    /// *Network usage*: background.
366    ///
367    /// *Syntax:*
368    ///
369    /// ```
370    /// /_reaction <str(chatRef)> <chatItemId> on|off <json(reaction)>
371    /// ```
372    fn api_chat_item_reaction(
373        &self,
374        command: ApiChatItemReaction,
375    ) -> impl Future<Output = Result<Arc<ChatItemReactionResponse>, Self::Error>> + Send {
376        async move {
377            let json = self.send_raw(command.interpret()).await?;
378            // Safe to unwrap because unrecognized JSON goes to undocumented variant
379            let response = serde_json::from_value(json).unwrap();
380            match response {
381                ApiChatItemReactionResponse::ChatItemReaction(resp) => Ok(Arc::new(resp)),
382                ApiChatItemReactionResponse::ChatCmdError(resp) => {
383                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
384                }
385                ApiChatItemReactionResponse::Undocumented(resp) => {
386                    Err(BadResponseError::Undocumented(resp).into())
387                }
388            }
389        }
390    }
391
392    /// ### File commands
393    ///
394    /// Commands to receive and to cancel files. Files are sent as part of the message, there are no separate commands to send files.
395    ///
396    /// ----
397    ///
398    /// Receive file.
399    ///
400    /// *Network usage*: no.
401    ///
402    /// *Syntax:*
403    ///
404    /// ```
405    /// /freceive <fileId>[ approved_relays=on][ encrypt=on|off][ inline=on|off][ <filePath>]
406    /// ```
407    fn receive_file(
408        &self,
409        command: ReceiveFile,
410    ) -> impl Future<Output = Result<ReceiveFileResponses, Self::Error>> + Send {
411        async move {
412            let json = self.send_raw(command.interpret()).await?;
413            // Safe to unwrap because unrecognized JSON goes to undocumented variant
414            let response = serde_json::from_value(json).unwrap();
415            match response {
416                ReceiveFileResponse::RcvFileAccepted(resp) => {
417                    Ok(ReceiveFileResponses::RcvFileAccepted(Arc::new(resp)))
418                }
419                ReceiveFileResponse::RcvFileAcceptedSndCancelled(resp) => Ok(
420                    ReceiveFileResponses::RcvFileAcceptedSndCancelled(Arc::new(resp)),
421                ),
422                ReceiveFileResponse::ChatCmdError(resp) => {
423                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
424                }
425                ReceiveFileResponse::Undocumented(resp) => {
426                    Err(BadResponseError::Undocumented(resp).into())
427                }
428            }
429        }
430    }
431
432    /// ### File commands
433    ///
434    /// Commands to receive and to cancel files. Files are sent as part of the message, there are no separate commands to send files.
435    ///
436    /// ----
437    ///
438    /// Cancel file.
439    ///
440    /// *Network usage*: background.
441    ///
442    /// *Syntax:*
443    ///
444    /// ```
445    /// /fcancel <fileId>
446    /// ```
447    fn cancel_file(
448        &self,
449        file_id: i64,
450    ) -> impl Future<Output = Result<CancelFileResponses, Self::Error>> + Send {
451        async move {
452            let command = CancelFile { file_id };
453            let json = self.send_raw(command.interpret()).await?;
454            // Safe to unwrap because unrecognized JSON goes to undocumented variant
455            let response = serde_json::from_value(json).unwrap();
456            match response {
457                CancelFileResponse::SndFileCancelled(resp) => {
458                    Ok(CancelFileResponses::SndFileCancelled(Arc::new(resp)))
459                }
460                CancelFileResponse::RcvFileCancelled(resp) => {
461                    Ok(CancelFileResponses::RcvFileCancelled(Arc::new(resp)))
462                }
463                CancelFileResponse::ChatCmdError(resp) => {
464                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
465                }
466                CancelFileResponse::Undocumented(resp) => {
467                    Err(BadResponseError::Undocumented(resp).into())
468                }
469            }
470        }
471    }
472
473    /// ### Group commands
474    ///
475    /// Commands to manage and moderate groups. These commands can be used with business chats as well - they are groups. E.g., a common scenario would be to add human agents to business chat with the customer who connected via business address.
476    ///
477    /// ----
478    ///
479    /// Add contact to group. Requires bot to have Admin role.
480    ///
481    /// *Network usage*: interactive.
482    ///
483    /// *Syntax:*
484    ///
485    /// ```
486    /// /_add #<groupId> <contactId> observer|author|member|moderator|admin|owner
487    /// ```
488    fn api_add_member(
489        &self,
490        group_id: i64,
491        contact_id: i64,
492        member_role: GroupMemberRole,
493    ) -> impl Future<Output = Result<Arc<SentGroupInvitationResponse>, Self::Error>> + Send {
494        async move {
495            let command = ApiAddMember {
496                group_id,
497                contact_id,
498                member_role,
499            };
500            let json = self.send_raw(command.interpret()).await?;
501            // Safe to unwrap because unrecognized JSON goes to undocumented variant
502            let response = serde_json::from_value(json).unwrap();
503            match response {
504                ApiAddMemberResponse::SentGroupInvitation(resp) => Ok(Arc::new(resp)),
505                ApiAddMemberResponse::ChatCmdError(resp) => {
506                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
507                }
508                ApiAddMemberResponse::Undocumented(resp) => {
509                    Err(BadResponseError::Undocumented(resp).into())
510                }
511            }
512        }
513    }
514
515    /// ### Group commands
516    ///
517    /// Commands to manage and moderate groups. These commands can be used with business chats as well - they are groups. E.g., a common scenario would be to add human agents to business chat with the customer who connected via business address.
518    ///
519    /// ----
520    ///
521    /// Join group.
522    ///
523    /// *Network usage*: interactive.
524    ///
525    /// *Syntax:*
526    ///
527    /// ```
528    /// /_join #<groupId>
529    /// ```
530    fn api_join_group(
531        &self,
532        group_id: i64,
533    ) -> impl Future<Output = Result<Arc<UserAcceptedGroupSentResponse>, Self::Error>> + Send {
534        async move {
535            let command = ApiJoinGroup { group_id };
536            let json = self.send_raw(command.interpret()).await?;
537            // Safe to unwrap because unrecognized JSON goes to undocumented variant
538            let response = serde_json::from_value(json).unwrap();
539            match response {
540                ApiJoinGroupResponse::UserAcceptedGroupSent(resp) => Ok(Arc::new(resp)),
541                ApiJoinGroupResponse::ChatCmdError(resp) => {
542                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
543                }
544                ApiJoinGroupResponse::Undocumented(resp) => {
545                    Err(BadResponseError::Undocumented(resp).into())
546                }
547            }
548        }
549    }
550
551    /// ### Group commands
552    ///
553    /// Commands to manage and moderate groups. These commands can be used with business chats as well - they are groups. E.g., a common scenario would be to add human agents to business chat with the customer who connected via business address.
554    ///
555    /// ----
556    ///
557    /// Accept group member. Requires Admin role.
558    ///
559    /// *Network usage*: background.
560    ///
561    /// *Syntax:*
562    ///
563    /// ```
564    /// /_accept member #<groupId> <groupMemberId> observer|author|member|moderator|admin|owner
565    /// ```
566    fn api_accept_member(
567        &self,
568        group_id: i64,
569        group_member_id: i64,
570        member_role: GroupMemberRole,
571    ) -> impl Future<Output = Result<Arc<MemberAcceptedResponse>, Self::Error>> + Send {
572        async move {
573            let command = ApiAcceptMember {
574                group_id,
575                group_member_id,
576                member_role,
577            };
578            let json = self.send_raw(command.interpret()).await?;
579            // Safe to unwrap because unrecognized JSON goes to undocumented variant
580            let response = serde_json::from_value(json).unwrap();
581            match response {
582                ApiAcceptMemberResponse::MemberAccepted(resp) => Ok(Arc::new(resp)),
583                ApiAcceptMemberResponse::ChatCmdError(resp) => {
584                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
585                }
586                ApiAcceptMemberResponse::Undocumented(resp) => {
587                    Err(BadResponseError::Undocumented(resp).into())
588                }
589            }
590        }
591    }
592
593    /// ### Group commands
594    ///
595    /// Commands to manage and moderate groups. These commands can be used with business chats as well - they are groups. E.g., a common scenario would be to add human agents to business chat with the customer who connected via business address.
596    ///
597    /// ----
598    ///
599    /// Set members role. Requires Admin role.
600    ///
601    /// *Network usage*: background.
602    ///
603    /// *Syntax:*
604    ///
605    /// ```
606    /// /_member role #<groupId> <groupMemberIds[0]>[,<groupMemberIds[1]>...] observer|author|member|moderator|admin|owner
607    /// ```
608    fn api_members_role(
609        &self,
610        group_id: i64,
611        group_member_ids: Vec<i64>,
612        member_role: GroupMemberRole,
613    ) -> impl Future<Output = Result<Arc<MembersRoleUserResponse>, Self::Error>> + Send {
614        async move {
615            let command = ApiMembersRole {
616                group_id,
617                group_member_ids,
618                member_role,
619            };
620            let json = self.send_raw(command.interpret()).await?;
621            // Safe to unwrap because unrecognized JSON goes to undocumented variant
622            let response = serde_json::from_value(json).unwrap();
623            match response {
624                ApiMembersRoleResponse::MembersRoleUser(resp) => Ok(Arc::new(resp)),
625                ApiMembersRoleResponse::ChatCmdError(resp) => {
626                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
627                }
628                ApiMembersRoleResponse::Undocumented(resp) => {
629                    Err(BadResponseError::Undocumented(resp).into())
630                }
631            }
632        }
633    }
634
635    /// ### Group commands
636    ///
637    /// Commands to manage and moderate groups. These commands can be used with business chats as well - they are groups. E.g., a common scenario would be to add human agents to business chat with the customer who connected via business address.
638    ///
639    /// ----
640    ///
641    /// Block members. Requires Moderator role.
642    ///
643    /// *Network usage*: background.
644    ///
645    /// *Syntax:*
646    ///
647    /// ```
648    /// /_block #<groupId> <groupMemberIds[0]>[,<groupMemberIds[1]>...] blocked=on|off
649    /// ```
650    fn api_block_members_for_all(
651        &self,
652        command: ApiBlockMembersForAll,
653    ) -> impl Future<Output = Result<Arc<MembersBlockedForAllUserResponse>, Self::Error>> + Send
654    {
655        async move {
656            let json = self.send_raw(command.interpret()).await?;
657            // Safe to unwrap because unrecognized JSON goes to undocumented variant
658            let response = serde_json::from_value(json).unwrap();
659            match response {
660                ApiBlockMembersForAllResponse::MembersBlockedForAllUser(resp) => Ok(Arc::new(resp)),
661                ApiBlockMembersForAllResponse::ChatCmdError(resp) => {
662                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
663                }
664                ApiBlockMembersForAllResponse::Undocumented(resp) => {
665                    Err(BadResponseError::Undocumented(resp).into())
666                }
667            }
668        }
669    }
670
671    /// ### Group commands
672    ///
673    /// Commands to manage and moderate groups. These commands can be used with business chats as well - they are groups. E.g., a common scenario would be to add human agents to business chat with the customer who connected via business address.
674    ///
675    /// ----
676    ///
677    /// Remove members. Requires Admin role.
678    ///
679    /// *Network usage*: background.
680    ///
681    /// *Syntax:*
682    ///
683    /// ```
684    /// /_remove #<groupId> <groupMemberIds[0]>[,<groupMemberIds[1]>...][ messages=on]
685    /// ```
686    fn api_remove_members(
687        &self,
688        command: ApiRemoveMembers,
689    ) -> impl Future<Output = Result<Arc<UserDeletedMembersResponse>, Self::Error>> + Send {
690        async move {
691            let json = self.send_raw(command.interpret()).await?;
692            // Safe to unwrap because unrecognized JSON goes to undocumented variant
693            let response = serde_json::from_value(json).unwrap();
694            match response {
695                ApiRemoveMembersResponse::UserDeletedMembers(resp) => Ok(Arc::new(resp)),
696                ApiRemoveMembersResponse::ChatCmdError(resp) => {
697                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
698                }
699                ApiRemoveMembersResponse::Undocumented(resp) => {
700                    Err(BadResponseError::Undocumented(resp).into())
701                }
702            }
703        }
704    }
705
706    /// ### Group commands
707    ///
708    /// Commands to manage and moderate groups. These commands can be used with business chats as well - they are groups. E.g., a common scenario would be to add human agents to business chat with the customer who connected via business address.
709    ///
710    /// ----
711    ///
712    /// Leave group.
713    ///
714    /// *Network usage*: background.
715    ///
716    /// *Syntax:*
717    ///
718    /// ```
719    /// /_leave #<groupId>
720    /// ```
721    fn api_leave_group(
722        &self,
723        group_id: i64,
724    ) -> impl Future<Output = Result<Arc<LeftMemberUserResponse>, Self::Error>> + Send {
725        async move {
726            let command = ApiLeaveGroup { group_id };
727            let json = self.send_raw(command.interpret()).await?;
728            // Safe to unwrap because unrecognized JSON goes to undocumented variant
729            let response = serde_json::from_value(json).unwrap();
730            match response {
731                ApiLeaveGroupResponse::LeftMemberUser(resp) => Ok(Arc::new(resp)),
732                ApiLeaveGroupResponse::ChatCmdError(resp) => {
733                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
734                }
735                ApiLeaveGroupResponse::Undocumented(resp) => {
736                    Err(BadResponseError::Undocumented(resp).into())
737                }
738            }
739        }
740    }
741
742    /// ### Group commands
743    ///
744    /// Commands to manage and moderate groups. These commands can be used with business chats as well - they are groups. E.g., a common scenario would be to add human agents to business chat with the customer who connected via business address.
745    ///
746    /// ----
747    ///
748    /// Get group members.
749    ///
750    /// *Network usage*: no.
751    ///
752    /// *Syntax:*
753    ///
754    /// ```
755    /// /_members #<groupId>
756    /// ```
757    fn api_list_members(
758        &self,
759        group_id: i64,
760    ) -> impl Future<Output = Result<Arc<GroupMembersResponse>, Self::Error>> + Send {
761        async move {
762            let command = ApiListMembers { group_id };
763            let json = self.send_raw(command.interpret()).await?;
764            // Safe to unwrap because unrecognized JSON goes to undocumented variant
765            let response = serde_json::from_value(json).unwrap();
766            match response {
767                ApiListMembersResponse::GroupMembers(resp) => Ok(Arc::new(resp)),
768                ApiListMembersResponse::ChatCmdError(resp) => {
769                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
770                }
771                ApiListMembersResponse::Undocumented(resp) => {
772                    Err(BadResponseError::Undocumented(resp).into())
773                }
774            }
775        }
776    }
777
778    /// ### Group commands
779    ///
780    /// Commands to manage and moderate groups. These commands can be used with business chats as well - they are groups. E.g., a common scenario would be to add human agents to business chat with the customer who connected via business address.
781    ///
782    /// ----
783    ///
784    /// Create group.
785    ///
786    /// *Network usage*: no.
787    ///
788    /// *Syntax:*
789    ///
790    /// ```
791    /// /_group <userId>[ incognito=on] <json(groupProfile)>
792    /// ```
793    fn api_new_group(
794        &self,
795        command: ApiNewGroup,
796    ) -> impl Future<Output = Result<Arc<GroupCreatedResponse>, Self::Error>> + Send {
797        async move {
798            let json = self.send_raw(command.interpret()).await?;
799            // Safe to unwrap because unrecognized JSON goes to undocumented variant
800            let response = serde_json::from_value(json).unwrap();
801            match response {
802                ApiNewGroupResponse::GroupCreated(resp) => Ok(Arc::new(resp)),
803                ApiNewGroupResponse::ChatCmdError(resp) => {
804                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
805                }
806                ApiNewGroupResponse::Undocumented(resp) => {
807                    Err(BadResponseError::Undocumented(resp).into())
808                }
809            }
810        }
811    }
812
813    /// ### Group commands
814    ///
815    /// Commands to manage and moderate groups. These commands can be used with business chats as well - they are groups. E.g., a common scenario would be to add human agents to business chat with the customer who connected via business address.
816    ///
817    /// ----
818    ///
819    /// Update group profile.
820    ///
821    /// *Network usage*: background.
822    ///
823    /// *Syntax:*
824    ///
825    /// ```
826    /// /_group_profile #<groupId> <json(groupProfile)>
827    /// ```
828    fn api_update_group_profile(
829        &self,
830        group_id: i64,
831        group_profile: GroupProfile,
832    ) -> impl Future<Output = Result<Arc<GroupUpdatedResponse>, Self::Error>> + Send {
833        async move {
834            let command = ApiUpdateGroupProfile {
835                group_id,
836                group_profile,
837            };
838            let json = self.send_raw(command.interpret()).await?;
839            // Safe to unwrap because unrecognized JSON goes to undocumented variant
840            let response = serde_json::from_value(json).unwrap();
841            match response {
842                ApiUpdateGroupProfileResponse::GroupUpdated(resp) => Ok(Arc::new(resp)),
843                ApiUpdateGroupProfileResponse::ChatCmdError(resp) => {
844                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
845                }
846                ApiUpdateGroupProfileResponse::Undocumented(resp) => {
847                    Err(BadResponseError::Undocumented(resp).into())
848                }
849            }
850        }
851    }
852
853    /// ### Group link commands
854    ///
855    /// These commands can be used by bots that manage multiple public groups
856    ///
857    /// ----
858    ///
859    /// Create group link.
860    ///
861    /// *Network usage*: interactive.
862    ///
863    /// *Syntax:*
864    ///
865    /// ```
866    /// /_create link #<groupId> observer|author|member|moderator|admin|owner
867    /// ```
868    fn api_create_group_link(
869        &self,
870        group_id: i64,
871        member_role: GroupMemberRole,
872    ) -> impl Future<Output = Result<Arc<GroupLinkCreatedResponse>, Self::Error>> + Send {
873        async move {
874            let command = ApiCreateGroupLink {
875                group_id,
876                member_role,
877            };
878            let json = self.send_raw(command.interpret()).await?;
879            // Safe to unwrap because unrecognized JSON goes to undocumented variant
880            let response = serde_json::from_value(json).unwrap();
881            match response {
882                ApiCreateGroupLinkResponse::GroupLinkCreated(resp) => Ok(Arc::new(resp)),
883                ApiCreateGroupLinkResponse::ChatCmdError(resp) => {
884                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
885                }
886                ApiCreateGroupLinkResponse::Undocumented(resp) => {
887                    Err(BadResponseError::Undocumented(resp).into())
888                }
889            }
890        }
891    }
892
893    /// ### Group link commands
894    ///
895    /// These commands can be used by bots that manage multiple public groups
896    ///
897    /// ----
898    ///
899    /// Set member role for group link.
900    ///
901    /// *Network usage*: no.
902    ///
903    /// *Syntax:*
904    ///
905    /// ```
906    /// /_set link role #<groupId> observer|author|member|moderator|admin|owner
907    /// ```
908    fn api_group_link_member_role(
909        &self,
910        group_id: i64,
911        member_role: GroupMemberRole,
912    ) -> impl Future<Output = Result<Arc<GroupLinkResponse>, Self::Error>> + Send {
913        async move {
914            let command = ApiGroupLinkMemberRole {
915                group_id,
916                member_role,
917            };
918            let json = self.send_raw(command.interpret()).await?;
919            // Safe to unwrap because unrecognized JSON goes to undocumented variant
920            let response = serde_json::from_value(json).unwrap();
921            match response {
922                ApiGroupLinkMemberRoleResponse::GroupLink(resp) => Ok(Arc::new(resp)),
923                ApiGroupLinkMemberRoleResponse::ChatCmdError(resp) => {
924                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
925                }
926                ApiGroupLinkMemberRoleResponse::Undocumented(resp) => {
927                    Err(BadResponseError::Undocumented(resp).into())
928                }
929            }
930        }
931    }
932
933    /// ### Group link commands
934    ///
935    /// These commands can be used by bots that manage multiple public groups
936    ///
937    /// ----
938    ///
939    /// Delete group link.
940    ///
941    /// *Network usage*: background.
942    ///
943    /// *Syntax:*
944    ///
945    /// ```
946    /// /_delete link #<groupId>
947    /// ```
948    fn api_delete_group_link(
949        &self,
950        group_id: i64,
951    ) -> impl Future<Output = Result<Arc<GroupLinkDeletedResponse>, Self::Error>> + Send {
952        async move {
953            let command = ApiDeleteGroupLink { group_id };
954            let json = self.send_raw(command.interpret()).await?;
955            // Safe to unwrap because unrecognized JSON goes to undocumented variant
956            let response = serde_json::from_value(json).unwrap();
957            match response {
958                ApiDeleteGroupLinkResponse::GroupLinkDeleted(resp) => Ok(Arc::new(resp)),
959                ApiDeleteGroupLinkResponse::ChatCmdError(resp) => {
960                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
961                }
962                ApiDeleteGroupLinkResponse::Undocumented(resp) => {
963                    Err(BadResponseError::Undocumented(resp).into())
964                }
965            }
966        }
967    }
968
969    /// ### Group link commands
970    ///
971    /// These commands can be used by bots that manage multiple public groups
972    ///
973    /// ----
974    ///
975    /// Get group link.
976    ///
977    /// *Network usage*: no.
978    ///
979    /// *Syntax:*
980    ///
981    /// ```
982    /// /_get link #<groupId>
983    /// ```
984    fn api_get_group_link(
985        &self,
986        group_id: i64,
987    ) -> impl Future<Output = Result<Arc<GroupLinkResponse>, Self::Error>> + Send {
988        async move {
989            let command = ApiGetGroupLink { group_id };
990            let json = self.send_raw(command.interpret()).await?;
991            // Safe to unwrap because unrecognized JSON goes to undocumented variant
992            let response = serde_json::from_value(json).unwrap();
993            match response {
994                ApiGetGroupLinkResponse::GroupLink(resp) => Ok(Arc::new(resp)),
995                ApiGetGroupLinkResponse::ChatCmdError(resp) => {
996                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
997                }
998                ApiGetGroupLinkResponse::Undocumented(resp) => {
999                    Err(BadResponseError::Undocumented(resp).into())
1000                }
1001            }
1002        }
1003    }
1004
1005    /// ### Connection commands
1006    ///
1007    /// These commands may be used to create connections. Most bots do not need to use them - bot users will connect via bot address with auto-accept enabled.
1008    ///
1009    /// ----
1010    ///
1011    /// Create 1-time invitation link.
1012    ///
1013    /// *Network usage*: interactive.
1014    ///
1015    /// *Syntax:*
1016    ///
1017    /// ```
1018    /// /_connect <userId>[ incognito=on]
1019    /// ```
1020    fn api_add_contact(
1021        &self,
1022        command: ApiAddContact,
1023    ) -> impl Future<Output = Result<Arc<InvitationResponse>, Self::Error>> + Send {
1024        async move {
1025            let json = self.send_raw(command.interpret()).await?;
1026            // Safe to unwrap because unrecognized JSON goes to undocumented variant
1027            let response = serde_json::from_value(json).unwrap();
1028            match response {
1029                ApiAddContactResponse::Invitation(resp) => Ok(Arc::new(resp)),
1030                ApiAddContactResponse::ChatCmdError(resp) => {
1031                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
1032                }
1033                ApiAddContactResponse::Undocumented(resp) => {
1034                    Err(BadResponseError::Undocumented(resp).into())
1035                }
1036            }
1037        }
1038    }
1039
1040    /// ### Connection commands
1041    ///
1042    /// These commands may be used to create connections. Most bots do not need to use them - bot users will connect via bot address with auto-accept enabled.
1043    ///
1044    /// ----
1045    ///
1046    /// Determine SimpleX link type and if the bot is already connected via this link.
1047    ///
1048    /// *Network usage*: interactive.
1049    ///
1050    /// *Syntax:*
1051    ///
1052    /// ```
1053    /// /_connect plan <userId> <connectionLink>
1054    /// ```
1055    fn api_connect_plan(
1056        &self,
1057        command: ApiConnectPlan,
1058    ) -> impl Future<Output = Result<Arc<ConnectionPlanResponse>, Self::Error>> + Send {
1059        async move {
1060            let json = self.send_raw(command.interpret()).await?;
1061            // Safe to unwrap because unrecognized JSON goes to undocumented variant
1062            let response = serde_json::from_value(json).unwrap();
1063            match response {
1064                ApiConnectPlanResponse::ConnectionPlan(resp) => Ok(Arc::new(resp)),
1065                ApiConnectPlanResponse::ChatCmdError(resp) => {
1066                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
1067                }
1068                ApiConnectPlanResponse::Undocumented(resp) => {
1069                    Err(BadResponseError::Undocumented(resp).into())
1070                }
1071            }
1072        }
1073    }
1074
1075    /// ### Connection commands
1076    ///
1077    /// These commands may be used to create connections. Most bots do not need to use them - bot users will connect via bot address with auto-accept enabled.
1078    ///
1079    /// ----
1080    ///
1081    /// Connect via prepared SimpleX link. The link can be 1-time invitation link, contact address or group link
1082    ///
1083    /// *Network usage*: interactive.
1084    ///
1085    /// *Syntax:*
1086    ///
1087    /// ```
1088    /// /_connect <userId>[ <str(preparedLink_)>]
1089    /// ```
1090    fn api_connect(
1091        &self,
1092        command: ApiConnect,
1093    ) -> impl Future<Output = Result<ApiConnectResponses, Self::Error>> + Send {
1094        async move {
1095            let json = self.send_raw(command.interpret()).await?;
1096            // Safe to unwrap because unrecognized JSON goes to undocumented variant
1097            let response = serde_json::from_value(json).unwrap();
1098            match response {
1099                ApiConnectResponse::SentConfirmation(resp) => {
1100                    Ok(ApiConnectResponses::SentConfirmation(Arc::new(resp)))
1101                }
1102                ApiConnectResponse::ContactAlreadyExists(resp) => {
1103                    Ok(ApiConnectResponses::ContactAlreadyExists(Arc::new(resp)))
1104                }
1105                ApiConnectResponse::SentInvitation(resp) => {
1106                    Ok(ApiConnectResponses::SentInvitation(Arc::new(resp)))
1107                }
1108                ApiConnectResponse::ChatCmdError(resp) => {
1109                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
1110                }
1111                ApiConnectResponse::Undocumented(resp) => {
1112                    Err(BadResponseError::Undocumented(resp).into())
1113                }
1114            }
1115        }
1116    }
1117
1118    /// ### Connection commands
1119    ///
1120    /// These commands may be used to create connections. Most bots do not need to use them - bot users will connect via bot address with auto-accept enabled.
1121    ///
1122    /// ----
1123    ///
1124    /// Connect via SimpleX link as string in the active user profile.
1125    ///
1126    /// *Network usage*: interactive.
1127    ///
1128    /// *Syntax:*
1129    ///
1130    /// ```
1131    /// /connect[ <connLink_>]
1132    /// ```
1133    fn connect(
1134        &self,
1135        command: Connect,
1136    ) -> impl Future<Output = Result<ConnectResponses, Self::Error>> + Send {
1137        async move {
1138            let json = self.send_raw(command.interpret()).await?;
1139            // Safe to unwrap because unrecognized JSON goes to undocumented variant
1140            let response = serde_json::from_value(json).unwrap();
1141            match response {
1142                ConnectResponse::SentConfirmation(resp) => {
1143                    Ok(ConnectResponses::SentConfirmation(Arc::new(resp)))
1144                }
1145                ConnectResponse::ContactAlreadyExists(resp) => {
1146                    Ok(ConnectResponses::ContactAlreadyExists(Arc::new(resp)))
1147                }
1148                ConnectResponse::SentInvitation(resp) => {
1149                    Ok(ConnectResponses::SentInvitation(Arc::new(resp)))
1150                }
1151                ConnectResponse::ChatCmdError(resp) => {
1152                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
1153                }
1154                ConnectResponse::Undocumented(resp) => {
1155                    Err(BadResponseError::Undocumented(resp).into())
1156                }
1157            }
1158        }
1159    }
1160
1161    /// ### Connection commands
1162    ///
1163    /// These commands may be used to create connections. Most bots do not need to use them - bot users will connect via bot address with auto-accept enabled.
1164    ///
1165    /// ----
1166    ///
1167    /// Accept contact request.
1168    ///
1169    /// *Network usage*: interactive.
1170    ///
1171    /// *Syntax:*
1172    ///
1173    /// ```
1174    /// /_accept <contactReqId>
1175    /// ```
1176    fn api_accept_contact(
1177        &self,
1178        contact_req_id: i64,
1179    ) -> impl Future<Output = Result<Arc<AcceptingContactRequestResponse>, Self::Error>> + Send
1180    {
1181        async move {
1182            let command = ApiAcceptContact { contact_req_id };
1183            let json = self.send_raw(command.interpret()).await?;
1184            // Safe to unwrap because unrecognized JSON goes to undocumented variant
1185            let response = serde_json::from_value(json).unwrap();
1186            match response {
1187                ApiAcceptContactResponse::AcceptingContactRequest(resp) => Ok(Arc::new(resp)),
1188                ApiAcceptContactResponse::ChatCmdError(resp) => {
1189                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
1190                }
1191                ApiAcceptContactResponse::Undocumented(resp) => {
1192                    Err(BadResponseError::Undocumented(resp).into())
1193                }
1194            }
1195        }
1196    }
1197
1198    /// ### Connection commands
1199    ///
1200    /// These commands may be used to create connections. Most bots do not need to use them - bot users will connect via bot address with auto-accept enabled.
1201    ///
1202    /// ----
1203    ///
1204    /// Reject contact request. The user who sent the request is **not notified**.
1205    ///
1206    /// *Network usage*: no.
1207    ///
1208    /// *Syntax:*
1209    ///
1210    /// ```
1211    /// /_reject <contactReqId>
1212    /// ```
1213    fn api_reject_contact(
1214        &self,
1215        contact_req_id: i64,
1216    ) -> impl Future<Output = Result<Arc<ContactRequestRejectedResponse>, Self::Error>> + Send {
1217        async move {
1218            let command = ApiRejectContact { contact_req_id };
1219            let json = self.send_raw(command.interpret()).await?;
1220            // Safe to unwrap because unrecognized JSON goes to undocumented variant
1221            let response = serde_json::from_value(json).unwrap();
1222            match response {
1223                ApiRejectContactResponse::ContactRequestRejected(resp) => Ok(Arc::new(resp)),
1224                ApiRejectContactResponse::ChatCmdError(resp) => {
1225                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
1226                }
1227                ApiRejectContactResponse::Undocumented(resp) => {
1228                    Err(BadResponseError::Undocumented(resp).into())
1229                }
1230            }
1231        }
1232    }
1233
1234    /// ### Chat commands
1235    ///
1236    /// Commands to list and delete conversations.
1237    ///
1238    /// ----
1239    ///
1240    /// Get contacts.
1241    ///
1242    /// *Network usage*: no.
1243    ///
1244    /// *Syntax:*
1245    ///
1246    /// ```
1247    /// /_contacts <userId>
1248    /// ```
1249    fn api_list_contacts(
1250        &self,
1251        user_id: i64,
1252    ) -> impl Future<Output = Result<Arc<ContactsListResponse>, Self::Error>> + Send {
1253        async move {
1254            let command = ApiListContacts { user_id };
1255            let json = self.send_raw(command.interpret()).await?;
1256            // Safe to unwrap because unrecognized JSON goes to undocumented variant
1257            let response = serde_json::from_value(json).unwrap();
1258            match response {
1259                ApiListContactsResponse::ContactsList(resp) => Ok(Arc::new(resp)),
1260                ApiListContactsResponse::ChatCmdError(resp) => {
1261                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
1262                }
1263                ApiListContactsResponse::Undocumented(resp) => {
1264                    Err(BadResponseError::Undocumented(resp).into())
1265                }
1266            }
1267        }
1268    }
1269
1270    /// ### Chat commands
1271    ///
1272    /// Commands to list and delete conversations.
1273    ///
1274    /// ----
1275    ///
1276    /// Get groups.
1277    ///
1278    /// *Network usage*: no.
1279    ///
1280    /// *Syntax:*
1281    ///
1282    /// ```
1283    /// /_groups <userId>[ @<contactId_>][ <search>]
1284    /// ```
1285    fn api_list_groups(
1286        &self,
1287        command: ApiListGroups,
1288    ) -> impl Future<Output = Result<Arc<GroupsListResponse>, Self::Error>> + Send {
1289        async move {
1290            let json = self.send_raw(command.interpret()).await?;
1291            // Safe to unwrap because unrecognized JSON goes to undocumented variant
1292            let response = serde_json::from_value(json).unwrap();
1293            match response {
1294                ApiListGroupsResponse::GroupsList(resp) => Ok(Arc::new(resp)),
1295                ApiListGroupsResponse::ChatCmdError(resp) => {
1296                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
1297                }
1298                ApiListGroupsResponse::Undocumented(resp) => {
1299                    Err(BadResponseError::Undocumented(resp).into())
1300                }
1301            }
1302        }
1303    }
1304
1305    /// ### Chat commands
1306    ///
1307    /// Commands to list and delete conversations.
1308    ///
1309    /// ----
1310    ///
1311    /// Delete chat.
1312    ///
1313    /// *Network usage*: background.
1314    ///
1315    /// *Syntax:*
1316    ///
1317    /// ```
1318    /// /_delete <str(chatRef)> <str(chatDeleteMode)>
1319    /// ```
1320    fn api_delete_chat(
1321        &self,
1322        chat_ref: ChatRef,
1323        chat_delete_mode: ChatDeleteMode,
1324    ) -> impl Future<Output = Result<ApiDeleteChatResponses, Self::Error>> + Send {
1325        async move {
1326            let command = ApiDeleteChat {
1327                chat_ref,
1328                chat_delete_mode,
1329            };
1330            let json = self.send_raw(command.interpret()).await?;
1331            // Safe to unwrap because unrecognized JSON goes to undocumented variant
1332            let response = serde_json::from_value(json).unwrap();
1333            match response {
1334                ApiDeleteChatResponse::ContactDeleted(resp) => {
1335                    Ok(ApiDeleteChatResponses::ContactDeleted(Arc::new(resp)))
1336                }
1337                ApiDeleteChatResponse::ContactConnectionDeleted(resp) => Ok(
1338                    ApiDeleteChatResponses::ContactConnectionDeleted(Arc::new(resp)),
1339                ),
1340                ApiDeleteChatResponse::GroupDeletedUser(resp) => {
1341                    Ok(ApiDeleteChatResponses::GroupDeletedUser(Arc::new(resp)))
1342                }
1343                ApiDeleteChatResponse::ChatCmdError(resp) => {
1344                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
1345                }
1346                ApiDeleteChatResponse::Undocumented(resp) => {
1347                    Err(BadResponseError::Undocumented(resp).into())
1348                }
1349            }
1350        }
1351    }
1352
1353    /// ### User profile commands
1354    ///
1355    /// Most bots don't need to use these commands, as bot profile can be configured manually via CLI or desktop client. These commands can be used by bots that need to manage multiple user profiles (e.g., the profiles of support agents).
1356    ///
1357    /// ----
1358    ///
1359    /// Get active user profile
1360    ///
1361    /// *Network usage*: no.
1362    ///
1363    /// *Syntax:*
1364    ///
1365    /// ```
1366    /// /user
1367    /// ```
1368    fn show_active_user(
1369        &self,
1370    ) -> impl Future<Output = Result<Arc<ActiveUserResponse>, Self::Error>> + Send {
1371        async move {
1372            let command = ShowActiveUser {};
1373            let json = self.send_raw(command.interpret()).await?;
1374            // Safe to unwrap because unrecognized JSON goes to undocumented variant
1375            let response = serde_json::from_value(json).unwrap();
1376            match response {
1377                ShowActiveUserResponse::ActiveUser(resp) => Ok(Arc::new(resp)),
1378                ShowActiveUserResponse::ChatCmdError(resp) => {
1379                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
1380                }
1381                ShowActiveUserResponse::Undocumented(resp) => {
1382                    Err(BadResponseError::Undocumented(resp).into())
1383                }
1384            }
1385        }
1386    }
1387
1388    /// ### User profile commands
1389    ///
1390    /// Most bots don't need to use these commands, as bot profile can be configured manually via CLI or desktop client. These commands can be used by bots that need to manage multiple user profiles (e.g., the profiles of support agents).
1391    ///
1392    /// ----
1393    ///
1394    /// Create new user profile
1395    ///
1396    /// *Network usage*: no.
1397    ///
1398    /// *Syntax:*
1399    ///
1400    /// ```
1401    /// /_create user <json(newUser)>
1402    /// ```
1403    fn create_active_user(
1404        &self,
1405        new_user: NewUser,
1406    ) -> impl Future<Output = Result<Arc<ActiveUserResponse>, Self::Error>> + Send {
1407        async move {
1408            let command = CreateActiveUser { new_user };
1409            let json = self.send_raw(command.interpret()).await?;
1410            // Safe to unwrap because unrecognized JSON goes to undocumented variant
1411            let response = serde_json::from_value(json).unwrap();
1412            match response {
1413                CreateActiveUserResponse::ActiveUser(resp) => Ok(Arc::new(resp)),
1414                CreateActiveUserResponse::ChatCmdError(resp) => {
1415                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
1416                }
1417                CreateActiveUserResponse::Undocumented(resp) => {
1418                    Err(BadResponseError::Undocumented(resp).into())
1419                }
1420            }
1421        }
1422    }
1423
1424    /// ### User profile commands
1425    ///
1426    /// Most bots don't need to use these commands, as bot profile can be configured manually via CLI or desktop client. These commands can be used by bots that need to manage multiple user profiles (e.g., the profiles of support agents).
1427    ///
1428    /// ----
1429    ///
1430    /// Get all user profiles
1431    ///
1432    /// *Network usage*: no.
1433    ///
1434    /// *Syntax:*
1435    ///
1436    /// ```
1437    /// /users
1438    /// ```
1439    fn list_users(
1440        &self,
1441    ) -> impl Future<Output = Result<Arc<UsersListResponse>, Self::Error>> + Send {
1442        async move {
1443            let command = ListUsers {};
1444            let json = self.send_raw(command.interpret()).await?;
1445            // Safe to unwrap because unrecognized JSON goes to undocumented variant
1446            let response = serde_json::from_value(json).unwrap();
1447            match response {
1448                ListUsersResponse::UsersList(resp) => Ok(Arc::new(resp)),
1449                ListUsersResponse::ChatCmdError(resp) => {
1450                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
1451                }
1452                ListUsersResponse::Undocumented(resp) => {
1453                    Err(BadResponseError::Undocumented(resp).into())
1454                }
1455            }
1456        }
1457    }
1458
1459    /// ### User profile commands
1460    ///
1461    /// Most bots don't need to use these commands, as bot profile can be configured manually via CLI or desktop client. These commands can be used by bots that need to manage multiple user profiles (e.g., the profiles of support agents).
1462    ///
1463    /// ----
1464    ///
1465    /// Set active user profile
1466    ///
1467    /// *Network usage*: no.
1468    ///
1469    /// *Syntax:*
1470    ///
1471    /// ```
1472    /// /_user <userId>[ <json(viewPwd)>]
1473    /// ```
1474    fn api_set_active_user(
1475        &self,
1476        command: ApiSetActiveUser,
1477    ) -> impl Future<Output = Result<Arc<ActiveUserResponse>, Self::Error>> + Send {
1478        async move {
1479            let json = self.send_raw(command.interpret()).await?;
1480            // Safe to unwrap because unrecognized JSON goes to undocumented variant
1481            let response = serde_json::from_value(json).unwrap();
1482            match response {
1483                ApiSetActiveUserResponse::ActiveUser(resp) => Ok(Arc::new(resp)),
1484                ApiSetActiveUserResponse::ChatCmdError(resp) => {
1485                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
1486                }
1487                ApiSetActiveUserResponse::Undocumented(resp) => {
1488                    Err(BadResponseError::Undocumented(resp).into())
1489                }
1490            }
1491        }
1492    }
1493
1494    /// ### User profile commands
1495    ///
1496    /// Most bots don't need to use these commands, as bot profile can be configured manually via CLI or desktop client. These commands can be used by bots that need to manage multiple user profiles (e.g., the profiles of support agents).
1497    ///
1498    /// ----
1499    ///
1500    /// Delete user profile.
1501    ///
1502    /// *Network usage*: background.
1503    ///
1504    /// *Syntax:*
1505    ///
1506    /// ```
1507    /// /_delete user <userId> del_smp=on|off[ <json(viewPwd)>]
1508    /// ```
1509    fn api_delete_user(
1510        &self,
1511        command: ApiDeleteUser,
1512    ) -> impl Future<Output = Result<Arc<CmdOkResponse>, Self::Error>> + Send {
1513        async move {
1514            let json = self.send_raw(command.interpret()).await?;
1515            // Safe to unwrap because unrecognized JSON goes to undocumented variant
1516            let response = serde_json::from_value(json).unwrap();
1517            match response {
1518                ApiDeleteUserResponse::CmdOk(resp) => Ok(Arc::new(resp)),
1519                ApiDeleteUserResponse::ChatCmdError(resp) => {
1520                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
1521                }
1522                ApiDeleteUserResponse::Undocumented(resp) => {
1523                    Err(BadResponseError::Undocumented(resp).into())
1524                }
1525            }
1526        }
1527    }
1528
1529    /// ### User profile commands
1530    ///
1531    /// Most bots don't need to use these commands, as bot profile can be configured manually via CLI or desktop client. These commands can be used by bots that need to manage multiple user profiles (e.g., the profiles of support agents).
1532    ///
1533    /// ----
1534    ///
1535    /// Update user profile.
1536    ///
1537    /// *Network usage*: background.
1538    ///
1539    /// *Syntax:*
1540    ///
1541    /// ```
1542    /// /_profile <userId> <json(profile)>
1543    /// ```
1544    fn api_update_profile(
1545        &self,
1546        user_id: i64,
1547        profile: Profile,
1548    ) -> impl Future<Output = Result<ApiUpdateProfileResponses, Self::Error>> + Send {
1549        async move {
1550            let command = ApiUpdateProfile { user_id, profile };
1551            let json = self.send_raw(command.interpret()).await?;
1552            // Safe to unwrap because unrecognized JSON goes to undocumented variant
1553            let response = serde_json::from_value(json).unwrap();
1554            match response {
1555                ApiUpdateProfileResponse::UserProfileUpdated(resp) => Ok(
1556                    ApiUpdateProfileResponses::UserProfileUpdated(Arc::new(resp)),
1557                ),
1558                ApiUpdateProfileResponse::UserProfileNoChange(resp) => Ok(
1559                    ApiUpdateProfileResponses::UserProfileNoChange(Arc::new(resp)),
1560                ),
1561                ApiUpdateProfileResponse::ChatCmdError(resp) => {
1562                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
1563                }
1564                ApiUpdateProfileResponse::Undocumented(resp) => {
1565                    Err(BadResponseError::Undocumented(resp).into())
1566                }
1567            }
1568        }
1569    }
1570
1571    /// ### User profile commands
1572    ///
1573    /// Most bots don't need to use these commands, as bot profile can be configured manually via CLI or desktop client. These commands can be used by bots that need to manage multiple user profiles (e.g., the profiles of support agents).
1574    ///
1575    /// ----
1576    ///
1577    /// Configure chat preference overrides for the contact.
1578    ///
1579    /// *Network usage*: background.
1580    ///
1581    /// *Syntax:*
1582    ///
1583    /// ```
1584    /// /_set prefs @<contactId> <json(preferences)>
1585    /// ```
1586    fn api_set_contact_prefs(
1587        &self,
1588        contact_id: i64,
1589        preferences: Preferences,
1590    ) -> impl Future<Output = Result<Arc<ContactPrefsUpdatedResponse>, Self::Error>> + Send {
1591        async move {
1592            let command = ApiSetContactPrefs {
1593                contact_id,
1594                preferences,
1595            };
1596            let json = self.send_raw(command.interpret()).await?;
1597            // Safe to unwrap because unrecognized JSON goes to undocumented variant
1598            let response = serde_json::from_value(json).unwrap();
1599            match response {
1600                ApiSetContactPrefsResponse::ContactPrefsUpdated(resp) => Ok(Arc::new(resp)),
1601                ApiSetContactPrefsResponse::ChatCmdError(resp) => {
1602                    Err(BadResponseError::ChatCmdError(Arc::new(resp)).into())
1603                }
1604                ApiSetContactPrefsResponse::Undocumented(resp) => {
1605                    Err(BadResponseError::Undocumented(resp).into())
1606                }
1607            }
1608        }
1609    }
1610}
1611
1612#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1613#[serde(tag = "type")]
1614pub enum ApiUpdateChatItemResponses {
1615    /// ChatItemUpdated: Message updated.
1616    #[serde(rename = "chatItemUpdated")]
1617    ChatItemUpdated(Arc<ChatItemUpdatedResponse>),
1618    /// ChatItemNotChanged: Message not changed.
1619    #[serde(rename = "chatItemNotChanged")]
1620    ChatItemNotChanged(Arc<ChatItemNotChangedResponse>),
1621}
1622
1623impl ApiUpdateChatItemResponses {
1624    pub fn chat_item_updated(&self) -> Option<&ChatItemUpdatedResponse> {
1625        if let Self::ChatItemUpdated(ret) = self {
1626            Some(ret)
1627        } else {
1628            None
1629        }
1630    }
1631
1632    pub fn chat_item_not_changed(&self) -> Option<&ChatItemNotChangedResponse> {
1633        if let Self::ChatItemNotChanged(ret) = self {
1634            Some(ret)
1635        } else {
1636            None
1637        }
1638    }
1639}
1640
1641#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1642#[serde(tag = "type")]
1643pub enum ReceiveFileResponses {
1644    /// RcvFileAccepted: File accepted to be received.
1645    #[serde(rename = "rcvFileAccepted")]
1646    RcvFileAccepted(Arc<RcvFileAcceptedResponse>),
1647    /// RcvFileAcceptedSndCancelled: File accepted, but no longer sent.
1648    #[serde(rename = "rcvFileAcceptedSndCancelled")]
1649    RcvFileAcceptedSndCancelled(Arc<RcvFileAcceptedSndCancelledResponse>),
1650}
1651
1652impl ReceiveFileResponses {
1653    pub fn rcv_file_accepted(&self) -> Option<&RcvFileAcceptedResponse> {
1654        if let Self::RcvFileAccepted(ret) = self {
1655            Some(ret)
1656        } else {
1657            None
1658        }
1659    }
1660
1661    pub fn rcv_file_accepted_snd_cancelled(&self) -> Option<&RcvFileAcceptedSndCancelledResponse> {
1662        if let Self::RcvFileAcceptedSndCancelled(ret) = self {
1663            Some(ret)
1664        } else {
1665            None
1666        }
1667    }
1668}
1669
1670#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1671#[serde(tag = "type")]
1672pub enum CancelFileResponses {
1673    /// SndFileCancelled: Cancelled sending file.
1674    #[serde(rename = "sndFileCancelled")]
1675    SndFileCancelled(Arc<SndFileCancelledResponse>),
1676    /// RcvFileCancelled: Cancelled receiving file.
1677    #[serde(rename = "rcvFileCancelled")]
1678    RcvFileCancelled(Arc<RcvFileCancelledResponse>),
1679}
1680
1681impl CancelFileResponses {
1682    pub fn snd_file_cancelled(&self) -> Option<&SndFileCancelledResponse> {
1683        if let Self::SndFileCancelled(ret) = self {
1684            Some(ret)
1685        } else {
1686            None
1687        }
1688    }
1689
1690    pub fn rcv_file_cancelled(&self) -> Option<&RcvFileCancelledResponse> {
1691        if let Self::RcvFileCancelled(ret) = self {
1692            Some(ret)
1693        } else {
1694            None
1695        }
1696    }
1697}
1698
1699#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1700#[serde(tag = "type")]
1701pub enum ApiConnectResponses {
1702    /// SentConfirmation: Confirmation sent to one-time invitation.
1703    #[serde(rename = "sentConfirmation")]
1704    SentConfirmation(Arc<SentConfirmationResponse>),
1705    /// ContactAlreadyExists: Contact already exists.
1706    #[serde(rename = "contactAlreadyExists")]
1707    ContactAlreadyExists(Arc<ContactAlreadyExistsResponse>),
1708    /// SentInvitation: Invitation sent to contact address.
1709    #[serde(rename = "sentInvitation")]
1710    SentInvitation(Arc<SentInvitationResponse>),
1711}
1712
1713impl ApiConnectResponses {
1714    pub fn sent_confirmation(&self) -> Option<&SentConfirmationResponse> {
1715        if let Self::SentConfirmation(ret) = self {
1716            Some(ret)
1717        } else {
1718            None
1719        }
1720    }
1721
1722    pub fn contact_already_exists(&self) -> Option<&ContactAlreadyExistsResponse> {
1723        if let Self::ContactAlreadyExists(ret) = self {
1724            Some(ret)
1725        } else {
1726            None
1727        }
1728    }
1729
1730    pub fn sent_invitation(&self) -> Option<&SentInvitationResponse> {
1731        if let Self::SentInvitation(ret) = self {
1732            Some(ret)
1733        } else {
1734            None
1735        }
1736    }
1737}
1738
1739#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1740#[serde(tag = "type")]
1741pub enum ConnectResponses {
1742    /// SentConfirmation: Confirmation sent to one-time invitation.
1743    #[serde(rename = "sentConfirmation")]
1744    SentConfirmation(Arc<SentConfirmationResponse>),
1745    /// ContactAlreadyExists: Contact already exists.
1746    #[serde(rename = "contactAlreadyExists")]
1747    ContactAlreadyExists(Arc<ContactAlreadyExistsResponse>),
1748    /// SentInvitation: Invitation sent to contact address.
1749    #[serde(rename = "sentInvitation")]
1750    SentInvitation(Arc<SentInvitationResponse>),
1751}
1752
1753impl ConnectResponses {
1754    pub fn sent_confirmation(&self) -> Option<&SentConfirmationResponse> {
1755        if let Self::SentConfirmation(ret) = self {
1756            Some(ret)
1757        } else {
1758            None
1759        }
1760    }
1761
1762    pub fn contact_already_exists(&self) -> Option<&ContactAlreadyExistsResponse> {
1763        if let Self::ContactAlreadyExists(ret) = self {
1764            Some(ret)
1765        } else {
1766            None
1767        }
1768    }
1769
1770    pub fn sent_invitation(&self) -> Option<&SentInvitationResponse> {
1771        if let Self::SentInvitation(ret) = self {
1772            Some(ret)
1773        } else {
1774            None
1775        }
1776    }
1777}
1778
1779#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1780#[serde(tag = "type")]
1781pub enum ApiDeleteChatResponses {
1782    /// ContactDeleted: Contact deleted.
1783    #[serde(rename = "contactDeleted")]
1784    ContactDeleted(Arc<ContactDeletedResponse>),
1785    /// ContactConnectionDeleted: Connection deleted.
1786    #[serde(rename = "contactConnectionDeleted")]
1787    ContactConnectionDeleted(Arc<ContactConnectionDeletedResponse>),
1788    /// GroupDeletedUser: User deleted group.
1789    #[serde(rename = "groupDeletedUser")]
1790    GroupDeletedUser(Arc<GroupDeletedUserResponse>),
1791}
1792
1793impl ApiDeleteChatResponses {
1794    pub fn contact_deleted(&self) -> Option<&ContactDeletedResponse> {
1795        if let Self::ContactDeleted(ret) = self {
1796            Some(ret)
1797        } else {
1798            None
1799        }
1800    }
1801
1802    pub fn contact_connection_deleted(&self) -> Option<&ContactConnectionDeletedResponse> {
1803        if let Self::ContactConnectionDeleted(ret) = self {
1804            Some(ret)
1805        } else {
1806            None
1807        }
1808    }
1809
1810    pub fn group_deleted_user(&self) -> Option<&GroupDeletedUserResponse> {
1811        if let Self::GroupDeletedUser(ret) = self {
1812            Some(ret)
1813        } else {
1814            None
1815        }
1816    }
1817}
1818
1819#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1820#[serde(tag = "type")]
1821pub enum ApiUpdateProfileResponses {
1822    /// UserProfileUpdated: User profile updated.
1823    #[serde(rename = "userProfileUpdated")]
1824    UserProfileUpdated(Arc<UserProfileUpdatedResponse>),
1825    /// UserProfileNoChange: User profile was not changed.
1826    #[serde(rename = "userProfileNoChange")]
1827    UserProfileNoChange(Arc<UserProfileNoChangeResponse>),
1828}
1829
1830impl ApiUpdateProfileResponses {
1831    pub fn user_profile_updated(&self) -> Option<&UserProfileUpdatedResponse> {
1832        if let Self::UserProfileUpdated(ret) = self {
1833            Some(ret)
1834        } else {
1835            None
1836        }
1837    }
1838
1839    pub fn user_profile_no_change(&self) -> Option<&UserProfileNoChangeResponse> {
1840        if let Self::UserProfileNoChange(ret) = self {
1841            Some(ret)
1842        } else {
1843            None
1844        }
1845    }
1846}
1847
1848#[derive(Debug)]
1849pub enum BadResponseError {
1850    ChatCmdError(Arc<ChatCmdErrorResponse>),
1851    Undocumented(BTreeMap<String, JsonObject>),
1852}
1853
1854impl std::error::Error for BadResponseError {}
1855
1856impl std::fmt::Display for BadResponseError {
1857    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1858        match self {
1859            Self::ChatCmdError(resp) => writeln!(
1860                f,
1861                "Bad server response:\n{}",
1862                serde_json::to_string_pretty(resp).unwrap()
1863            ),
1864            Self::Undocumented(resp) => writeln!(
1865                f,
1866                "Unexpected server response:\n{}",
1867                serde_json::to_string_pretty(resp).unwrap()
1868            ),
1869        }
1870    }
1871}
1872
1873pub enum UndocumentedResponse<T> {
1874    Documented(T),
1875    Undocumented(BTreeMap<String, JsonObject>),
1876}
1877
1878/// If you want to ~~suffer~~ handle undocumented responses you can use this extension trait on
1879/// client API return values to move `Undocumented` from `Err` to `Ok` variant.
1880///
1881/// Example:
1882///
1883/// ```ignore
1884///     match client
1885///         .api_create_my_address(1)
1886///         .await
1887///         .allow_undocumented()?
1888///     {
1889///         UndocumentedResponse::Documented(resp) => {
1890///              // Process expected response...
1891///         }
1892///         UndocumentedResponse::Undocumented(resp) => {
1893///             // Do something with the unexpected response...
1894///         }
1895///     }
1896/// }
1897/// ```
1898pub trait AllowUndocumentedResponses<T, E> {
1899    fn allow_undocumented(self) -> Result<UndocumentedResponse<T>, E>;
1900}
1901
1902impl<T, E> AllowUndocumentedResponses<T, E> for Result<T, E>
1903where
1904    E: ClientApiError,
1905{
1906    fn allow_undocumented(self) -> Result<UndocumentedResponse<T>, E> {
1907        match self {
1908            Ok(resp) => Ok(UndocumentedResponse::Documented(resp)),
1909            Err(mut e) => match e.bad_response_mut() {
1910                Some(BadResponseError::Undocumented(btree_map)) => Ok(
1911                    UndocumentedResponse::Undocumented(std::mem::take(btree_map)),
1912                ),
1913                _ => Err(e),
1914            },
1915        }
1916    }
1917}