Skip to main content

agentmail/client/
attachments.rs

1use crate::{Client, Error, types::*};
2
3impl Client {
4    /// Download an attachment's bytes from its presigned `download_url`. The URL
5    /// is a short-lived S3 link fetched without the API bearer token, so obtain
6    /// the [`Attachment`] from one of the `get_*_attachment` calls first (a
7    /// plain response attachment carries no `download_url` and yields
8    /// [`Error::NoDownloadUrl`]).
9    pub async fn download_attachment(&self, attachment: &Attachment) -> Result<Vec<u8>, Error> {
10        let url = attachment
11            .download_url
12            .as_deref()
13            .ok_or(Error::NoDownloadUrl)?;
14        self.download_url(url).await
15    }
16
17    /// Download the raw `.eml` bytes from a [`RawMessage`]'s presigned URL.
18    pub async fn download_raw(&self, raw: &RawMessage) -> Result<Vec<u8>, Error> {
19        self.download_url(&raw.download_url).await
20    }
21
22    /// GET a presigned URL without the API bearer token (it is already an
23    /// authenticated URL) and return the bytes.
24    async fn download_url(&self, url: &str) -> Result<Vec<u8>, Error> {
25        let resp = self.http.get(url).send().await?;
26        let status = resp.status();
27        let bytes = resp.bytes().await?;
28        if !status.is_success() {
29            return Err(Error::Api {
30                status,
31                body: String::from_utf8_lossy(&bytes).into_owned(),
32            });
33        }
34        Ok(bytes.to_vec())
35    }
36}