cal_core/device/
client.rs1use crate::device::device::{
2 AiOptions, CallControl, Connector, Endpoint, RecordOptions, TranscribeOptions,
3};
4use crate::device::utils::{get_caller_id, get_listen, get_transcribe};
5use crate::{ConnectState, FlowState, NumberFormat, RecordReference, 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 Client {
14 pub username: String,
15 pub password: String,
16 #[serde(default = "crate::device::device::build_client_profile")]
17 pub profile: ClientProfile,
18 pub user: Option<RecordReference>,
19 #[serde(default = "crate::device::device::build_format")]
20 pub format: NumberFormat,
21 #[serde(default = "crate::device::device::build_present")]
22 pub present: String,
23 #[serde(default = "crate::device::device::build_country_code")]
24 pub country_code: String,
25 #[serde(default = "crate::device::device::build_connect_to")]
26 pub on_complete: String,
27 #[serde(default = "crate::device::device::build_connect_to")]
28 pub on_busy: String,
29 #[serde(default = "crate::device::device::build_connect_to")]
30 pub on_fail: String,
31 #[serde(default = "crate::device::device::build_connect_to")]
32 pub on_no_answer: String,
33 #[serde(default = "crate::device::device::build_ring_time")]
34 pub ring_time: u8,
35 #[serde(default = "crate::device::device::build_call_time")]
36 pub max_call_time: u16,
37 #[serde(default)]
38 pub transcribe_options: TranscribeOptions,
39 #[serde(default)]
40 pub record_options: RecordOptions,
41 #[serde(default)]
42 pub ai_options: AiOptions,
43 #[serde(default)]
44 pub call_control: CallControl,
45}
46
47impl Endpoint for Client {
48 fn get_caller_id(&self, state: &FlowState) -> String {
49 get_caller_id(&self.format, state)
50 }
51
52 fn get_called_id(&self, state: &FlowState) -> String {
53 let country_code = state.account.country_code();
54 let mut called_id = match state.data.get("to") {
55 Some(dt) => dt.value.clone(),
56 None => state.initial_request.to.clone(),
57 };
58 called_id = format_number(
59 called_id.as_str(),
60 state.account.country_code(),
61 self.format.clone(),
62 );
63 match self.profile {
64 ClientProfile::GenericSoftphone
65 | ClientProfile::CallablePhone
66 | ClientProfile::Avaya
67 | ClientProfile::Generic => called_id,
68 ClientProfile::GenericE164Plus => {
69 format_number(called_id.as_str(), country_code, NumberFormat::E164Plus)
70 }
71 ClientProfile::AvayaE164 => {
72 format_number(called_id.as_str(), country_code, NumberFormat::E164)
73 }
74 }
75 }
76
77 fn get_listen(&self, state: &FlowState) -> Option<Listen> {
78 get_listen(&self.record_options, self.ai_options.clone(), state)
79 }
80
81 fn get_transcribe(&self, _state: &FlowState) -> Option<TranscribeDial> {
82 get_transcribe(self.transcribe_options.clone())
83 }
84}
85
86impl Connector for Client {
87 fn get_connect_to(&mut self, state: &mut FlowState) -> ConnectState {
88 match &state.get_dial_status() {
89 Some(status) => match status {
90 SIPStatus::Ok => ConnectState::complete(self.on_complete.as_str()),
91 SIPStatus::RequestTerminated => ConnectState::no_answer(self.on_no_answer.as_str()),
92 SIPStatus::BusyHere | SIPStatus::BusyEverywhere => {
93 ConnectState::busy(self.on_busy.as_str())
94 }
95 _ => ConnectState::fail(self.on_fail.as_str()),
96 },
97 None => ConnectState::dialling(),
98 }
99 }
100}
101
102#[derive(Serialize, Deserialize, Clone)]
103#[serde(rename_all = "snake_case")]
104pub enum ClientProfile {
105 Generic,
106 GenericE164Plus,
107 GenericSoftphone,
108 CallablePhone,
109 Avaya,
110 AvayaE164,
111}