use serde::{Deserialize, Serialize};
use crate::client::Sendly;
use crate::error::Result;
#[derive(Debug, Clone, Deserialize)]
pub struct TenDlcBrand {
pub id: String,
#[serde(alias = "legalName")]
pub legal_name: String,
#[serde(default)]
pub dba: Option<String>,
#[serde(alias = "entityType")]
pub entity_type: String,
#[serde(default)]
pub ein: Option<String>,
#[serde(default)]
pub vertical: Option<String>,
#[serde(default)]
pub website: Option<String>,
pub status: String,
#[serde(default, alias = "identityStatus")]
pub identity_status: Option<String>,
#[serde(default, alias = "failureReasons")]
pub failure_reasons: Option<Vec<String>>,
#[serde(alias = "createdAt")]
pub created_at: String,
#[serde(alias = "updatedAt")]
pub updated_at: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TenDlcBrandListResponse {
#[serde(default)]
pub data: Vec<TenDlcBrand>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TenDlcBrandResponse {
pub data: TenDlcBrand,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateTenDlcBrandRequest {
pub legal_name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub dba: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ein: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub entity_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub vertical: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub website: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub phone: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mobile_phone: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub street: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub city: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub state: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub postal_code: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub country: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub verification_id: Option<String>,
}
impl CreateTenDlcBrandRequest {
pub fn new(legal_name: impl Into<String>) -> Self {
Self {
legal_name: legal_name.into(),
dba: None,
ein: None,
entity_type: None,
vertical: None,
website: None,
email: None,
phone: None,
mobile_phone: None,
street: None,
city: None,
state: None,
postal_code: None,
country: None,
verification_id: None,
}
}
pub fn dba(mut self, dba: impl Into<String>) -> Self {
self.dba = Some(dba.into());
self
}
pub fn ein(mut self, ein: impl Into<String>) -> Self {
self.ein = Some(ein.into());
self
}
pub fn entity_type(mut self, entity_type: impl Into<String>) -> Self {
self.entity_type = Some(entity_type.into());
self
}
pub fn vertical(mut self, vertical: impl Into<String>) -> Self {
self.vertical = Some(vertical.into());
self
}
pub fn website(mut self, website: impl Into<String>) -> Self {
self.website = Some(website.into());
self
}
pub fn email(mut self, email: impl Into<String>) -> Self {
self.email = Some(email.into());
self
}
pub fn phone(mut self, phone: impl Into<String>) -> Self {
self.phone = Some(phone.into());
self
}
pub fn mobile_phone(mut self, mobile_phone: impl Into<String>) -> Self {
self.mobile_phone = Some(mobile_phone.into());
self
}
pub fn street(mut self, street: impl Into<String>) -> Self {
self.street = Some(street.into());
self
}
pub fn city(mut self, city: impl Into<String>) -> Self {
self.city = Some(city.into());
self
}
pub fn state(mut self, state: impl Into<String>) -> Self {
self.state = Some(state.into());
self
}
pub fn postal_code(mut self, postal_code: impl Into<String>) -> Self {
self.postal_code = Some(postal_code.into());
self
}
pub fn country(mut self, country: impl Into<String>) -> Self {
self.country = Some(country.into());
self
}
pub fn verification_id(mut self, verification_id: impl Into<String>) -> Self {
self.verification_id = Some(verification_id.into());
self
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct TenDlcThroughput {
pub tier: String,
#[serde(alias = "carriersReady")]
pub carriers_ready: i64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TenDlcQualifyResult {
#[serde(alias = "useCase")]
pub use_case: String,
pub qualified: bool,
#[serde(default)]
pub reason: Option<String>,
#[serde(default)]
pub throughput: Option<TenDlcThroughput>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TenDlcQualifyResponse {
pub data: TenDlcQualifyResult,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TenDlcCampaign {
pub id: String,
#[serde(alias = "brandId")]
pub brand_id: String,
#[serde(alias = "useCase")]
pub use_case: String,
#[serde(default, alias = "subUseCases")]
pub sub_use_cases: Vec<String>,
#[serde(default)]
pub description: Option<String>,
pub status: String,
#[serde(default, alias = "sampleMessages")]
pub sample_messages: Vec<String>,
#[serde(default)]
pub throughput: Option<TenDlcThroughput>,
#[serde(default, alias = "failureReasons")]
pub failure_reasons: Option<Vec<String>>,
#[serde(alias = "createdAt")]
pub created_at: String,
#[serde(alias = "updatedAt")]
pub updated_at: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TenDlcCampaignListResponse {
#[serde(default)]
pub data: Vec<TenDlcCampaign>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TenDlcCampaignResponse {
pub data: TenDlcCampaign,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateTenDlcCampaignRequest {
pub brand_id: String,
pub use_case: String,
pub description: String,
pub message_flow: String,
pub sample_messages: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sub_use_cases: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub opt_in_keywords: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub opt_out_keywords: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub help_keywords: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub opt_in_message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub opt_out_message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub help_message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub embedded_link: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub embedded_phone: Option<bool>,
}
impl CreateTenDlcCampaignRequest {
pub fn new(
brand_id: impl Into<String>,
use_case: impl Into<String>,
description: impl Into<String>,
message_flow: impl Into<String>,
sample_messages: Vec<String>,
) -> Self {
Self {
brand_id: brand_id.into(),
use_case: use_case.into(),
description: description.into(),
message_flow: message_flow.into(),
sample_messages,
sub_use_cases: None,
opt_in_keywords: None,
opt_out_keywords: None,
help_keywords: None,
opt_in_message: None,
opt_out_message: None,
help_message: None,
embedded_link: None,
embedded_phone: None,
}
}
pub fn sub_use_cases(mut self, sub_use_cases: Vec<String>) -> Self {
self.sub_use_cases = Some(sub_use_cases);
self
}
pub fn opt_in_keywords(mut self, opt_in_keywords: impl Into<String>) -> Self {
self.opt_in_keywords = Some(opt_in_keywords.into());
self
}
pub fn opt_out_keywords(mut self, opt_out_keywords: impl Into<String>) -> Self {
self.opt_out_keywords = Some(opt_out_keywords.into());
self
}
pub fn help_keywords(mut self, help_keywords: impl Into<String>) -> Self {
self.help_keywords = Some(help_keywords.into());
self
}
pub fn opt_in_message(mut self, opt_in_message: impl Into<String>) -> Self {
self.opt_in_message = Some(opt_in_message.into());
self
}
pub fn opt_out_message(mut self, opt_out_message: impl Into<String>) -> Self {
self.opt_out_message = Some(opt_out_message.into());
self
}
pub fn help_message(mut self, help_message: impl Into<String>) -> Self {
self.help_message = Some(help_message.into());
self
}
pub fn embedded_link(mut self, embedded_link: bool) -> Self {
self.embedded_link = Some(embedded_link);
self
}
pub fn embedded_phone(mut self, embedded_phone: bool) -> Self {
self.embedded_phone = Some(embedded_phone);
self
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct TenDlcAssignment {
pub id: String,
#[serde(alias = "campaignId")]
pub campaign_id: String,
#[serde(alias = "phoneNumber")]
pub phone_number: String,
pub status: String,
#[serde(default, alias = "assignedAt")]
pub assigned_at: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TenDlcAssignmentResponse {
pub data: TenDlcAssignment,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TenDlcAssignmentListResponse {
#[serde(default)]
pub data: Vec<TenDlcAssignment>,
}
pub struct TenDlcResource<'a> {
client: &'a Sendly,
}
impl<'a> TenDlcResource<'a> {
pub(crate) fn new(client: &'a Sendly) -> Self {
Self { client }
}
pub async fn list_brands(&self) -> Result<TenDlcBrandListResponse> {
let response = self.client.get("/tendlc/brands", &[]).await?;
Ok(response.json().await?)
}
pub async fn create_brand(
&self,
request: CreateTenDlcBrandRequest,
) -> Result<TenDlcBrandResponse> {
let response = self.client.post("/tendlc/brands", &request).await?;
Ok(response.json().await?)
}
pub async fn get_brand(&self, id: &str) -> Result<TenDlcBrandResponse> {
let response = self
.client
.get(&format!("/tendlc/brands/{}", id), &[])
.await?;
Ok(response.json().await?)
}
pub async fn qualify(&self, brand_id: &str, use_case: &str) -> Result<TenDlcQualifyResponse> {
let response = self
.client
.get(
&format!("/tendlc/brands/{}/qualify/{}", brand_id, use_case),
&[],
)
.await?;
Ok(response.json().await?)
}
pub async fn list_campaigns(&self) -> Result<TenDlcCampaignListResponse> {
let response = self.client.get("/tendlc/campaigns", &[]).await?;
Ok(response.json().await?)
}
pub async fn create_campaign(
&self,
request: CreateTenDlcCampaignRequest,
) -> Result<TenDlcCampaignResponse> {
let response = self.client.post("/tendlc/campaigns", &request).await?;
Ok(response.json().await?)
}
pub async fn get_campaign(&self, id: &str) -> Result<TenDlcCampaignResponse> {
let response = self
.client
.get(&format!("/tendlc/campaigns/{}", id), &[])
.await?;
Ok(response.json().await?)
}
pub async fn assign_number(
&self,
campaign_id: &str,
phone_number: &str,
) -> Result<TenDlcAssignmentResponse> {
let response = self
.client
.post(
&format!("/tendlc/campaigns/{}/assign", campaign_id),
&serde_json::json!({ "phoneNumber": phone_number }),
)
.await?;
Ok(response.json().await?)
}
pub async fn list_assignments(&self) -> Result<TenDlcAssignmentListResponse> {
let response = self.client.get("/tendlc/assignments", &[]).await?;
Ok(response.json().await?)
}
}