use crate::client::Unosend;
use crate::error::UnosendError;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
pub struct EmailsApi {
client: Unosend,
}
impl EmailsApi {
pub(crate) fn new(client: Unosend) -> Self {
Self { client }
}
pub async fn send(&self, request: SendEmailRequest) -> Result<SendEmailResponse, UnosendError> {
self.client.post("/emails", &request).await
}
pub async fn get(&self, email_id: &str) -> Result<EmailDetails, UnosendError> {
self.client.get(&format!("/emails/{}", email_id)).await
}
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct SendEmailRequest {
pub from: String,
#[serde(flatten)]
pub to: EmailRecipient,
pub subject: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub html: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub text: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cc: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bcc: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reply_to: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub priority: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub template_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub template_data: Option<HashMap<String, serde_json::Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scheduled_for: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub attachments: Option<Vec<Attachment>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub headers: Option<HashMap<String, String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tags: Option<HashMap<String, String>>,
}
#[derive(Debug, Clone, Serialize, Default)]
#[serde(untagged)]
pub enum EmailRecipient {
#[default]
None,
Single {
to: String,
},
Multiple {
to: Vec<String>,
},
}
impl From<&str> for EmailRecipient {
fn from(s: &str) -> Self {
EmailRecipient::Single { to: s.to_string() }
}
}
impl From<String> for EmailRecipient {
fn from(s: String) -> Self {
EmailRecipient::Single { to: s }
}
}
impl From<Vec<String>> for EmailRecipient {
fn from(v: Vec<String>) -> Self {
EmailRecipient::Multiple { to: v }
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Attachment {
pub filename: String,
pub content: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub content_type: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct SendEmailResponse {
pub id: String,
pub from: String,
pub to: Vec<String>,
pub subject: String,
pub status: String,
pub created_at: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct EmailDetails {
pub id: String,
pub from: String,
pub to: Vec<String>,
pub subject: String,
pub status: String,
pub created_at: String,
pub html: Option<String>,
pub text: Option<String>,
pub sent_at: Option<String>,
pub delivered_at: Option<String>,
}