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