gmail/
lib.rs

1//! [`GmailClient`](struct.GmailClient.html) is the main entry point for this library.
2//!
3//! Library created with [`libninja`](https://www.libninja.com).
4#![allow(non_camel_case_types)]
5#![allow(unused)]
6pub mod model;
7pub mod request;
8mod batch;
9
10pub use httpclient::{Error, Result, InMemoryResponseExt};
11use std::sync::{Arc, OnceLock};
12use std::borrow::Cow;
13use httpclient::{InMemoryBody, InMemoryRequest, InMemoryResponse, ProtocolError};
14use httpclient::multipart::Form;
15use httpclient::oauth2::RefreshData;
16use crate::batch::Batch;
17use crate::model::*;
18
19pub mod header_ext {
20    use http::HeaderName;
21
22    pub const IN_REPLY_TO: HeaderName = HeaderName::from_static("in-reply-to");
23    pub const REFERENCES: HeaderName = HeaderName::from_static("references");
24    pub const THREAD_ID: HeaderName = HeaderName::from_static("threadid");
25}
26
27static SHARED_HTTPCLIENT: OnceLock<httpclient::Client> = OnceLock::new();
28pub fn default_http_client() -> httpclient::Client {
29    httpclient::Client::new().base_url("https://gmail.googleapis.com")
30}
31/// Use this method if you want to add custom middleware to the httpclient.
32/// It must be called before any requests are made, otherwise it will have no effect.
33/// Example usage:
34///
35/// ```
36/// init_http_client(default_http_client()
37///     .with_middleware(..)
38/// );
39/// ```
40pub fn init_http_client(init: httpclient::Client) {
41    SHARED_HTTPCLIENT.set(init).expect("Failed to manually init httpclient");
42}
43fn shared_http_client() -> Cow<'static, httpclient::Client> {
44    Cow::Borrowed(SHARED_HTTPCLIENT.get_or_init(default_http_client))
45}
46static SHARED_OAUTH2FLOW: OnceLock<httpclient::oauth2::OAuth2Flow> = OnceLock::new();
47pub fn init_oauth2_flow(init: httpclient::oauth2::OAuth2Flow) {
48    let _ = SHARED_OAUTH2FLOW.set(init);
49}
50pub fn shared_oauth2_flow() -> &'static httpclient::oauth2::OAuth2Flow {
51    SHARED_OAUTH2FLOW
52        .get_or_init(|| httpclient::oauth2::OAuth2Flow {
53            client_id: std::env::var("GMAIL_CLIENT_ID")
54                .expect("GMAIL_CLIENT_ID must be set"),
55            client_secret: std::env::var("GMAIL_CLIENT_SECRET")
56                .expect("GMAIL_CLIENT_SECRET must be set"),
57            init_endpoint: "https://accounts.google.com/o/oauth2/auth".to_string(),
58            exchange_endpoint: "https://accounts.google.com/o/oauth2/token".to_string(),
59            refresh_endpoint: "https://accounts.google.com/o/oauth2/token".to_string(),
60            redirect_uri: std::env::var("GMAIL_REDIRECT_URI")
61                .expect("GMAIL_REDIRECT_URI must be set"),
62        })
63}
64#[derive(Clone)]
65pub struct FluentRequest<'a, T> {
66    pub(crate) client: &'a GmailClient,
67    pub params: T,
68}
69pub struct GmailClient {
70    client: Cow<'static, httpclient::Client>,
71    authentication: GmailAuth,
72}
73impl GmailClient {
74    pub fn from_env() -> Self {
75        Self {
76            client: shared_http_client(),
77            authentication: GmailAuth::from_env(),
78        }
79    }
80    pub fn with_auth(authentication: GmailAuth) -> Self {
81        Self {
82            client: shared_http_client(),
83            authentication,
84        }
85    }
86    pub fn new_with(client: httpclient::Client, authentication: GmailAuth) -> Self {
87        Self {
88            client: Cow::Owned(client),
89            authentication,
90        }
91    }
92}
93impl GmailClient {
94    pub(crate) fn authenticate<'a>(
95        &self,
96        mut r: httpclient::RequestBuilder<'a>,
97    ) -> httpclient::RequestBuilder<'a> {
98        match &self.authentication {
99            GmailAuth::OAuth2 { middleware } => {
100                r.middlewares.insert(0, middleware.clone());
101            }
102        }
103        r
104    }
105    ///Lists the drafts in the user's mailbox.
106    pub fn drafts_list(
107        &self,
108        user_id: &str,
109    ) -> FluentRequest<'_, request::DraftsListRequest> {
110        FluentRequest {
111            client: self,
112            params: request::DraftsListRequest {
113                include_spam_trash: None,
114                max_results: None,
115                page_token: None,
116                q: None,
117                user_id: user_id.to_owned(),
118            },
119        }
120    }
121    ///Creates a new draft with the `DRAFT` label.
122    pub fn drafts_create(
123        &self,
124        user_id: &str,
125    ) -> FluentRequest<'_, request::DraftsCreateRequest> {
126        FluentRequest {
127            client: self,
128            params: request::DraftsCreateRequest {
129                user_id: user_id.to_owned(),
130            },
131        }
132    }
133    ///Sends the specified, existing draft to the recipients in the `To`, `Cc`, and `Bcc` headers.
134    pub fn drafts_send(
135        &self,
136        user_id: &str,
137    ) -> FluentRequest<'_, request::DraftsSendRequest> {
138        FluentRequest {
139            client: self,
140            params: request::DraftsSendRequest {
141                user_id: user_id.to_owned(),
142            },
143        }
144    }
145    ///Gets the specified draft.
146    pub fn drafts_get(
147        &self,
148        id: &str,
149        user_id: &str,
150    ) -> FluentRequest<'_, request::DraftsGetRequest> {
151        FluentRequest {
152            client: self,
153            params: request::DraftsGetRequest {
154                format: None,
155                id: id.to_owned(),
156                user_id: user_id.to_owned(),
157            },
158        }
159    }
160    ///Replaces a draft's content.
161    pub fn drafts_update(
162        &self,
163        id: &str,
164        user_id: &str,
165    ) -> FluentRequest<'_, request::DraftsUpdateRequest> {
166        FluentRequest {
167            client: self,
168            params: request::DraftsUpdateRequest {
169                id: id.to_owned(),
170                user_id: user_id.to_owned(),
171            },
172        }
173    }
174    ///Immediately and permanently deletes the specified draft. Does not simply trash it.
175    pub fn drafts_delete(
176        &self,
177        id: &str,
178        user_id: &str,
179    ) -> FluentRequest<'_, request::DraftsDeleteRequest> {
180        FluentRequest {
181            client: self,
182            params: request::DraftsDeleteRequest {
183                id: id.to_owned(),
184                user_id: user_id.to_owned(),
185            },
186        }
187    }
188    ///Lists the history of all changes to the given mailbox. History results are returned in chronological order (increasing `historyId`).
189    pub fn history_list(
190        &self,
191        user_id: &str,
192        start_history_id: &str,
193    ) -> FluentRequest<'_, request::HistoryListRequest> {
194        FluentRequest {
195            client: self,
196            params: request::HistoryListRequest {
197                history_types: None,
198                label_id: None,
199                max_results: None,
200                page_token: None,
201                start_history_id: start_history_id.to_owned(),
202                user_id: user_id.to_owned(),
203            },
204        }
205    }
206    ///Lists all labels in the user's mailbox.
207    pub fn labels_list(
208        &self,
209        user_id: &str,
210    ) -> FluentRequest<'_, request::LabelsListRequest> {
211        FluentRequest {
212            client: self,
213            params: request::LabelsListRequest {
214                user_id: user_id.to_owned(),
215            },
216        }
217    }
218    ///Creates a new label.
219    pub fn labels_create(
220        &self,
221        user_id: &str,
222    ) -> FluentRequest<'_, request::LabelsCreateRequest> {
223        FluentRequest {
224            client: self,
225            params: request::LabelsCreateRequest {
226                color: None,
227                id: None,
228                label_list_visibility: None,
229                message_list_visibility: None,
230                messages_total: None,
231                messages_unread: None,
232                name: None,
233                threads_total: None,
234                threads_unread: None,
235                type_: None,
236                user_id: user_id.to_owned(),
237            },
238        }
239    }
240    ///Gets the specified label.
241    pub fn labels_get(
242        &self,
243        id: &str,
244        user_id: &str,
245    ) -> FluentRequest<'_, request::LabelsGetRequest> {
246        FluentRequest {
247            client: self,
248            params: request::LabelsGetRequest {
249                id: id.to_owned(),
250                user_id: user_id.to_owned(),
251            },
252        }
253    }
254    ///Updates the specified label.
255    pub fn labels_update(
256        &self,
257        id: &str,
258        user_id: &str,
259    ) -> FluentRequest<'_, request::LabelsUpdateRequest> {
260        FluentRequest {
261            client: self,
262            params: request::LabelsUpdateRequest {
263                color: None,
264                id: id.to_owned(),
265                label_list_visibility: None,
266                message_list_visibility: None,
267                messages_total: None,
268                messages_unread: None,
269                name: None,
270                threads_total: None,
271                threads_unread: None,
272                type_: None,
273                user_id: user_id.to_owned(),
274            },
275        }
276    }
277    ///Immediately and permanently deletes the specified label and removes it from any messages and threads that it is applied to.
278    pub fn labels_delete(
279        &self,
280        id: &str,
281        user_id: &str,
282    ) -> FluentRequest<'_, request::LabelsDeleteRequest> {
283        FluentRequest {
284            client: self,
285            params: request::LabelsDeleteRequest {
286                id: id.to_owned(),
287                user_id: user_id.to_owned(),
288            },
289        }
290    }
291    ///Patch the specified label.
292    pub fn labels_patch(
293        &self,
294        id: &str,
295        user_id: &str,
296    ) -> FluentRequest<'_, request::LabelsPatchRequest> {
297        FluentRequest {
298            client: self,
299            params: request::LabelsPatchRequest {
300                color: None,
301                id: id.to_owned(),
302                label_list_visibility: None,
303                message_list_visibility: None,
304                messages_total: None,
305                messages_unread: None,
306                name: None,
307                threads_total: None,
308                threads_unread: None,
309                type_: None,
310                user_id: user_id.to_owned(),
311            },
312        }
313    }
314    ///Lists the messages in the user's mailbox.
315    pub fn messages_list(
316        &self,
317        user_id: &str,
318    ) -> FluentRequest<'_, request::MessagesListRequest> {
319        FluentRequest {
320            client: self,
321            params: request::MessagesListRequest {
322                include_spam_trash: None,
323                label_ids: None,
324                max_results: None,
325                page_token: None,
326                q: None,
327                user_id: user_id.to_owned(),
328            },
329        }
330    }
331    ///Directly inserts a message into only this user's mailbox similar to `IMAP APPEND`, bypassing most scanning and classification. Does not send a message.
332    pub fn messages_insert(
333        &self,
334        user_id: &str,
335    ) -> FluentRequest<'_, request::MessagesInsertRequest> {
336        FluentRequest {
337            client: self,
338            params: request::MessagesInsertRequest {
339                deleted: None,
340                internal_date_source: None,
341                user_id: user_id.to_owned(),
342            },
343        }
344    }
345    ///Deletes many messages by message ID. Provides no guarantees that messages were not already deleted or even existed at all.
346    pub fn messages_batch_delete(
347        &self,
348        user_id: &str,
349    ) -> FluentRequest<'_, request::MessagesBatchDeleteRequest> {
350        FluentRequest {
351            client: self,
352            params: request::MessagesBatchDeleteRequest {
353                ids: None,
354                user_id: user_id.to_owned(),
355            },
356        }
357    }
358    ///Modifies the labels on the specified messages.
359    pub fn messages_batch_modify(
360        &self,
361        user_id: &str,
362    ) -> FluentRequest<'_, request::MessagesBatchModifyRequest> {
363        FluentRequest {
364            client: self,
365            params: request::MessagesBatchModifyRequest {
366                add_label_ids: None,
367                ids: None,
368                remove_label_ids: None,
369                user_id: user_id.to_owned(),
370            },
371        }
372    }
373    ///Imports a message into only this user's mailbox, with standard email delivery scanning and classification similar to receiving via SMTP. This method doesn't perform SPF checks, so it might not work for some spam messages, such as those attempting to perform domain spoofing. This method does not send a message. Note: This function doesn't trigger forwarding rules or filters set up by the user.
374    pub fn messages_import(
375        &self,
376        user_id: &str,
377    ) -> FluentRequest<'_, request::MessagesImportRequest> {
378        FluentRequest {
379            client: self,
380            params: request::MessagesImportRequest {
381                deleted: None,
382                internal_date_source: None,
383                never_mark_spam: None,
384                process_for_calendar: None,
385                user_id: user_id.to_owned(),
386            },
387        }
388    }
389    ///Sends the specified message to the recipients in the `To`, `Cc`, and `Bcc` headers.
390    pub fn messages_send(
391        &self,
392        user_id: &str,
393        message: InMemoryBody,
394        thread_id: Option<String>,
395    ) -> FluentRequest<'_, request::MessagesSendRequest> {
396        FluentRequest {
397            client: self,
398            params: request::MessagesSendRequest {
399                user_id: user_id.to_owned(),
400                message,
401                thread_id,
402            },
403        }
404    }
405    ///Gets the specified message.
406    pub fn messages_get(
407        &self,
408        id: &str,
409        user_id: &str,
410    ) -> FluentRequest<'_, request::MessagesGetRequest> {
411        FluentRequest {
412            client: self,
413            params: request::MessagesGetRequest {
414                format: None,
415                id: id.to_owned(),
416                metadata_headers: None,
417                user_id: user_id.to_owned(),
418            },
419        }
420    }
421    ///Immediately and permanently deletes the specified message. This operation cannot be undone. Prefer `messages.trash` instead.
422    pub fn messages_delete(
423        &self,
424        id: &str,
425        user_id: &str,
426    ) -> FluentRequest<'_, request::MessagesDeleteRequest> {
427        FluentRequest {
428            client: self,
429            params: request::MessagesDeleteRequest {
430                id: id.to_owned(),
431                user_id: user_id.to_owned(),
432            },
433        }
434    }
435    ///Modifies the labels on the specified message.
436    pub fn messages_modify(
437        &self,
438        id: &str,
439        user_id: &str,
440    ) -> FluentRequest<'_, request::MessagesModifyRequest> {
441        FluentRequest {
442            client: self,
443            params: request::MessagesModifyRequest {
444                add_label_ids: None,
445                id: id.to_owned(),
446                remove_label_ids: None,
447                user_id: user_id.to_owned(),
448            },
449        }
450    }
451    ///Moves the specified message to the trash.
452    pub fn messages_trash(
453        &self,
454        id: &str,
455        user_id: &str,
456    ) -> FluentRequest<'_, request::MessagesTrashRequest> {
457        FluentRequest {
458            client: self,
459            params: request::MessagesTrashRequest {
460                id: id.to_owned(),
461                user_id: user_id.to_owned(),
462            },
463        }
464    }
465    ///Removes the specified message from the trash.
466    pub fn messages_untrash(
467        &self,
468        id: &str,
469        user_id: &str,
470    ) -> FluentRequest<'_, request::MessagesUntrashRequest> {
471        FluentRequest {
472            client: self,
473            params: request::MessagesUntrashRequest {
474                id: id.to_owned(),
475                user_id: user_id.to_owned(),
476            },
477        }
478    }
479    ///Gets the specified message attachment.
480    pub fn messages_attachments_get(
481        &self,
482        id: &str,
483        message_id: &str,
484        user_id: &str,
485    ) -> FluentRequest<'_, request::MessagesAttachmentsGetRequest> {
486        FluentRequest {
487            client: self,
488            params: request::MessagesAttachmentsGetRequest {
489                id: id.to_owned(),
490                message_id: message_id.to_owned(),
491                user_id: user_id.to_owned(),
492            },
493        }
494    }
495    ///Gets the current user's Gmail profile.
496    pub fn get_profile(
497        &self,
498        user_id: &str,
499    ) -> FluentRequest<'_, request::GetProfileRequest> {
500        FluentRequest {
501            client: self,
502            params: request::GetProfileRequest {
503                user_id: user_id.to_owned(),
504            },
505        }
506    }
507    ///Gets the auto-forwarding setting for the specified account.
508    pub fn settings_get_auto_forwarding(
509        &self,
510        user_id: &str,
511    ) -> FluentRequest<'_, request::SettingsGetAutoForwardingRequest> {
512        FluentRequest {
513            client: self,
514            params: request::SettingsGetAutoForwardingRequest {
515                user_id: user_id.to_owned(),
516            },
517        }
518    }
519    ///Updates the auto-forwarding setting for the specified account. A verified forwarding address must be specified when auto-forwarding is enabled. This method is only available to service account clients that have been delegated domain-wide authority.
520    pub fn settings_update_auto_forwarding(
521        &self,
522        user_id: &str,
523    ) -> FluentRequest<'_, request::SettingsUpdateAutoForwardingRequest> {
524        FluentRequest {
525            client: self,
526            params: request::SettingsUpdateAutoForwardingRequest {
527                disposition: None,
528                email_address: None,
529                enabled: None,
530                user_id: user_id.to_owned(),
531            },
532        }
533    }
534    ///Lists the delegates for the specified account. This method is only available to service account clients that have been delegated domain-wide authority.
535    pub fn settings_delegates_list(
536        &self,
537        user_id: &str,
538    ) -> FluentRequest<'_, request::SettingsDelegatesListRequest> {
539        FluentRequest {
540            client: self,
541            params: request::SettingsDelegatesListRequest {
542                user_id: user_id.to_owned(),
543            },
544        }
545    }
546    ///Adds a delegate with its verification status set directly to `accepted`, without sending any verification email. The delegate user must be a member of the same G Suite organization as the delegator user. Gmail imposes limitations on the number of delegates and delegators each user in a G Suite organization can have. These limits depend on your organization, but in general each user can have up to 25 delegates and up to 10 delegators. Note that a delegate user must be referred to by their primary email address, and not an email alias. Also note that when a new delegate is created, there may be up to a one minute delay before the new delegate is available for use. This method is only available to service account clients that have been delegated domain-wide authority.
547    pub fn settings_delegates_create(
548        &self,
549        user_id: &str,
550    ) -> FluentRequest<'_, request::SettingsDelegatesCreateRequest> {
551        FluentRequest {
552            client: self,
553            params: request::SettingsDelegatesCreateRequest {
554                delegate_email: None,
555                user_id: user_id.to_owned(),
556                verification_status: None,
557            },
558        }
559    }
560    ///Gets the specified delegate. Note that a delegate user must be referred to by their primary email address, and not an email alias. This method is only available to service account clients that have been delegated domain-wide authority.
561    pub fn settings_delegates_get(
562        &self,
563        delegate_email: &str,
564        user_id: &str,
565    ) -> FluentRequest<'_, request::SettingsDelegatesGetRequest> {
566        FluentRequest {
567            client: self,
568            params: request::SettingsDelegatesGetRequest {
569                delegate_email: delegate_email.to_owned(),
570                user_id: user_id.to_owned(),
571            },
572        }
573    }
574    ///Removes the specified delegate (which can be of any verification status), and revokes any verification that may have been required for using it. Note that a delegate user must be referred to by their primary email address, and not an email alias. This method is only available to service account clients that have been delegated domain-wide authority.
575    pub fn settings_delegates_delete(
576        &self,
577        delegate_email: &str,
578        user_id: &str,
579    ) -> FluentRequest<'_, request::SettingsDelegatesDeleteRequest> {
580        FluentRequest {
581            client: self,
582            params: request::SettingsDelegatesDeleteRequest {
583                delegate_email: delegate_email.to_owned(),
584                user_id: user_id.to_owned(),
585            },
586        }
587    }
588    ///Lists the message filters of a Gmail user.
589    pub fn settings_filters_list(
590        &self,
591        user_id: &str,
592    ) -> FluentRequest<'_, request::SettingsFiltersListRequest> {
593        FluentRequest {
594            client: self,
595            params: request::SettingsFiltersListRequest {
596                user_id: user_id.to_owned(),
597            },
598        }
599    }
600    ///Creates a filter. Note: you can only create a maximum of 1,000 filters.
601    pub fn settings_filters_create(
602        &self,
603        user_id: &str,
604    ) -> FluentRequest<'_, request::SettingsFiltersCreateRequest> {
605        FluentRequest {
606            client: self,
607            params: request::SettingsFiltersCreateRequest {
608                action: None,
609                criteria: None,
610                id: None,
611                user_id: user_id.to_owned(),
612            },
613        }
614    }
615    ///Gets a filter.
616    pub fn settings_filters_get(
617        &self,
618        id: &str,
619        user_id: &str,
620    ) -> FluentRequest<'_, request::SettingsFiltersGetRequest> {
621        FluentRequest {
622            client: self,
623            params: request::SettingsFiltersGetRequest {
624                id: id.to_owned(),
625                user_id: user_id.to_owned(),
626            },
627        }
628    }
629    ///Deletes a filter.
630    pub fn settings_filters_delete(
631        &self,
632        id: &str,
633        user_id: &str,
634    ) -> FluentRequest<'_, request::SettingsFiltersDeleteRequest> {
635        FluentRequest {
636            client: self,
637            params: request::SettingsFiltersDeleteRequest {
638                id: id.to_owned(),
639                user_id: user_id.to_owned(),
640            },
641        }
642    }
643    ///Lists the forwarding addresses for the specified account.
644    pub fn settings_forwarding_addresses_list(
645        &self,
646        user_id: &str,
647    ) -> FluentRequest<'_, request::SettingsForwardingAddressesListRequest> {
648        FluentRequest {
649            client: self,
650            params: request::SettingsForwardingAddressesListRequest {
651                user_id: user_id.to_owned(),
652            },
653        }
654    }
655    ///Creates a forwarding address. If ownership verification is required, a message will be sent to the recipient and the resource's verification status will be set to `pending`; otherwise, the resource will be created with verification status set to `accepted`. This method is only available to service account clients that have been delegated domain-wide authority.
656    pub fn settings_forwarding_addresses_create(
657        &self,
658        user_id: &str,
659    ) -> FluentRequest<'_, request::SettingsForwardingAddressesCreateRequest> {
660        FluentRequest {
661            client: self,
662            params: request::SettingsForwardingAddressesCreateRequest {
663                forwarding_email: None,
664                user_id: user_id.to_owned(),
665                verification_status: None,
666            },
667        }
668    }
669    ///Gets the specified forwarding address.
670    pub fn settings_forwarding_addresses_get(
671        &self,
672        forwarding_email: &str,
673        user_id: &str,
674    ) -> FluentRequest<'_, request::SettingsForwardingAddressesGetRequest> {
675        FluentRequest {
676            client: self,
677            params: request::SettingsForwardingAddressesGetRequest {
678                forwarding_email: forwarding_email.to_owned(),
679                user_id: user_id.to_owned(),
680            },
681        }
682    }
683    ///Deletes the specified forwarding address and revokes any verification that may have been required. This method is only available to service account clients that have been delegated domain-wide authority.
684    pub fn settings_forwarding_addresses_delete(
685        &self,
686        forwarding_email: &str,
687        user_id: &str,
688    ) -> FluentRequest<'_, request::SettingsForwardingAddressesDeleteRequest> {
689        FluentRequest {
690            client: self,
691            params: request::SettingsForwardingAddressesDeleteRequest {
692                forwarding_email: forwarding_email.to_owned(),
693                user_id: user_id.to_owned(),
694            },
695        }
696    }
697    ///Gets IMAP settings.
698    pub fn settings_get_imap(
699        &self,
700        user_id: &str,
701    ) -> FluentRequest<'_, request::SettingsGetImapRequest> {
702        FluentRequest {
703            client: self,
704            params: request::SettingsGetImapRequest {
705                user_id: user_id.to_owned(),
706            },
707        }
708    }
709    ///Updates IMAP settings.
710    pub fn settings_update_imap(
711        &self,
712        user_id: &str,
713    ) -> FluentRequest<'_, request::SettingsUpdateImapRequest> {
714        FluentRequest {
715            client: self,
716            params: request::SettingsUpdateImapRequest {
717                auto_expunge: None,
718                enabled: None,
719                expunge_behavior: None,
720                max_folder_size: None,
721                user_id: user_id.to_owned(),
722            },
723        }
724    }
725    ///Gets language settings.
726    pub fn settings_get_language(
727        &self,
728        user_id: &str,
729    ) -> FluentRequest<'_, request::SettingsGetLanguageRequest> {
730        FluentRequest {
731            client: self,
732            params: request::SettingsGetLanguageRequest {
733                user_id: user_id.to_owned(),
734            },
735        }
736    }
737    ///Updates language settings. If successful, the return object contains the `displayLanguage` that was saved for the user, which may differ from the value passed into the request. This is because the requested `displayLanguage` may not be directly supported by Gmail but have a close variant that is, and so the variant may be chosen and saved instead.
738    pub fn settings_update_language(
739        &self,
740        user_id: &str,
741    ) -> FluentRequest<'_, request::SettingsUpdateLanguageRequest> {
742        FluentRequest {
743            client: self,
744            params: request::SettingsUpdateLanguageRequest {
745                display_language: None,
746                user_id: user_id.to_owned(),
747            },
748        }
749    }
750    ///Gets POP settings.
751    pub fn settings_get_pop(
752        &self,
753        user_id: &str,
754    ) -> FluentRequest<'_, request::SettingsGetPopRequest> {
755        FluentRequest {
756            client: self,
757            params: request::SettingsGetPopRequest {
758                user_id: user_id.to_owned(),
759            },
760        }
761    }
762    ///Updates POP settings.
763    pub fn settings_update_pop(
764        &self,
765        user_id: &str,
766    ) -> FluentRequest<'_, request::SettingsUpdatePopRequest> {
767        FluentRequest {
768            client: self,
769            params: request::SettingsUpdatePopRequest {
770                access_window: None,
771                disposition: None,
772                user_id: user_id.to_owned(),
773            },
774        }
775    }
776    ///Lists the send-as aliases for the specified account. The result includes the primary send-as address associated with the account as well as any custom "from" aliases.
777    pub fn settings_send_as_list(
778        &self,
779        user_id: &str,
780    ) -> FluentRequest<'_, request::SettingsSendAsListRequest> {
781        FluentRequest {
782            client: self,
783            params: request::SettingsSendAsListRequest {
784                user_id: user_id.to_owned(),
785            },
786        }
787    }
788    ///Creates a custom "from" send-as alias. If an SMTP MSA is specified, Gmail will attempt to connect to the SMTP service to validate the configuration before creating the alias. If ownership verification is required for the alias, a message will be sent to the email address and the resource's verification status will be set to `pending`; otherwise, the resource will be created with verification status set to `accepted`. If a signature is provided, Gmail will sanitize the HTML before saving it with the alias. This method is only available to service account clients that have been delegated domain-wide authority.
789    pub fn settings_send_as_create(
790        &self,
791        user_id: &str,
792    ) -> FluentRequest<'_, request::SettingsSendAsCreateRequest> {
793        FluentRequest {
794            client: self,
795            params: request::SettingsSendAsCreateRequest {
796                display_name: None,
797                is_default: None,
798                is_primary: None,
799                reply_to_address: None,
800                send_as_email: None,
801                signature: None,
802                smtp_msa: None,
803                treat_as_alias: None,
804                user_id: user_id.to_owned(),
805                verification_status: None,
806            },
807        }
808    }
809    ///Gets the specified send-as alias. Fails with an HTTP 404 error if the specified address is not a member of the collection.
810    pub fn settings_send_as_get(
811        &self,
812        send_as_email: &str,
813        user_id: &str,
814    ) -> FluentRequest<'_, request::SettingsSendAsGetRequest> {
815        FluentRequest {
816            client: self,
817            params: request::SettingsSendAsGetRequest {
818                send_as_email: send_as_email.to_owned(),
819                user_id: user_id.to_owned(),
820            },
821        }
822    }
823    ///Updates a send-as alias. If a signature is provided, Gmail will sanitize the HTML before saving it with the alias. Addresses other than the primary address for the account can only be updated by service account clients that have been delegated domain-wide authority.
824    pub fn settings_send_as_update(
825        &self,
826        send_as_email: &str,
827        user_id: &str,
828    ) -> FluentRequest<'_, request::SettingsSendAsUpdateRequest> {
829        FluentRequest {
830            client: self,
831            params: request::SettingsSendAsUpdateRequest {
832                display_name: None,
833                is_default: None,
834                is_primary: None,
835                reply_to_address: None,
836                send_as_email: send_as_email.to_owned(),
837                signature: None,
838                smtp_msa: None,
839                treat_as_alias: None,
840                user_id: user_id.to_owned(),
841                verification_status: None,
842            },
843        }
844    }
845    ///Deletes the specified send-as alias. Revokes any verification that may have been required for using it. This method is only available to service account clients that have been delegated domain-wide authority.
846    pub fn settings_send_as_delete(
847        &self,
848        send_as_email: &str,
849        user_id: &str,
850    ) -> FluentRequest<'_, request::SettingsSendAsDeleteRequest> {
851        FluentRequest {
852            client: self,
853            params: request::SettingsSendAsDeleteRequest {
854                send_as_email: send_as_email.to_owned(),
855                user_id: user_id.to_owned(),
856            },
857        }
858    }
859    ///Patch the specified send-as alias.
860    pub fn settings_send_as_patch(
861        &self,
862        send_as_email: &str,
863        user_id: &str,
864    ) -> FluentRequest<'_, request::SettingsSendAsPatchRequest> {
865        FluentRequest {
866            client: self,
867            params: request::SettingsSendAsPatchRequest {
868                display_name: None,
869                is_default: None,
870                is_primary: None,
871                reply_to_address: None,
872                send_as_email: send_as_email.to_owned(),
873                signature: None,
874                smtp_msa: None,
875                treat_as_alias: None,
876                user_id: user_id.to_owned(),
877                verification_status: None,
878            },
879        }
880    }
881    ///Lists S/MIME configs for the specified send-as alias.
882    pub fn settings_send_as_smime_info_list(
883        &self,
884        send_as_email: &str,
885        user_id: &str,
886    ) -> FluentRequest<'_, request::SettingsSendAsSmimeInfoListRequest> {
887        FluentRequest {
888            client: self,
889            params: request::SettingsSendAsSmimeInfoListRequest {
890                send_as_email: send_as_email.to_owned(),
891                user_id: user_id.to_owned(),
892            },
893        }
894    }
895    ///Insert (upload) the given S/MIME config for the specified send-as alias. Note that pkcs12 format is required for the key.
896    pub fn settings_send_as_smime_info_insert(
897        &self,
898        send_as_email: &str,
899        user_id: &str,
900    ) -> FluentRequest<'_, request::SettingsSendAsSmimeInfoInsertRequest> {
901        FluentRequest {
902            client: self,
903            params: request::SettingsSendAsSmimeInfoInsertRequest {
904                encrypted_key_password: None,
905                expiration: None,
906                id: None,
907                is_default: None,
908                issuer_cn: None,
909                pem: None,
910                pkcs12: None,
911                send_as_email: send_as_email.to_owned(),
912                user_id: user_id.to_owned(),
913            },
914        }
915    }
916    ///Gets the specified S/MIME config for the specified send-as alias.
917    pub fn settings_send_as_smime_info_get(
918        &self,
919        id: &str,
920        send_as_email: &str,
921        user_id: &str,
922    ) -> FluentRequest<'_, request::SettingsSendAsSmimeInfoGetRequest> {
923        FluentRequest {
924            client: self,
925            params: request::SettingsSendAsSmimeInfoGetRequest {
926                id: id.to_owned(),
927                send_as_email: send_as_email.to_owned(),
928                user_id: user_id.to_owned(),
929            },
930        }
931    }
932    ///Deletes the specified S/MIME config for the specified send-as alias.
933    pub fn settings_send_as_smime_info_delete(
934        &self,
935        id: &str,
936        send_as_email: &str,
937        user_id: &str,
938    ) -> FluentRequest<'_, request::SettingsSendAsSmimeInfoDeleteRequest> {
939        FluentRequest {
940            client: self,
941            params: request::SettingsSendAsSmimeInfoDeleteRequest {
942                id: id.to_owned(),
943                send_as_email: send_as_email.to_owned(),
944                user_id: user_id.to_owned(),
945            },
946        }
947    }
948    ///Sets the default S/MIME config for the specified send-as alias.
949    pub fn settings_send_as_smime_info_set_default(
950        &self,
951        id: &str,
952        send_as_email: &str,
953        user_id: &str,
954    ) -> FluentRequest<'_, request::SettingsSendAsSmimeInfoSetDefaultRequest> {
955        FluentRequest {
956            client: self,
957            params: request::SettingsSendAsSmimeInfoSetDefaultRequest {
958                id: id.to_owned(),
959                send_as_email: send_as_email.to_owned(),
960                user_id: user_id.to_owned(),
961            },
962        }
963    }
964    ///Sends a verification email to the specified send-as alias address. The verification status must be `pending`. This method is only available to service account clients that have been delegated domain-wide authority.
965    pub fn settings_send_as_verify(
966        &self,
967        send_as_email: &str,
968        user_id: &str,
969    ) -> FluentRequest<'_, request::SettingsSendAsVerifyRequest> {
970        FluentRequest {
971            client: self,
972            params: request::SettingsSendAsVerifyRequest {
973                send_as_email: send_as_email.to_owned(),
974                user_id: user_id.to_owned(),
975            },
976        }
977    }
978    ///Gets vacation responder settings.
979    pub fn settings_get_vacation(
980        &self,
981        user_id: &str,
982    ) -> FluentRequest<'_, request::SettingsGetVacationRequest> {
983        FluentRequest {
984            client: self,
985            params: request::SettingsGetVacationRequest {
986                user_id: user_id.to_owned(),
987            },
988        }
989    }
990    ///Updates vacation responder settings.
991    pub fn settings_update_vacation(
992        &self,
993        user_id: &str,
994    ) -> FluentRequest<'_, request::SettingsUpdateVacationRequest> {
995        FluentRequest {
996            client: self,
997            params: request::SettingsUpdateVacationRequest {
998                enable_auto_reply: None,
999                end_time: None,
1000                response_body_html: None,
1001                response_body_plain_text: None,
1002                response_subject: None,
1003                restrict_to_contacts: None,
1004                restrict_to_domain: None,
1005                start_time: None,
1006                user_id: user_id.to_owned(),
1007            },
1008        }
1009    }
1010    ///Stop receiving push notifications for the given user mailbox.
1011    pub fn stop(&self, user_id: &str) -> FluentRequest<'_, request::StopRequest> {
1012        FluentRequest {
1013            client: self,
1014            params: request::StopRequest {
1015                user_id: user_id.to_owned(),
1016            },
1017        }
1018    }
1019    ///Lists the threads in the user's mailbox.
1020    pub fn threads_list(
1021        &self,
1022        user_id: &str,
1023    ) -> FluentRequest<'_, request::ThreadsListRequest> {
1024        FluentRequest {
1025            client: self,
1026            params: request::ThreadsListRequest {
1027                include_spam_trash: None,
1028                label_ids: None,
1029                max_results: None,
1030                page_token: None,
1031                q: None,
1032                user_id: user_id.to_owned(),
1033            },
1034        }
1035    }
1036    ///Gets the specified thread.
1037    pub fn threads_get(
1038        &self,
1039        id: &str,
1040        user_id: &str,
1041    ) -> FluentRequest<'_, request::ThreadsGetRequest> {
1042        FluentRequest {
1043            client: self,
1044            params: request::ThreadsGetRequest {
1045                format: None,
1046                id: id.to_owned(),
1047                metadata_headers: None,
1048                user_id: user_id.to_owned(),
1049            },
1050        }
1051    }
1052    ///Immediately and permanently deletes the specified thread. This operation cannot be undone. Prefer `threads.trash` instead.
1053    pub fn threads_delete(
1054        &self,
1055        id: &str,
1056        user_id: &str,
1057    ) -> FluentRequest<'_, request::ThreadsDeleteRequest> {
1058        FluentRequest {
1059            client: self,
1060            params: request::ThreadsDeleteRequest {
1061                id: id.to_owned(),
1062                user_id: user_id.to_owned(),
1063            },
1064        }
1065    }
1066    ///Modifies the labels applied to the thread. This applies to all messages in the thread.
1067    pub fn threads_modify(
1068        &self,
1069        id: &str,
1070        user_id: &str,
1071    ) -> FluentRequest<'_, request::ThreadsModifyRequest> {
1072        FluentRequest {
1073            client: self,
1074            params: request::ThreadsModifyRequest {
1075                add_label_ids: None,
1076                id: id.to_owned(),
1077                remove_label_ids: None,
1078                user_id: user_id.to_owned(),
1079            },
1080        }
1081    }
1082    ///Moves the specified thread to the trash.
1083    pub fn threads_trash(
1084        &self,
1085        id: &str,
1086        user_id: &str,
1087    ) -> FluentRequest<'_, request::ThreadsTrashRequest> {
1088        FluentRequest {
1089            client: self,
1090            params: request::ThreadsTrashRequest {
1091                id: id.to_owned(),
1092                user_id: user_id.to_owned(),
1093            },
1094        }
1095    }
1096    ///Removes the specified thread from the trash.
1097    pub fn threads_untrash(
1098        &self,
1099        id: &str,
1100        user_id: &str,
1101    ) -> FluentRequest<'_, request::ThreadsUntrashRequest> {
1102        FluentRequest {
1103            client: self,
1104            params: request::ThreadsUntrashRequest {
1105                id: id.to_owned(),
1106                user_id: user_id.to_owned(),
1107            },
1108        }
1109    }
1110    ///Set up or update a push notification watch on the given user mailbox.
1111    pub fn watch(&self, user_id: &str) -> FluentRequest<'_, request::WatchRequest> {
1112        FluentRequest {
1113            client: self,
1114            params: request::WatchRequest {
1115                label_filter_action: None,
1116                label_ids: None,
1117                topic_name: None,
1118                user_id: user_id.to_owned(),
1119            },
1120        }
1121    }
1122
1123    pub async fn batch(&self, form: Form<InMemoryRequest>) -> Result<Form<InMemoryResponse>> {
1124        use serde::de::Error as SerdeError;
1125        let r = self.client.post("/batch");
1126        let r = self.authenticate(r);
1127        let res = r.multipart(form).await?;
1128        let Some(form) = Form::from_response(res) else {
1129            // this shouldn't really be a json error
1130            let err = serde_json::Error::custom("Failed to parse multipart");
1131            return Err(Error::Protocol(ProtocolError::JsonError(err)));
1132        };
1133        Ok(form)
1134    }
1135}
1136pub enum GmailAuth {
1137    OAuth2 { middleware: Arc<httpclient::oauth2::OAuth2> },
1138}
1139impl GmailAuth {
1140    pub fn from_env() -> Self {
1141        let access = std::env::var("GMAIL_ACCESS_TOKEN").unwrap();
1142        let refresh = std::env::var("GMAIL_REFRESH_TOKEN").unwrap();
1143        let mw = shared_oauth2_flow().bearer_middleware(access, refresh);
1144        Self::OAuth2 {
1145            middleware: Arc::new(mw),
1146        }
1147    }
1148    pub fn oauth2(access: impl Into<String>, refresh: impl Into<String>, callback: Option<Box<dyn Fn(RefreshData) + Send + Sync + 'static>>) -> Self {
1149        let mut mw = shared_oauth2_flow().bearer_middleware(access.into(), refresh.into());
1150        if let Some(cb) = callback {
1151            mw.callback(cb);
1152        }
1153        Self::OAuth2 {
1154            middleware: Arc::new(mw),
1155        }
1156    }
1157}