/*
* Zernio API
*
* API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api Versioning and deprecation: all endpoints are versioned in the URL path (current version: /v1). Breaking changes only ship in a new path version; existing versions keep working. Deprecated operations are marked 'deprecated: true' in this spec and announced in the changelog (https://zernio.com/changelog) before removal. Errors: every 4xx/5xx response is application/json with a machine-readable 'code' and a human-readable 'error' message (see the ErrorResponse schema). Request ids: responses carry an X-Request-Id header with the id we log the request under. Quote it when reporting a problem. A valid x-request-id you send is reused as that id.
*
* The version of the OpenAPI document: 1.504.0
* Contact: support@zernio.com
* Generated by: https://openapi-generator.tech
*/
use super::{configuration, ContentType, Error};
use crate::{apis::ResponseContent, models};
use reqwest;
use serde::{de::Error as _, Deserialize, Serialize};
/// struct for typed errors of method [`download_email_attachment`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum DownloadEmailAttachmentError {
Status400(models::ErrorResponse),
Status401(models::ErrorResponse),
Status404(models::InlineObject1),
Status412(models::ErrorResponse),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_email_message`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetEmailMessageError {
Status400(models::ErrorResponse),
Status401(models::ErrorResponse),
Status404(models::InlineObject1),
Status412(models::ErrorResponse),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_email_thread`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetEmailThreadError {
Status400(models::ErrorResponse),
Status401(models::ErrorResponse),
Status404(models::InlineObject1),
Status412(models::ErrorResponse),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`list_email_folders`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ListEmailFoldersError {
Status400(models::ErrorResponse),
Status401(models::ErrorResponse),
Status412(models::ErrorResponse),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`list_email_messages`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ListEmailMessagesError {
Status400(models::ErrorResponse),
Status401(models::ErrorResponse),
Status412(models::ErrorResponse),
Status429(models::ErrorResponse),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`list_email_threads`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ListEmailThreadsError {
Status400(models::ErrorResponse),
Status401(models::ErrorResponse),
Status412(models::ErrorResponse),
Status429(models::ErrorResponse),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`reply_email_message`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ReplyEmailMessageError {
Status400(models::ErrorResponse),
Status401(models::ErrorResponse),
Status402(models::InlineObject4),
Status404(models::InlineObject1),
Status412(models::ErrorResponse),
Status429(models::ErrorResponse),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`send_email_message`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum SendEmailMessageError {
Status400(models::ErrorResponse),
Status401(models::ErrorResponse),
Status402(models::InlineObject4),
Status412(models::ErrorResponse),
Status429(models::ErrorResponse),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`trash_email_message`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum TrashEmailMessageError {
Status400(models::ErrorResponse),
Status401(models::ErrorResponse),
Status404(models::InlineObject1),
Status412(models::ErrorResponse),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`update_email_message`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UpdateEmailMessageError {
Status400(models::ErrorResponse),
Status401(models::ErrorResponse),
Status404(models::InlineObject1),
Status412(models::ErrorResponse),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`update_email_thread`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UpdateEmailThreadError {
Status400(models::ErrorResponse),
Status401(models::ErrorResponse),
Status404(models::InlineObject1),
Status412(models::ErrorResponse),
UnknownValue(serde_json::Value),
}
/// Streams the attachment bytes with its `Content-Type` and a `Content-Disposition` carrying the filename.
pub async fn download_email_attachment(
configuration: &configuration::Configuration,
attachment_id: &str,
account_id: &str,
message_id: &str,
) -> Result<reqwest::Response, Error<DownloadEmailAttachmentError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_attachment_id = attachment_id;
let p_query_account_id = account_id;
let p_query_message_id = message_id;
let uri_str = format!(
"{}/v1/email/attachments/{attachmentId}",
configuration.base_path,
attachmentId = crate::apis::urlencode(p_path_attachment_id)
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
req_builder = req_builder.query(&[("accountId", &p_query_account_id.to_string())]);
req_builder = req_builder.query(&[("messageId", &p_query_message_id.to_string())]);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(resp)
} else {
let content = resp.text().await?;
let entity: Option<DownloadEmailAttachmentError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
pub async fn get_email_message(
configuration: &configuration::Configuration,
message_id: &str,
account_id: &str,
include_headers: Option<bool>,
raw: Option<bool>,
) -> Result<models::SendEmailMessage201Response, Error<GetEmailMessageError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_message_id = message_id;
let p_query_account_id = account_id;
let p_query_include_headers = include_headers;
let p_query_raw = raw;
let uri_str = format!(
"{}/v1/email/messages/{messageId}",
configuration.base_path,
messageId = crate::apis::urlencode(p_path_message_id)
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
req_builder = req_builder.query(&[("accountId", &p_query_account_id.to_string())]);
if let Some(ref param_value) = p_query_include_headers {
req_builder = req_builder.query(&[("includeHeaders", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_raw {
req_builder = req_builder.query(&[("raw", ¶m_value.to_string())]);
}
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::SendEmailMessage201Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::SendEmailMessage201Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetEmailMessageError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
pub async fn get_email_thread(
configuration: &configuration::Configuration,
thread_id: &str,
account_id: &str,
) -> Result<models::GetEmailThread200Response, Error<GetEmailThreadError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_thread_id = thread_id;
let p_query_account_id = account_id;
let uri_str = format!(
"{}/v1/email/threads/{threadId}",
configuration.base_path,
threadId = crate::apis::urlencode(p_path_thread_id)
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
req_builder = req_builder.query(&[("accountId", &p_query_account_id.to_string())]);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GetEmailThread200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetEmailThread200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetEmailThreadError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// On Google, folders are Gmail labels (system labels carry `wellKnown`; `unreadCount` and `totalCount` are present only where Gmail reports them). There is no archive folder on Google; archived mail is listed with `folder=archive`.
pub async fn list_email_folders(
configuration: &configuration::Configuration,
account_id: &str,
) -> Result<models::ListEmailFolders200Response, Error<ListEmailFoldersError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_query_account_id = account_id;
let uri_str = format!("{}/v1/email/folders", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
req_builder = req_builder.query(&[("accountId", &p_query_account_id.to_string())]);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ListEmailFolders200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ListEmailFolders200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<ListEmailFoldersError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Same filters and envelope as `GET /v1/email/threads`, one row per message. Bodies are omitted; fetch a message to read `text` and `html`. ### On Google - List rows also omit `attachments` (Gmail's metadata pages carry headers only); `hasAttachment=true` still filters server-side. - `sortOrder=asc` reverses the fetched page. - `archive` means mail without the inbox, trash or spam labels.
pub async fn list_email_messages(
configuration: &configuration::Configuration,
account_id: &str,
folder: Option<&str>,
unread: Option<bool>,
starred: Option<bool>,
has_attachment: Option<bool>,
subject: Option<&str>,
from: Option<&str>,
to: Option<&str>,
cc: Option<&str>,
bcc: Option<&str>,
any_email: Option<&str>,
after: Option<String>,
before: Option<String>,
search_query_native: Option<&str>,
sort_order: Option<&str>,
cursor: Option<&str>,
limit: Option<i32>,
) -> Result<models::ListEmailMessages200Response, Error<ListEmailMessagesError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_query_account_id = account_id;
let p_query_folder = folder;
let p_query_unread = unread;
let p_query_starred = starred;
let p_query_has_attachment = has_attachment;
let p_query_subject = subject;
let p_query_from = from;
let p_query_to = to;
let p_query_cc = cc;
let p_query_bcc = bcc;
let p_query_any_email = any_email;
let p_query_after = after;
let p_query_before = before;
let p_query_search_query_native = search_query_native;
let p_query_sort_order = sort_order;
let p_query_cursor = cursor;
let p_query_limit = limit;
let uri_str = format!("{}/v1/email/messages", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
req_builder = req_builder.query(&[("accountId", &p_query_account_id.to_string())]);
if let Some(ref param_value) = p_query_folder {
req_builder = req_builder.query(&[("folder", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_unread {
req_builder = req_builder.query(&[("unread", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_starred {
req_builder = req_builder.query(&[("starred", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_has_attachment {
req_builder = req_builder.query(&[("hasAttachment", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_subject {
req_builder = req_builder.query(&[("subject", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_from {
req_builder = req_builder.query(&[("from", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_to {
req_builder = req_builder.query(&[("to", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_cc {
req_builder = req_builder.query(&[("cc", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_bcc {
req_builder = req_builder.query(&[("bcc", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_any_email {
req_builder = req_builder.query(&[("anyEmail", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_after {
req_builder = req_builder.query(&[("after", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_before {
req_builder = req_builder.query(&[("before", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_search_query_native {
req_builder = req_builder.query(&[("searchQueryNative", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_sort_order {
req_builder = req_builder.query(&[("sortOrder", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_cursor {
req_builder = req_builder.query(&[("cursor", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_limit {
req_builder = req_builder.query(&[("limit", ¶m_value.to_string())]);
}
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ListEmailMessages200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ListEmailMessages200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<ListEmailMessagesError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Threads of a connected Google or Microsoft mailbox, newest first. Every filter that the provider cannot apply server-side is applied to the fetched page instead and named in `meta.filteredClientSide`, so a filtered page can hold fewer than `limit` items while `pagination.hasMore` stays true. On Google, folders are Gmail labels: `folder` takes a well-known name or a label id, `archive` means mail carrying none of the inbox, trash or spam labels, and `sortOrder=asc` reverses the fetched page (Gmail lists newest first only). The account must have been connected with `scopes=email` (412 `account_scope_missing` otherwise).
pub async fn list_email_threads(
configuration: &configuration::Configuration,
account_id: &str,
folder: Option<&str>,
unread: Option<bool>,
starred: Option<bool>,
has_attachment: Option<bool>,
subject: Option<&str>,
from: Option<&str>,
to: Option<&str>,
cc: Option<&str>,
bcc: Option<&str>,
any_email: Option<&str>,
after: Option<String>,
before: Option<String>,
search_query_native: Option<&str>,
sort_order: Option<&str>,
cursor: Option<&str>,
limit: Option<i32>,
) -> Result<models::ListEmailThreads200Response, Error<ListEmailThreadsError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_query_account_id = account_id;
let p_query_folder = folder;
let p_query_unread = unread;
let p_query_starred = starred;
let p_query_has_attachment = has_attachment;
let p_query_subject = subject;
let p_query_from = from;
let p_query_to = to;
let p_query_cc = cc;
let p_query_bcc = bcc;
let p_query_any_email = any_email;
let p_query_after = after;
let p_query_before = before;
let p_query_search_query_native = search_query_native;
let p_query_sort_order = sort_order;
let p_query_cursor = cursor;
let p_query_limit = limit;
let uri_str = format!("{}/v1/email/threads", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
req_builder = req_builder.query(&[("accountId", &p_query_account_id.to_string())]);
if let Some(ref param_value) = p_query_folder {
req_builder = req_builder.query(&[("folder", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_unread {
req_builder = req_builder.query(&[("unread", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_starred {
req_builder = req_builder.query(&[("starred", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_has_attachment {
req_builder = req_builder.query(&[("hasAttachment", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_subject {
req_builder = req_builder.query(&[("subject", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_from {
req_builder = req_builder.query(&[("from", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_to {
req_builder = req_builder.query(&[("to", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_cc {
req_builder = req_builder.query(&[("cc", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_bcc {
req_builder = req_builder.query(&[("bcc", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_any_email {
req_builder = req_builder.query(&[("anyEmail", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_after {
req_builder = req_builder.query(&[("after", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_before {
req_builder = req_builder.query(&[("before", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_search_query_native {
req_builder = req_builder.query(&[("searchQueryNative", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_sort_order {
req_builder = req_builder.query(&[("sortOrder", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_cursor {
req_builder = req_builder.query(&[("cursor", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_limit {
req_builder = req_builder.query(&[("limit", ¶m_value.to_string())]);
}
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ListEmailThreads200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ListEmailThreads200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<ListEmailThreadsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Replies inside the provider's thread: the provider builds the quoted original and threading headers, your `html` or `text` goes above the quote. `to`, `cc`, `bcc`, `replyTo`, `subject`, `headers` and `attachments` are honoured; `scheduledFor` and `holdAsDraft` are rejected like on send. Same protection, caps and headers as sending.
pub async fn reply_email_message(
configuration: &configuration::Configuration,
message_id: &str,
reply_email_message_request: models::ReplyEmailMessageRequest,
) -> Result<models::SendEmailMessage201Response, Error<ReplyEmailMessageError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_message_id = message_id;
let p_body_reply_email_message_request = reply_email_message_request;
let uri_str = format!(
"{}/v1/email/messages/{messageId}/reply",
configuration.base_path,
messageId = crate::apis::urlencode(p_path_message_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_reply_email_message_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::SendEmailMessage201Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::SendEmailMessage201Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<ReplyEmailMessageError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Sends from the connected mailbox and returns the stored sent copy. The message is mirrored into the inbox (`message.sent` fires once) and counted against the mailbox's daily cap. The cap is reported in the `X-Zernio-Send-Limit`, `X-Zernio-Send-Remaining` and `X-Zernio-Send-Reset` response headers. ### Sending limits These mailboxes are for one-to-one mail, not bulk sends. Protection on every mailbox: - Daily cap: Microsoft 1,000; Google Workspace 500; Gmail consumer 200. Reaching it answers 429 `email_send_cap_reached` with `details.cap`. - The same body reaching more than 50 distinct recipients within an hour pauses the mailbox with an escalating cooldown (429 `rate_limited`, `account.rate_limited` webhook). ### Other errors - 402: Gmail sends need a payment method on the workspace. Reading, calendar and files do not. - 400: `scheduledFor` and `holdAsDraft` are reserved and currently rejected.
pub async fn send_email_message(
configuration: &configuration::Configuration,
send_email_request: models::SendEmailRequest,
) -> Result<models::SendEmailMessage201Response, Error<SendEmailMessageError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_send_email_request = send_email_request;
let uri_str = format!("{}/v1/email/messages", configuration.base_path);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_send_email_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::SendEmailMessage201Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::SendEmailMessage201Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<SendEmailMessageError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
pub async fn trash_email_message(
configuration: &configuration::Configuration,
message_id: &str,
account_id: &str,
) -> Result<models::TrashEmailMessage200Response, Error<TrashEmailMessageError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_message_id = message_id;
let p_query_account_id = account_id;
let uri_str = format!(
"{}/v1/email/messages/{messageId}",
configuration.base_path,
messageId = crate::apis::urlencode(p_path_message_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::DELETE, &uri_str);
req_builder = req_builder.query(&[("accountId", &p_query_account_id.to_string())]);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::TrashEmailMessage200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::TrashEmailMessage200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<TrashEmailMessageError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// `folder` moves the message. On Google a move swaps the inbox, trash and spam labels and keeps every other label; `archive` removes the inbox label.
pub async fn update_email_message(
configuration: &configuration::Configuration,
message_id: &str,
email_message_patch: models::EmailMessagePatch,
) -> Result<models::SendEmailMessage201Response, Error<UpdateEmailMessageError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_message_id = message_id;
let p_body_email_message_patch = email_message_patch;
let uri_str = format!(
"{}/v1/email/messages/{messageId}",
configuration.base_path,
messageId = crate::apis::urlencode(p_path_message_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::PATCH, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_email_message_patch);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::SendEmailMessage201Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::SendEmailMessage201Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<UpdateEmailMessageError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Applies `unread`, `starred` or a `folder` move to each message of the thread.
pub async fn update_email_thread(
configuration: &configuration::Configuration,
thread_id: &str,
email_message_patch: models::EmailMessagePatch,
) -> Result<models::UpdateEmailThread200Response, Error<UpdateEmailThreadError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_thread_id = thread_id;
let p_body_email_message_patch = email_message_patch;
let uri_str = format!(
"{}/v1/email/threads/{threadId}",
configuration.base_path,
threadId = crate::apis::urlencode(p_path_thread_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::PATCH, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_email_message_patch);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UpdateEmailThread200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UpdateEmailThread200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<UpdateEmailThreadError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}