1use crate::{apis, ws};
2use futures_util::StreamExt;
3use std::collections::HashMap;
4use std::future::Future;
5use std::ops::Deref;
6use std::pin::Pin;
7use std::sync::Arc;
8use tracing::debug;
9
10type Handler = Arc<
11 dyn Fn(Arc<apis::client::Client>, ws::models::Event) -> Pin<Box<dyn Future<Output = ()> + Send>>
12 + Send
13 + Sync,
14>;
15
16#[derive(Clone)]
19pub struct AriClient {
20 client: Arc<apis::client::Client>,
21 ws: Arc<ws::client::Client>,
22 event_handlers: HashMap<String, Handler>,
23}
24
25impl AriClient {
26 pub fn with_config(config: crate::config::Config) -> Self {
36 AriClient {
37 client: Arc::new(apis::client::Client::with_config(config.clone())),
38 ws: Arc::new(ws::client::Client::with_config(config)),
39 event_handlers: HashMap::new(),
40 }
41 }
42
43 pub fn on_unknown_event<F, Fut>(&mut self, handler: F) -> &mut Self
53 where
54 F: Fn(Arc<apis::client::Client>, ws::models::Event) -> Fut + Send + Sync + 'static,
55 Fut: Future<Output = ()> + Send + 'static,
56 {
57 self.event_handlers.insert(
58 "Unknown".to_string(),
59 Arc::new(move |client, event| Box::pin(handler(client, event))),
60 );
61 self
62 }
63
64 pub fn on_event<F, Fut>(&mut self, key: String, handler: F) -> &mut Self
75 where
76 F: Fn(Arc<apis::client::Client>, ws::models::Event) -> Fut + Send + Sync + 'static,
77 Fut: Future<Output = ()> + Send + 'static,
78 {
79 self.event_handlers.insert(
80 key,
81 Arc::new(move |client, event| Box::pin(handler(client, event))),
82 );
83 self
84 }
85
86 pub async fn start(&self, application_name: String) -> crate::errors::Result<()> {
96 let mut stream = self
97 .ws
98 .connect(ws::params::ListenRequest::new(application_name))
99 .await?;
100
101 while let Some(event) = stream.next().await {
102 if let Some(handler) = self.event_handlers.get(&event.to_string()) {
103 handler(self.client.clone(), event).await;
104 } else {
105 debug!(
107 "No handler registered for event type: {}",
108 event.to_string()
109 );
110 }
111 }
112
113 Ok(())
114 }
115
116 pub fn stop(&self) {
118 self.ws.disconnect();
119 }
120
121 pub fn ws(&self) -> &ws::client::Client {
127 &self.ws
128 }
129
130 pub fn client(&self) -> &apis::client::Client {
136 &self.client
137 }
138}
139
140impl Deref for AriClient {
141 type Target = apis::client::Client;
142
143 fn deref(&self) -> &Self::Target {
149 &self.client
150 }
151}
152
153macro_rules! create_event_handler {
155 ($($event_name:ident => $event_variant:ident),*) => {
156 impl AriClient {
157 $(
158 pub fn $event_name<F, Fut>(&mut self, handler: F) -> &mut Self
168 where
169 F: Fn(Arc<apis::client::Client>, ws::models::BaseEvent<ws::models::$event_variant>) -> Fut
170 + Send
171 + Sync
172 + 'static,
173 Fut: Future<Output = ()> + Send + 'static,
174 {
175 let handler = Arc::new(handler); self.on_event(stringify!($event_variant).to_string(), move |client, event| {
178 let handler = handler.clone(); async move {
180 if let ws::models::Event::$event_variant(e) = event {
181 handler(client, e).await;
182 } else {
183 unreachable!(); }
185 }
186 });
187
188 self
189 }
190 )*
191 }
192 };
193}
194
195create_event_handler!(
196 on_application_move_failed => ApplicationMoveFailed,
197 on_application_replaced => ApplicationReplaced,
198 on_bridge_attended_transfer => BridgeAttendedTransfer,
199 on_bridge_blind_transfer => BridgeBlindTransfer,
200 on_bridge_created => BridgeCreated,
201 on_bridge_destroyed => BridgeDestroyed,
202 on_bridge_merged => BridgeMerged,
203 on_bridge_video_source_changed => BridgeVideoSourceChanged,
204 on_channel_caller_id => ChannelCallerId,
205 on_channel_connected_line => ChannelConnectedLine,
206 on_channel_created => ChannelCreated,
207 on_channel_destroyed => ChannelDestroyed,
208 on_channel_dialplan => ChannelDialplan,
209 on_channel_dtmf_received => ChannelDtmfReceived,
210 on_channel_entered_bridge => ChannelEnteredBridge,
211 on_channel_hangup_request => ChannelHangupRequest,
212 on_channel_hold => ChannelHold,
213 on_channel_left_bridge => ChannelLeftBridge,
214 on_channel_state_change => ChannelStateChange,
215 on_channel_talking_finished => ChannelTalkingFinished,
216 on_channel_talking_started => ChannelTalkingStarted,
217 on_channel_tone_detected => ChannelToneDetected,
218 on_channel_unhold => ChannelUnhold,
219 on_channel_user_event => ChannelUserEvent,
220 on_channel_var_set => ChannelVarSet,
221 on_contact_info => ContactInfo,
222 on_contact_status_change => ContactStatusChange,
223 on_device_state_changed => DeviceStateChanged,
224 on_dial => Dial,
225 on_endpoint_state_change => EndpointStateChange,
226 on_missing_params => MissingParams,
227 on_peer => Peer,
228 on_peer_status_change => PeerStatusChange,
229 on_playback_continuing => PlaybackContinuing,
230 on_playback_finished => PlaybackFinished,
231 on_playback_started => PlaybackStarted,
232 on_recording_failed => RecordingFailed,
233 on_recording_finished => RecordingFinished,
234 on_recording_started => RecordingStarted,
235 on_stasis_end => StasisEnd,
236 on_stasis_start => StasisStart,
237 on_text_message_received => TextMessageReceived
238);