clickatell_api/one_api/
client.rs1use crate::one_api::{balance, message_status, send_messages};
2use crate::one_api::{error::Error, result::Result};
3use reqwest::{
4 header::HeaderMap, header::HeaderValue, header::ACCEPT, header::AUTHORIZATION,
5 header::CONTENT_TYPE, Client as HTTPClient,
6};
7use std::default::Default;
8
9pub const HOSTNAME: &str = "https://platform.clickatell.com";
10const MESSAGE_PATH: &str = "/v1/message";
11const BALANCE_PATH: &str = "/v1/balance";
12const APPLICATION_JSON: &str = "application/json";
13
14pub struct Client {
16 hostname: String,
17 http_client: HTTPClient,
18}
19
20impl Client {
21 pub fn new(api_key: &str) -> Result<Self> {
22 Self::builder().api_key(api_key).build()
23 }
24
25 pub fn builder() -> ClientBuilder {
26 ClientBuilder::default()
27 }
28
29 pub async fn send_messages(
46 &self,
47 send_messages_request: send_messages::Request,
48 ) -> Result<send_messages::Response> {
49 if send_messages_request.message_count() >= 100 {
50 return Err(Error::TooManyMessages);
51 }
52
53 let response = self
54 .http_client
55 .post(format!("{}{MESSAGE_PATH}", self.hostname))
56 .json(&send_messages_request)
57 .send()
58 .await?;
59
60 Ok(response.json::<send_messages::Response>().await?)
61 }
62
63 pub async fn message_status(
71 &self,
72 request: message_status::Request,
73 ) -> Result<message_status::Response> {
74 let response = self
75 .http_client
76 .get(format!("{}{MESSAGE_PATH}/{}", self.hostname, request))
77 .send()
78 .await?;
79
80 Ok(response.json::<message_status::Response>().await?)
81 }
82
83 pub async fn balance(&self) -> Result<balance::Response> {
90 let response = self
91 .http_client
92 .get(format!("{}{BALANCE_PATH}", self.hostname))
93 .send()
94 .await?;
95
96 Ok(response.json::<balance::Response>().await?)
97 }
98}
99
100pub struct ClientBuilder {
103 hostname: Option<String>,
104 api_key: Option<String>,
105}
106
107impl Default for ClientBuilder {
108 fn default() -> Self {
109 ClientBuilder {
110 hostname: Some(HOSTNAME.to_string()),
111 api_key: None,
112 }
113 }
114}
115
116impl ClientBuilder {
117 pub fn api_key(mut self, api_key: &str) -> Self {
118 self.api_key = Some(api_key.to_string());
119 self
120 }
121
122 pub fn hostname(mut self, hostname: &str) -> Self {
123 self.hostname = Some(hostname.to_string());
124 self
125 }
126
127 pub fn build(self) -> Result<Client> {
128 match (self.api_key, self.hostname) {
129 (Some(api_key), Some(hostname)) => {
130 let mut headers = HeaderMap::new();
131
132 let mut auth_value = HeaderValue::from_str(&api_key)?;
133 auth_value.set_sensitive(true);
134
135 headers.insert(AUTHORIZATION, auth_value);
136 headers.insert(CONTENT_TYPE, HeaderValue::from_str(APPLICATION_JSON)?);
137 headers.insert(ACCEPT, HeaderValue::from_str(APPLICATION_JSON)?);
138
139 let http_client = HTTPClient::builder().default_headers(headers).build()?;
140
141 Ok(Client {
142 hostname,
143 http_client,
144 })
145 }
146 (None, _) => Err(Error::ApiKeyNotSet),
147 (Some(_), None) => Err(Error::HostnameNotSet),
148 }
149 }
150}