1use crate::{
2 core::{
3 api_req::ApiRequest, api_resp::ApiResponseTrait, config::Config,
4 constants::AccessTokenType, http::Transport, req_option::RequestOption,
5 standard_response::StandardResponse, trait_system::executable_builder::ExecutableBuilder,
6 SDKResult,
7 },
8 service::contact::models::*,
9};
10use async_trait::async_trait;
11use serde::{Deserialize, Serialize};
12
13pub struct UserService {
22 config: Config,
23}
24
25impl UserService {
26 pub fn new(config: Config) -> Self {
27 Self { config }
28 }
29
30 pub async fn create(
32 &self,
33 req: &CreateUserRequest,
34 ) -> crate::core::SDKResult<CreateUserResponse> {
35 let api_req = ApiRequest {
36 http_method: reqwest::Method::POST,
37 api_path: "/open-apis/contact/v3/users".to_string(),
38 supported_access_token_types: vec![AccessTokenType::Tenant],
39 body: serde_json::to_vec(req)?,
40 ..Default::default()
41 };
42
43 let resp = Transport::<CreateUserResponse>::request(api_req, &self.config, None).await?;
44 resp.into_result()
45 }
46
47 pub async fn patch(
49 &self,
50 user_id: &str,
51 req: &PatchUserRequest,
52 ) -> crate::core::SDKResult<PatchUserResponse> {
53 let api_req = ApiRequest {
54 http_method: reqwest::Method::PATCH,
55 api_path: format!("/open-apis/contact/v3/users/{user_id}"),
56 supported_access_token_types: vec![AccessTokenType::Tenant],
57 body: serde_json::to_vec(req)?,
58 ..Default::default()
59 };
60
61 let resp = Transport::<PatchUserResponse>::request(api_req, &self.config, None).await?;
62 resp.into_result()
63 }
64
65 pub async fn update_user_id(
67 &self,
68 user_id: &str,
69 req: &UpdateUserIdRequest,
70 ) -> crate::core::SDKResult<UpdateUserIdResponse> {
71 let api_req = ApiRequest {
72 http_method: reqwest::Method::PATCH,
73 api_path: format!("/open-apis/contact/v3/users/{user_id}/update_user_id"),
74 supported_access_token_types: vec![AccessTokenType::Tenant],
75 body: serde_json::to_vec(req)?,
76 ..Default::default()
77 };
78
79 let resp = Transport::<UpdateUserIdResponse>::request(api_req, &self.config, None).await?;
80 resp.into_result()
81 }
82
83 pub async fn get(
85 &self,
86 user_id: &str,
87 _req: &GetUserRequest,
88 ) -> crate::core::SDKResult<GetUserResponse> {
89 let api_req = ApiRequest {
90 http_method: reqwest::Method::GET,
91 api_path: format!("/open-apis/contact/v3/users/{user_id}"),
92 supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
93 body: Vec::new(),
94 query_params: std::collections::HashMap::new(),
95 ..Default::default()
96 };
97
98 let resp = Transport::<GetUserResponse>::request(api_req, &self.config, None).await?;
99 resp.into_result()
100 }
101
102 pub async fn batch(
104 &self,
105 req: &BatchGetUsersRequest,
106 ) -> crate::core::SDKResult<BatchGetUsersResponse> {
107 let api_req = ApiRequest {
108 http_method: reqwest::Method::POST,
109 api_path: "/open-apis/contact/v3/users/batch".to_string(),
110 supported_access_token_types: vec![AccessTokenType::Tenant],
111 body: serde_json::to_vec(req)?,
112 ..Default::default()
113 };
114
115 let resp = Transport::<BatchGetUsersResponse>::request(api_req, &self.config, None).await?;
116 resp.into_result()
117 }
118
119 pub async fn find_by_department(
121 &self,
122 _req: &FindUsersByDepartmentRequest,
123 ) -> crate::core::SDKResult<FindUsersByDepartmentResponse> {
124 let api_req = ApiRequest {
125 http_method: reqwest::Method::GET,
126 api_path: "/open-apis/contact/v3/users/find_by_department".to_string(),
127 supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
128 body: Vec::new(),
129 query_params: std::collections::HashMap::new(),
130 ..Default::default()
131 };
132
133 let resp = Transport::<FindUsersByDepartmentResponse>::request(api_req, &self.config, None)
134 .await?;
135 resp.into_result()
136 }
137
138 pub async fn batch_get_id(
140 &self,
141 req: &BatchGetUserIdRequest,
142 ) -> crate::core::SDKResult<BatchGetUserIdResponse> {
143 let api_req = ApiRequest {
144 http_method: reqwest::Method::POST,
145 api_path: "/open-apis/contact/v3/users/batch_get_id".to_string(),
146 supported_access_token_types: vec![AccessTokenType::Tenant],
147 body: serde_json::to_vec(req)?,
148 ..Default::default()
149 };
150
151 let resp =
152 Transport::<BatchGetUserIdResponse>::request(api_req, &self.config, None).await?;
153 resp.into_result()
154 }
155
156 pub async fn search(
158 &self,
159 req: &SearchUsersRequest,
160 ) -> crate::core::SDKResult<SearchUsersResponse> {
161 let api_req = ApiRequest {
162 http_method: reqwest::Method::POST,
163 api_path: "/open-apis/contact/v3/users/search".to_string(),
164 supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
165 body: serde_json::to_vec(req)?,
166 ..Default::default()
167 };
168
169 let resp = Transport::<SearchUsersResponse>::request(api_req, &self.config, None).await?;
170 resp.into_result()
171 }
172
173 pub async fn delete(
175 &self,
176 user_id: &str,
177 _req: &DeleteUserRequest,
178 ) -> crate::core::SDKResult<DeleteUserResponse> {
179 let api_req = ApiRequest {
180 http_method: reqwest::Method::DELETE,
181 api_path: format!("/open-apis/contact/v3/users/{user_id}"),
182 supported_access_token_types: vec![AccessTokenType::Tenant],
183 body: Vec::new(),
184 query_params: std::collections::HashMap::new(),
185 ..Default::default()
186 };
187
188 let resp = Transport::<DeleteUserResponse>::request(api_req, &self.config, None).await?;
189 resp.into_result()
190 }
191
192 pub async fn resurrect(
194 &self,
195 user_id: &str,
196 req: &ResurrectUserRequest,
197 ) -> crate::core::SDKResult<ResurrectUserResponse> {
198 let api_req = ApiRequest {
199 http_method: reqwest::Method::POST,
200 api_path: format!("/open-apis/contact/v3/users/{user_id}/resurrect"),
201 supported_access_token_types: vec![AccessTokenType::Tenant],
202 body: serde_json::to_vec(req)?,
203 ..Default::default()
204 };
205
206 let resp = Transport::<ResurrectUserResponse>::request(api_req, &self.config, None).await?;
207 resp.into_result()
208 }
209
210 pub async fn list(&self, req: &ListUsersRequest) -> crate::core::SDKResult<ListUsersResponse> {
212 let mut query_params = std::collections::HashMap::new();
213
214 if let Some(page_size) = req.page_size {
215 query_params.insert("page_size".to_string(), page_size.to_string());
216 }
217 if let Some(page_token) = &req.page_token {
218 query_params.insert("page_token".to_string(), page_token.clone());
219 }
220 if let Some(user_id_type) = &req.user_id_type {
221 query_params.insert("user_id_type".to_string(), user_id_type.clone());
222 }
223 if let Some(department_id_type) = &req.department_id_type {
224 query_params.insert("department_id_type".to_string(), department_id_type.clone());
225 }
226
227 let api_req = ApiRequest {
228 http_method: reqwest::Method::GET,
229 api_path: "/open-apis/contact/v3/users".to_string(),
230 supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
231 body: Vec::new(),
232 query_params,
233 ..Default::default()
234 };
235
236 let resp = Transport::<ListUsersResponse>::request(api_req, &self.config, None).await?;
237 resp.into_result()
238 }
239
240 pub fn create_user_builder(&self) -> CreateUserBuilder {
244 CreateUserBuilder::new()
245 }
246}
247
248#[derive(Default)]
250pub struct CreateUserBuilder {
251 user: Option<User>,
252 user_id_type: Option<String>,
253 department_id_type: Option<String>,
254}
255
256impl CreateUserBuilder {
257 pub fn new() -> Self {
258 Self::default()
259 }
260
261 pub fn user(mut self, user: User) -> Self {
263 self.user = Some(user);
264 self
265 }
266
267 pub fn user_id_type(mut self, user_id_type: impl ToString) -> Self {
269 self.user_id_type = Some(user_id_type.to_string());
270 self
271 }
272
273 pub fn department_id_type(mut self, department_id_type: impl ToString) -> Self {
275 self.department_id_type = Some(department_id_type.to_string());
276 self
277 }
278
279 pub fn build(self) -> CreateUserRequest {
280 CreateUserRequest {
281 user: self.user.unwrap_or_default(),
282 user_id_type: self.user_id_type,
283 department_id_type: self.department_id_type,
284 }
285 }
286}
287
288#[async_trait]
289impl ExecutableBuilder<UserService, CreateUserRequest, CreateUserResponse> for CreateUserBuilder {
290 fn build(self) -> CreateUserRequest {
291 self.build()
292 }
293
294 async fn execute(self, service: &UserService) -> SDKResult<CreateUserResponse> {
295 let req = self.build();
296 service.create(&req).await
297 }
298
299 async fn execute_with_options(
300 self,
301 service: &UserService,
302 _option: RequestOption,
303 ) -> SDKResult<CreateUserResponse> {
304 let req = self.build();
306 service.create(&req).await
307 }
308}
309
310#[derive(Debug, Clone, Serialize, Deserialize)]
314pub struct CreateUserRequest {
315 pub user: User,
317 #[serde(skip_serializing_if = "Option::is_none")]
319 pub user_id_type: Option<String>,
320 #[serde(skip_serializing_if = "Option::is_none")]
322 pub department_id_type: Option<String>,
323}
324
325#[derive(Debug, Clone, Serialize, Deserialize, Default)]
327pub struct CreateUserResponse {
328 pub user: User,
330}
331
332impl ApiResponseTrait for CreateUserResponse {
333 fn data_format() -> crate::core::api_resp::ResponseFormat {
334 crate::core::api_resp::ResponseFormat::Data
335 }
336}
337
338#[derive(Debug, Clone, Serialize, Deserialize)]
340pub struct PatchUserRequest {
341 pub user: User,
343 #[serde(skip_serializing_if = "Option::is_none")]
345 pub user_id_type: Option<String>,
346 #[serde(skip_serializing_if = "Option::is_none")]
348 pub department_id_type: Option<String>,
349}
350
351#[derive(Debug, Clone, Serialize, Deserialize, Default)]
353pub struct PatchUserResponse {
354 pub user: User,
356}
357
358impl ApiResponseTrait for PatchUserResponse {
359 fn data_format() -> crate::core::api_resp::ResponseFormat {
360 crate::core::api_resp::ResponseFormat::Data
361 }
362}
363
364#[derive(Debug, Clone, Serialize, Deserialize)]
366pub struct UpdateUserIdRequest {
367 pub new_user_id: String,
369 #[serde(skip_serializing_if = "Option::is_none")]
371 pub user_id_type: Option<String>,
372}
373
374#[derive(Debug, Clone, Serialize, Deserialize, Default)]
376pub struct UpdateUserIdResponse {}
377
378impl ApiResponseTrait for UpdateUserIdResponse {
379 fn data_format() -> crate::core::api_resp::ResponseFormat {
380 crate::core::api_resp::ResponseFormat::Data
381 }
382}
383
384#[derive(Debug, Clone, Default, Serialize, Deserialize)]
386pub struct GetUserRequest {
387 #[serde(skip_serializing_if = "Option::is_none")]
389 pub user_id_type: Option<String>,
390 #[serde(skip_serializing_if = "Option::is_none")]
392 pub department_id_type: Option<String>,
393}
394
395#[derive(Debug, Clone, Serialize, Deserialize, Default)]
397pub struct GetUserResponse {
398 pub user: User,
400}
401
402impl ApiResponseTrait for GetUserResponse {
403 fn data_format() -> crate::core::api_resp::ResponseFormat {
404 crate::core::api_resp::ResponseFormat::Data
405 }
406}
407
408#[derive(Debug, Clone, Serialize, Deserialize)]
410pub struct BatchGetUsersRequest {
411 pub user_ids: Vec<String>,
413 #[serde(skip_serializing_if = "Option::is_none")]
415 pub user_id_type: Option<String>,
416 #[serde(skip_serializing_if = "Option::is_none")]
418 pub department_id_type: Option<String>,
419}
420
421#[derive(Debug, Clone, Serialize, Deserialize, Default)]
423pub struct BatchGetUsersResponse {
424 pub items: Vec<User>,
426}
427
428impl ApiResponseTrait for BatchGetUsersResponse {
429 fn data_format() -> crate::core::api_resp::ResponseFormat {
430 crate::core::api_resp::ResponseFormat::Data
431 }
432}
433
434#[derive(Debug, Clone, Default, Serialize, Deserialize)]
436pub struct FindUsersByDepartmentRequest {
437 #[serde(skip_serializing_if = "Option::is_none")]
439 pub department_id: Option<String>,
440 #[serde(skip_serializing_if = "Option::is_none")]
442 pub user_id_type: Option<String>,
443 #[serde(skip_serializing_if = "Option::is_none")]
445 pub department_id_type: Option<String>,
446 #[serde(skip_serializing_if = "Option::is_none")]
448 pub page_size: Option<i32>,
449 #[serde(skip_serializing_if = "Option::is_none")]
451 pub page_token: Option<String>,
452}
453
454#[derive(Debug, Clone, Serialize, Deserialize, Default)]
456pub struct FindUsersByDepartmentResponse {
457 pub items: Vec<User>,
459 #[serde(skip_serializing_if = "Option::is_none")]
461 pub has_more: Option<bool>,
462 #[serde(skip_serializing_if = "Option::is_none")]
464 pub page_token: Option<String>,
465}
466
467impl ApiResponseTrait for FindUsersByDepartmentResponse {
468 fn data_format() -> crate::core::api_resp::ResponseFormat {
469 crate::core::api_resp::ResponseFormat::Data
470 }
471}
472
473#[derive(Debug, Clone, Serialize, Deserialize)]
475pub struct BatchGetUserIdRequest {
476 #[serde(skip_serializing_if = "Option::is_none")]
478 pub emails: Option<Vec<String>>,
479 #[serde(skip_serializing_if = "Option::is_none")]
481 pub mobiles: Option<Vec<String>>,
482 #[serde(skip_serializing_if = "Option::is_none")]
484 pub include_resigned: Option<bool>,
485}
486
487#[derive(Debug, Clone, Serialize, Deserialize, Default)]
489pub struct BatchGetUserIdResponse {
490 pub user_list: Vec<UserIdInfo>,
492}
493
494impl ApiResponseTrait for BatchGetUserIdResponse {
495 fn data_format() -> crate::core::api_resp::ResponseFormat {
496 crate::core::api_resp::ResponseFormat::Data
497 }
498}
499
500#[derive(Debug, Clone, Serialize, Deserialize)]
502pub struct UserIdInfo {
503 #[serde(skip_serializing_if = "Option::is_none")]
505 pub user_id: Option<String>,
506 #[serde(skip_serializing_if = "Option::is_none")]
508 pub email: Option<String>,
509 #[serde(skip_serializing_if = "Option::is_none")]
511 pub mobile: Option<String>,
512}
513
514#[derive(Debug, Clone, Serialize, Deserialize)]
516pub struct SearchUsersRequest {
517 pub query: String,
519 #[serde(skip_serializing_if = "Option::is_none")]
521 pub page_size: Option<i32>,
522 #[serde(skip_serializing_if = "Option::is_none")]
524 pub page_token: Option<String>,
525 #[serde(skip_serializing_if = "Option::is_none")]
527 pub user_id_type: Option<String>,
528 #[serde(skip_serializing_if = "Option::is_none")]
530 pub department_id_type: Option<String>,
531}
532
533#[derive(Debug, Clone, Serialize, Deserialize, Default)]
535pub struct SearchUsersResponse {
536 pub items: Vec<User>,
538 #[serde(skip_serializing_if = "Option::is_none")]
540 pub has_more: Option<bool>,
541 #[serde(skip_serializing_if = "Option::is_none")]
543 pub page_token: Option<String>,
544}
545
546impl ApiResponseTrait for SearchUsersResponse {
547 fn data_format() -> crate::core::api_resp::ResponseFormat {
548 crate::core::api_resp::ResponseFormat::Data
549 }
550}
551
552#[derive(Debug, Clone, Default, Serialize, Deserialize)]
554pub struct DeleteUserRequest {
555 #[serde(skip_serializing_if = "Option::is_none")]
557 pub user_id_type: Option<String>,
558 #[serde(skip_serializing_if = "Option::is_none")]
560 pub department_id_type: Option<String>,
561}
562
563#[derive(Debug, Clone, Serialize, Deserialize, Default)]
565pub struct DeleteUserResponse {}
566
567impl ApiResponseTrait for DeleteUserResponse {
568 fn data_format() -> crate::core::api_resp::ResponseFormat {
569 crate::core::api_resp::ResponseFormat::Data
570 }
571}
572
573#[derive(Debug, Clone, Serialize, Deserialize)]
575pub struct ResurrectUserRequest {
576 #[serde(skip_serializing_if = "Option::is_none")]
578 pub user_id_type: Option<String>,
579 #[serde(skip_serializing_if = "Option::is_none")]
581 pub department_id_type: Option<String>,
582}
583
584#[derive(Debug, Clone, Serialize, Deserialize, Default)]
586pub struct ResurrectUserResponse {
587 pub user: User,
589}
590
591impl ApiResponseTrait for ResurrectUserResponse {
592 fn data_format() -> crate::core::api_resp::ResponseFormat {
593 crate::core::api_resp::ResponseFormat::Data
594 }
595}
596
597#[derive(Debug, Clone, Default, Serialize, Deserialize)]
599pub struct ListUsersRequest {
600 #[serde(skip_serializing_if = "Option::is_none")]
602 pub page_size: Option<i32>,
603 #[serde(skip_serializing_if = "Option::is_none")]
605 pub page_token: Option<String>,
606 #[serde(skip_serializing_if = "Option::is_none")]
608 pub user_id_type: Option<String>,
609 #[serde(skip_serializing_if = "Option::is_none")]
611 pub department_id_type: Option<String>,
612}
613
614#[derive(Debug, Clone, Serialize, Deserialize, Default)]
616pub struct ListUsersResponse {
617 pub items: Vec<User>,
619 #[serde(skip_serializing_if = "Option::is_none")]
621 pub has_more: Option<bool>,
622 #[serde(skip_serializing_if = "Option::is_none")]
624 pub page_token: Option<String>,
625}
626
627impl ApiResponseTrait for ListUsersResponse {
628 fn data_format() -> crate::core::api_resp::ResponseFormat {
629 crate::core::api_resp::ResponseFormat::Data
630 }
631}