cal_core/device/
device.rs

1use crate::core::*;
2use crate::device::client::{Client, ClientProfile};
3use crate::device::hunt_group::HuntGroup;
4use crate::device::remote::Remote;
5use crate::device::sip_extension::SipExtension;
6use crate::sip_gateway::SipGateway;
7use crate::teams::Teams;
8use crate::{AsrVendor, ConnectState, FlowState, NumberFormat, QueueItemType, VoiceServer};
9use bson::DateTime;
10use cal_jambonz::dial::TranscribeDial;
11use cal_jambonz::listen::{Listen, MixType, SampleRate};
12use cal_jambonz::recognizer::Recognizer;
13use cal_jambonz::shared::shared::SIPStatus;
14use chrono::{Datelike, Local, Utc};
15use serde::{Deserialize, Deserializer, Serialize};
16use serde_json::Value;
17
18pub trait Connector {
19    fn get_connect_to(&mut self, state: &mut FlowState) -> ConnectState;
20}
21
22pub trait BaseDevice {
23    fn get_id(&mut self) -> String;
24    fn get_name(&mut self) -> String;
25    fn get_extension(&mut self) -> u16;
26}
27
28#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
29pub enum DeviceType {
30    #[serde(rename = "ROUTE_START")]
31    InboundFlow,
32    #[serde(rename = "MATCH_START")]
33    OutboundFlow,
34    #[serde(rename = "WHATSAPP_START")]
35    WhatsAppFlow,
36    #[serde(rename = "APP_START")]
37    AppFlow,
38    #[serde(rename = "ANI_ROUTER")]
39    AniRouter,
40    #[serde(rename = "DNIS_ROUTER")]
41    DnisRouter,
42    #[serde(rename = "NUMBER_PLAN")]
43    DigitRouter,
44    #[serde(rename = "TIME_RANGE_ROUTER")]
45    TimeRangeRouter,
46    #[serde(rename = "DAY_OF_WEEK_ROUTER")]
47    DayOfWeekRouter,
48    #[serde(rename = "DATE_RANGE_ROUTER")]
49    DateRangeRouter,
50    #[serde(rename = "HUNT_GROUP")]
51    HuntGroup,
52    #[serde(rename = "CLIENT")]
53    Client,
54    #[serde(rename = "TEAMS")]
55    Teams,
56    #[serde(rename = "SIP")]
57    SipExtension,
58    #[serde(rename = "SIP_GATEWAY")]
59    SipGateway,
60    #[serde(rename = "REMOTE")]
61    Remote,
62    #[serde(rename = "PLUGIN")]
63    Plugin,
64    #[serde(rename = "PLAY")]
65    Play,
66    #[serde(rename = "SAY")]
67    Say,
68    #[serde(rename = "VOICEMAIL")]
69    Voicemail,
70    #[serde(rename = "SCRIPT")]
71    Script,
72    #[serde(rename = "QUEUE")]
73    Queue,
74    #[serde(rename = "SMS")]
75    Sms,
76    #[serde(rename = "EMAIL")]
77    Email,
78    #[serde(rename = "TAG")]
79    Tag,
80    #[serde(rename = "TAG_ROUTER")]
81    TagRouter,
82    #[serde(rename = "MESSAGE_PLUGIN")]
83    MessagePlugin,
84    #[serde(rename = "MESSAGE_TEXT")]
85    MessageText,
86    #[serde(rename = "MESSAGE_BUTTONS")]
87    MessageButtons,
88    #[serde(rename = "MESSAGE_TEMPLATE")]
89    MessageTemplate,
90    #[serde(rename = "MESSAGE_ANI_ROUTER")]
91    MessageAniRouter,
92    #[serde(rename = "SERVICE")]
93    Service,
94    //todo MESSAGE_BUTTONS, MESSAGE_TEMPLATE
95}
96
97#[derive(Serialize, Deserialize, Clone)]
98#[serde(untagged)]
99pub enum Device {
100    InboundFlow(InboundFlow),
101    OutboundFlow(OutboundFlow),
102    WhatsAppFlow(WhatsAppFlow),
103    AppFlow(AppFlow),
104    AniRouter(ANIRouter),
105    DnisRouter(DNISRouter),
106    DigitRouter(DigitRouter),
107    TimeRangeRouter(TimeRangeRouter),
108    DayOfWeekRouter(DayOfWeekRouter),
109    DateRangeRouter(DateRangeRouter),
110    HuntGroup(HuntGroup),
111    Client(Client),
112    Teams(Teams),
113    SipExtension(SipExtension),
114    SipGateway(SipGateway),
115    Remote(Remote),
116    Plugin(Plugin),
117    Play(Play),
118    Say(Say),
119    Voicemail(VoiceMail),
120    Script(Script),
121    Queue(Queue),
122    Sms(Sms),
123    Email(Email),
124    Tag(Tag),
125    TagRouter(TagRouter),
126    MessagePlugin(MessagePlugin),
127    MessageButtons(MessageButtons),
128    MessageText(MessageText),
129    MessageTemplate(MessageTemplate),
130    MessageAniRouter(MessageAniRouter),
131    Service(Service),
132}
133
134#[derive(Serialize, Deserialize, Clone)]
135#[serde(rename_all = "camelCase")]
136pub struct DeviceStruct {
137    #[serde(rename = "_id")]
138    pub id: String,
139
140    #[serde(rename = "type")]
141    pub device_type: DeviceType,
142
143    pub name: String,
144
145    #[serde(deserialize_with = "from_str")]
146    pub extension: u16,
147
148    #[serde(default)]
149    pub tags: Vec<DeviceTag>,
150
151    #[serde(rename = "startRoute")]
152    #[serde(skip_serializing_if = "Option::is_none")]
153    pub start_route: Option<InboundFlow>,
154
155    #[serde(rename = "regexRoute")]
156    #[serde(skip_serializing_if = "Option::is_none")]
157    pub regex_route: Option<OutboundFlow>,
158
159    #[serde(rename = "appRoute")]
160    #[serde(skip_serializing_if = "Option::is_none")]
161    pub app_route: Option<AppFlow>,
162
163    #[serde(rename = "numberPlan")]
164    #[serde(skip_serializing_if = "Option::is_none")]
165    pub number_plan: Option<DigitRouter>,
166
167    #[serde(rename = "aniRouter")]
168    #[serde(skip_serializing_if = "Option::is_none")]
169    pub ani_router: Option<ANIRouter>,
170
171    #[serde(rename = "dnisRouter")]
172    #[serde(skip_serializing_if = "Option::is_none")]
173    pub dnis_router: Option<DNISRouter>,
174
175    #[serde(rename = "zoneRouter")]
176    #[serde(skip_serializing_if = "Option::is_none")]
177    pub zone_router: Option<ZoneRouter>,
178
179    #[serde(rename = "tagRouter")]
180    #[serde(skip_serializing_if = "Option::is_none")]
181    pub tag_router: Option<TagRouter>,
182
183    #[serde(rename = "timeRangeRoute")]
184    #[serde(skip_serializing_if = "Option::is_none")]
185    pub time_range_router: Option<TimeRangeRouter>,
186
187    #[serde(rename = "dayOfWeekRoute")]
188    #[serde(skip_serializing_if = "Option::is_none")]
189    pub day_of_week_router: Option<DayOfWeekRouter>,
190
191    #[serde(rename = "dateRangeRoute")]
192    #[serde(skip_serializing_if = "Option::is_none")]
193    pub date_range_router: Option<DateRangeRouter>,
194
195    #[serde(rename = "huntGroup")]
196    #[serde(skip_serializing_if = "Option::is_none")]
197    pub hunt_group: Option<HuntGroup>,
198
199    #[serde(rename = "client")]
200    #[serde(skip_serializing_if = "Option::is_none")]
201    pub client: Option<Client>,
202
203    #[serde(rename = "teams")]
204    #[serde(skip_serializing_if = "Option::is_none")]
205    pub teams: Option<Teams>,
206
207    #[serde(rename = "sipExtension")]
208    #[serde(skip_serializing_if = "Option::is_none")]
209    pub sip_extension: Option<SipExtension>,
210
211    #[serde(rename = "sipGateway")]
212    #[serde(skip_serializing_if = "Option::is_none")]
213    pub sip_gateway: Option<SipGateway>,
214
215    #[serde(rename = "remote")]
216    #[serde(skip_serializing_if = "Option::is_none")]
217    pub remote: Option<Remote>,
218
219    #[serde(rename = "voicemail")]
220    #[serde(skip_serializing_if = "Option::is_none")]
221    pub voice_mail: Option<VoiceMail>,
222
223    #[serde(rename = "queue")]
224    #[serde(skip_serializing_if = "Option::is_none")]
225    pub queue: Option<Queue>,
226
227    #[serde(rename = "plugin")]
228    #[serde(skip_serializing_if = "Option::is_none")]
229    pub plugin: Option<Plugin>,
230
231    #[serde(rename = "service")]
232    #[serde(skip_serializing_if = "Option::is_none")]
233    pub service: Option<Service>,
234
235    #[serde(rename = "play")]
236    #[serde(skip_serializing_if = "Option::is_none")]
237    pub play: Option<Play>,
238
239    #[serde(rename = "say")]
240    #[serde(skip_serializing_if = "Option::is_none")]
241    pub say: Option<Say>,
242
243    #[serde(rename = "script")]
244    #[serde(skip_serializing_if = "Option::is_none")]
245    pub script: Option<Script>,
246
247    #[serde(rename = "email")]
248    #[serde(skip_serializing_if = "Option::is_none")]
249    pub email: Option<Email>,
250
251    #[serde(rename = "sms")]
252    #[serde(skip_serializing_if = "Option::is_none")]
253    pub sms: Option<Sms>,
254
255    #[serde(rename = "tag")]
256    #[serde(skip_serializing_if = "Option::is_none")]
257    pub tag: Option<Tag>,
258
259    #[serde(rename = "event")]
260    #[serde(skip_serializing_if = "Option::is_none")]
261    pub event: Option<Event>,
262
263    #[serde(rename = "whatsAppRoute")]
264    #[serde(skip_serializing_if = "Option::is_none")]
265    pub whats_app_flow: Option<WhatsAppFlow>,
266
267    #[serde(rename = "messagePlugin")]
268    #[serde(skip_serializing_if = "Option::is_none")]
269    pub message_plugin: Option<MessagePlugin>,
270
271    #[serde(rename = "messageText")]
272    #[serde(skip_serializing_if = "Option::is_none")]
273    pub message_text: Option<MessageText>,
274
275    #[serde(rename = "messageButtons")]
276    #[serde(skip_serializing_if = "Option::is_none")]
277    pub message_buttons: Option<MessageButtons>,
278
279    #[serde(rename = "messageTemplate")]
280    #[serde(skip_serializing_if = "Option::is_none")]
281    pub message_template: Option<MessageTemplate>,
282
283    #[serde(rename = "messageANIRouter")]
284    #[serde(skip_serializing_if = "Option::is_none")]
285    pub message_ani_router: Option<MessageAniRouter>,
286
287    #[serde(rename = "messageDNISRouter")]
288    #[serde(skip_serializing_if = "Option::is_none")]
289    pub message_dnis_router: Option<MessageDnisRouter>,
290}
291
292fn from_str<'de, D>(deserializer: D) -> Result<u16, D::Error>
293where
294    D: Deserializer<'de>,
295{
296    let value = Value::deserialize(deserializer)?;
297    if value.is_string() {
298        Ok(value.as_str().unwrap().parse().unwrap())
299    } else if value.is_u64() {
300        Ok(value.as_u64().unwrap() as u16)
301    } else if value.is_i64() {
302        Ok(value.as_i64().unwrap() as u16)
303    } else {
304        Err(serde::de::Error::custom("Cannot map extension to u16"))
305    }
306}
307
308impl DeviceStruct {
309    pub fn value(&self) -> Device {
310        match &self.device_type {
311            DeviceType::InboundFlow => Device::InboundFlow(self.clone().start_route.unwrap()),
312            DeviceType::OutboundFlow => Device::OutboundFlow(self.clone().regex_route.unwrap()),
313            DeviceType::WhatsAppFlow => Device::WhatsAppFlow(self.clone().whats_app_flow.unwrap()),
314            DeviceType::AppFlow => Device::AppFlow(self.clone().app_route.unwrap()),
315            DeviceType::AniRouter => Device::AniRouter(self.clone().ani_router.unwrap()),
316            DeviceType::DnisRouter => Device::DnisRouter(self.clone().dnis_router.unwrap()),
317            DeviceType::DigitRouter => Device::DigitRouter(self.clone().number_plan.unwrap()),
318            DeviceType::TimeRangeRouter => {
319                Device::TimeRangeRouter(self.clone().time_range_router.unwrap())
320            }
321            DeviceType::DayOfWeekRouter => {
322                Device::DayOfWeekRouter(self.clone().day_of_week_router.unwrap())
323            }
324            DeviceType::DateRangeRouter => {
325                Device::DateRangeRouter(self.clone().date_range_router.unwrap())
326            }
327            DeviceType::HuntGroup => Device::HuntGroup(self.clone().hunt_group.unwrap()),
328            DeviceType::Client => Device::Client(self.clone().client.unwrap()),
329            DeviceType::Teams => Device::Teams(self.clone().teams.unwrap()),
330            DeviceType::SipExtension => Device::SipExtension(self.clone().sip_extension.unwrap()),
331            DeviceType::SipGateway => Device::SipGateway(self.clone().sip_gateway.unwrap()),
332            DeviceType::Remote => Device::Remote(self.clone().remote.unwrap()),
333            DeviceType::Plugin => Device::Plugin(self.clone().plugin.unwrap()),
334            DeviceType::Play => Device::Play(self.clone().play.unwrap()),
335            DeviceType::Say => Device::Say(self.clone().say.unwrap()),
336            DeviceType::Voicemail => Device::Voicemail(self.clone().voice_mail.unwrap()),
337            DeviceType::Script => Device::Script(self.clone().script.unwrap()),
338            DeviceType::Queue => Device::Queue(self.clone().queue.unwrap()),
339            DeviceType::Sms => Device::Sms(self.clone().sms.unwrap()),
340            DeviceType::Email => Device::Email(self.clone().email.unwrap()),
341            DeviceType::Tag => Device::Tag(self.clone().tag.unwrap()),
342            DeviceType::TagRouter => Device::TagRouter(self.clone().tag_router.unwrap()),
343            DeviceType::MessagePlugin => {
344                Device::MessagePlugin(self.clone().message_plugin.unwrap())
345            }
346            DeviceType::MessageText => Device::MessageText(self.clone().message_text.unwrap()),
347            DeviceType::MessageButtons => {
348                Device::MessageButtons(self.clone().message_buttons.unwrap())
349            }
350            DeviceType::MessageTemplate => {
351                Device::MessageTemplate(self.clone().message_template.unwrap())
352            }
353            DeviceType::MessageAniRouter => {
354                Device::MessageAniRouter(self.clone().message_ani_router.unwrap())
355            }
356            DeviceType::Service => Device::Service(self.clone().service.unwrap()),
357        }
358    }
359
360    pub fn record_options(&self) -> Option<RecordOptions> {
361        match &self.device_type {
362            DeviceType::HuntGroup => Some(self.clone().hunt_group.unwrap().record_options),
363            DeviceType::Client => Some(self.clone().client.unwrap().record_options),
364            DeviceType::Teams => Some(self.clone().teams.unwrap().record_options),
365            DeviceType::SipExtension => Some(self.clone().sip_extension.unwrap().record_options),
366            DeviceType::SipGateway => Some(self.clone().sip_gateway.unwrap().record_options),
367            DeviceType::Remote => Some(self.clone().remote.unwrap().record_options),
368            DeviceType::Plugin => Some(self.clone().plugin.unwrap().record_options),
369            DeviceType::Voicemail => Some(self.clone().voice_mail.unwrap().record_options),
370            _ => None,
371        }
372    }
373
374    pub fn transcribe_options(&self) -> Option<TranscribeOptions> {
375        match &self.device_type {
376            DeviceType::HuntGroup => Some(self.clone().hunt_group.unwrap().transcribe_options),
377            DeviceType::Client => Some(self.clone().client.unwrap().transcribe_options),
378            DeviceType::Teams => Some(self.clone().teams.unwrap().transcribe_options),
379            DeviceType::SipExtension => {
380                Some(self.clone().sip_extension.unwrap().transcribe_options)
381            }
382            DeviceType::SipGateway => Some(self.clone().sip_gateway.unwrap().transcribe_options),
383            DeviceType::Remote => Some(self.clone().remote.unwrap().transcribe_options),
384            DeviceType::Plugin => Some(self.clone().plugin.unwrap().transcribe_options),
385            DeviceType::Voicemail => Some(self.clone().voice_mail.unwrap().transcribe_options),
386            _ => None,
387        }
388    }
389
390    pub fn is_id(&self, _id: &str) -> bool {
391        self.id == _id
392    }
393
394    pub fn is_device_type(&self, device_type: DeviceType) -> bool {
395        self.device_type == device_type
396    }
397
398    pub fn match_device(&self, str: &str) -> bool {
399        let matched = match &self.value() {
400            Device::InboundFlow(v) => v.ddis.contains(&str.to_string()),
401            Device::Client(v) => v.username.eq(&str),
402            Device::SipGateway(v) => v.trunks.contains(&str.to_string()),
403            _ => false,
404        };
405        matched || self.id.eq(&str) || self.extension.to_string().eq(&str)
406    }
407
408    pub fn match_outbound_flow(&self) -> bool {
409        match &self.value() {
410            Device::OutboundFlow(_value) => true,
411            _ => false,
412        }
413    }
414
415    pub fn is_connector(&self) -> bool {
416        vec![
417            DeviceType::InboundFlow,
418            DeviceType::OutboundFlow,
419            DeviceType::AppFlow,
420            DeviceType::WhatsAppFlow,
421            DeviceType::AniRouter,
422            DeviceType::DnisRouter,
423            DeviceType::DigitRouter,
424            DeviceType::TimeRangeRouter,
425            DeviceType::DayOfWeekRouter,
426            DeviceType::DateRangeRouter,
427            DeviceType::Play,
428            DeviceType::Say,
429            DeviceType::Voicemail,
430            DeviceType::Script,
431            DeviceType::Queue,
432            DeviceType::Sms,
433            DeviceType::Email,
434            DeviceType::Tag,
435            DeviceType::TagRouter,
436            DeviceType::Service,
437        ]
438        .contains(&self.device_type)
439    }
440
441    pub fn is_call_handler(&self) -> bool {
442        vec![
443            DeviceType::HuntGroup,
444            DeviceType::Client,
445            DeviceType::Teams,
446            DeviceType::SipExtension,
447            DeviceType::SipGateway,
448            DeviceType::Remote,
449            DeviceType::Plugin,
450        ]
451        .contains(&self.device_type)
452    }
453}
454
455#[derive(Serialize, Deserialize, Clone)]
456#[serde(rename_all = "camelCase")]
457pub struct DeviceTag {
458    #[serde(rename = "type")]
459    pub tag_type: TagType,
460    pub name: String,
461    pub value: String,
462}
463
464#[derive(Serialize, Deserialize, Eq, PartialEq, Clone)]
465#[serde(rename_all = "camelCase")]
466pub enum TagType {
467    Session,
468    Global,
469}
470
471#[derive(Serialize, Deserialize, Clone)]
472#[serde(rename_all = "camelCase")]
473pub struct InboundFlow {
474    #[serde(default)]
475    pub ddis: Vec<String>,
476    #[serde(default = "build_connect_to")]
477    pub connect_to: String,
478}
479
480impl Connector for InboundFlow {
481    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
482        ConnectState::default(&self.connect_to, None)
483    }
484}
485
486#[derive(Serialize, Deserialize, Clone)]
487#[serde(rename_all = "camelCase")]
488pub struct OutboundFlow {
489    pub reg_exp: String,
490    #[serde(default = "build_connect_to")]
491    pub connect_to: String,
492}
493
494impl Connector for OutboundFlow {
495    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
496        ConnectState::default(&self.connect_to, None)
497    }
498}
499
500#[derive(Serialize, Deserialize, Clone)]
501#[serde(rename_all = "camelCase")]
502pub struct WhatsAppFlow {
503    #[serde(default)]
504    pub ddis: Vec<String>,
505    #[serde(default = "build_connect_to")]
506    pub connect_to: String,
507}
508
509impl Connector for WhatsAppFlow {
510    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
511        ConnectState::default(&self.connect_to, None)
512    }
513}
514
515#[derive(Serialize, Deserialize, Clone)]
516#[serde(rename_all = "camelCase")]
517pub struct AppFlow {
518    #[serde(default = "build_connect_to")]
519    pub connect_to: String,
520}
521
522impl Connector for AppFlow {
523    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
524        ConnectState::default(&self.connect_to, None)
525    }
526}
527
528#[derive(Serialize, Deserialize, Clone)]
529#[serde(rename_all = "camelCase")]
530pub struct ANIRouter {
531    #[serde(default)]
532    pub options: Vec<RouterOption>,
533    #[serde(default = "build_connect_to")]
534    pub connect_to: String,
535}
536
537impl ANIRouter {
538    fn get_opts(&mut self) -> Vec<RouterOption> {
539        let opts = &mut self.options.clone();
540        opts.sort_by_key(|o| o.option.chars().count());
541        opts.reverse();
542        opts.clone()
543    }
544}
545
546impl Connector for ANIRouter {
547    fn get_connect_to(&mut self, state: &mut FlowState) -> ConnectState {
548        let str = state.get_paid_or_from();
549        self.get_opts()
550            .iter()
551            .find(|o| o.option.starts_with(str.as_str()))
552            .map(|o| {
553                ConnectState::matched(
554                    o.connect_to.as_str(),
555                    Some(str.to_string()),
556                    Some(o.option.clone()),
557                )
558            })
559            .unwrap_or_else(|| {
560                ConnectState::default(self.connect_to.as_str(), Some(str.to_string()))
561            })
562    }
563}
564
565#[derive(Serialize, Deserialize, Clone)]
566#[serde(rename_all = "camelCase")]
567pub struct DNISRouter {
568    #[serde(default)]
569    pub options: Vec<RouterOption>,
570    #[serde(default = "build_connect_to")]
571    pub connect_to: String,
572}
573
574#[derive(Serialize, Deserialize, Clone)]
575#[serde(rename_all = "camelCase")]
576pub struct ZoneRouter {
577    #[serde(default)]
578    pub options: Vec<RouterOption>,
579    #[serde(default = "build_connect_to")]
580    pub connect_to: String,
581}
582
583impl DNISRouter {
584    fn get_opts(&mut self) -> Vec<RouterOption> {
585        let opts = &mut self.options.clone();
586        opts.sort_by_key(|o| o.option.chars().count());
587        opts.reverse();
588        opts.clone()
589    }
590}
591impl Connector for DNISRouter {
592    fn get_connect_to(&mut self, state: &mut FlowState) -> ConnectState {
593        let str = state.get_to();
594        self.get_opts()
595            .iter()
596            .find(|o| o.option.starts_with(str.as_str()))
597            .map(|o| {
598                ConnectState::matched(
599                    o.connect_to.as_str(),
600                    Some(str.to_string()),
601                    Some(o.option.clone()),
602                )
603            })
604            .unwrap_or_else(|| {
605                ConnectState::default(self.connect_to.as_str(), Some(str.to_string()))
606            })
607    }
608}
609
610#[derive(Serialize, Deserialize, Clone)]
611#[serde(rename_all = "camelCase")]
612pub struct DigitRouter {
613    pub text: String,
614    #[serde(rename = "ttsLanguage")]
615    #[serde(default = "build_tts_voice")]
616    pub tts_voice: String,
617    #[serde(default = "build_finish_key")]
618    pub finish_on_key: String,
619    #[serde(default = "build_connect_to")]
620    pub connect_to: String,
621    #[serde(default)]
622    pub options: Vec<RouterOption>,
623    #[serde(default = "build_digit_timeout")]
624    pub timeout: u8,
625    #[serde(default = "build_max_digits")]
626    pub max_digits: u8,
627}
628
629impl DigitRouter {
630    fn get_opts(&mut self) -> Vec<RouterOption> {
631        let opts = &mut self.options.clone();
632        opts.sort_by_key(|o| o.option.chars().count());
633        opts.reverse();
634        opts.clone()
635    }
636}
637impl Connector for DigitRouter {
638    fn get_connect_to(&mut self, state: &mut FlowState) -> ConnectState {
639        match &state.get_digits() {
640            Some(d) => self
641                .get_opts()
642                .iter()
643                .find(|o| o.option.eq(d.as_str()))
644                .map(|o| {
645                    ConnectState::matched(
646                        &o.connect_to.to_string(),
647                        Some(d.to_string()),
648                        Some(o.option.clone()),
649                    )
650                })
651                .unwrap_or_else(|| {
652                    ConnectState::default(&self.connect_to.to_string(), Some(d.to_string()))
653                }),
654            None => ConnectState::default(
655                &self.connect_to.to_string(),
656                Some(self.connect_to.to_string()),
657            ),
658        }
659    }
660}
661
662pub trait Endpoint {
663    fn get_caller_id(&self, state: &FlowState) -> String {
664        state.initial_request.from.clone()
665    }
666    fn get_called_id(&self, state: &FlowState) -> String {
667        state.initial_request.to.clone()
668    }
669    fn get_listen(&self, state: &FlowState) -> Option<Listen>;
670    fn get_proxy(&self, _state: &FlowState) -> Option<VoiceServer> {
671        None
672    }
673    fn get_transcribe(&self, _state: &FlowState) -> Option<TranscribeDial> {
674        None
675    }
676}
677
678#[derive(Serialize, Deserialize, Clone)]
679#[serde(rename_all = "camelCase")]
680pub struct Plugin {
681    //todo MapBox info
682    pub plugin: String,
683    pub data: String,
684    #[serde(default = "build_present")]
685    pub present: String,
686    #[serde(default = "build_country_code")]
687    pub country_code: String,
688    #[serde(default = "build_ring_time")]
689    pub ring_time: u8,
690    #[serde(default = "build_call_time")]
691    pub max_call_time: u16,
692    #[serde(default = "build_connect_to")]
693    pub on_transfer: String,
694    #[serde(default = "build_connect_to")]
695    pub on_error: String,
696    #[serde(default = "build_connect_to")]
697    pub on_complete: String,
698    #[serde(default = "build_connect_to")]
699    pub on_busy: String,
700    #[serde(default = "build_connect_to")]
701    pub on_fail: String,
702    #[serde(default = "build_connect_to")]
703    pub on_no_answer: String,
704    #[serde(default)]
705    pub record_options: RecordOptions,
706    #[serde(default)]
707    pub transcribe_options: TranscribeOptions,
708    #[serde(default)]
709    pub ai_options: AiOptions,
710    #[serde(default)]
711    pub call_control: CallControl,
712}
713
714impl Connector for Plugin {
715    fn get_connect_to(&mut self, state: &mut FlowState) -> ConnectState {
716        match &state.get_dial_status() {
717            Some(status) => match status {
718                SIPStatus::Ok => ConnectState::complete(self.on_complete.as_str()),
719                SIPStatus::RequestTerminated => ConnectState::no_answer(self.on_no_answer.as_str()),
720                SIPStatus::BusyHere | SIPStatus::BusyEverywhere => {
721                    ConnectState::busy(self.on_busy.as_str())
722                }
723                _ => ConnectState::fail(self.on_fail.as_str()),
724            },
725            None => ConnectState::dialling(),
726        }
727    }
728}
729
730#[derive(Serialize, Deserialize, Clone)]
731#[serde(rename_all = "camelCase")]
732pub struct Play {
733    pub url: String,
734    pub connect_to: String,
735}
736
737impl Connector for Play {
738    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
739        ConnectState::default(&self.connect_to, None)
740    }
741}
742
743#[derive(Serialize, Deserialize, Clone)]
744#[serde(rename_all = "camelCase")]
745pub struct Say {
746    pub text: String,
747    #[serde(rename = "ttsLanguage")]
748    #[serde(default = "build_tts_voice")]
749    pub tts_voice: String,
750    #[serde(default = "build_connect_to")]
751    pub connect_to: String,
752}
753
754impl Connector for Say {
755    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
756        ConnectState::default(&self.connect_to, None)
757    }
758}
759
760#[derive(Serialize, Deserialize, Clone)]
761#[serde(rename_all = "camelCase")]
762pub struct VoiceMail {
763    pub text: String,
764    #[serde(rename = "ttsLanguage")]
765    #[serde(default = "build_tts_voice")]
766    pub tts_voice: String,
767    #[serde(default = "build_vm_finish_key")]
768    pub finish_on_key: String,
769    #[serde(default)]
770    pub email_recipients: Vec<String>,
771    #[serde(default = "build_vm_timeout")]
772    pub timeout: u8,
773    #[serde(default = "build_vm_max_length")]
774    pub max_length: u8,
775    #[serde(default)]
776    pub transcribe_options: TranscribeOptions,
777    #[serde(default)]
778    pub record_options: RecordOptions,
779    #[serde(default)]
780    pub play_beep: bool,
781    #[serde(default = "build_connect_to")]
782    pub connect_to: String,
783}
784
785impl Connector for VoiceMail {
786    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
787        ConnectState::default(&self.connect_to, None)
788    }
789}
790
791#[derive(Serialize, Deserialize, Clone)]
792#[serde(rename_all = "camelCase")]
793pub struct TimeRangeRouter {
794    start: DateTime,
795    end: DateTime,
796    #[serde(default = "build_default_timezone")]
797    pub timezone: String,
798    #[serde(default = "build_connect_to")]
799    pub on_match: String,
800    #[serde(default = "build_connect_to")]
801    pub connect_to: String,
802}
803
804impl Connector for TimeRangeRouter {
805    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
806        let now = Local::now().naive_utc().time();
807        let start = self.start.to_chrono().naive_utc().time();
808        let end = self.end.to_chrono().naive_utc().time();
809        let within = now < end && now > start;
810        if within {
811            ConnectState::matched(self.on_match.as_str(), Some(now.to_string()), None)
812        } else {
813            ConnectState::default(self.on_match.as_str(), Some(now.to_string()))
814        }
815    }
816}
817
818#[derive(Serialize, Deserialize, Clone)]
819#[serde(rename_all = "camelCase")]
820pub struct DayOfWeekRouter {
821    #[serde(default)]
822    pub days: Vec<u32>,
823    #[serde(default = "build_default_timezone")]
824    pub timezone: String,
825    #[serde(default = "build_connect_to")]
826    pub on_match: String,
827    #[serde(default = "build_connect_to")]
828    pub connect_to: String,
829}
830
831impl Connector for DayOfWeekRouter {
832    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
833        let now = Local::now().naive_local();
834        let within = self.days.contains(&now.day());
835        if within {
836            ConnectState::matched(self.on_match.as_str(), Some(now.to_string()), None)
837        } else {
838            ConnectState::default(self.connect_to.as_str(), Some(now.to_string()))
839        }
840    }
841}
842
843#[derive(Serialize, Deserialize, Clone)]
844#[serde(rename_all = "camelCase")]
845pub struct DateRangeRouter {
846    start: DateTime,
847    end: DateTime,
848    #[serde(default = "build_default_timezone")]
849    pub timezone: String,
850    #[serde(default = "build_connect_to")]
851    pub on_match: String,
852    #[serde(default = "build_connect_to")]
853    pub connect_to: String,
854}
855
856impl Connector for DateRangeRouter {
857    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
858        let now = Utc::now().naive_utc();
859        let start = self.start.to_chrono().naive_utc();
860        let end = self.end.to_chrono().naive_utc();
861        let within = now < end && now > start;
862        if within {
863            ConnectState::matched(self.on_match.as_str(), Some(now.to_string()), None)
864        } else {
865            ConnectState::default(self.connect_to.as_str(), Some(now.to_string()))
866        }
867    }
868}
869
870#[derive(Serialize, Deserialize, Clone)]
871#[serde(rename_all = "camelCase")]
872pub struct Script {
873    pub code: String,
874    #[serde(default = "build_connect_to")]
875    pub connect_to: String,
876}
877
878impl Connector for Script {
879    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
880        ConnectState::default(&self.connect_to, None)
881    }
882}
883
884#[derive(Serialize, Deserialize, Clone)]
885#[serde(rename_all = "camelCase")]
886pub struct Queue {
887    #[serde(default = "build_connect_to")]
888    pub connect_to: String,
889    // #[serde(default)]
890    // hangup: bool,
891    // #[serde(rename = "loop")]
892    // loop_count: u8,
893    // queue_name: String,
894    // ring_endpoints: bool,
895    // tts_language: String,
896    // items: Vec<QueueItem>,
897}
898
899//todo()
900impl Connector for Queue {
901    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
902        ConnectState::default(&self.connect_to, None)
903    }
904}
905
906#[derive(Serialize, Deserialize, Clone)]
907#[serde(rename_all = "camelCase")]
908pub struct QueueItem {
909    pub text: String,
910    #[serde(rename = "type")]
911    pub item_type: QueueItemType,
912}
913
914#[derive(Serialize, Deserialize, Clone)]
915#[serde(rename_all = "camelCase")]
916pub struct Email {
917    #[serde(default = "build_connect_to")]
918    pub connect_to: String,
919}
920
921impl Connector for Email {
922    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
923        ConnectState::default(&self.connect_to, None)
924    }
925}
926
927#[derive(Serialize, Deserialize, Clone)]
928#[serde(rename_all = "camelCase")]
929pub struct Sms {
930    #[serde(default = "build_connect_to")]
931    pub connect_to: String,
932}
933
934impl Connector for Sms {
935    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
936        ConnectState::default(&self.connect_to, None)
937    }
938}
939
940#[derive(Serialize, Deserialize, Clone)]
941#[serde(rename_all = "camelCase")]
942pub struct Tag {
943    #[serde(default = "build_connect_to")]
944    pub connect_to: String,
945}
946
947impl Connector for Tag {
948    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
949        ConnectState::default(&self.connect_to, None)
950    }
951}
952
953#[derive(Serialize, Deserialize, Clone)]
954#[serde(rename_all = "camelCase")]
955pub struct TagRouter {
956    #[serde(default = "build_connect_to")]
957    pub connect_to: String,
958}
959
960impl Connector for TagRouter {
961    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
962        ConnectState::default(&self.connect_to, None)
963    }
964}
965
966#[derive(Serialize, Deserialize, Clone)]
967#[serde(rename_all = "camelCase")]
968pub struct Service {
969    #[serde(default = "build_connect_to")]
970    pub connect_to: String,
971}
972
973impl Connector for Service {
974    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
975        ConnectState::default(&self.connect_to, None)
976    }
977}
978
979#[derive(Serialize, Deserialize, Clone)]
980#[serde(rename_all = "camelCase")]
981pub struct MessagePlugin {
982    #[serde(default = "build_connect_to")]
983    pub connect_to: String,
984}
985
986impl Connector for MessagePlugin {
987    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
988        ConnectState::default(&self.connect_to, None)
989    }
990}
991
992#[derive(Serialize, Deserialize, Clone)]
993#[serde(rename_all = "camelCase")]
994pub struct MessageText {
995    #[serde(default = "build_connect_to")]
996    pub connect_to: String,
997}
998
999#[derive(Serialize, Deserialize, Clone)]
1000#[serde(rename_all = "camelCase")]
1001pub struct MessageButtons {
1002    #[serde(default = "build_connect_to")]
1003    pub connect_to: String,
1004}
1005
1006#[derive(Serialize, Deserialize, Clone)]
1007#[serde(rename_all = "camelCase")]
1008pub struct MessageTemplate {
1009    #[serde(default = "build_connect_to")]
1010    pub connect_to: String,
1011}
1012
1013#[derive(Serialize, Deserialize, Clone)]
1014#[serde(rename_all = "camelCase")]
1015pub struct MessageAniRouter {
1016    #[serde(default = "build_connect_to")]
1017    pub connect_to: String,
1018}
1019
1020#[derive(Serialize, Deserialize, Clone)]
1021#[serde(rename_all = "camelCase")]
1022pub struct MessageDnisRouter {
1023    #[serde(default = "build_connect_to")]
1024    pub connect_to: String,
1025}
1026
1027impl Connector for MessageText {
1028    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
1029        ConnectState::default(&self.connect_to, None)
1030    }
1031}
1032#[derive(Serialize, Deserialize, Clone)]
1033#[serde(rename_all = "camelCase")]
1034pub struct Event {
1035    #[serde(default = "build_connect_to")]
1036    pub connect_to: String,
1037}
1038impl Connector for Event {
1039    fn get_connect_to(&mut self, _state: &mut FlowState) -> ConnectState {
1040        ConnectState::default(&self.connect_to, None)
1041    }
1042}
1043
1044#[derive(Serialize, Deserialize, Clone)]
1045#[serde(rename_all = "camelCase")]
1046pub struct MapBox {
1047    #[serde(default)]
1048    pub bounds: MapBoxBoundary,
1049    #[serde(default)]
1050    pub features: Vec<MapBoxFeature>,
1051}
1052
1053#[derive(Serialize, Deserialize, Clone)]
1054#[serde(rename_all = "camelCase")]
1055pub struct MapBoxBoundary {
1056    pub xmin: f32,
1057    pub ymin: f32,
1058    pub xmax: f32,
1059    pub ymax: f32,
1060}
1061
1062impl Default for MapBoxBoundary {
1063    fn default() -> Self {
1064        Self {
1065            xmin: 0.00,
1066            ymin: 1.00,
1067            xmax: 0.01,
1068            ymax: 1.01,
1069        }
1070    }
1071}
1072
1073#[derive(Serialize, Deserialize, Clone)]
1074#[serde(rename_all = "camelCase")]
1075pub struct MapBoxFeature {
1076    pub id: String,
1077    #[serde(rename = "type")]
1078    pub feature_type: String,
1079    pub geometry: MapBoxGeometry,
1080}
1081
1082#[derive(Serialize, Deserialize, Clone)]
1083#[serde(rename_all = "camelCase")]
1084pub struct MapBoxGeometry {
1085    #[serde(rename = "type")]
1086    pub geometry_type: String,
1087    pub coordinates: Vec<Vec<(f32, f32)>>,
1088}
1089
1090#[derive(Serialize, Deserialize, Clone)]
1091#[serde(rename_all = "camelCase")]
1092pub struct RouterOption {
1093    pub option: String,
1094    #[serde(default = "build_connect_to")]
1095    pub connect_to: String,
1096}
1097
1098#[derive(Serialize, Deserialize, Clone)]
1099pub struct TranscribeOptions {
1100    pub enabled: bool,
1101    pub language: AsrVendor,
1102}
1103
1104impl Default for TranscribeOptions {
1105    fn default() -> Self {
1106        Self {
1107            enabled: false,
1108            language: AsrVendor::Google,
1109        }
1110    }
1111}
1112
1113#[derive(Serialize, Deserialize, Clone)]
1114#[serde(rename_all = "camelCase")]
1115pub struct RecordOptions {
1116    #[serde(default = "build_record")]
1117    pub enabled: bool,
1118    #[serde(default = "build_record_retention")]
1119    pub retention: String,
1120    #[serde(default = "build_mix_type")]
1121    pub mix_type: MixType,
1122    #[serde(default = "build_sample_rate")]
1123    pub sample_rate: SampleRate,
1124}
1125
1126impl Default for RecordOptions {
1127    fn default() -> Self {
1128        Self {
1129            enabled: false,
1130            retention: String::from(DEFAULT_RECORDING_RETENTION),
1131            mix_type: MixType::Stereo,
1132            sample_rate: SampleRate::SR8000,
1133        }
1134    }
1135}
1136
1137#[derive(Serialize, Deserialize, Clone)]
1138pub struct AiOptions {
1139    pub transcribe: bool,
1140    pub summary: bool,
1141    pub recognizer: Option<Recognizer>,
1142}
1143
1144impl Default for AiOptions {
1145    fn default() -> Self {
1146        Self {
1147            transcribe: false,
1148            summary: false,
1149            recognizer: None,
1150        }
1151    }
1152}
1153
1154#[derive(Serialize, Deserialize, Clone)]
1155pub struct CallControl {
1156    enabled: bool,
1157    channels: u8,
1158    stats: bool,
1159    action: CacAction,
1160}
1161
1162impl Default for CallControl {
1163    fn default() -> Self {
1164        CallControl {
1165            enabled: false,
1166            channels: 0,
1167            stats: false,
1168            action: CacAction::Warn,
1169        }
1170    }
1171}
1172
1173#[derive(Serialize, Deserialize, Clone)]
1174#[serde(rename_all = "camelCase")]
1175pub enum CacAction {
1176    Warn,
1177    Deny,
1178}
1179pub fn build_record() -> bool {
1180    false
1181}
1182
1183pub fn build_record_retention() -> String {
1184    String::from(DEFAULT_RECORDING_RETENTION)
1185}
1186
1187pub fn build_mix_type() -> MixType {
1188    MixType::Stereo
1189}
1190
1191pub fn build_sample_rate() -> SampleRate {
1192    SampleRate::SR8000
1193}
1194
1195pub fn build_connect_to() -> String {
1196    String::from(HANG_UP_CONNECT)
1197}
1198
1199pub fn build_tts_voice() -> String {
1200    String::from(DEFAULT_TTS_VOICE)
1201}
1202
1203pub fn build_vm_finish_key() -> String {
1204    String::from(DEFAULT_VM_FINISH_KEY)
1205}
1206
1207pub fn build_default_timezone() -> String {
1208    String::from(DEFAULT_TIMEZONE)
1209}
1210
1211pub fn build_vm_timeout() -> u8 {
1212    DEFAULT_VM_TIMEOUT
1213}
1214
1215pub fn build_vm_max_length() -> u8 {
1216    DEFAULT_VM_MAX_LENGTH
1217}
1218
1219pub fn build_present() -> String {
1220    String::from(DEFAULT_ENDPOINT_PRESENT)
1221}
1222
1223pub fn build_destination() -> String {
1224    String::from(DEFAULT_REMOTE_DESTINATION)
1225}
1226
1227pub fn build_format() -> NumberFormat {
1228    NumberFormat::National
1229}
1230
1231pub fn build_client_profile() -> ClientProfile {
1232    ClientProfile::GenericE164Plus
1233}
1234
1235pub fn build_country_code() -> String {
1236    String::from(DEFAULT_COUNTRY_CODE)
1237}
1238
1239pub fn build_finish_key() -> String {
1240    String::from(DEFAULT_DIGITS_FINISH_KEY)
1241}
1242
1243pub fn build_call_time() -> u16 {
1244    DEFAULT_CALL_TIME
1245}
1246
1247pub fn build_ring_time() -> u8 {
1248    DEFAULT_RING_TIME
1249}
1250
1251pub fn build_digit_timeout() -> u8 {
1252    DEFAULT_DIGIT_TIMEOUT
1253}
1254
1255pub fn build_max_digits() -> u8 {
1256    DEFAULT_MAX_DIGITS
1257}