smbcloud_email_sdk/
client.rs1use crate::client_credentials::EmailCredentials;
2use crate::error::EmailError;
3use crate::message::{EmailMessage, SendEmail};
4use smbcloud_network::environment::Environment;
5
6#[derive(Debug, Clone)]
18pub struct EmailClient {
19 base_url: String,
20 api_key: String,
21 http: reqwest::Client,
22}
23
24impl EmailClient {
25 pub fn from_credentials(environment: Environment, credentials: EmailCredentials<'_>) -> Self {
31 EmailClient {
32 base_url: crate::client_credentials::base_url(&environment),
33 api_key: credentials.api_key.to_string(),
34 http: reqwest::Client::new(),
35 }
36 }
37
38 pub async fn send(&self, message: &SendEmail) -> Result<EmailMessage, EmailError> {
44 let url = format!("{}/v1/email/messages", self.base_url);
45 let response = self
46 .authed(self.http.post(&url))
47 .json(message)
48 .send()
49 .await?;
50
51 if response.status().is_success() {
52 return Ok(response.json().await?);
53 }
54 Err(self.api_error(response).await)
55 }
56
57 pub async fn get_message(&self, id: &str) -> Result<EmailMessage, EmailError> {
60 let url = format!("{}/v1/email/messages/{}", self.base_url, id);
61 let response = self.authed(self.http.get(&url)).send().await?;
62
63 if response.status().is_success() {
64 return Ok(response.json().await?);
65 }
66 Err(self.api_error(response).await)
67 }
68
69 pub async fn list_messages(
73 &self,
74 status: Option<&str>,
75 limit: Option<u32>,
76 ) -> Result<Vec<EmailMessage>, EmailError> {
77 let url = format!("{}/v1/email/messages", self.base_url);
78
79 let mut params: Vec<(&str, String)> = Vec::new();
80 if let Some(status) = status {
81 params.push(("status", status.to_string()));
82 }
83 if let Some(limit) = limit {
84 params.push(("limit", limit.to_string()));
85 }
86
87 let response = self
88 .authed(self.http.get(&url))
89 .query(¶ms)
90 .send()
91 .await?;
92
93 if response.status().is_success() {
94 return Ok(response.json().await?);
95 }
96 Err(self.api_error(response).await)
97 }
98
99 fn authed(&self, builder: reqwest::RequestBuilder) -> reqwest::RequestBuilder {
100 builder.header("Authorization", format!("Bearer {}", self.api_key))
101 }
102
103 async fn api_error(&self, response: reqwest::Response) -> EmailError {
104 let status = response.status().as_u16();
105 let message = response
106 .text()
107 .await
108 .unwrap_or_else(|_| "unreadable response body".to_string());
109 EmailError::Api { status, message }
110 }
111}