use crate::client_credentials::EmailCredentials;
use crate::error::EmailError;
use crate::message::{EmailMessage, SendEmail};
use smbcloud_network::environment::Environment;
#[derive(Debug, Clone)]
pub struct EmailClient {
base_url: String,
api_key: String,
http: reqwest::Client,
}
impl EmailClient {
pub fn from_credentials(environment: Environment, credentials: EmailCredentials<'_>) -> Self {
EmailClient {
base_url: crate::client_credentials::base_url(&environment),
api_key: credentials.api_key.to_string(),
http: reqwest::Client::new(),
}
}
pub async fn send(&self, message: &SendEmail) -> Result<EmailMessage, EmailError> {
let url = format!("{}/v1/email/messages", self.base_url);
let response = self
.authed(self.http.post(&url))
.json(message)
.send()
.await?;
if response.status().is_success() {
return Ok(response.json().await?);
}
Err(self.api_error(response).await)
}
pub async fn get_message(&self, id: &str) -> Result<EmailMessage, EmailError> {
let url = format!("{}/v1/email/messages/{}", self.base_url, id);
let response = self.authed(self.http.get(&url)).send().await?;
if response.status().is_success() {
return Ok(response.json().await?);
}
Err(self.api_error(response).await)
}
pub async fn list_messages(
&self,
status: Option<&str>,
limit: Option<u32>,
) -> Result<Vec<EmailMessage>, EmailError> {
let url = format!("{}/v1/email/messages", self.base_url);
let mut params: Vec<(&str, String)> = Vec::new();
if let Some(status) = status {
params.push(("status", status.to_string()));
}
if let Some(limit) = limit {
params.push(("limit", limit.to_string()));
}
let response = self
.authed(self.http.get(&url))
.query(¶ms)
.send()
.await?;
if response.status().is_success() {
return Ok(response.json().await?);
}
Err(self.api_error(response).await)
}
fn authed(&self, builder: reqwest::RequestBuilder) -> reqwest::RequestBuilder {
builder.header("Authorization", format!("Bearer {}", self.api_key))
}
async fn api_error(&self, response: reqwest::Response) -> EmailError {
let status = response.status().as_u16();
let message = response
.text()
.await
.unwrap_or_else(|_| "unreadable response body".to_string());
EmailError::Api { status, message }
}
}