1use crate::accounting::Address;
4use crate::core::*;
5use crate::device::device::{Connector, Device, DeviceStruct};
6use crate::utils::*;
7use crate::RecordReference;
8use bson::DateTime;
9use phonenumber::country;
10use phonenumber::country::Id;
11use serde::{Deserialize, Serialize};
12use std::collections::HashMap;
13use std::fmt::{Debug, Formatter};
14#[cfg(feature = "openapi")]
15use utoipa::ToSchema;
16#[derive(Serialize, Deserialize, Clone, Debug)]
17#[cfg_attr(feature = "openapi", derive(ToSchema))]
18#[serde(rename_all = "camelCase")]
19pub struct AccountLite {
20 #[serde(deserialize_with = "crate::shared::object_id_as_string", rename = "_id")]
21 pub id: String,
22 pub name: String,
23 pub mbn: String,
24 pub domain: String,
25 #[serde(default = "crate::shared::build_timestamp")]
26 pub created: DateTime,
27 pub organisation: RecordReference,
28 #[serde(default)]
29 pub teams: TeamsAccount,
30 #[serde(default)]
31 pub environment: Environment,
32 #[serde(default)]
33 pub spend_cap: SpendCap,
34 #[serde(default)]
35 pub concurrency: Concurrency,
36 #[serde(default)]
37 pub class_of_service: ClassOfService,
38 pub cluster_settings: Cluster,
39}
40
41
42
43impl AccountLite {
44 pub fn country_code(&self) -> &str {
45 self.environment.country_code.as_str()
46 }
47
48 pub fn country_code_parsed(&self) -> Id {
49 self.environment.country_code_parsed()
50 }
51
52 pub fn clean_str(&self, str: &str) -> String {
53 clean_str(self.environment.country_code_parsed(), str)
54 }
55}
56
57#[derive(Serialize, Deserialize, Clone, Debug)]
58#[cfg_attr(feature = "openapi", derive(ToSchema))]
59#[serde(rename_all = "camelCase")]
60pub struct Account {
61 #[serde(deserialize_with = "crate::shared::object_id_as_string", rename = "_id")]
62 pub id: String,
63 pub name: String,
64 pub mbn: String,
65 pub domain: String,
66 #[serde(default = "crate::shared::build_timestamp")]
67 pub created: DateTime,
68 pub organisation: RecordReference,
69 #[serde(default)]
70 pub ddis: Vec<DDI>,
71 #[serde(default)]
72 pub trunks: Vec<Trunk>,
73 #[serde(default)]
74 #[serde(rename = "callbackURLS")]
75 pub hooks: Vec<Hook>,
76 #[serde(default)]
77 pub devices: Vec<DeviceStruct>,
78 #[serde(default)]
79 pub assets: Vec<Asset>,
80 #[serde(default)]
81 pub address: Address,
82 #[serde(default)]
83 pub addresses: Vec<Address>,
84 #[serde(default)]
85 pub teams: TeamsAccount,
86 #[serde(default)]
87 pub environment: Environment,
88 #[serde(default)]
89 pub spend_cap: SpendCap,
90 #[serde(default)]
91 pub concurrency: Concurrency,
92 #[serde(default)]
93 pub class_of_service: ClassOfService,
94 pub cluster_settings: Cluster,
95 #[serde(default)]
96 pub api_keys: APIKeys,
97}
98
99impl From<Account> for AccountLite {
100 fn from(account: Account) -> Self {
101 AccountLite {
102 id: account.id,
103 name: account.name,
104 mbn: account.mbn,
105 domain: account.domain,
106 created: account.created,
107 organisation: account.organisation,
108 teams: account.teams,
109 environment: account.environment,
110 spend_cap: account.spend_cap,
111 concurrency: account.concurrency,
112 class_of_service: account.class_of_service,
113 cluster_settings: account.cluster_settings,
114 }
115 }
116}
117
118impl From<&Account> for AccountLite {
120 fn from(account: &Account) -> Self {
121 AccountLite {
122 id: account.id.clone(),
123 name: account.name.clone(),
124 mbn: account.mbn.clone(),
125 domain: account.domain.clone(),
126 created: account.created.clone(),
127 organisation: account.organisation.clone(),
128 teams: account.teams.clone(),
129 environment: account.environment.clone(),
130 spend_cap: account.spend_cap.clone(),
131 concurrency: account.concurrency.clone(),
132 class_of_service: account.class_of_service.clone(),
133 cluster_settings: account.cluster_settings.clone(),
134 }
135 }
136}
137
138#[derive(Serialize, Deserialize, Clone, Debug)]
139#[serde(rename_all = "camelCase")]
140pub struct Cluster {
141 #[serde(deserialize_with = "crate::shared::object_id_as_string", rename = "_id")]
142 pub id: String,
143 pub name: String,
144 pub server_a: String,
145}
146
147#[derive(Serialize, Deserialize, Clone, Debug)]
148#[serde(rename_all = "camelCase")]
149pub struct APIKeys {
150 #[serde(default)]
151 keys: Vec<APIKey>,
152}
153
154impl Default for APIKeys {
155 fn default() -> Self {
156 Self { keys: Vec::new() }
157 }
158}
159
160#[derive(Serialize, Deserialize, Clone, Debug)]
161#[serde(rename_all = "camelCase")]
162pub struct APIKey {
163 key: String,
164}
165
166#[derive(Serialize, Deserialize, Clone, Debug)]
167#[serde(rename_all = "camelCase")]
168pub struct Environment {
169 #[serde(default = "build_logger")]
170 pub logger: LoggerLevel,
171 #[serde(rename = "dialTimeLimit")]
172 #[serde(default = "build_call_time")]
173 pub max_call_time: u16,
174 #[serde(rename = "dialTimeout")]
175 #[serde(default = "build_ring_time")]
176 pub ring_time: u8,
177 #[serde(default = "build_tts_vendor")]
178 pub tts_vendor: String,
179 #[serde(default = "build_tts_language")]
180 #[serde(rename = "ttsLanguageV2")]
181 pub tts_language: String,
182 #[serde(default = "build_tts_voice")]
183 pub tts_voice: String,
184 #[serde(default = "build_asr_vendor")]
185 pub asr_vendor: AsrVendor,
186 #[serde(default = "build_asr_language")]
187 pub asr_language: String,
188 #[serde(default = "build_default_timezone")]
189 pub time_zone: String,
190 #[serde(default = "build_country_code")]
191 pub country_code: String,
192 #[serde(default = "build_record_retention")]
193 pub recording_retention: String,
194 pub ingress_script: Option<String>,
195}
196
197impl Environment {
198 pub fn country_code_parsed(&self) -> Id {
199 self.country_code.parse().unwrap_or_else(|_| country::GB)
200 }
201}
202impl Default for Environment {
203 fn default() -> Self {
204 Self {
205 logger: LoggerLevel::Warn,
206 max_call_time: DEFAULT_CALL_TIME,
207 ring_time: DEFAULT_RING_TIME,
208 tts_vendor: DEFAULT_TTS_VENDOR.to_string(),
209 tts_language: DEFAULT_TTS_LANGUAGE.to_string(),
210 tts_voice: DEFAULT_TTS_VOICE.to_string(),
211 asr_vendor: AsrVendor::Google,
212 asr_language: DEFAULT_ASR_LANGUAGE.to_string(),
213 time_zone: DEFAULT_TIMEZONE.to_string(),
214 country_code: DEFAULT_COUNTRY_CODE.to_string(),
215 recording_retention: DEFAULT_RECORDING_RETENTION.to_string(),
216 ingress_script: None,
217 }
218 }
219}
220
221#[derive(Serialize, Deserialize, Clone, Debug)]
222#[serde(rename_all = "camelCase")]
223pub struct SpendCap {
224 #[serde(default = "build_spend_cap_value")]
225 value: u16,
226 #[serde(default = "build_spend_cap_level")]
227 warn: u8,
228 #[serde(default = "build_spend_cap_action")]
229 action: RouteAction,
230 #[serde(default)]
231 email_recipients: Vec<String>,
232}
233
234impl Default for SpendCap {
235 fn default() -> Self {
236 Self {
237 value: 100,
238 warn: 80,
239 action: RouteAction::Warn,
240 email_recipients: Vec::new(),
241 }
242 }
243}
244
245#[derive(Serialize, Deserialize, Clone, Debug)]
246#[serde(rename_all = "camelCase")]
247pub struct Concurrency {
248 #[serde(rename = "type")]
249 #[serde(default = "build_license")]
250 license: Licence,
251 #[serde(default = "build_concurrency_action")]
252 action: RouteAction,
253 #[serde(default)]
254 email_recipients: Vec<String>,
255}
256
257impl Default for Concurrency {
258 fn default() -> Self {
259 Concurrency {
260 license: Licence::Standard,
261 action: RouteAction::Warn,
262 email_recipients: vec![],
263 }
264 }
265}
266
267#[derive(Serialize, Deserialize, Clone, Debug)]
268#[serde(rename_all = "camelCase")]
269pub struct ClassOfService {
270 #[serde(rename = "type")]
271 #[serde(default = "build_cos_action")]
272 license: COSAction,
273 #[serde(default)]
274 countries: Vec<String>,
275 #[serde(default)]
276 prefix_exceptions: String,
277 #[serde(rename = "maxPPM")]
278 #[serde(default = "build_cos_ppm")]
279 max_ppm: f32,
280 #[serde(rename = "maxPPC")]
281 #[serde(default = "build_cos_ppc")]
282 max_ppc: f32,
283}
284
285impl Default for ClassOfService {
286 fn default() -> Self {
287 Self {
288 license: COSAction::Allow,
289 countries: Vec::new(),
290 prefix_exceptions: String::from(""),
291 max_ppc: 10.00,
292 max_ppm: 10.00,
293 }
294 }
295}
296
297#[derive(Serialize, Deserialize, Clone, Debug)]
298#[serde(rename_all = "camelCase")]
299pub enum LoggerLevel {
300 Debug,
301 Info,
302 Warn,
303 Error,
304}
305
306#[derive(Serialize, Deserialize, Clone, Debug)]
307#[serde(rename_all = "camelCase")]
308pub enum Licence {
309 Standard,
310 Professional,
311 Enterprise,
312}
313
314#[derive(Serialize, Deserialize, Clone, Debug)]
315pub enum COSAction {
316 #[serde(alias = "DENY")]
317 #[serde(rename = "deny")]
318 Deny,
319 #[serde(alias = "ALLOW")]
320 #[serde(rename = "allow")]
321 Allow,
322 #[serde(alias = "WARN")]
323 #[serde(rename = "warn")]
324 Warn,
325}
326
327#[derive(Serialize, Deserialize, Clone, Debug)]
328pub enum RouteAction {
329 #[serde(rename = "warn")]
330 Warn,
331 #[serde(rename = "restrict")]
332 Restrict,
333 #[serde(rename = "deny")]
334 Deny,
335}
336
337#[derive(Serialize, Deserialize, Clone, Debug)]
338#[serde(rename_all = "camelCase")]
339pub struct TeamsAccount {
340 #[serde(rename = "type")]
341 pub domain_type: TeamsDomainType,
342 #[serde(default)]
343 pub domain: String,
344 pub txt: Option<String>,
345 }
350
351#[derive(Serialize, Deserialize, Clone, Debug)]
352#[serde(rename_all = "camelCase")]
353pub enum TeamsDomainType {
354 Callable,
355 Legacy,
356}
357
358impl Default for TeamsAccount {
359 fn default() -> Self {
360 Self {
361 domain_type: TeamsDomainType::Callable,
362 domain: String::from(""),
363 txt: None,
364 }
365 }
366}
367
368
369#[derive(Serialize, Deserialize, Clone, Debug)]
370#[serde(rename_all = "camelCase")]
371pub struct Asset {
372 #[serde(deserialize_with = "crate::shared::object_id_as_string", rename = "_id")]
373 pub id: String,
374 pub bucket: String,
375 pub key: String,
376 pub filename: String,
377 pub name: String,
378 pub mime_type: String,
379 pub size: u32,
380 #[serde(default = "crate::shared::build_timestamp")]
381 pub created: DateTime,
382 #[serde(default)]
383 pub meta: HashMap<String, String>,
384}
385
386#[derive(Serialize, Deserialize, Clone, Debug)]
387#[serde(rename_all = "camelCase")]
388pub struct Setting {
389 #[serde(default)]
390 #[serde(deserialize_with = "crate::shared::object_id_as_string", rename = "_id")]
391 pub id: String,
392 pub key: String,
393 #[serde(rename = "type")]
394 pub setting_type: String,
395 pub value: String,
396}
397
398#[derive(Serialize, Deserialize, Debug, Clone)]
401#[cfg_attr(feature = "openapi", derive(ToSchema))]
402#[serde(rename_all = "camelCase")]
403pub struct DDI {
404 #[serde(deserialize_with = "crate::shared::object_id_as_string", rename = "_id")]
405 pub id: String,
406 pub name: String,
407 #[serde(default)]
408 pub meta: HashMap<String, String>,
409
410 #[serde(skip_serializing_if = "Option::is_none")]
412 pub classification: Option<String>,
413 #[serde(skip_serializing_if = "Option::is_none")]
414 pub ticket_id: Option<String>,
415 #[serde(skip_serializing_if = "Option::is_none")]
416 pub global_id: Option<String>,
417 #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
418 pub ddi_type: Option<String>,
419 #[serde(default)]
420 pub features: Vec<String>,
421 #[serde(skip_serializing_if = "Option::is_none")]
422 pub created: Option<DateTime>,
423
424 #[serde(skip_serializing_if = "Option::is_none")]
426 pub dialog_channel: Option<DialogChannel>,
427 #[serde(skip_serializing_if = "Option::is_none")]
428 pub dialog_key: Option<DialogKey>,
429 #[serde(skip_serializing_if = "Option::is_none")]
430 pub whats_app_account: Option<WhatsAppAccount>,
431}
432
433#[derive(Serialize, Deserialize, Debug, Clone)]
435#[serde(rename_all = "camelCase")]
436pub struct DialogChannel {
437 #[serde(rename = "_id")]
438 pub id: String,
439 pub setup_info: SetupInfo,
440 pub status: String,
441 pub account_mode: String,
442 pub created_at: String,
443 pub client_id: String,
444 pub client: DialogClient,
445 pub waba_account: WabaAccount,
446 pub integration: Integration,
447 pub current_limit: Option<String>,
448 pub current_quality_rating: String,
449 pub hub_status: String,
450 pub is_migrated: bool,
451 pub is_oba: bool,
452 pub version: i32,
453}
454
455#[derive(Serialize, Deserialize, Debug, Clone)]
456#[serde(rename_all = "camelCase")]
457pub struct SetupInfo {
458 pub phone_number: String,
459 pub phone_name: String,
460}
461
462#[derive(Serialize, Deserialize, Debug, Clone)]
463#[serde(rename_all = "camelCase")]
464pub struct DialogClient {
465 #[serde(rename = "_id")]
466 pub id: String,
467 pub name: String,
468 pub contact_info: ContactInfo,
469}
470
471#[derive(Serialize, Deserialize, Debug, Clone)]
472pub struct ContactInfo {
473 pub email: String,
474}
475
476#[derive(Serialize, Deserialize, Debug, Clone)]
477#[serde(rename_all = "camelCase")]
478pub struct WabaAccount {
479 #[serde(rename = "_id")]
480 pub id: String,
481 pub on_behalf_of_business_info: OnBehalfOfBusinessInfo,
482 pub fb_account_status: String,
483 pub external_id: String,
484 pub fb_business_id: String,
485}
486
487#[derive(Serialize, Deserialize, Debug, Clone)]
488#[serde(rename_all = "camelCase")]
489pub struct OnBehalfOfBusinessInfo {
490 #[serde(rename = "_id")]
491 pub id: String,
492 pub name: String,
493 #[serde(rename = "type")]
494 pub business_type: String,
495 pub status: String,
496}
497
498#[derive(Serialize, Deserialize, Debug, Clone)]
499#[serde(rename_all = "camelCase")]
500pub struct Integration {
501 pub app_id: String,
502 pub hosting_platform_type: String,
503 pub enabled: bool,
504 pub state: String,
505}
506
507#[derive(Serialize, Deserialize, Debug, Clone)]
508#[serde(rename_all = "camelCase")]
509pub struct DialogKey {
510 #[serde(rename = "_id")]
511 pub id: String,
512 pub address: String,
513 pub api_key: String,
514 pub app_id: String,
515}
516
517#[derive(Serialize, Deserialize, Debug, Clone)]
518#[serde(rename_all = "camelCase")]
519pub struct WhatsAppAccount {
520 pub account: WhatsAppAccountDetails,
521 pub phone_number: WhatsAppPhoneNumber,
522}
523
524#[derive(Serialize, Deserialize, Debug, Clone)]
525#[serde(rename_all = "camelCase")]
526pub struct WhatsAppAccountDetails {
527 #[serde(rename = "_id")]
528 pub id: String,
529 pub name: String,
530 pub timezone_id: String,
531 pub message_template_namespace: String,
532 pub on_behalf_of: Option<OnBehalfOf>,
533 pub phone_numbers: PhoneNumbers,
534}
535
536#[derive(Serialize, Deserialize, Debug, Clone)]
537#[serde(rename_all = "camelCase")]
538pub struct OnBehalfOf {
539 #[serde(rename = "_id")]
540 pub id: String,
541 pub name: String,
542 pub status: String,
543}
544
545#[derive(Serialize, Deserialize, Debug, Clone)]
546pub struct PhoneNumbers {
547 pub data: Vec<WhatsAppPhoneNumber>,
548}
549
550#[derive(Serialize, Deserialize, Debug, Clone)]
551#[serde(rename_all = "camelCase")]
552pub struct WhatsAppPhoneNumber {
553 #[serde(rename = "_id")]
554 pub id: String,
555 pub verified_name: String,
556 pub code_verification_status: String,
557 pub display_phone_number: String,
558 pub quality_rating: String,
559 pub last_onboarded_time: Option<String>,
560 pub platform_type: String,
561 pub throughput: Throughput,
562}
563
564#[derive(Serialize, Deserialize, Debug, Clone)]
565pub struct Throughput {
566 pub level: String,
567}
568
569#[derive(Serialize, Deserialize, Clone, Debug)]
570#[serde(rename_all = "camelCase")]
571pub struct Trunk {
572 #[serde(deserialize_with = "crate::shared::object_id_as_string", rename = "_id")]
573 pub id: String,
574 pub ip: String,
575 #[serde(default = "build_trunk_description")]
576 pub description: String,
577 #[serde(deserialize_with = "crate::shared::from_str", default = "build_trunk_port")]
578 pub port: u16,
579}
580
581
582
583#[derive(Serialize, Deserialize, Clone, Debug)]
584#[serde(rename_all = "camelCase")]
585pub struct Hook {
586 #[serde(deserialize_with = "crate::shared::object_id_as_string", rename = "_id")]
587 pub id: String,
588 pub app: String,
589 pub url: String,
590 #[serde(default = "AuthType::default_method")]
591 pub auth_type: AuthType,
592 #[serde(default = "HookMethod::default_method")]
593 pub method: HookMethod,
594 #[serde(default)]
595 pub meta: HashMap<String, String>,
596 #[serde(default)]
597 pub api_key_name: String,
598 #[serde(default)]
599 pub api_key_value: String,
600 #[serde(default)]
601 pub api_secret_name: String,
602 #[serde(default)]
603 pub api_secret_value: String,
604}
605
606#[derive(Serialize, Deserialize, Clone)]
607pub enum HookMethod {
608 #[serde(rename = "POST")]
609 Post,
610 #[serde(rename = "GET")]
611 Get,
612}
613
614impl Debug for HookMethod {
615 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
616 match self {
617 HookMethod::Post => write!(f, "HookMethod::Post"),
618 HookMethod::Get => write!(f, "HookMethod::Get"),
619 }
620 }
621}
622
623
624impl HookMethod {
625 fn default_method() -> Self {
626 HookMethod::Post
627 }
628}
629
630#[derive(Serialize, Deserialize, Clone, Debug)]
631pub enum AuthType {
632 #[serde(rename = "DISABLED")]
633 Disabled,
634 #[serde(rename = "KEY")]
635 Key,
636 #[serde(rename = "KEY_SECRET")]
637 KeySecret,
638 #[serde(rename = "BASIC_AUTH")]
639 BasicAuth,
640 #[serde(rename = "OAUTH")]
641 OAuth,
642}
643
644impl AuthType {
645 fn default_method() -> Self {
646 AuthType::Disabled
647 }
648}
649
650impl Connector for Device {
651 fn get_connect_to(&mut self, state: &mut FlowState) -> ConnectState {
652 match self {
653 Device::InboundFlow(value) => value.get_connect_to(state),
654 Device::OutboundFlow(value) => value.get_connect_to(state),
655 Device::AppFlow(value) => value.get_connect_to(state),
656 Device::WhatsAppFlow(value) => value.get_connect_to(state),
657 Device::AniRouter(value) => value.get_connect_to(state),
658 Device::DnisRouter(value) => value.get_connect_to(state),
659 Device::DigitRouter(value) => value.get_connect_to(state),
660 Device::TimeRangeRouter(value) => value.get_connect_to(state),
661 Device::DayOfWeekRouter(value) => value.get_connect_to(state),
662 Device::DateRangeRouter(value) => value.get_connect_to(state),
663 Device::Play(value) => value.get_connect_to(state),
664 Device::Say(value) => value.get_connect_to(state),
665 Device::Voicemail(value) => value.get_connect_to(state),
666 Device::Script(value) => value.get_connect_to(state),
667 Device::Queue(value) => value.get_connect_to(state),
668 Device::Sms(value) => value.get_connect_to(state),
669 Device::Email(value) => value.get_connect_to(state),
670 Device::Tag(value) => value.get_connect_to(state),
671 Device::TagRouter(value) => value.get_connect_to(state),
672 Device::Service(value) => value.get_connect_to(state),
673 Device::Client(value) => value.get_connect_to(state),
674 Device::Teams(value) => value.get_connect_to(state),
675 Device::Remote(value) => value.get_connect_to(state),
676 Device::HuntGroup(value) => value.get_connect_to(state),
677 Device::SipGateway(value) => value.get_connect_to(state),
678 Device::SipExtension(value) => value.get_connect_to(state),
679 _ => ConnectState::device_error(HANG_UP_CONNECT),
680 }
681 }
682}
683
684#[derive(Serialize, Deserialize, Clone)]
685#[serde(rename_all = "camelCase")]
686pub enum AsrVendor {
687 Deepgram,
688 Google,
689 Aws,
690 Ibm,
691 Microsoft,
692 Nuance,
693 Nvidia,
694 Soniox,
695}
696
697fn build_asr_vendor() -> AsrVendor {
698 AsrVendor::Google
699}
700
701fn build_asr_language() -> String {
702 String::from(DEFAULT_ASR_LANGUAGE)
703}
704
705fn build_tts_vendor() -> String {
706 String::from(DEFAULT_TTS_VENDOR)
707}
708
709fn build_tts_language() -> String {
710 String::from(DEFAULT_TTS_LANGUAGE)
711}
712
713fn build_tts_voice() -> String {
714 String::from(DEFAULT_TTS_VOICE)
715}
716
717fn build_default_timezone() -> String {
718 String::from(DEFAULT_TIMEZONE)
719}
720
721fn build_trunk_description() -> String {
722 String::from(DEFAULT_TRUNK_DESCRIPTION)
723}
724
725fn build_trunk_port() -> u16 {
726 DEFAULT_TRUNK_PORT
727}
728
729fn build_country_code() -> String {
730 String::from(DEFAULT_COUNTRY_CODE)
731}
732
733fn build_logger() -> LoggerLevel {
734 LoggerLevel::Warn
735}
736
737fn build_call_time() -> u16 {
738 DEFAULT_CALL_TIME
739}
740
741fn build_ring_time() -> u8 {
742 DEFAULT_RING_TIME
743}
744
745fn build_spend_cap_value() -> u16 {
746 100
747}
748
749fn build_spend_cap_level() -> u8 {
750 80
751}
752
753fn build_spend_cap_action() -> RouteAction {
754 RouteAction::Warn
755}
756
757fn build_concurrency_action() -> RouteAction {
758 RouteAction::Warn
759}
760
761fn build_cos_action() -> COSAction {
762 COSAction::Allow
763}
764
765fn build_cos_ppm() -> f32 {
766 15.00
767}
768
769fn build_cos_ppc() -> f32 {
770 15.00
771}
772
773fn build_license() -> Licence {
774 Licence::Standard
775}
776
777fn build_record_retention() -> String {
778 String::from(DEFAULT_RECORDING_RETENTION)
779}
780
781
782
783