use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Recipients {
One(String),
Many(Vec<String>),
}
impl Default for Recipients {
fn default() -> Self {
Recipients::Many(Vec::new())
}
}
impl From<&str> for Recipients {
fn from(value: &str) -> Self {
Recipients::One(value.to_string())
}
}
impl From<String> for Recipients {
fn from(value: String) -> Self {
Recipients::One(value)
}
}
impl From<Vec<String>> for Recipients {
fn from(value: Vec<String>) -> Self {
Recipients::Many(value)
}
}
impl From<Vec<&str>> for Recipients {
fn from(value: Vec<&str>) -> Self {
Recipients::Many(value.into_iter().map(String::from).collect())
}
}
impl<const N: usize> From<[&str; N]> for Recipients {
fn from(value: [&str; N]) -> Self {
Recipients::Many(value.iter().map(|s| s.to_string()).collect())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Tag {
pub name: String,
pub value: String,
}
#[derive(Debug, Clone)]
pub struct Idempotent<T> {
pub data: T,
pub idempotency_key: Option<String>,
}
impl<T> From<T> for Idempotent<T> {
fn from(data: T) -> Self {
Idempotent {
data,
idempotency_key: None,
}
}
}
impl<'a, T, const N: usize> From<&'a [T; N]> for Idempotent<&'a [T]> {
fn from(data: &'a [T; N]) -> Self {
Idempotent::from(data.as_slice())
}
}
impl<'a, T> From<&'a Vec<T>> for Idempotent<&'a [T]> {
fn from(data: &'a Vec<T>) -> Self {
Idempotent::from(data.as_slice())
}
}
pub trait IdempotentTrait: Sized {
fn with_idempotency_key(self, key: impl Into<String>) -> Idempotent<Self> {
Idempotent {
data: self,
idempotency_key: Some(key.into()),
}
}
}
impl IdempotentTrait for &SendEmailOptions {}
impl IdempotentTrait for &[SendEmailOptions] {}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BatchValidation {
Strict,
Permissive,
}
impl BatchValidation {
pub(crate) fn as_str(self) -> &'static str {
match self {
BatchValidation::Strict => "strict",
BatchValidation::Permissive => "permissive",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct BatchError {
pub index: u32,
pub message: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct Deleted {
pub object: String,
pub id: String,
pub deleted: bool,
}
#[derive(Debug, Clone, Default)]
pub struct ListOptions {
pub limit: Option<u32>,
pub after: Option<String>,
pub before: Option<String>,
}
impl ListOptions {
pub(crate) fn to_query(&self) -> Vec<(&'static str, String)> {
let mut query = Vec::new();
if let Some(limit) = self.limit {
query.push(("limit", limit.to_string()));
}
if let Some(after) = &self.after {
query.push(("after", after.clone()));
}
if let Some(before) = &self.before {
query.push(("before", before.clone()));
}
query
}
}
pub(crate) fn list_query(options: Option<&ListOptions>) -> Vec<(&'static str, String)> {
options.map(ListOptions::to_query).unwrap_or_default()
}
#[derive(Debug, Clone, Deserialize)]
pub struct List<T> {
pub object: String,
pub data: Vec<T>,
pub has_more: bool,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct SendEmailOptions {
pub from: String,
pub to: Recipients,
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<Recipients>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bcc: Option<Recipients>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reply_to: Option<Recipients>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scheduled_at: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tags: Option<Vec<Tag>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub topic_id: 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 template: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize)]
pub struct Attachment {
pub filename: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub content: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub content_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub content_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub path: Option<String>,
}
impl SendEmailOptions {
pub fn new(
from: impl Into<String>,
to: impl Into<Recipients>,
subject: impl Into<String>,
) -> Self {
SendEmailOptions {
from: from.into(),
to: to.into(),
subject: subject.into(),
..Default::default()
}
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct CreateEmailResponse {
pub id: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct Email {
pub object: String,
pub id: String,
pub from: String,
pub to: Vec<String>,
pub cc: Option<Vec<String>>,
pub bcc: Option<Vec<String>>,
pub reply_to: Option<Vec<String>>,
pub subject: String,
pub html: Option<String>,
pub text: Option<String>,
pub created_at: String,
pub scheduled_at: Option<String>,
pub message_id: String,
pub last_event: String,
pub score: Option<f64>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct EmailInsights {
pub object: String,
pub email_id: String,
pub score: f64,
pub score_version: u32,
pub band: String,
pub marketing: bool,
pub html_size_bytes: Option<u64>,
pub computed_at: String,
pub checks: Vec<InsightCheck>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct InsightCheck {
pub id: String,
pub severity: String,
pub status: String,
pub penalty: f64,
#[serde(default)]
pub detail: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CancelEmailResponse {
pub object: String,
pub id: String,
}
#[derive(Debug, Clone, Serialize)]
pub struct UpdateEmailOptions {
pub scheduled_at: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct UpdateEmailResponse {
pub object: String,
pub id: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct EmailListItem {
pub id: String,
pub from: String,
pub to: Vec<String>,
pub cc: Option<Vec<String>>,
pub bcc: Option<Vec<String>>,
pub reply_to: Option<Vec<String>>,
pub subject: String,
pub created_at: String,
pub scheduled_at: Option<String>,
pub last_event: String,
}
pub type DeleteEmailResponse = Deleted;
#[derive(Debug, Clone, Deserialize)]
pub struct BatchResponse {
pub data: Vec<CreateEmailResponse>,
#[serde(default)]
pub errors: Vec<BatchError>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DeliverabilityReport {
pub object: String,
pub score: Option<f64>,
pub band: Option<String>,
pub content_score: Option<f64>,
pub outcome_score: Option<f64>,
pub complaint_rate: f64,
pub hard_bounce_rate: f64,
pub emails_sent: u64,
pub scored_recipients: u64,
pub window_days: u32,
pub insufficient_outcome_data: bool,
pub guardrail_status: String,
pub score_version: u32,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct CreateContactOptions {
pub email: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub first_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub unsubscribed: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub properties: Option<HashMap<String, serde_json::Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub segments: Option<Vec<SegmentRef>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub topics: Option<Vec<ContactTopicUpdate>>,
}
impl CreateContactOptions {
pub fn new(email: impl Into<String>) -> Self {
CreateContactOptions {
email: email.into(),
..Default::default()
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct SegmentRef {
pub id: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OnConflict {
Error,
Skip,
Upsert,
}
impl OnConflict {
pub(crate) fn as_str(self) -> &'static str {
match self {
OnConflict::Error => "error",
OnConflict::Skip => "skip",
OnConflict::Upsert => "upsert",
}
}
}
#[derive(Debug, Clone, Default)]
pub struct BatchContactsOptions {
pub on_conflict: Option<OnConflict>,
pub batch_validation: Option<BatchValidation>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct BatchContactsResponse {
pub data: Vec<BatchContactResult>,
pub counts: BatchContactsCounts,
#[serde(default)]
pub errors: Vec<BatchError>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct BatchContactResult {
pub object: String,
pub index: u32,
pub id: String,
pub status: BatchContactStatus,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum BatchContactStatus {
Created,
Updated,
Skipped,
}
#[derive(Debug, Clone, Deserialize)]
pub struct BatchContactsCounts {
pub created: u32,
pub updated: u32,
pub skipped: u32,
pub failed: u32,
}
#[derive(Debug, Clone, Deserialize)]
pub struct AddContactSegmentResponse {
pub id: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RemoveContactSegmentResponse {
pub id: String,
#[serde(rename = "audienceId")]
pub audience_id: String,
pub deleted: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ContactPropertyType {
String,
Number,
}
#[derive(Debug, Clone, Serialize)]
pub struct CreateContactPropertyOptions {
pub key: String,
pub r#type: ContactPropertyType,
#[serde(skip_serializing_if = "Option::is_none")]
pub fallback_value: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct UpdateContactPropertyOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub fallback_value: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ContactProperty {
pub id: String,
pub key: String,
pub r#type: ContactPropertyType,
pub fallback_value: Option<serde_json::Value>,
pub created_at: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ContactPropertyId {
pub object: String,
pub id: String,
}
pub type DeleteContactPropertyResponse = Deleted;
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct ContactAddress {
pub id: Option<String>,
pub email: Option<String>,
}
impl ContactAddress {
pub fn id(id: impl Into<String>) -> Self {
ContactAddress {
id: Some(id.into()),
..Default::default()
}
}
pub fn email(email: impl Into<String>) -> Self {
ContactAddress {
email: Some(email.into()),
..Default::default()
}
}
pub(crate) fn key(&self) -> &str {
self.email.as_deref().or(self.id.as_deref()).unwrap_or("")
}
}
impl From<&str> for ContactAddress {
fn from(value: &str) -> Self {
ContactAddress::id(value)
}
}
impl From<String> for ContactAddress {
fn from(value: String) -> Self {
ContactAddress::id(value)
}
}
impl From<&String> for ContactAddress {
fn from(value: &String) -> Self {
ContactAddress::id(value.clone())
}
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct UpdateContactOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub first_name: Option<Option<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_name: Option<Option<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub unsubscribed: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub properties: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ContactId {
pub object: String,
pub id: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct Contact {
pub object: String,
pub id: String,
pub email: String,
pub first_name: Option<String>,
pub last_name: Option<String>,
pub created_at: String,
pub unsubscribed: bool,
#[serde(default)]
pub properties: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ContactListItem {
pub id: String,
pub email: String,
pub first_name: Option<String>,
pub last_name: Option<String>,
pub created_at: String,
pub unsubscribed: bool,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DeleteContactResponse {
pub object: String,
pub contact: String,
pub deleted: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TopicSubscription {
OptIn,
OptOut,
}
#[derive(Debug, Clone, Serialize)]
pub struct ContactTopicUpdate {
pub id: String,
pub subscription: TopicSubscription,
}
#[derive(Debug, Clone, Deserialize)]
pub struct UpdateContactTopicsResponse {
pub id: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TopicVisibility {
Private,
Public,
}
#[derive(Debug, Clone, Serialize)]
pub struct CreateTopicOptions {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub default_subscription: TopicSubscription,
#[serde(skip_serializing_if = "Option::is_none")]
pub visibility: Option<TopicVisibility>,
}
impl CreateTopicOptions {
pub fn new(name: impl Into<String>, default_subscription: TopicSubscription) -> Self {
CreateTopicOptions {
name: name.into(),
description: None,
default_subscription,
visibility: None,
}
}
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct UpdateTopicOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub visibility: Option<TopicVisibility>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct Topic {
pub id: String,
pub name: String,
#[serde(default)]
pub description: Option<String>,
pub default_subscription: TopicSubscription,
#[serde(default)]
pub visibility: Option<TopicVisibility>,
pub created_at: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TopicId {
pub id: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TopicList {
pub data: Vec<Topic>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DeleteTopicResponse {
pub id: String,
pub object: String,
pub deleted: bool,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct CreateBroadcastOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub segment_id: Option<String>,
pub from: String,
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 reply_to: Option<Recipients>,
#[serde(skip_serializing_if = "Option::is_none")]
pub preview_text: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub topic_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub send: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scheduled_at: Option<String>,
}
impl CreateBroadcastOptions {
pub fn new(from: impl Into<String>, subject: impl Into<String>) -> Self {
CreateBroadcastOptions {
from: from.into(),
subject: subject.into(),
..Default::default()
}
}
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct UpdateBroadcastOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub segment_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub from: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub subject: Option<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 reply_to: Option<Recipients>,
#[serde(skip_serializing_if = "Option::is_none")]
pub preview_text: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub topic_id: Option<String>,
#[serde(skip)]
pub clear_topic_id: bool,
}
#[derive(Debug, Clone, Deserialize)]
pub struct BroadcastId {
pub id: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct BroadcastListItem {
pub id: String,
pub name: Option<String>,
pub segment_id: Option<String>,
pub status: String,
pub created_at: String,
pub scheduled_at: Option<String>,
pub sent_at: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct Broadcast {
pub object: String,
pub id: String,
pub name: Option<String>,
pub segment_id: Option<String>,
pub status: String,
pub created_at: String,
pub scheduled_at: Option<String>,
pub sent_at: Option<String>,
pub from: String,
pub subject: String,
pub reply_to: Option<Vec<String>>,
pub preview_text: Option<String>,
pub topic_id: Option<String>,
pub html: Option<String>,
pub text: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CancelBroadcastResponse {
pub object: String,
pub id: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DeleteBroadcastResponse {
pub object: String,
pub id: String,
pub deleted: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SegmentMatch {
All,
Any,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SegmentCondition {
pub field: String,
pub op: String,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub value: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SegmentFilter {
#[serde(rename = "match")]
pub match_: SegmentMatch,
pub conditions: Vec<SegmentCondition>,
}
#[derive(Debug, Clone, Serialize)]
pub struct CreateSegmentOptions {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub filter: Option<SegmentFilter>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct UpdateSegmentOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub filter: Option<Option<SegmentFilter>>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct Segment {
pub object: String,
pub id: String,
pub name: String,
pub filter: Option<SegmentFilter>,
pub created_at: String,
#[serde(default)]
pub contact_count: Option<u64>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DeleteSegmentResponse {
pub object: String,
pub id: String,
pub deleted: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SuppressionOrigin {
Bounce,
Complaint,
Manual,
Unsubscribe,
}
impl SuppressionOrigin {
pub(crate) fn as_str(self) -> &'static str {
match self {
SuppressionOrigin::Bounce => "bounce",
SuppressionOrigin::Complaint => "complaint",
SuppressionOrigin::Manual => "manual",
SuppressionOrigin::Unsubscribe => "unsubscribe",
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct AddSuppressionOptions {
pub email: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub origin: Option<SuppressionOrigin>,
}
impl AddSuppressionOptions {
pub fn new(email: impl Into<String>) -> Self {
AddSuppressionOptions {
email: email.into(),
origin: None,
}
}
}
#[derive(Debug, Clone, Default)]
pub struct ListSuppressionsOptions {
pub limit: Option<u32>,
pub after: Option<String>,
pub before: Option<String>,
pub origin: Option<SuppressionOrigin>,
}
impl ListSuppressionsOptions {
pub(crate) fn to_query(&self) -> Vec<(&'static str, String)> {
let mut query = ListOptions {
limit: self.limit,
after: self.after.clone(),
before: self.before.clone(),
}
.to_query();
if let Some(origin) = self.origin {
query.push(("origin", origin.as_str().to_string()));
}
query
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct SuppressionId {
pub object: String,
pub id: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct Suppression {
pub id: String,
pub email: String,
pub origin: SuppressionOrigin,
pub source_id: Option<String>,
pub created_at: String,
}
pub type DeleteSuppressionResponse = Deleted;
#[derive(Debug, Clone, Serialize)]
pub struct BatchAddSuppressionOptions {
pub emails: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub origin: Option<SuppressionOrigin>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct BatchAddSuppressionResponse {
pub data: Vec<SuppressionId>,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum BatchRemoveSuppressionOptions {
Emails(Vec<String>),
Ids(Vec<String>),
}
#[derive(Debug, Clone, Deserialize)]
pub struct BatchRemoveSuppressionsResponse {
pub data: Vec<Deleted>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct CreateDomainOptions {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub region: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub custom_return_path: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub open_tracking: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub click_tracking: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tracking_subdomain: Option<String>,
}
impl CreateDomainOptions {
pub fn new(name: impl Into<String>) -> Self {
CreateDomainOptions {
name: name.into(),
..Default::default()
}
}
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct UpdateDomainOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub open_tracking: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub click_tracking: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tracking_subdomain: Option<Option<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tls: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub capabilities: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct Domain {
pub id: String,
pub name: String,
pub status: String,
pub created_at: String,
pub region: String,
pub open_tracking: bool,
pub click_tracking: bool,
pub tracking_subdomain: Option<String>,
pub capabilities: DomainCapabilities,
#[serde(default)]
pub records: Vec<DomainRecord>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DomainCapabilities {
pub sending: String,
pub receiving: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DomainRecord {
pub record: String,
pub name: String,
pub r#type: String,
pub ttl: String,
pub status: String,
pub value: String,
#[serde(default)]
pub priority: Option<u32>,
}
pub type DeleteDomainResponse = Deleted;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ApiKeyPermission {
FullAccess,
SendingAccess,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct CreateApiKeyOptions {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub permission: Option<ApiKeyPermission>,
#[serde(skip_serializing_if = "Option::is_none")]
pub domain_id: Option<String>,
}
impl CreateApiKeyOptions {
pub fn new(name: impl Into<String>) -> Self {
CreateApiKeyOptions {
name: name.into(),
..Default::default()
}
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct ApiKeyToken {
pub id: String,
pub token: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ApiKey {
pub id: String,
pub name: String,
pub created_at: String,
pub last_used_at: Option<String>,
}
pub type DeleteApiKeyResponse = Deleted;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum WebhookStatus {
Enabled,
Disabled,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct CreateWebhookOptions {
pub endpoint: String,
pub events: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub signing_secret: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CreateWebhookResponse {
pub object: String,
pub id: String,
pub signing_secret: String,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct UpdateWebhookOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub endpoint: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub events: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<WebhookStatus>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct Webhook {
pub id: String,
pub endpoint: String,
pub created_at: String,
pub status: WebhookStatus,
pub events: Option<Vec<String>>,
#[serde(default)]
pub signing_secret: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WebhookId {
pub object: String,
pub id: String,
}
pub type DeleteWebhookResponse = Deleted;
#[derive(Debug, Clone, Default, Serialize)]
pub struct CreateTemplateOptions {
pub name: String,
pub html: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub subject: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub text: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub alias: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub from: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reply_to: Option<Recipients>,
#[serde(skip_serializing_if = "Option::is_none")]
pub variables: Option<Vec<serde_json::Value>>,
}
impl CreateTemplateOptions {
pub fn new(name: impl Into<String>, html: impl Into<String>) -> Self {
CreateTemplateOptions {
name: name.into(),
html: html.into(),
..Default::default()
}
}
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct UpdateTemplateOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub html: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub subject: Option<Option<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub text: Option<Option<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub alias: Option<Option<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub from: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reply_to: Option<Recipients>,
#[serde(skip_serializing_if = "Option::is_none")]
pub variables: Option<Vec<serde_json::Value>>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TemplateId {
pub object: String,
pub id: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TemplateListItem {
pub id: String,
pub name: String,
pub alias: Option<String>,
pub status: String,
pub published_at: String,
pub created_at: String,
pub updated_at: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct Template {
pub object: String,
pub id: String,
pub name: String,
pub alias: Option<String>,
pub status: String,
pub published_at: String,
pub created_at: String,
pub updated_at: String,
pub current_version_id: String,
pub from: Option<String>,
pub subject: Option<String>,
pub reply_to: Option<Recipients>,
pub html: String,
pub text: Option<String>,
#[serde(default)]
pub variables: Vec<serde_json::Value>,
pub has_unpublished_versions: bool,
}
pub type DeleteTemplateResponse = Deleted;
#[derive(Debug, Clone, Deserialize)]
pub struct UsageReport {
pub object: String,
pub cloud: bool,
pub plan: Option<String>,
pub limits: UsageLimits,
pub today: UsageToday,
pub team: UsageTeam,
pub app_url: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct UsageLimits {
pub emails_per_day: Option<u64>,
pub domains: Option<u64>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct UsageToday {
pub emails_sent: u64,
pub resets_at: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct UsageTeam {
pub id: String,
pub name: String,
}