cal_core/
account.rs

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