Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,14 @@ impl HttpClient {
self.request("PUT", path, &[], Some(body), None).await
}

pub async fn patch<T, B>(&self, path: &str, body: &B) -> Result<T>
where
T: DeserializeOwned,
B: Serialize + Sync + ?Sized,
{
self.request("PATCH", path, &[], Some(body), None).await
}

pub async fn delete<T>(&self, path: &str) -> Result<T>
where
T: DeserializeOwned,
Expand Down Expand Up @@ -332,6 +340,10 @@ impl ApiClient {
Ok(self.client.get_raw("/ping", &[]).await?.trim().to_string())
}

pub async fn blocked_file_types(&self) -> Result<crate::types::BlockedFileTypesResponse> {
self.client.get("/blocked-file-types", &[]).await
}

pub fn domains(&self) -> endpoints::Domains<'_> {
endpoints::Domains::new(&self.client)
}
Expand Down
57 changes: 53 additions & 4 deletions src/email.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
use crate::client::EmailClient;
use crate::error::Result;
use crate::types::{EmailAttachment, SendBatchMailResponse, SendMailRequest, SendMailResponse};
use crate::types::{
EmailAttachment, SendBatchMailResponse, SendMailRequest, SendMailResponse, TlsPolicy,
};
use serde::Serialize;
use std::collections::BTreeMap;

#[derive(Clone, Debug, Default, PartialEq, Serialize)]
pub struct EmailSettings {
#[serde(skip_serializing_if = "Option::is_none")]
pub track_opens: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub track_clicks: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tls: Option<TlsPolicy>,
}

impl EmailClient {
pub fn email(&self) -> EmailBuilder<'_> {
EmailBuilder::new(self)
Expand All @@ -15,6 +28,17 @@ impl EmailClient {
pub async fn send_batch(&self, payload: &[SendMailRequest]) -> Result<SendBatchMailResponse> {
self.client.post("/send/batch", payload).await
}

pub async fn send_batch_with_idempotency_key(
&self,
payload: &[SendMailRequest],
key: impl Into<String>,
) -> Result<SendBatchMailResponse> {
let headers = BTreeMap::from([("idempotency-key".into(), key.into())]);
self.client
.post_with_headers("/send/batch", payload, Some(headers))
.await
}
}

pub struct EmailBuilder<'a> {
Expand Down Expand Up @@ -71,6 +95,11 @@ impl<'a> EmailBuilder<'a> {
self
}

pub fn scheduled_at(mut self, scheduled_at: impl Into<String>) -> Self {
self.payload.scheduled_at = Some(scheduled_at.into());
self
}

pub fn html(mut self, html: impl Into<String>) -> Self {
self.payload.html = Some(html.into());
self
Expand Down Expand Up @@ -107,12 +136,27 @@ impl<'a> EmailBuilder<'a> {
self
}

pub fn attach(mut self, filename: impl Into<String>, content: impl Into<String>) -> Self {
pub fn tags(mut self, tags: Vec<serde_json::Value>) -> Self {
self.payload.tags = Some(tags);
self
}

pub fn attach(self, filename: impl Into<String>, content: impl Into<String>) -> Self {
self.attach_with_options(filename, content, None, None)
}

pub fn attach_with_options(
mut self,
filename: impl Into<String>,
content: impl Into<String>,
content_id: Option<String>,
content_type: Option<String>,
) -> Self {
let attachment = EmailAttachment {
filename: filename.into(),
content: content.into(),
content_type: None,
content_id: None,
content_type,
content_id,
};
self.payload
.attachments
Expand All @@ -121,6 +165,11 @@ impl<'a> EmailBuilder<'a> {
self
}

pub fn settings(mut self, settings: EmailSettings) -> Self {
self.payload.settings = Some(serde_json::to_value(settings).expect("settings serialize"));
self
}

pub fn idempotency_key(mut self, key: impl Into<String>) -> Self {
self.idempotency_key = Some(key.into());
self
Expand Down
101 changes: 51 additions & 50 deletions src/endpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ pub const OPERATION_IDS: &[&str] = &[
"domain.verifySpecificDnsRecord",
"domain.updateProjects",
"v1.ping",
"v1.blockedFileTypes",
"message.index",
"message.show",
"rescheduleMessage",
"cancelScheduledMessage",
"message.events",
"message.source",
"message.html",
Expand All @@ -27,9 +30,6 @@ pub const OPERATION_IDS: &[&str] = &[
"project.update",
"project.destroy",
"project.rotateToken",
"project.updateMembers",
"project.addMember",
"project.removeMember",
"route.index",
"route.store",
"route.show",
Expand All @@ -43,7 +43,10 @@ pub const OPERATION_IDS: &[&str] = &[
"team.show",
"team.update",
"team.usage",
"team.roles",
"team.members",
"team.members.show",
"team.members.assignment.update",
"webhook.index",
"webhook.store",
"webhook.show",
Expand Down Expand Up @@ -154,6 +157,25 @@ impl<'a> Messages<'a> {
.await
}

pub async fn reschedule(
&self,
message_id: &str,
payload: &types::RescheduleMessageRequest,
) -> Result<types::RescheduleMessageResponse> {
self.client
.patch(&format!("/messages/{}", segment(message_id)), payload)
.await
}

pub async fn cancel(&self, message_id: &str) -> Result<types::RescheduleMessageResponse> {
self.client
.post(
&format!("/messages/{}/cancel", segment(message_id)),
&serde_json::json!({}),
)
.await
}

pub async fn events(
&self,
message_id: &str,
Expand Down Expand Up @@ -240,53 +262,6 @@ impl<'a> Projects<'a> {
.await
}

pub async fn update_members<B>(
&self,
project_id: &str,
payload: &B,
) -> Result<types::ProjectUpdateMembersResponse>
where
B: Serialize + Sync,
{
self.client
.put(
&format!("/projects/{}/members", segment(project_id)),
payload,
)
.await
}

pub async fn add_member(
&self,
project_id: &str,
team_member_id: &str,
) -> Result<types::ProjectAddMemberResponse> {
self.client
.post(
&format!(
"/projects/{}/members/{}",
segment(project_id),
segment(team_member_id)
),
&empty_body(),
)
.await
}

pub async fn remove_member(
&self,
project_id: &str,
team_member_id: &str,
) -> Result<types::ProjectRemoveMemberResponse> {
self.client
.delete(&format!(
"/projects/{}/members/{}",
segment(project_id),
segment(team_member_id)
))
.await
}

pub async fn routes(
&self,
project_id: &str,
Expand Down Expand Up @@ -422,9 +397,35 @@ impl<'a> Team<'a> {
self.client.get("/team/usage", &[]).await
}

pub async fn roles(&self) -> Result<types::TeamRolesResponse> {
self.client.get("/team/roles", &[]).await
}

pub async fn members(&self, query: Query<'_>) -> Result<types::TeamMembersResponse> {
self.client.get("/team/members", query).await
}

pub async fn member(&self, user_id: &str) -> Result<types::TeamMembersShowResponse> {
self.client
.get(&format!("/team/members/{}", segment(user_id)), &[])
.await
}

pub async fn update_member_assignment<B>(
&self,
user_id: &str,
payload: &B,
) -> Result<types::TeamMembersAssignmentUpdateResponse>
where
B: Serialize + Sync,
{
self.client
.put(
&format!("/team/members/{}/assignment", segment(user_id)),
payload,
)
.await
}
}

pub struct Webhooks<'a> {
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ pub mod types;
pub mod webhook;

pub use client::{ApiClient, EmailClient, Lettermint};
pub use email::EmailBuilder;
pub use email::{EmailBuilder, EmailSettings};
pub use error::{Error, Result};
pub use webhook::Webhook;
Loading
Loading