cal_core/device/
teams.rs

1use crate::device::device::{
2    AiOptions, CallControl, Connector, Endpoint, RecordOptions, TagType, TranscribeOptions,
3};
4use crate::device::utils::{get_caller_id, get_listen, get_transcribe};
5use crate::{ConnectState, FlowState, NumberFormat, VoiceServer, format_number};
6use cal_jambonz::dial::TranscribeDial;
7use cal_jambonz::listen::Listen;
8use cal_jambonz::shared::shared::SIPStatus;
9use serde::{Deserialize, Serialize};
10
11#[derive(Serialize, Deserialize, Clone)]
12#[serde(rename_all = "camelCase")]
13pub struct Teams {
14    pub to: String,
15    #[serde(default = "crate::device::device::build_present")]
16    pub present: String,
17    #[serde(default = "crate::device::device::build_country_code")]
18    pub country_code: String,
19    #[serde(default = "crate::device::device::build_connect_to")]
20    pub on_complete: String,
21    #[serde(default = "crate::device::device::build_connect_to")]
22    pub on_busy: String,
23    #[serde(default = "crate::device::device::build_connect_to")]
24    pub on_fail: String,
25    #[serde(default = "crate::device::device::build_connect_to")]
26    pub on_no_answer: String,
27    #[serde(default = "crate::device::device::build_ring_time")]
28    pub ring_time: u8,
29    #[serde(default = "crate::device::device::build_call_time")]
30    pub max_call_time: u16,
31    #[serde(default)]
32    pub transcribe_options: TranscribeOptions,
33    #[serde(default)]
34    pub record_options: RecordOptions,
35    #[serde(default)]
36    pub ai_options: AiOptions,
37    #[serde(default)]
38    pub call_control: CallControl,
39}
40
41impl Connector for Teams {
42    fn get_connect_to(&mut self, state: &mut FlowState) -> ConnectState {
43        match &state.get_dial_status() {
44            Some(status) => match status {
45                SIPStatus::Ok => ConnectState::complete(self.on_complete.as_str()),
46                SIPStatus::RequestTerminated => ConnectState::no_answer(self.on_no_answer.as_str()),
47                SIPStatus::BusyHere | SIPStatus::BusyEverywhere => {
48                    ConnectState::busy(self.on_busy.as_str())
49                }
50                _ => ConnectState::fail(self.on_fail.as_str()),
51            },
52            None => ConnectState::dialling(),
53        }
54    }
55}
56
57impl Endpoint for Teams {
58    fn get_caller_id(&self, state: &FlowState) -> String {
59        if self.present == "pass-through" {
60            get_caller_id(&NumberFormat::E164Plus, state)
61        } else {
62            format_number(
63                &self.present,
64                state.get_country_code(),
65                NumberFormat::E164Plus.clone(),
66            )
67        }
68    }
69
70    fn get_called_id(&self, state: &FlowState) -> String {
71        let mut destination = self.to.clone();
72        for (key, value) in state.data.clone() {
73            if value.tag_type == TagType::Session {
74                let formatted = format_number(
75                    value.value.clone().as_str(),
76                    state.get_country_code(),
77                    NumberFormat::E164Plus,
78                );
79                let replace = format!("[request.{}]", key);
80                destination = destination.replace(replace.as_str(), formatted.as_str());
81            }
82        }
83        destination.clone()
84    }
85
86    fn get_listen(&self, state: &FlowState) -> Option<Listen> {
87        get_listen(&self.record_options, self.ai_options.clone(), state)
88    }
89
90    fn get_proxy(&self, state: &FlowState) -> Option<VoiceServer> {
91        let mut voice_server: Option<VoiceServer> = None;
92        if state.account.teams.domain != "" {
93            for region in state.regions.iter() {
94                for vs in &region.voice_servers {
95                    if vs.public_ip == state.account.cluster_settings.server_a {
96                        voice_server = Some(vs.clone());
97                    }
98                }
99            }
100        }
101        voice_server
102    }
103
104    fn get_transcribe(&self, _state: &FlowState) -> Option<TranscribeDial> {
105        get_transcribe(self.transcribe_options.clone())
106    }
107}