8
8
Core ,
9
9
EventEnum
10
10
};
11
+ use RTCKit \Eqivo \Rest \Controller \V0_1 \Call ;
11
12
13
+ use React \EventLoop \Loop ;
14
+ use RTCKit \ESL ;
12
15
use stdClass as Event ;
13
16
14
17
class Custom implements HandlerInterface
@@ -20,36 +23,156 @@ class Custom implements HandlerInterface
20
23
21
24
public function execute (Core $ core , Event $ event ): void
22
25
{
23
- if (!isset ($ event ->{'Event-Subclass ' }, $ event -> Action , $ event ->{ ' Conference-Unique-ID ' } )) {
26
+ if (!isset ($ event ->{'Event-Subclass ' })) {
24
27
return ;
25
28
}
26
29
27
- if ($ event ->{'Event-Subclass ' } === 'conference::maintenance ' ) {
28
- $ conference = $ core ->getConference ($ event ->{'Conference-Unique-ID ' });
30
+ switch ($ event ->{'Event-Subclass ' }) {
31
+ case 'conference::maintenance ' :
32
+ if (!isset ($ event ->Action , $ event ->{'Conference-Unique-ID ' })) {
33
+ return ;
34
+ }
29
35
30
- if (!isset ($ conference )) {
31
- return ;
32
- }
36
+ $ conference = $ core ->getConference ($ event ->{'Conference-Unique-ID ' });
37
+
38
+ if (!isset ($ conference )) {
39
+ return ;
40
+ }
41
+
42
+ switch ($ event ->Action ) {
43
+ case 'stop-recording ' :
44
+ if (!isset ($ this ->app ->config ->recordUrl )) {
45
+ return ;
46
+ }
33
47
34
- switch ($ event ->Action ) {
35
- case 'stop-recording ' :
36
- if (!isset ($ this ->app ->config ->recordUrl )) {
48
+ $ params = [
49
+ 'RecordFile ' => $ event ->Path ,
50
+ 'RecordDuration ' => isset ($ event ->{'Milliseconds-Elapsed ' }) ? (int )$ event ->{'Milliseconds-Elapsed ' } : -1 ,
51
+ ];
52
+
53
+ $ this ->app ->inboundServer ->logger ->info ('Conference Record Stop event ' . json_encode ($ params ));
54
+ $ this ->app ->inboundServer ->controller ->fireConferenceCallback ($ conference , $ this ->app ->config ->recordUrl , $ this ->app ->config ->defaultHttpMethod , $ params );
55
+ return ;
56
+
57
+ case 'conference-destroy ' :
58
+ $ core ->removeConference ($ event ->{'Conference-Unique-ID ' });
37
59
return ;
60
+ }
61
+
62
+ return ;
63
+
64
+ case 'amd::info ' :
65
+ $ session = $ core ->getSession ($ event ->{'Unique-ID ' });
66
+
67
+ if (!isset ($ session )) {
68
+ return ;
69
+ }
70
+
71
+ $ this ->app ->inboundServer ->logger ->info ('AMD event ' . json_encode ($ event ));
72
+ $ isAmdEvent = true ;
73
+
74
+ $ session ->amdDuration = (int )(((int )$ event ->variable_amd_result_microtime - (int )$ event ->{'Caller-Channel-Answered-Time ' }) / 1000 );
75
+ $ session ->amdAnsweredBy = 'unknown ' ;
76
+
77
+ $ result = $ event ->variable_amd_result ?? 'NOTSURE ' ;
78
+ $ isMachine = false ;
79
+
80
+ switch ($ result ) {
81
+ case 'HUMAN ' :
82
+ $ session ->amdAnsweredBy = 'human ' ;
83
+ break ;
84
+
85
+ case 'MACHINE ' :
86
+ $ isMachine = true ;
87
+ $ session ->amdAnsweredBy = 'machine_start ' ;
88
+ break ;
89
+ }
90
+
91
+ $ session ->amdMethod = $ event ->{"variable_ {$ this ->app ->config ->appPrefix }_amd_method " } ?? Call::DEFAULT_AMD_METHOD ;
92
+ $ session ->amdAsync = $ event ->{"variable_ {$ this ->app ->config ->appPrefix }_amd_async " } === 'on ' ;
93
+
94
+ if ($ session ->amdAsync ) {
95
+ $ urlVar = "variable_ {$ this ->app ->config ->appPrefix }_amd_url " ;
96
+
97
+ if (isset ($ event ->{$ urlVar })) {
98
+ $ session ->amdUrl = $ event ->{$ urlVar };
38
99
}
100
+ } else {
101
+ $ session ->amdUrl = $ event ->{"variable_ {$ this ->app ->config ->appPrefix }_amd_target_url " };
102
+ }
103
+
104
+ if ($ isMachine && isset ($ event ->{"variable_ {$ this ->app ->config ->appPrefix }_amd_msg_end " })) {
105
+ /* Kick off AVMD */
106
+ $ this ->app ->inboundServer ->logger ->info ('Activating AVMD (DetectMessageEnd enabled) ' );
107
+
108
+ $ session ->client ->sendMsg (
109
+ (new ESL \Request \SendMsg )
110
+ ->setHeader ('call-command ' , 'execute ' )
111
+ ->setHeader ('execute-app-name ' , 'avmd_start ' )
112
+ );
113
+
114
+ $ timeout = (float )$ event ->{"variable_ {$ this ->app ->config ->appPrefix }_amd_timeout " } - ($ session ->amdDuration / 1000 );
115
+
116
+ $ session ->avmdTimer = Loop::addTimer ($ timeout , function () use ($ session ): void {
117
+ unset($ session ->avmdTimer );
39
118
40
- $ params = [
41
- 'RecordFile ' => $ event ->Path ,
42
- 'RecordDuration ' => isset ($ event ->{'Milliseconds-Elapsed ' }) ? (int )$ event ->{'Milliseconds-Elapsed ' } : -1 ,
43
- ];
119
+ $ session ->client ->sendMsg (
120
+ (new ESL \Request \SendMsg )
121
+ ->setHeader ('call-command ' , 'execute ' )
122
+ ->setHeader ('execute-app-name ' , 'event ' )
123
+ ->setHeader ('execute-app-arg ' , 'Event-Subclass=avmd::timeout,Event-Name=CUSTOM ' )
124
+ );
125
+ });
44
126
45
- $ this ->app ->inboundServer ->logger ->info ('Conference Record Stop event ' . json_encode ($ params ));
46
- $ this ->app ->inboundServer ->controller ->fireConferenceCallback ($ conference , $ this ->app ->config ->recordUrl , $ this ->app ->config ->defaultHttpMethod , $ params );
47
127
return ;
128
+ }
129
+
130
+ case 'avmd::timeout ' :
131
+ case 'avmd::beep ' :
132
+ if (!isset ($ isAmdEvent )) {
133
+ $ session = $ core ->getSession ($ event ->{'Unique-ID ' });
134
+
135
+ if (!isset ($ session )) {
136
+ return ;
137
+ }
138
+
139
+ $ this ->app ->inboundServer ->logger ->info ('AVMD event ' . json_encode ($ event ));
48
140
49
- case 'conference-destroy ' :
50
- $ core ->removeConference ($ event ->{'Conference-Unique-ID ' });
141
+ if (isset ($ session ->avmdTimer )) {
142
+ Loop::cancelTimer ($ session ->avmdTimer );
143
+ unset($ session ->avmdTimer );
144
+ }
145
+
146
+ $ session ->client ->sendMsg (
147
+ (new ESL \Request \SendMsg )
148
+ ->setHeader ('call-command ' , 'execute ' )
149
+ ->setHeader ('execute-app-name ' , 'avmd_stop ' )
150
+ );
151
+
152
+ $ session ->amdAnsweredBy = ($ event ->{'Event-Subclass ' } === 'avmd::beep ' ) ? 'machine_end_beep ' : 'machine_end_other ' ;
153
+ }
154
+
155
+ if (!isset ($ session )) {
51
156
return ;
52
- }
157
+ }
158
+
159
+ $ method = $ event ->{"variable_ {$ this ->app ->config ->appPrefix }_amd_method " } ?? Call::DEFAULT_AMD_METHOD ;
160
+ $ params = [
161
+ 'AnsweredBy ' => $ session ->amdAnsweredBy ,
162
+ 'MachineDetectionDuration ' => $ session ->amdDuration ,
163
+ ];
164
+
165
+ if ($ session ->amdAsync ) {
166
+ /* Asynchronous, just fire the callback, if configured */
167
+ if (isset ($ session ->amdUrl )) {
168
+ $ this ->app ->inboundServer ->controller ->fireSessionCallback ($ session , $ session ->amdUrl , $ session ->amdMethod , $ params );
169
+ }
170
+ } else {
171
+ /* Synchronous? Kick off call flow execution */
172
+ $ this ->app ->outboundServer ->controller ->fetchAndExecuteRestXml ($ session , $ session ->amdUrl , $ session ->amdMethod , $ params );
173
+ }
174
+
175
+ return ;
53
176
}
54
177
}
55
178
}
0 commit comments