1use crate::core::*;
2use crate::device::{Connector, Device};
3use crate::utils::*;
4use phonenumber::country;
5use phonenumber::country::Id;
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9
10
11#[derive(Serialize, Deserialize, Clone)]
12#[serde(rename_all = "camelCase")]
13pub struct RecordReference {
14 id: String,
15 name: String,
16}
17
18#[derive(Serialize, Deserialize, Clone)]
19#[serde(rename_all = "camelCase")]
20pub struct AccountLite {
21 pub id: String,
22 pub name: String,
23 pub mbn: String,
24 pub domain: String,
25 pub created: Option<String>,
26 pub organisation: RecordReference,
27 #[serde(default)]
28 pub ddis: Vec<DDI>,
29 #[serde(default)]
30 pub trunks: Vec<Trunk>,
31 #[serde(rename = "callbackURLS")]
32 pub hooks: Vec<Hook>,
33 #[serde(default)]
34 pub devices: Vec<Device>,
35 #[serde(default)]
36 pub environment: Environment,
37}
38
39impl AccountLite {
40 pub fn country_code(&self) -> &str {
41 self.environment.country_code.as_str()
42 }
43
44 pub fn country_code_parsed(&self) -> Id {
45 self.environment.country_code_parsed()
46 }
47
48 pub fn inbound_flow(&self, str: &str) -> Option<Device> {
49 match self.ddi(str) {
50 Some(ddi) => self.device(&ddi.id),
51 None => None,
52 }
53 }
54
55 pub fn outbound_flow(&self) -> Option<Device> {
56 self.devices
57 .iter()
58 .find(|d| d.match_outbound_flow())
59 .map(|d| d.clone())
60 }
61
62 pub fn device(&self, id: &str) -> Option<Device> {
63 self.devices
64 .iter()
65 .find(|d| d.match_device(id))
66 .map(|d| d.clone())
67 }
68
69 pub fn ddi(&self, str: &str) -> Option<DDI> {
70 let id = self.clean_str(str);
71 self.ddis
72 .iter()
73 .find(|ddi| ddi.id == id || ddi.name == id)
74 .map(|ddi| ddi.clone())
75 }
76
77 pub fn traverse(&self, state: &mut FlowState) -> Vec<FlowState> {
78 let mut states: Vec<FlowState> = Vec::new();
79 while state.device.is_some() {
80 match &state.device {
81 Some(d) => {
82 let nd = d.clone().get_connect_to(state);
83 states.push(nd);
84 }
85 None => {
86 }
88 }
89 }
90 states
91 }
92
93 pub fn clean_str(&self, str: &str) -> String {
94 clean_str(self.environment.country_code_parsed(), str)
95 }
96}
97
98#[derive(Serialize, Deserialize, Clone)]
99#[serde(rename_all = "camelCase")]
100pub struct Account {
101 pub id: String,
102 pub name: String,
103 pub mbn: String,
104 pub domain: String,
105 pub created: Option<String>,
107 pub organisation: RecordReference,
108 #[serde(default)]
109 pub ddis: Vec<DDI>,
110 #[serde(default)]
111 pub trunks: Vec<Trunk>,
112 #[serde(default)]
113 #[serde(rename = "callbackURLS")]
114 pub hooks: Vec<Hook>,
115 #[serde(default)]
116 pub devices: Vec<Device>,
117 #[serde(default)]
118 pub settings: Vec<Setting>,
119 #[serde(default)]
120 pub assets: Vec<Asset>,
121 #[serde(default)]
122 pub address: Address,
123 #[serde(default)]
124 pub teams: TeamsAccount,
125 #[serde(default)]
126 pub environment: Environment,
127 #[serde(default)]
128 pub spend_cap: SpendCap,
129 pub concurrency: Concurrency,
130 #[serde(default)]
131 pub class_of_service: ClassOfService,
132 #[serde(default)]
133 pub api_keys: APIKeys,
134 pub cluster_settings: Cluster,
135 pub domain_settings: Domain,
136}
137
138#[derive(Serialize, Deserialize, Clone)]
139#[serde(rename_all = "camelCase")]
140pub struct Cluster {
141 id: String,
142 name: String,
143 router: RecordReference,
144}
145
146#[derive(Serialize, Deserialize, Clone)]
147#[serde(rename_all = "camelCase")]
148pub struct Domain {
149 #[serde(rename = "serverA")]
150 server_a: String,
151 #[serde(rename = "serverB")]
152 server_b: String,
153}
154
155#[derive(Serialize, Deserialize, Clone)]
156#[serde(rename_all = "camelCase")]
157pub struct APIKeys {
158 #[serde(default)]
159 keys: Vec<APIKey>,
160}
161
162impl Default for APIKeys {
163 fn default() -> Self {
164 Self { keys: Vec::new() }
165 }
166}
167
168#[derive(Serialize, Deserialize, Clone)]
169#[serde(rename_all = "camelCase")]
170pub struct APIKey {
171 key: String,
172}
173
174#[derive(Serialize, Deserialize, Clone)]
175#[serde(rename_all = "camelCase")]
176pub struct Environment {
177 #[serde(default = "build_logger")]
178 pub logger: LoggerLevel,
179 #[serde(rename = "dialTimeLimit")]
180 #[serde(default = "build_call_time")]
181 pub max_call_time: u16,
182 #[serde(rename = "dialTimeout")]
183 #[serde(default = "build_ring_time")]
184 pub ring_time: u8,
185 #[serde(default = "build_tts_vendor")]
186 pub tts_vendor: String,
187 #[serde(default = "build_tts_language")]
188 #[serde(rename = "ttsLanguageV2")]
189 pub tts_language: String,
190 #[serde(default = "build_tts_voice")]
191 pub tts_voice: String,
192 #[serde(default = "build_asr_vendor")]
193 pub asr_vendor: String,
194 #[serde(default = "build_asr_language")]
195 pub asr_language: String,
196 #[serde(default = "build_default_timezone")]
197 pub time_zone: String,
198 #[serde(default = "build_country_code")]
199 pub country_code: String,
200 #[serde(default = "build_record_retention")]
201 pub recording_retention: String,
202 pub ingress_script: Option<String>,
203}
204
205impl Environment {
206 pub fn country_code_parsed(&self) -> Id {
207 self.country_code.parse().unwrap_or_else(|_| country::GB)
208 }
209}
210impl Default for Environment {
211 fn default() -> Self {
212 Self {
213 logger: LoggerLevel::Warn,
214 max_call_time: DEFAULT_CALL_TIME,
215 ring_time: DEFAULT_RING_TIME,
216 tts_vendor: DEFAULT_TTS_VENDOR.to_string(),
217 tts_language: DEFAULT_TTS_LANGUAGE.to_string(),
218 tts_voice: DEFAULT_TTS_VOICE.to_string(),
219 asr_vendor: DEFAULT_ASR_VENDOR.to_string(),
220 asr_language: DEFAULT_ASR_LANGUAGE.to_string(),
221 time_zone: DEFAULT_TIMEZONE.to_string(),
222 country_code: DEFAULT_COUNTRY_CODE.to_string(),
223 recording_retention: DEFAULT_RECORDING_RETENTION.to_string(),
224 ingress_script: None,
225 }
226 }
227}
228
229#[derive(Serialize, Deserialize, Clone)]
230#[serde(rename_all = "camelCase")]
231pub struct SpendCap {
232 #[serde(default = "build_spend_cap_value")]
233 value: u16,
234 #[serde(default = "build_spend_cap_level")]
235 warn: u8,
236 #[serde(default = "build_spend_cap_action")]
237 action: RouteAction,
238 #[serde(default)]
239 email_recipients: Vec<String>,
240}
241
242impl Default for SpendCap {
243 fn default() -> Self {
244 Self {
245 value: 100,
246 warn: 80,
247 action: RouteAction::Warn,
248 email_recipients: Vec::new(),
249 }
250 }
251}
252
253#[derive(Serialize, Deserialize, Clone)]
254#[serde(rename_all = "camelCase")]
255pub struct Concurrency {
256 #[serde(rename = "type")]
257 #[serde(default = "build_license")]
258 license: Licence,
259 #[serde(default = "build_concurrency_action")]
260 action: RouteAction,
261 #[serde(default)]
262 email_recipients: Vec<String>,
263}
264
265#[derive(Serialize, Deserialize, Clone)]
266#[serde(rename_all = "camelCase")]
267pub struct ClassOfService {
268 #[serde(rename = "type")]
269 #[serde(default = "build_cos_action")]
270 license: COSAction,
271 #[serde(default)]
272 countries: Vec<String>,
273 #[serde(default)]
274 prefix_exceptions: String,
275 #[serde(rename = "maxPPM")]
276 #[serde(default = "build_cos_ppm")]
277 max_ppm: f32,
278 #[serde(rename = "maxPPC")]
279 #[serde(default = "build_cos_ppc")]
280 max_ppc: f32,
281}
282
283impl Default for ClassOfService {
284 fn default() -> Self {
285 Self {
286 license: COSAction::Allow,
287 countries: Vec::new(),
288 prefix_exceptions: String::from(""),
289 max_ppc: 10.00,
290 max_ppm: 10.00,
291 }
292 }
293}
294
295#[derive(Serialize, Deserialize, Clone)]
296pub enum LoggerLevel {
297 #[serde(rename = "info")]
298 Info,
299 #[serde(rename = "warn")]
300 Warn,
301 #[serde(rename = "error")]
302 Error,
303}
304
305#[derive(Serialize, Deserialize, Clone)]
306pub enum Licence {
307 #[serde(rename = "standard")]
308 Standard,
309 #[serde(rename = "professional")]
310 Professional,
311 #[serde(rename = "enterprise")]
312 Enterprise,
313}
314
315#[derive(Serialize, Deserialize, Clone)]
316pub enum COSAction {
317 #[serde(rename = "DENY")]
318 Deny,
319 #[serde(rename = "ALLOW")]
320 Allow,
321}
322
323#[derive(Serialize, Deserialize, Clone)]
324pub enum RouteAction {
325 #[serde(rename = "warn")]
326 Warn,
327 #[serde(rename = "restrict")]
328 Restrict,
329 #[serde(rename = "deny")]
330 Deny,
331}
332
333#[derive(Serialize, Deserialize, Clone)]
334#[serde(rename_all = "camelCase")]
335pub struct TeamsAccount {
336 #[serde(rename = "type")]
337 pub domain_type: String,
338 #[serde(default)]
339 pub domain: String,
340 pub txt: Option<String>,
341 #[serde(rename = "serverA")]
342 pub server_a: String,
343 #[serde(rename = "serverB")]
344 pub server_b: String,
345}
346
347impl Default for TeamsAccount {
348 fn default() -> Self {
349 Self {
350 domain_type: String::from("callable"),
351 domain: String::from(""),
352 server_a: String::from(""),
353 server_b: String::from(""),
354 txt: None,
355 }
356 }
357}
358
359#[derive(Serialize, Deserialize, Clone)]
360#[serde(rename_all = "camelCase")]
361pub struct Address {
362 #[serde(default)]
363 pub line1: String,
364 #[serde(default)]
365 pub line2: String,
366 #[serde(default)]
367 pub level1: String,
368 #[serde(default)]
369 pub level2: String,
370 #[serde(default)]
371 pub postal_code: String,
372 #[serde(default)]
373 pub country: String,
374}
375
376impl Default for Address {
377 fn default() -> Self {
378 Self {
379 line1: String::from(""),
380 line2: String::from(""),
381 level1: String::from(""),
382 level2: String::from(""),
383 postal_code: String::from(""),
384 country: String::from(""),
385 }
386 }
387}
388
389#[derive(Serialize, Deserialize, Clone)]
390#[serde(rename_all = "camelCase")]
391pub struct Asset {
392 id: String,
393 bucket: String,
394 key: String,
395 filename: String,
396 name: String,
397 mime_type: String,
398 size: u32,
399 created: String,
400 #[serde(default)]
401 meta: HashMap<String, String>,
402}
403
404#[derive(Serialize, Deserialize, Clone)]
405#[serde(rename_all = "camelCase")]
406pub struct Setting {
407 #[serde(default)]
408 pub id: String,
409 pub key: String,
410 #[serde(rename = "type")]
411 pub setting_type: String,
412 pub value: String,
413}
414
415#[derive(Serialize, Deserialize, Debug, Clone)]
416#[serde(rename_all = "camelCase")]
417pub struct DDI {
418 pub id: String,
419 pub name: String,
420 #[serde(default)]
421 pub meta: HashMap<String, String>,
422}
423
424#[derive(Serialize, Deserialize, Clone)]
425#[serde(rename_all = "camelCase")]
426pub struct Trunk {
427 pub id: String,
428 pub ip: String,
429 #[serde(default = "build_trunk_description")]
430 pub description: String,
431 #[serde(default = "build_trunk_port")]
432 pub port: u16,
433}
434
435#[derive(Serialize, Deserialize, Clone)]
436#[serde(rename_all = "camelCase")]
437pub struct Hook {
438 pub id: String,
439 pub app: String,
440 pub url: String,
441 #[serde(default = "AuthType::default_method")]
442 pub auth_type: AuthType,
443 #[serde(default = "HookMethod::default_method")]
444 pub method: HookMethod,
445 #[serde(default)]
446 pub meta: HashMap<String, String>,
447 #[serde(default)]
448 pub api_key_name: String,
449 #[serde(default)]
450 pub api_key_value: String,
451 #[serde(default)]
452 pub api_secret_name: String,
453 #[serde(default)]
454 pub api_secret_value: String,
455}
456
457#[derive(Serialize, Deserialize, Clone)]
458pub enum HookMethod {
459 #[serde(rename = "POST")]
460 Post,
461 #[serde(rename = "GET")]
462 Get,
463}
464
465#[derive(Serialize, Deserialize, Clone)]
466pub enum QueueItemType {
467 #[serde(rename = "play")]
468 Play,
469 #[serde(rename = "say")]
470 Say,
471 #[serde(rename = "pause")]
472 Pause,
473}
474
475impl HookMethod {
476 fn default_method() -> Self {
477 HookMethod::Post
478 }
479}
480
481#[derive(Serialize, Deserialize, Clone)]
482pub enum AuthType {
483 #[serde(rename = "DISABLED")]
484 Disabled,
485 #[serde(rename = "KEY")]
486 Key,
487 #[serde(rename = "KEY_SECRET")]
488 KeySecret,
489 #[serde(rename = "BASIC_AUTH")]
490 BasicAuth,
491}
492
493impl AuthType {
494 fn default_method() -> Self {
495 AuthType::Disabled
496 }
497}
498
499impl Connector for Device {
500 fn get_connect_to(&mut self, state: &mut FlowState) -> FlowState {
501 match self {
502 Device::InboundFlow(value) => value.get_connect_to(state),
503 Device::OutboundFlow(value) => value.get_connect_to(state),
504 Device::AppFlow(value) => value.get_connect_to(state),
505 Device::WhatsAppFlow(value) => value.get_connect_to(state),
506 Device::AniRouter(value) => value.get_connect_to(state),
507 Device::DnisRouter(value) => value.get_connect_to(state),
508 Device::DigitRouter(value) => value.get_connect_to(state),
509 Device::TimeRangeRouter(value) => value.get_connect_to(state),
510 Device::DayOfWeekRouter(value) => value.get_connect_to(state),
511 Device::DateRangeRouter(value) => value.get_connect_to(state),
512 Device::Play(value) => value.get_connect_to(state),
513 Device::Say(value) => value.get_connect_to(state),
514 Device::Voicemail(value) => value.get_connect_to(state),
515 Device::Script(value) => value.get_connect_to(state),
516 Device::Queue(value) => value.get_connect_to(state),
517 Device::Sms(value) => value.get_connect_to(state),
518 Device::Email(value) => value.get_connect_to(state),
519 Device::Tag(value) => value.get_connect_to(state),
520 Device::TagRouter(value) => value.get_connect_to(state),
521 Device::Service(value) => value.get_connect_to(state),
522 _ => state.clone(),
523 }
524 }
525}
526
527fn build_asr_vendor() -> String {
528 String::from(DEFAULT_ASR_VENDOR)
529}
530
531fn build_asr_language() -> String {
532 String::from(DEFAULT_ASR_LANGUAGE)
533}
534
535fn build_tts_vendor() -> String {
536 String::from(DEFAULT_TTS_VENDOR)
537}
538
539fn build_tts_language() -> String {
540 String::from(DEFAULT_TTS_LANGUAGE)
541}
542
543fn build_tts_voice() -> String {
544 String::from(DEFAULT_TTS_VOICE)
545}
546
547fn build_default_timezone() -> String {
548 String::from(DEFAULT_TIMEZONE)
549}
550
551fn build_trunk_description() -> String {
552 String::from(DEFAULT_TRUNK_DESCRIPTION)
553}
554
555fn build_trunk_port() -> u16 {
556 DEFAULT_TRUNK_PORT
557}
558
559fn build_country_code() -> String {
560 String::from(DEFAULT_COUNTRY_CODE)
561}
562
563fn build_logger() -> LoggerLevel {
564 LoggerLevel::Warn
565}
566
567fn build_call_time() -> u16 {
568 DEFAULT_CALL_TIME
569}
570
571fn build_ring_time() -> u8 {
572 DEFAULT_RING_TIME
573}
574
575fn build_spend_cap_value() -> u16 {
576 100
577}
578
579fn build_spend_cap_level() -> u8 {
580 80
581}
582
583fn build_spend_cap_action() -> RouteAction {
584 RouteAction::Warn
585}
586
587fn build_concurrency_action() -> RouteAction {
588 RouteAction::Warn
589}
590
591fn build_cos_action() -> COSAction {
592 COSAction::Allow
593}
594
595fn build_cos_ppm() -> f32 {
596 15.00
597}
598
599fn build_cos_ppc() -> f32 {
600 15.00
601}
602
603fn build_license() -> Licence {
604 Licence::Standard
605}
606
607fn build_record_retention() -> String {
608 String::from(DEFAULT_RECORDING_RETENTION)
609}
610