Skip to main content

agentmail/client/
inboxes.rs

1use crate::client::NoBody;
2use crate::client::scope::{Inboxes, Scoped};
3use crate::{Error, Page, types::*, util::urlish};
4
5impl<S: Inboxes> Scoped<'_, S> {
6    /// POST `{scope}/inboxes`, a new agent-owned email address. At [`Client::org`](crate::Client::org)
7    /// this creates a standalone inbox; at [`Client::pod`](crate::Client::pod) it creates the inbox
8    /// inside that pod. Free plans get `{username}@agentmail.to`; custom domains
9    /// must be verified first.
10    pub async fn create_inbox(&self, inbox: CreateInbox) -> Result<Inbox, Error> {
11        self.client
12            .request(
13                reqwest::Method::POST,
14                &format!("{}/inboxes", self.base()),
15                &[],
16                Some(&inbox),
17            )
18            .await
19    }
20
21    /// GET `{scope}/inboxes`, one page.
22    pub async fn list_inboxes(&self, page: Page) -> Result<InboxList, Error> {
23        self.client
24            .request(
25                reqwest::Method::GET,
26                &format!("{}/inboxes", self.base()),
27                &page.query(),
28                None::<&NoBody>,
29            )
30            .await
31    }
32
33    /// Every inbox in the scope, draining pagination.
34    pub async fn list_all_inboxes(&self) -> Result<Vec<Inbox>, Error> {
35        let mut out = Vec::new();
36        let mut token = None;
37        loop {
38            let resp = self
39                .list_inboxes(Page {
40                    limit: None,
41                    page_token: token,
42                })
43                .await?;
44            let next = resp.next_page_token;
45            out.extend(resp.inboxes);
46            match next {
47                Some(t) => token = Some(t),
48                None => return Ok(out),
49            }
50        }
51    }
52
53    /// GET `{scope}/inboxes/{inbox_id}`.
54    pub async fn get_inbox(&self, inbox_id: &str) -> Result<Inbox, Error> {
55        self.client
56            .request(
57                reqwest::Method::GET,
58                &format!("{}/inboxes/{}", self.base(), urlish(inbox_id)),
59                &[],
60                None::<&NoBody>,
61            )
62            .await
63    }
64
65    /// PATCH `{scope}/inboxes/{inbox_id}`, update display name and/or metadata.
66    pub async fn update_inbox(&self, inbox_id: &str, update: UpdateInbox) -> Result<Inbox, Error> {
67        self.client
68            .request(
69                reqwest::Method::PATCH,
70                &format!("{}/inboxes/{}", self.base(), urlish(inbox_id)),
71                &[],
72                Some(&update),
73            )
74            .await
75    }
76
77    /// DELETE `{scope}/inboxes/{inbox_id}`.
78    pub async fn delete_inbox(&self, inbox_id: &str) -> Result<(), Error> {
79        self.client
80            .request(
81                reqwest::Method::DELETE,
82                &format!("{}/inboxes/{}", self.base(), urlish(inbox_id)),
83                &[],
84                None::<&NoBody>,
85            )
86            .await
87    }
88
89    /// GET `{scope}/inboxes/search`, full-text search over the scope's
90    /// inboxes (display name, address, metadata).
91    pub async fn search_inboxes(&self, q: &str, page: Page) -> Result<InboxList, Error> {
92        let mut query = page.query();
93        query.push(("q", q.to_string()));
94        self.client
95            .request(
96                reqwest::Method::GET,
97                &format!("{}/inboxes/search", self.base()),
98                &query,
99                None::<&NoBody>,
100            )
101            .await
102    }
103
104    /// Every inbox matching `q`, draining pagination.
105    pub async fn list_all_matching_inboxes(&self, q: &str) -> Result<Vec<Inbox>, Error> {
106        let mut out = Vec::new();
107        let mut token = None;
108        loop {
109            let resp = self
110                .search_inboxes(
111                    q,
112                    Page {
113                        limit: None,
114                        page_token: token,
115                    },
116                )
117                .await?;
118            let next = resp.next_page_token;
119            out.extend(resp.inboxes);
120            match next {
121                Some(t) => token = Some(t),
122                None => return Ok(out),
123            }
124        }
125    }
126}
127
128impl Scoped<'_, crate::client::scope::InboxScope<'_>> {
129    /// POST `/v0/inboxes/{inbox_id}/authorize`, complete the browser
130    /// authorization flow for this inbox: the human approves in their browser,
131    /// and this call exchanges the resulting `auth_token` for a scoped API
132    /// key ([`AuthorizeInboxResult::api_key_id`]).
133    pub async fn authorize(
134        &self,
135        authorize: AuthorizeInbox,
136    ) -> Result<AuthorizeInboxResult, Error> {
137        self.client
138            .request(
139                reqwest::Method::POST,
140                &format!("/v0/inboxes/{}/authorize", urlish(self.scope.0)),
141                &[],
142                Some(&authorize),
143            )
144            .await
145    }
146}