1use super::playbacks::Playback;
2#[cfg(feature = "parse-event-datetimes")]
3use crate::models::channels::ari_date_format;
4use crate::models::channels::Channel;
5use crate::models::recordings::Recording;
6#[cfg(feature = "parse-event-datetimes")]
7use chrono::{DateTime, Utc};
8use serde::{Deserialize, Serialize};
9
10#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
15pub struct Message {
16 #[serde(rename = "type")]
18 pub r#type: String,
19
20 #[serde(skip_serializing_if = "Option::is_none")]
22 pub asterisk_id: Option<String>,
23}
24
25#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
26pub struct Event {
27 #[serde(rename = "type")]
29 pub r#type: String,
30
31 #[serde(skip_serializing_if = "Option::is_none")]
33 pub asterisk_id: Option<String>,
34
35 pub application: String,
37
38 #[cfg(feature = "parse-event-datetimes")]
40 #[serde(with = "ari_date_format")]
41 pub timestamp: DateTime<Utc>,
42
43 #[cfg(not(feature = "parse-event-datetimes"))]
44 pub timestamp: String,
45}
46
47#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
48pub struct StasisStart {
49 #[serde(skip_serializing_if = "Option::is_none")]
51 pub asterisk_id: Option<String>,
52
53 pub application: String,
55
56 #[cfg(feature = "parse-event-datetimes")]
58 #[serde(with = "ari_date_format")]
59 pub timestamp: DateTime<Utc>,
60
61 #[cfg(not(feature = "parse-event-datetimes"))]
62 pub timestamp: String,
63
64 pub args: Vec<String>,
66
67 pub channel: Channel,
69
70 #[serde(skip_serializing_if = "Option::is_none")]
72 pub replace_channel: Option<Channel>,
73}
74
75#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
76pub struct ChannelDtmfReceived {
77 #[serde(skip_serializing_if = "Option::is_none")]
79 pub asterisk_id: Option<String>,
80
81 pub application: String,
83
84 #[cfg(feature = "parse-event-datetimes")]
86 #[serde(with = "ari_date_format")]
87 pub timestamp: DateTime<Utc>,
88
89 #[cfg(not(feature = "parse-event-datetimes"))]
90 pub timestamp: String,
91
92 pub digit: String,
94
95 pub duration_ms: i64,
97
98 pub channel: Channel,
100}
101
102#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
103pub struct ChannelHangupRequest {
104 #[serde(skip_serializing_if = "Option::is_none")]
106 pub asterisk_id: Option<String>,
107
108 pub application: String,
110
111 #[cfg(feature = "parse-event-datetimes")]
113 #[serde(with = "ari_date_format")]
114 pub timestamp: DateTime<Utc>,
115
116 #[cfg(not(feature = "parse-event-datetimes"))]
117 pub timestamp: String,
118
119 #[serde(skip_serializing_if = "Option::is_none")]
121 pub cause: Option<i64>,
122
123 #[serde(skip_serializing_if = "Option::is_none")]
125 pub soft: Option<bool>,
126
127 pub channel: Channel,
129}
130
131#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
132pub struct StasisEnd {
133 #[serde(skip_serializing_if = "Option::is_none")]
135 pub asterisk_id: Option<String>,
136
137 pub application: String,
139
140 #[cfg(feature = "parse-event-datetimes")]
142 #[serde(with = "ari_date_format")]
143 pub timestamp: DateTime<Utc>,
144
145 #[cfg(not(feature = "parse-event-datetimes"))]
146 pub timestamp: String,
147
148 pub channel: Channel,
150}
151
152#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
153pub struct ChannelTalkingFinished {
154 #[serde(skip_serializing_if = "Option::is_none")]
156 pub asterisk_id: Option<String>,
157
158 pub application: String,
160
161 #[cfg(feature = "parse-event-datetimes")]
163 #[serde(with = "ari_date_format")]
164 pub timestamp: DateTime<Utc>,
165
166 #[cfg(not(feature = "parse-event-datetimes"))]
167 pub timestamp: String,
168
169 pub channel: Channel,
171
172 pub duration: i64,
174}
175
176#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
177pub struct ChannelTalkingStarted {
178 #[serde(skip_serializing_if = "Option::is_none")]
180 pub asterisk_id: Option<String>,
181
182 pub application: String,
184
185 #[cfg(feature = "parse-event-datetimes")]
187 #[serde(with = "ari_date_format")]
188 pub timestamp: DateTime<Utc>,
189
190 #[cfg(not(feature = "parse-event-datetimes"))]
191 pub timestamp: String,
192
193 pub channel: Channel,
195}
196
197#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
198pub struct ChannelDestroyed {
199 #[serde(skip_serializing_if = "Option::is_none")]
201 pub asterisk_id: Option<String>,
202
203 pub application: String,
205
206 #[cfg(feature = "parse-event-datetimes")]
208 #[serde(with = "ari_date_format")]
209 pub timestamp: DateTime<Utc>,
210
211 #[cfg(not(feature = "parse-event-datetimes"))]
212 pub timestamp: String,
213
214 pub cause: i64,
216
217 pub cause_txt: String,
219
220 pub channel: Channel,
222}
223
224#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
225pub struct PlaybackStarted {
226 #[serde(skip_serializing_if = "Option::is_none")]
228 pub asterisk_id: Option<String>,
229
230 pub application: String,
232
233 #[cfg(feature = "parse-event-datetimes")]
235 #[serde(with = "ari_date_format")]
236 pub timestamp: DateTime<Utc>,
237
238 #[cfg(not(feature = "parse-event-datetimes"))]
239 pub timestamp: String,
240
241 pub playback: Playback,
243}
244
245#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
246pub struct PlaybackFinished {
247 #[serde(skip_serializing_if = "Option::is_none")]
249 pub asterisk_id: Option<String>,
250
251 pub application: String,
253
254 #[cfg(feature = "parse-event-datetimes")]
256 #[serde(with = "ari_date_format")]
257 pub timestamp: DateTime<Utc>,
258
259 #[cfg(not(feature = "parse-event-datetimes"))]
260 pub timestamp: String,
261
262 pub playback: Playback,
264}
265
266#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
267pub struct ChannelStateChange {
268 #[serde(skip_serializing_if = "Option::is_none")]
270 pub asterisk_id: Option<String>,
271
272 pub application: String,
274
275 #[cfg(feature = "parse-event-datetimes")]
277 #[serde(with = "ari_date_format")]
278 pub timestamp: DateTime<Utc>,
279
280 #[cfg(not(feature = "parse-event-datetimes"))]
281 pub timestamp: String,
282
283 pub channel: Channel,
285}
286
287#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
288pub struct ChannelVarset {
289 #[serde(skip_serializing_if = "Option::is_none")]
291 pub asterisk_id: Option<String>,
292
293 pub application: String,
295
296 #[cfg(feature = "parse-event-datetimes")]
298 #[serde(with = "ari_date_format")]
299 pub timestamp: DateTime<Utc>,
300
301 #[cfg(not(feature = "parse-event-datetimes"))]
302 pub timestamp: String,
303
304 pub channel: Channel,
306
307 pub variable: String,
308
309 pub value: String,
310}
311
312#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
313pub struct RecordingStarted {
314 #[serde(skip_serializing_if = "Option::is_none")]
316 pub asterisk_id: Option<String>,
317
318 pub application: String,
320
321 #[cfg(feature = "parse-event-datetimes")]
323 #[serde(with = "ari_date_format")]
324 pub timestamp: DateTime<Utc>,
325
326 #[cfg(not(feature = "parse-event-datetimes"))]
327 pub timestamp: String,
328
329 pub recording: Recording,
331}
332
333#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
334pub struct RecordingFinished {
335 #[serde(skip_serializing_if = "Option::is_none")]
337 pub asterisk_id: Option<String>,
338
339 pub application: String,
341
342 #[cfg(feature = "parse-event-datetimes")]
344 #[serde(with = "ari_date_format")]
345 pub timestamp: DateTime<Utc>,
346
347 #[cfg(not(feature = "parse-event-datetimes"))]
348 pub timestamp: String,
349
350 pub recording: Recording,
352}
353
354#[derive(Debug, Serialize, Deserialize)]
355#[serde(tag = "type")]
356pub enum AriEvent {
357 StasisStart(StasisStart),
358 ChannelDtmfReceived(ChannelDtmfReceived),
359 ChannelHangupRequest(ChannelHangupRequest),
360 StasisEnd(StasisEnd),
361 ChannelTalkingFinished(ChannelTalkingFinished),
362 ChannelTalkingStarted(ChannelTalkingStarted),
363 ChannelDestroyed(ChannelDestroyed),
364 PlaybackStarted(PlaybackStarted),
365 PlaybackFinished(PlaybackFinished),
366 ChannelStateChange(ChannelStateChange),
367 ChannelVarset(ChannelVarset),
368 RecordingStarted(RecordingStarted),
369 RecordingFinished(RecordingFinished),
370}
371
372#[cfg(test)]
373mod tests {
374 use super::*;
375
376 const STR_JSON: &str = "{\n \"type\": \"StasisStart\",\n \"timestamp\": \"2020-11-22T20:17:06.150+0000\",\n \"args\": [\n \"its-va-demo-app\",\n \"en-US\"\n ],\n \"channel\": {\n \"id\": \"1606076223.3\",\n \"name\": \"PJSIP/6001-00000003\",\n \"state\": \"Up\",\n \"caller\": {\n \"name\": \"\",\n \"number\": \"6001\"\n },\n \"connected\": {\n \"name\": \"\",\n \"number\": \"\"\n },\n \"accountcode\": \"\",\n \"dialplan\": {\n \"context\": \"from-internal\",\n \"exten\": \"101\",\n \"priority\": 6,\n \"app_name\": \"Stasis\",\n \"app_data\": \"va-voicegw,its-va-demo-app,en-US\"\n },\n \"creationtime\": \"2020-11-22T20:17:03.741+0000\",\n \"language\": \"en\"\n },\n \"asterisk_id\": \"00:15:5d:01:65:04\",\n \"application\": \"va-voicegw\"\n}";
377 const STR_JSON2: &str = "{\n \"type\": \"StasisStart\",\n \"timestamp\": \"2021-01-07T21:12:57.268+0100\",\n \"args\": [\n \"freight-cs-voice\",\n \"en-US\"\n ],\n \"channel\": {\n \"id\": \"1610050377.0\",\n \"name\": \"SIP/1004-00000000\",\n \"state\": \"Ring\",\n \"caller\": {\n \"name\": \"Adam\",\n \"number\": \"1004\"\n },\n \"connected\": {\n \"name\": \"\",\n \"number\": \"\"\n },\n \"accountcode\": \"\",\n \"dialplan\": {\n \"context\": \"internal\",\n \"exten\": \"158\",\n \"priority\": 10,\n \"app_name\": \"Stasis\",\n \"app_data\": \"va-voicegw-rs,freight-cs-voice,en-US\"\n },\n \"creationtime\": \"2021-01-07T21:12:57.267+0100\",\n \"language\": \"en\"\n },\n \"asterisk_id\": \"00:50:56:98:74:21\",\n \"application\": \"va-voicegw-rs\"\n}";
378
379 const STR_JSON_CHNL_STATE_CHANGED: &str = "{\n \"type\": \"ChannelStateChange\",\n \"timestamp\": \"2021-01-07T22:12:29.571+0100\",\n \"channel\": {\n \"id\": \"1610053949.0\",\n \"name\": \"SIP/1004-00000000\",\n \"state\": \"Up\",\n \"caller\": {\n \"name\": \"Adam\",\n \"number\": \"1004\"\n },\n \"connected\": {\n \"name\": \"\",\n \"number\": \"\"\n },\n \"accountcode\": \"\",\n \"dialplan\": {\n \"context\": \"internal\",\n \"exten\": \"158\",\n \"priority\": 10,\n \"app_name\": \"Stasis\",\n \"app_data\": \"va-voicegw-rs,freight-cs-voice,en-US\"\n },\n \"creationtime\": \"2021-01-07T22:12:29.369+0100\",\n \"language\": \"en\"\n },\n \"asterisk_id\": \"00:50:56:98:74:21\",\n \"application\": \"va-voicegw-rs\"\n}";
380
381 #[test]
383 fn test_parse_stasis_start() {
384 let ari_event: StasisStart = serde_json::from_str(STR_JSON).unwrap();
385 println!("{:#?}", ari_event);
386 }
387
388 #[test]
398 fn test_2_parse_stasis_start() {
399 let ari_event: StasisStart = serde_json::from_str(STR_JSON2).unwrap();
400 println!("{:#?}", ari_event);
401 }
402
403 #[test]
405 fn test_parse_channel_state_change() {
406 let ari_event: ChannelStateChange =
407 serde_json::from_str(STR_JSON_CHNL_STATE_CHANGED).unwrap();
408 println!("{:#?}", ari_event);
409 }
410
411 #[test]
414 fn test_parse_ari_event_stasis_start() {
415 let ari_event: AriEvent = serde_json::from_str(STR_JSON).unwrap();
416 println!("{:#?}", ari_event);
417 }
418}