/*
* Zernio API
*
* API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api Versioning and deprecation: all endpoints are versioned in the URL path (current version: /v1). Breaking changes only ship in a new path version; existing versions keep working. Deprecated operations are marked 'deprecated: true' in this spec and announced in the changelog (https://zernio.com/changelog) before removal. Errors: every 4xx/5xx response is application/json with a machine-readable 'code' and a human-readable 'error' message (see the ErrorResponse schema).
*
* The version of the OpenAPI document: 1.16.0
* Contact: support@zernio.com
* Generated by: https://openapi-generator.tech
*/
use super::{configuration, ContentType, Error};
use crate::{apis::ResponseContent, models};
use reqwest;
use serde::{de::Error as _, Deserialize, Serialize};
use tokio::fs::File as TokioFile;
use tokio_util::codec::{BytesCodec, FramedRead};
/// struct for typed errors of method [`appeal_sms_registration`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum AppealSmsRegistrationError {
Status400(),
Status401(models::InlineObject1),
Status404(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`create_sms_sender_id`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum CreateSmsSenderIdError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
Status402(),
Status403(),
Status409(),
Status422(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`deactivate_sms_registration`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum DeactivateSmsRegistrationError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
Status404(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`delete_sms_sender_id`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum DeleteSmsSenderIdError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
Status404(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`disable_sms_on_number`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum DisableSmsOnNumberError {
Status401(models::InlineObject1),
Status404(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`enable_sms_on_number`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum EnableSmsOnNumberError {
Status401(models::InlineObject1),
Status404(),
Status422(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_sms_registration`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetSmsRegistrationError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
Status404(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`list_sms_opt_outs`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ListSmsOptOutsError {
Status401(models::InlineObject1),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`list_sms_registrations`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ListSmsRegistrationsError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`list_sms_sender_ids`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ListSmsSenderIdsError {
Status401(models::InlineObject1),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`lookup_sms_number`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum LookupSmsNumberError {
Status401(models::InlineObject1),
Status502(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`preflight_sms_registration`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum PreflightSmsRegistrationError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`request_sms_sender_id_limit_increase`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum RequestSmsSenderIdLimitIncreaseError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
Status409(),
Status503(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`resend_sms_registration_otp`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ResendSmsRegistrationOtpError {
Status400(),
Status401(models::InlineObject1),
Status404(),
Status429(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`respond_to_sms_registration_review`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum RespondToSmsRegistrationReviewError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
Status404(),
Status409(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`reuse_sms_registration_for_number`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ReuseSmsRegistrationForNumberError {
Status401(models::InlineObject1),
Status404(),
Status409(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`send_sms`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum SendSmsError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
Status404(),
Status409(),
Status422(),
Status502(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`share_sms_registration`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ShareSmsRegistrationError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
Status404(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`start_sms_registration`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum StartSmsRegistrationError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
Status422(),
Status409(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`upload_sms_opt_in_proof`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UploadSmsOptInProofError {
Status401(models::InlineObject1),
Status404(),
Status422(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`upload_sms_opt_in_proof_file`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UploadSmsOptInProofFileError {
Status401(models::InlineObject1),
Status422(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`verify_sms_registration_otp`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum VerifySmsRegistrationOtpError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
Status404(),
UnknownValue(serde_json::Value),
}
/// Appeals a rejected 10DLC campaign with the carrier registry. Only a registration that reached campaign creation can be appealed; a brand-level rejection should be fixed and re-verified instead. On success the registration returns to `pending`. Content rejections (e.g. an opt-in flow without a verifiable form link, or unrealistic samples) should be FIXED in the same call: pass the corrected `messageFlow` / `sample1` / `sample2` and the campaign is updated before the appeal is filed, so the reviewer sees the new content. The current content is on `GET /v1/sms/registrations/{id}` (`campaignContent`).
pub async fn appeal_sms_registration(
configuration: &configuration::Configuration,
id: &str,
appeal_sms_registration_request: models::AppealSmsRegistrationRequest,
) -> Result<models::AppealSmsRegistration200Response, Error<AppealSmsRegistrationError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_id = id;
let p_body_appeal_sms_registration_request = appeal_sms_registration_request;
let uri_str = format!(
"{}/v1/sms/registrations/{id}/appeal",
configuration.base_path,
id = crate::apis::urlencode(p_path_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_appeal_sms_registration_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::AppealSmsRegistration200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::AppealSmsRegistration200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<AppealSmsRegistrationError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Registers an alphanumeric sender ID (e.g. `ZERNIO`), a branded `from` for one-way international SMS. No phone number purchase or carrier registration is needed; once created, pass it as `from` on `POST /v1/sms/messages`. Constraints: 3-11 characters (letters, digits, spaces; at least one letter). Sends cannot reach the US, Canada, or Puerto Rico, are text-only, and recipients cannot reply. Sender IDs that impersonate well-known brands or institutions are rejected. Names are not exclusive: the same sender ID can be registered by any number of teams. Creating the same sender ID again is a no-op (re-activates it after a delete).
pub async fn create_sms_sender_id(
configuration: &configuration::Configuration,
create_sms_sender_id_request: models::CreateSmsSenderIdRequest,
) -> Result<models::CreateSmsSenderId200Response, Error<CreateSmsSenderIdError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_create_sms_sender_id_request = create_sms_sender_id_request;
let uri_str = format!("{}/v1/sms/sender-ids", configuration.base_path);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_create_sms_sender_id_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::CreateSmsSenderId200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::CreateSmsSenderId200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<CreateSmsSenderIdError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Terminates the campaign with the carrier registry so the recurring monthly campaign fee stops (carriers bill the first 3 months of a campaign regardless). Numbers covered by it can no longer SEND texts (receiving is unaffected) until they're registered under a new brand. Irreversible: a deactivated campaign cannot be restored; texting again later requires a new registration (new one-time and review fees). Idempotent.
pub async fn deactivate_sms_registration(
configuration: &configuration::Configuration,
id: &str,
) -> Result<models::DeactivateSmsRegistration200Response, Error<DeactivateSmsRegistrationError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_id = id;
let uri_str = format!(
"{}/v1/sms/registrations/{id}",
configuration.base_path,
id = crate::apis::urlencode(p_path_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::DELETE, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::DeactivateSmsRegistration200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::DeactivateSmsRegistration200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<DeactivateSmsRegistrationError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Deactivates the sender ID so it can no longer send. Re-creating the same sender ID via `POST /v1/sms/sender-ids` re-activates it.
pub async fn delete_sms_sender_id(
configuration: &configuration::Configuration,
id: &str,
) -> Result<models::DeleteSmsSenderId200Response, Error<DeleteSmsSenderIdError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_id = id;
let uri_str = format!(
"{}/v1/sms/sender-ids/{id}",
configuration.base_path,
id = crate::apis::urlencode(p_path_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::DELETE, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::DeleteSmsSenderId200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::DeleteSmsSenderId200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<DeleteSmsSenderIdError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Turns off SMS for the number (deactivates its SMS account). The carrier registration is untouched, so re-enabling later reactivates it, with no re-registration.
pub async fn disable_sms_on_number(
configuration: &configuration::Configuration,
id: &str,
) -> Result<models::DisableSmsOnNumber200Response, Error<DisableSmsOnNumberError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_id = id;
let uri_str = format!(
"{}/v1/phone-numbers/{id}/sms",
configuration.base_path,
id = crate::apis::urlencode(p_path_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::DELETE, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::DisableSmsOnNumber200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::DisableSmsOnNumber200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<DisableSmsOnNumberError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Turns on SMS for one of your numbers. The number's real carrier capability is checked first: some number types can't do SMS at all (`smsCapable: false`), and a number still provisioning at the carrier returns `notReady: true` (try again once provisioning finishes). US numbers additionally need a carrier registration before messages deliver; the response tells you which path applies: - `alreadyRegistered: true`: a prior registration still covers this number; SMS was reactivated. - `reusable` set: you have an approved registration this number can join in one click via `POST /v1/phone-numbers/{id}/sms/reuse-registration` (no new brand/campaign, no extra carrier fee). - `needsRegistration: true` and no `reusable`: start one via `POST /v1/sms/registrations`. Idempotent: re-running re-attempts any carrier-side setup that failed.
pub async fn enable_sms_on_number(
configuration: &configuration::Configuration,
id: &str,
) -> Result<models::EnableSmsOnNumber200Response, Error<EnableSmsOnNumberError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_id = id;
let uri_str = format!(
"{}/v1/phone-numbers/{id}/sms",
configuration.base_path,
id = crate::apis::urlencode(p_path_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::EnableSmsOnNumber200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::EnableSmsOnNumber200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<EnableSmsOnNumberError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Poll this for approval progress after starting a registration.
pub async fn get_sms_registration(
configuration: &configuration::Configuration,
id: &str,
) -> Result<models::GetSmsRegistration200Response, Error<GetSmsRegistrationError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_id = id;
let uri_str = format!(
"{}/v1/sms/registrations/{id}",
configuration.base_path,
id = crate::apis::urlencode(p_path_id)
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GetSmsRegistration200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetSmsRegistration200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetSmsRegistrationError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// The recipients who opted out of SMS (replied STOP) across your numbers, most recent first. Compliance surface: you must be able to see and export your opt-out list. Read-only: a recipient is re-subscribed only by replying START. Pass `format=csv` to download a CSV instead of JSON.
pub async fn list_sms_opt_outs(
configuration: &configuration::Configuration,
format: Option<&str>,
limit: Option<i32>,
) -> Result<models::ListSmsOptOuts200Response, Error<ListSmsOptOutsError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_query_format = format;
let p_query_limit = limit;
let uri_str = format!("{}/v1/sms/opt-outs", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref param_value) = p_query_format {
req_builder = req_builder.query(&[("format", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_limit {
req_builder = req_builder.query(&[("limit", ¶m_value.to_string())]);
}
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ListSmsOptOuts200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ListSmsOptOuts200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<ListSmsOptOutsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
pub async fn list_sms_registrations(
configuration: &configuration::Configuration,
include_deactivated: Option<bool>,
) -> Result<models::ListSmsRegistrations200Response, Error<ListSmsRegistrationsError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_query_include_deactivated = include_deactivated;
let uri_str = format!("{}/v1/sms/registrations", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref param_value) = p_query_include_deactivated {
req_builder = req_builder.query(&[("includeDeactivated", ¶m_value.to_string())]);
}
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ListSmsRegistrations200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ListSmsRegistrations200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<ListSmsRegistrationsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
pub async fn list_sms_sender_ids(
configuration: &configuration::Configuration,
) -> Result<models::ListSmsSenderIds200Response, Error<ListSmsSenderIdsError>> {
let uri_str = format!("{}/v1/sms/sender-ids", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ListSmsSenderIds200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ListSmsSenderIds200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<ListSmsSenderIdsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Carrier name and line type (mobile / landline / voip / toll-free) for a number, plus `smsReachable` (landlines can't receive SMS). Use it to validate recipients before sending. Each lookup is billed by the carrier-data provider, so call it explicitly (e.g. pre-validating an opt-in list), not on every send.
pub async fn lookup_sms_number(
configuration: &configuration::Configuration,
number: &str,
) -> Result<models::LookupSmsNumber200Response, Error<LookupSmsNumberError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_query_number = number;
let uri_str = format!("{}/v1/sms/lookup", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
req_builder = req_builder.query(&[("number", &p_query_number.to_string())]);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::LookupSmsNumber200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::LookupSmsNumber200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<LookupSmsNumberError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Dry-run of `POST /v1/sms/registrations` for 10DLC: validates and composes the exact brand/campaign payloads a submission would store (branding, disclosures, auto-replies), runs deterministic compliance lints plus an AI reviewer over them, and returns the findings WITHOUT creating anything. Use it to fix issues before submitting; `block` severity findings indicate a near-certain carrier rejection.
pub async fn preflight_sms_registration(
configuration: &configuration::Configuration,
preflight_sms_registration_request: models::PreflightSmsRegistrationRequest,
) -> Result<models::PreflightSmsRegistration200Response, Error<PreflightSmsRegistrationError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_preflight_sms_registration_request = preflight_sms_registration_request;
let uri_str = format!("{}/v1/sms/registrations/preflight", configuration.base_path);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_preflight_sms_registration_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::PreflightSmsRegistration200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::PreflightSmsRegistration200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<PreflightSmsRegistrationError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Asks support to raise the team's daily sender-ID message cap. There is no self-serve raise: the request (desired cap + use case) is reviewed manually, usually within a business day.
pub async fn request_sms_sender_id_limit_increase(
configuration: &configuration::Configuration,
request_sms_sender_id_limit_increase_request: models::RequestSmsSenderIdLimitIncreaseRequest,
) -> Result<
models::RequestSmsSenderIdLimitIncrease200Response,
Error<RequestSmsSenderIdLimitIncreaseError>,
> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_request_sms_sender_id_limit_increase_request =
request_sms_sender_id_limit_increase_request;
let uri_str = format!(
"{}/v1/sms/sender-ids/limit-request",
configuration.base_path
);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_request_sms_sender_id_limit_increase_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::RequestSmsSenderIdLimitIncrease200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::RequestSmsSenderIdLimitIncrease200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<RequestSmsSenderIdLimitIncreaseError> =
serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Re-sends the sole-proprietor verification PIN to the brand's mobile number. Use it when the original code expired or never arrived. Only valid while the registration is pending and awaiting its OTP; rate limited to one send per minute.
pub async fn resend_sms_registration_otp(
configuration: &configuration::Configuration,
id: &str,
) -> Result<models::ResendSmsRegistrationOtp200Response, Error<ResendSmsRegistrationOtpError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_id = id;
let uri_str = format!(
"{}/v1/sms/registrations/{id}/resend-otp",
configuration.base_path,
id = crate::apis::urlencode(p_path_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ResendSmsRegistrationOtp200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ResendSmsRegistrationOtp200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<ResendSmsRegistrationOtpError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Replies to a reviewer change request on a registration in `changes_requested` state: a note, hosted document URLs (from `POST /v1/sms/opt-in-proof`), or both, sent together. The registration returns to `requested` (back in review), and you do not need to resubmit the whole registration. To change the submitted brand/campaign fields themselves, resubmit via `POST /v1/sms/registrations` with `resubmitRequestId` instead.
pub async fn respond_to_sms_registration_review(
configuration: &configuration::Configuration,
id: &str,
respond_to_sms_registration_review_request: models::RespondToSmsRegistrationReviewRequest,
) -> Result<
models::RespondToSmsRegistrationReview200Response,
Error<RespondToSmsRegistrationReviewError>,
> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_id = id;
let p_body_respond_to_sms_registration_review_request =
respond_to_sms_registration_review_request;
let uri_str = format!(
"{}/v1/sms/registrations/{id}/respond",
configuration.base_path,
id = crate::apis::urlencode(p_path_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_respond_to_sms_registration_review_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::RespondToSmsRegistrationReview200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::RespondToSmsRegistrationReview200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<RespondToSmsRegistrationReviewError> =
serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Attaches this number to your existing approved 10DLC campaign instead of running a fresh registration: the number inherits the campaign's approval (no new brand or campaign, no extra carrier fee). Enable SMS on the number first (`POST /v1/phone-numbers/{id}/sms`; its response tells you whether a reusable registration exists).
pub async fn reuse_sms_registration_for_number(
configuration: &configuration::Configuration,
id: &str,
) -> Result<
models::ReuseSmsRegistrationForNumber200Response,
Error<ReuseSmsRegistrationForNumberError>,
> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_id = id;
let uri_str = format!(
"{}/v1/phone-numbers/{id}/sms/reuse-registration",
configuration.base_path,
id = crate::apis::urlencode(p_path_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ReuseSmsRegistrationForNumber200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ReuseSmsRegistrationForNumber200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<ReuseSmsRegistrationForNumberError> =
serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Sends an SMS (or MMS when `mediaUrls` is set) from one of your SMS-enabled numbers. At least one of `text` / `mediaUrls` is required. Both numbers are normalized to E.164, so `from` matches regardless of formatting and replies thread into the same inbox conversation. US numbers must have an approved carrier registration (`/v1/sms/registrations`) before messages deliver. **Replies and delivery status arrive as webhooks**, not by polling: an inbound reply fires `message.received` with `platform: \"sms\"`, the first message of a new thread also fires `conversation.started`, and this message's own outcome fires `message.delivered` or `message.failed` (the latter carrying the carrier's error code). **Opted-out recipients:** a send to a number that replied STOP is refused with `409`, never silently dropped. **Idempotency:** send an `Idempotency-Key` header to make retries safe: same key + same body replays the original response instead of sending a second message; same key + different body returns 422; a key still in flight returns 409.
pub async fn send_sms(
configuration: &configuration::Configuration,
send_sms_request: models::SendSmsRequest,
idempotency_key: Option<&str>,
) -> Result<models::SendSms200Response, Error<SendSmsError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_send_sms_request = send_sms_request;
let p_header_idempotency_key = idempotency_key;
let uri_str = format!("{}/v1/sms/messages", configuration.base_path);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(param_value) = p_header_idempotency_key {
req_builder = req_builder.header("Idempotency-Key", param_value.to_string());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_send_sms_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::SendSms200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::SendSms200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<SendSmsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Creates a single-use, expiring link (valid 7 days) that lets someone else (whoever has the legal business details) fill in the carrier registration form for one of your numbers, without a Zernio login. The registration is created under your account once the form is submitted.
pub async fn share_sms_registration(
configuration: &configuration::Configuration,
share_sms_registration_request: models::ShareSmsRegistrationRequest,
) -> Result<models::ShareSmsRegistration200Response, Error<ShareSmsRegistrationError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_share_sms_registration_request = share_sms_registration_request;
let uri_str = format!("{}/v1/sms/registrations/share", configuration.base_path);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_share_sms_registration_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ShareSmsRegistration200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ShareSmsRegistration200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<ShareSmsRegistrationError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Starts the US carrier registration that a number needs before SMS delivers: 10DLC (standard company or sole-proprietor) or toll-free verification. 10DLC needs `brand` + `campaign`; toll-free needs `tollFree`. Approval is asynchronous; poll `GET /v1/sms/registrations/{id}` (sole-prop registrations first need the OTP step: a code is texted to the brand's mobile number, submit it via `/verify-otp`). Already have an approved registration? Add another number to it with `POST /v1/phone-numbers/{id}/sms/reuse-registration` instead of registering (and paying the carrier brand fee) again. Rather have your client fill in the legal business details? Create a share link with `POST /v1/sms/registrations/share`.
pub async fn start_sms_registration(
configuration: &configuration::Configuration,
start_sms_registration_request: models::StartSmsRegistrationRequest,
) -> Result<models::StartSmsRegistration200Response, Error<StartSmsRegistrationError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_start_sms_registration_request = start_sms_registration_request;
let uri_str = format!("{}/v1/sms/registrations", configuration.base_path);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_start_sms_registration_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::StartSmsRegistration200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::StartSmsRegistration200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<StartSmsRegistrationError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Hosts a screenshot (or PDF) of your SMS opt-in form and returns its public URL. Carrier reviewers reject campaigns whose consent can't be verified and ask for a \"link/screenshot of the opt-in form\". The registry has no attachment field, so include the returned URL inside the `messageFlow` you submit with the appeal (`POST /v1/sms/registrations/{id}/appeal`).
pub async fn upload_sms_opt_in_proof(
configuration: &configuration::Configuration,
id: &str,
file: std::path::PathBuf,
) -> Result<models::UploadSmsOptInProofFile200Response, Error<UploadSmsOptInProofError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_id = id;
let p_form_file = file;
let uri_str = format!(
"{}/v1/sms/registrations/{id}/opt-in-proof",
configuration.base_path,
id = crate::apis::urlencode(p_path_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let mut multipart_form = reqwest::multipart::Form::new();
let file = TokioFile::open(&p_form_file).await?;
let stream = FramedRead::new(file, BytesCodec::new());
let file_name = p_form_file
.file_name()
.map(|n| n.to_string_lossy().to_string())
.unwrap_or_default();
let file_part =
reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name);
multipart_form = multipart_form.part("file", file_part);
req_builder = req_builder.multipart(multipart_form);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UploadSmsOptInProofFile200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UploadSmsOptInProofFile200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<UploadSmsOptInProofError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Hosts a screenshot (or PDF) of your SMS opt-in form and returns its public URL. Include that URL in the campaign's `messageFlow` (the opt-in workflow text). The carrier registry has no attachment field, so reviewers verify consent by opening links in that answer. Works before a registration exists (use it when registering) and for appeals. `/v1/sms/registrations/{id}/opt-in-proof` is an alias.
pub async fn upload_sms_opt_in_proof_file(
configuration: &configuration::Configuration,
file: std::path::PathBuf,
) -> Result<models::UploadSmsOptInProofFile200Response, Error<UploadSmsOptInProofFileError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_form_file = file;
let uri_str = format!("{}/v1/sms/opt-in-proof", configuration.base_path);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let mut multipart_form = reqwest::multipart::Form::new();
let file = TokioFile::open(&p_form_file).await?;
let stream = FramedRead::new(file, BytesCodec::new());
let file_name = p_form_file
.file_name()
.map(|n| n.to_string_lossy().to_string())
.unwrap_or_default();
let file_part =
reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name);
multipart_form = multipart_form.part("file", file_part);
req_builder = req_builder.multipart(multipart_form);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UploadSmsOptInProofFile200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UploadSmsOptInProofFile200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<UploadSmsOptInProofFileError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Completes sole-proprietor 10DLC brand verification by submitting the one-time PIN texted to the brand's mobile number. On success the registration continues to campaign creation automatically.
pub async fn verify_sms_registration_otp(
configuration: &configuration::Configuration,
id: &str,
verify_sms_registration_otp_request: models::VerifySmsRegistrationOtpRequest,
) -> Result<models::VerifySmsRegistrationOtp200Response, Error<VerifySmsRegistrationOtpError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_id = id;
let p_body_verify_sms_registration_otp_request = verify_sms_registration_otp_request;
let uri_str = format!(
"{}/v1/sms/registrations/{id}/verify-otp",
configuration.base_path,
id = crate::apis::urlencode(p_path_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_verify_sms_registration_otp_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::VerifySmsRegistrationOtp200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::VerifySmsRegistrationOtp200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<VerifySmsRegistrationOtpError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}