sms_client/http/types.rs
1//! HTTP interface related request/response types.
2
3use serde::{Serialize, Deserialize};
4
5/// HTTP pagination options allow for lazy reading of large sets of data,
6/// for example if thousands of messages have been sent and received from
7/// a phone number it would be impractical to request all of them at the
8/// same time, instead it can be read in shorter pages using limit+offset.
9/// This is applied at the server level when requesting data from database.
10#[derive(Serialize, PartialEq, Default, Debug, Clone, Copy)]
11pub struct HttpPaginationOptions {
12
13 /// The maximum amount of return values.
14 #[serde(skip_serializing_if = "Option::is_none")]
15 pub limit: Option<u64>,
16
17 /// The offset in index to start getting values from.
18 /// Eg, if the limit was 5, and you want to view page 2,
19 /// the offset would be 5, then 10, 15, ...
20 #[serde(skip_serializing_if = "Option::is_none")]
21 pub offset: Option<u64>,
22
23 /// Should return values be reversed? This is useful for getting the
24 /// first results from a large set without having to know it's size.
25 #[serde(skip_serializing_if = "Option::is_none")]
26 pub reverse: Option<bool>
27}
28impl HttpPaginationOptions {
29
30 /// Set the limit/page size.
31 pub fn with_limit(mut self, limit: u64) -> Self {
32 self.limit = Some(limit);
33 self
34 }
35
36 /// Set request position offset.
37 pub fn with_offset(mut self, offset: u64) -> Self {
38 self.offset = Some(offset);
39 self
40 }
41
42 /// Set the reverse state for options.
43 pub fn with_reverse(mut self, reverse: bool) -> Self {
44 self.reverse = Some(reverse);
45 self
46 }
47
48 /// Add pagination options to a json Value.
49 pub fn add_to_body(&self, body: &mut serde_json::Value) {
50 if let Some(limit) = self.limit {
51 body["limit"] = serde_json::json!(limit);
52 }
53 if let Some(offset) = self.offset {
54 body["offset"] = serde_json::json!(offset);
55 }
56 if let Some(reverse) = self.reverse {
57 body["reverse"] = serde_json::json!(reverse);
58 }
59 }
60}
61
62/// The outgoing SMS message to be sent to a target number.
63#[derive(Serialize, PartialEq, Default, Debug, Clone)]
64pub struct HttpOutgoingSmsMessage {
65
66 /// The target phone number, this should be in international format.
67 pub to: String,
68
69 /// The full message content. This will be split into multiple messages
70 /// by the server if required. This also supports Unicode emojis etc.
71 pub content: String,
72
73 /// The relative validity period to use for message sending. This determines
74 /// how long the message should remain waiting while undelivered.
75 /// By default, this is determined by the server (24 hours).
76 #[serde(skip_serializing_if = "Option::is_none")]
77 pub validity_period: Option<u8>,
78
79 /// Should the SMS message be sent as a Silent class? This makes a popup
80 /// show on the users device with the message content if they're logged in.
81 #[serde(skip_serializing_if = "Option::is_none")]
82 pub flash: Option<bool>,
83
84 /// A timeout that should be applied to the entire request.
85 /// If one is not set, the default timeout is used.
86 #[serde(skip_serializing_if = "Option::is_none")]
87 pub timeout: Option<u32>
88}
89impl HttpOutgoingSmsMessage {
90
91 /// Create a new outgoing message with a default validity period and no flash.
92 /// The default validity period is applied by SMS-API, so usually 24 hours.
93 pub fn simple_message(
94 to: impl Into<String>,
95 content: impl Into<String>
96 ) -> Self {
97 Self {
98 to: to.into(),
99 content: content.into(),
100 ..Default::default()
101 }
102 }
103
104 /// Set the message flash state. This will show a popup if the recipient is
105 /// logged-in to their phone, otherwise as a normal text message.
106 pub fn with_flash(mut self, flash: bool) -> Self {
107 self.flash = Some(flash);
108 self
109 }
110
111 /// Set a relative validity period value.
112 pub fn with_validity_period(mut self, period: u8) -> Self {
113 self.validity_period = Some(period);
114 self
115 }
116
117 /// Set a request timeout value.
118 pub fn with_timeout(mut self, timeout: u32) -> Self {
119 self.timeout = Some(timeout);
120 self
121 }
122}
123
124/// Response returned after sending an SMS message.
125#[derive(Deserialize, PartialEq, Debug, Clone, Copy)]
126pub struct HttpSmsSendResponse {
127
128 /// The unique ID assigned to the already sent message.
129 pub message_id: i64,
130
131 /// Reference ID for tracking the message.
132 pub reference_id: u8
133}
134
135/// Delivery report for an already sent SMS message.
136#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, Copy)]
137pub struct HttpSmsDeliveryReport {
138
139 /// Unique identifier for this delivery report.
140 pub report_id: Option<i64>,
141
142 /// Delivery status code from the network.
143 pub status: u8,
144
145 /// Whether this is the final delivery report for the message.
146 pub is_final: bool,
147
148 /// Unix timestamp when this report was created.
149 pub created_at: Option<u32>
150}
151
152/// Network registration status of the modem.
153#[derive(Deserialize, PartialEq, Debug, Clone, Copy)]
154pub struct HttpModemNetworkStatusResponse {
155
156 /// Registration status code (0=not registered, 1=registered home, 5=registered roaming).
157 pub registration: u8,
158
159 /// Network technology in use (e.g., 2G, 3G, 4G).
160 pub technology: u8
161}
162
163/// Signal strength information from the modem.
164#[derive(Deserialize, PartialEq, Debug, Clone, Copy)]
165pub struct HttpModemSignalStrengthResponse {
166
167 /// Received Signal Strength Indicator (0-31, 99=unknown).
168 pub rssi: u8,
169
170 /// Bit Error Rate (0-7, 99=unknown).
171 pub ber: u8
172}
173
174/// Network operator information from the modem.
175#[derive(Deserialize, PartialEq, Debug, Clone)]
176pub struct HttpModemNetworkOperatorResponse {
177
178 /// Operator selection status (0=automatic, 1=manual).
179 pub status: u8,
180
181 /// Format of the operator name (0=long alphanumeric, 1=short alphanumeric, 2=numeric).
182 pub format: u8,
183
184 /// Name or code of the network operator.
185 pub operator: String
186}
187
188/// Battery status information from the modem.
189#[derive(Deserialize, PartialEq, Debug, Clone, Copy)]
190pub struct HttpModemBatteryLevelResponse {
191
192 /// Battery status (0=not charging, 1=charging, 2=no battery).
193 pub status: u8,
194
195 /// Battery charge level percentage (0-100).
196 pub charge: u8,
197
198 /// Battery voltage in volts.
199 pub voltage: f32
200}
201
202/// Combine an outgoing message and send response into a dummy SmsStoredMessage.
203impl From<(HttpOutgoingSmsMessage, HttpSmsSendResponse)> for crate::types::SmsStoredMessage {
204 fn from(value: (HttpOutgoingSmsMessage, HttpSmsSendResponse)) -> crate::types::SmsStoredMessage {
205 crate::types::SmsStoredMessage {
206 message_id: value.1.message_id,
207 phone_number: value.0.to,
208 message_content: value.0.content,
209 message_reference: Some(value.1.reference_id),
210 is_outgoing: true,
211 status: "Unknown".to_string(),
212 created_at: None,
213 completed_at: None
214 }
215 }
216}
217
218/// The raw DeviceInfoResponse with raw values.
219#[derive(Deserialize, PartialEq, Debug, Clone)]
220pub struct HttpSmsDeviceInfoResponse {
221
222 /// SMS API version string, including features.
223 pub version: String,
224
225 /// The phone number associated with the SMS device
226 pub phone_number: Option<String>,
227
228 /// The name of the cellular service provider
229 pub service_provider: Option<String>,
230
231 /// Network operator information as (code1, code2, operator_name)
232 pub network_operator: Option<(u8, u8, String)>,
233
234 /// Current network connection status as (status_code, strength_indicator)
235 pub network_status: Option<(u8, u8)>,
236
237 /// Battery information as (level_percentage, charging_status, voltage)
238 pub battery: Option<(u8, u8, f32)>,
239
240 /// Signal strength information as (strength_level, quality_indicator)
241 pub signal: Option<(u8, u8)>
242}
243
244/// Formatted device info response, with each value packed into a proper optional response.
245#[derive(Deserialize, PartialEq, Debug, Clone)]
246pub struct HttpSmsDeviceInfoData {
247
248 /// SMS API version string, including features.
249 pub version: String,
250
251 /// The phone number associated with the SMS device
252 pub phone_number: Option<String>,
253
254 /// The name of the cellular service provider
255 pub service_provider: Option<String>,
256
257 /// Detailed network operator information and capabilities
258 pub network_operator: Option<HttpModemNetworkOperatorResponse>,
259
260 /// Current network connection status and diagnostics
261 pub network_status: Option<HttpModemNetworkStatusResponse>,
262
263 /// Battery level, charging state, and power metrics
264 pub battery: Option<HttpModemBatteryLevelResponse>,
265
266 /// Signal strength measurements and quality indicators
267 pub signal: Option<HttpModemSignalStrengthResponse>
268}
269impl From<HttpSmsDeviceInfoResponse> for HttpSmsDeviceInfoData {
270 fn from(value: HttpSmsDeviceInfoResponse) -> HttpSmsDeviceInfoData {
271 HttpSmsDeviceInfoData {
272 version: value.version,
273 phone_number: value.phone_number,
274 service_provider: value.service_provider,
275 network_operator: value.network_operator.map(|v|
276 HttpModemNetworkOperatorResponse {
277 status: v.0, format: v.1, operator: v.2
278 }
279 ),
280 network_status: value.network_status.map(|v|
281 HttpModemNetworkStatusResponse {
282 registration: v.0, technology: v.1
283 }
284 ),
285 battery: value.battery.map(|v|
286 HttpModemBatteryLevelResponse {
287 status: v.0, charge: v.1, voltage: v.2
288 }
289 ),
290 signal: value.signal.map(|v|
291 HttpModemSignalStrengthResponse {
292 rssi: v.0, ber: v.1
293 }
294 ),
295 }
296 }
297}
298
299/// Used in latest-numbers return value, as a number and friendly name.
300pub type LatestNumberFriendlyNamePair = (String, Option<String>);