| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package SignalWire::Agents::Relay::Action; |
|
2
|
4
|
|
|
4
|
|
2714
|
use strict; |
|
|
4
|
|
|
|
|
14
|
|
|
|
4
|
|
|
|
|
211
|
|
|
3
|
4
|
|
|
4
|
|
43
|
use warnings; |
|
|
4
|
|
|
|
|
12
|
|
|
|
4
|
|
|
|
|
251
|
|
|
4
|
4
|
|
|
4
|
|
22
|
use Moo; |
|
|
4
|
|
|
|
|
8
|
|
|
|
4
|
|
|
|
|
27
|
|
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
# Base Action class for long-running RELAY operations. |
|
7
|
|
|
|
|
|
|
# Tracks control_id, completion state, and supports blocking wait. |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
has 'control_id' => ( is => 'ro', required => 1 ); |
|
10
|
|
|
|
|
|
|
has 'call_id' => ( is => 'ro', default => sub { '' } ); |
|
11
|
|
|
|
|
|
|
has 'node_id' => ( is => 'ro', default => sub { '' } ); |
|
12
|
|
|
|
|
|
|
has 'state' => ( is => 'rw', default => sub { 'created' } ); |
|
13
|
|
|
|
|
|
|
has 'completed' => ( is => 'rw', default => sub { 0 } ); # boolean |
|
14
|
|
|
|
|
|
|
has 'result' => ( is => 'rw', default => sub { undef } ); |
|
15
|
|
|
|
|
|
|
has 'events' => ( is => 'rw', default => sub { [] } ); |
|
16
|
|
|
|
|
|
|
has 'payload' => ( is => 'rw', default => sub { {} } ); # latest event payload |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
has '_on_completed' => ( is => 'rw', default => sub { undef } ); |
|
19
|
|
|
|
|
|
|
has '_client' => ( is => 'rw', default => sub { undef } ); |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# Register on_completed callback |
|
22
|
|
|
|
|
|
|
sub on_completed { |
|
23
|
3
|
|
|
3
|
0
|
17
|
my ($self, $cb) = @_; |
|
24
|
3
|
50
|
|
|
|
6
|
if ($cb) { |
|
25
|
3
|
|
|
|
|
9
|
$self->_on_completed($cb); |
|
26
|
|
|
|
|
|
|
# If already done, fire immediately |
|
27
|
3
|
100
|
|
|
|
5
|
if ($self->completed) { |
|
28
|
1
|
|
|
|
|
2
|
eval { $cb->($self) }; |
|
|
1
|
|
|
|
|
3
|
|
|
29
|
1
|
50
|
|
|
|
4
|
warn "on_completed callback error: $@" if $@; |
|
30
|
|
|
|
|
|
|
} |
|
31
|
3
|
|
|
|
|
6
|
return $self; |
|
32
|
|
|
|
|
|
|
} |
|
33
|
0
|
|
|
|
|
0
|
return $self->_on_completed; |
|
34
|
|
|
|
|
|
|
} |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
# Check if the action is done |
|
37
|
|
|
|
|
|
|
sub is_done { |
|
38
|
4
|
|
|
4
|
0
|
2212
|
my ($self) = @_; |
|
39
|
4
|
|
|
|
|
25
|
return $self->completed; |
|
40
|
|
|
|
|
|
|
} |
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
# Blocking wait using select() polling loop |
|
43
|
|
|
|
|
|
|
sub wait { |
|
44
|
1
|
|
|
1
|
0
|
4
|
my ($self, %opts) = @_; |
|
45
|
1
|
|
50
|
|
|
3
|
my $timeout = $opts{timeout} || 30; |
|
46
|
1
|
|
|
|
|
2
|
my $start = time(); |
|
47
|
1
|
|
33
|
|
|
6
|
while (!$self->completed && (time() - $start) < $timeout) { |
|
48
|
0
|
|
|
|
|
0
|
select(undef, undef, undef, 0.1); # sleep 100ms |
|
49
|
|
|
|
|
|
|
} |
|
50
|
1
|
|
|
|
|
4
|
return $self->result; |
|
51
|
|
|
|
|
|
|
} |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
# Called by event dispatch when an event is received for this action |
|
54
|
|
|
|
|
|
|
sub _handle_event { |
|
55
|
0
|
|
|
0
|
|
0
|
my ($self, $event) = @_; |
|
56
|
0
|
|
|
|
|
0
|
push @{$self->events}, $event; |
|
|
0
|
|
|
|
|
0
|
|
|
57
|
0
|
|
0
|
|
|
0
|
$self->payload($event->params // {}); |
|
58
|
|
|
|
|
|
|
|
|
59
|
0
|
0
|
|
|
|
0
|
my $state = $event->can('state') ? $event->state : ''; |
|
60
|
0
|
0
|
|
|
|
0
|
$self->state($state) if $state; |
|
61
|
|
|
|
|
|
|
} |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
# Mark the action as completed with a result |
|
64
|
|
|
|
|
|
|
sub _resolve { |
|
65
|
7
|
|
|
7
|
|
547
|
my ($self, $result) = @_; |
|
66
|
7
|
100
|
|
|
|
22
|
return if $self->completed; |
|
67
|
6
|
|
|
|
|
15
|
$self->completed(1); |
|
68
|
6
|
|
|
|
|
19
|
$self->result($result); |
|
69
|
|
|
|
|
|
|
|
|
70
|
6
|
100
|
|
|
|
27
|
if (my $cb = $self->_on_completed) { |
|
71
|
2
|
|
|
|
|
2
|
eval { $cb->($self) }; |
|
|
2
|
|
|
|
|
5
|
|
|
72
|
2
|
50
|
|
|
|
9
|
warn "on_completed callback error: $@" if $@; |
|
73
|
|
|
|
|
|
|
} |
|
74
|
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
# Send a sub-command on this action (e.g., play.stop, record.pause) |
|
77
|
|
|
|
|
|
|
sub _execute_subcommand { |
|
78
|
0
|
|
|
0
|
|
0
|
my ($self, $method) = @_; |
|
79
|
0
|
|
|
|
|
0
|
my $client = $self->_client; |
|
80
|
0
|
0
|
|
|
|
0
|
return unless $client; |
|
81
|
0
|
|
|
|
|
0
|
return $client->execute($method, { |
|
82
|
|
|
|
|
|
|
node_id => $self->node_id, |
|
83
|
|
|
|
|
|
|
call_id => $self->call_id, |
|
84
|
|
|
|
|
|
|
control_id => $self->control_id, |
|
85
|
|
|
|
|
|
|
}); |
|
86
|
|
|
|
|
|
|
} |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
# Stop the action |
|
89
|
|
|
|
|
|
|
sub stop { |
|
90
|
0
|
|
|
0
|
0
|
0
|
my ($self) = @_; |
|
91
|
0
|
0
|
|
|
|
0
|
return if $self->completed; |
|
92
|
0
|
|
|
|
|
0
|
return $self->_execute_subcommand($self->_stop_method); |
|
93
|
|
|
|
|
|
|
} |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
# Override in subclasses |
|
96
|
0
|
|
|
0
|
|
0
|
sub _stop_method { return '' } |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# --- PlayAction --- |
|
99
|
|
|
|
|
|
|
package SignalWire::Agents::Relay::Action::Play; |
|
100
|
4
|
|
|
4
|
|
5447
|
use Moo; |
|
|
4
|
|
|
|
|
10
|
|
|
|
4
|
|
|
|
|
21
|
|
|
101
|
|
|
|
|
|
|
extends 'SignalWire::Agents::Relay::Action'; |
|
102
|
|
|
|
|
|
|
|
|
103
|
1
|
|
|
1
|
|
619
|
sub _stop_method { 'calling.play.stop' } |
|
104
|
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
sub pause { |
|
106
|
0
|
|
|
0
|
0
|
0
|
my ($self) = @_; |
|
107
|
0
|
|
|
|
|
0
|
return $self->_execute_subcommand('calling.play.pause'); |
|
108
|
|
|
|
|
|
|
} |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
sub resume { |
|
111
|
0
|
|
|
0
|
0
|
0
|
my ($self) = @_; |
|
112
|
0
|
|
|
|
|
0
|
return $self->_execute_subcommand('calling.play.resume'); |
|
113
|
|
|
|
|
|
|
} |
|
114
|
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
sub volume { |
|
116
|
0
|
|
|
0
|
0
|
0
|
my ($self, $vol) = @_; |
|
117
|
0
|
|
|
|
|
0
|
my $client = $self->_client; |
|
118
|
0
|
0
|
|
|
|
0
|
return unless $client; |
|
119
|
0
|
|
|
|
|
0
|
return $client->execute('calling.play.volume', { |
|
120
|
|
|
|
|
|
|
node_id => $self->node_id, |
|
121
|
|
|
|
|
|
|
call_id => $self->call_id, |
|
122
|
|
|
|
|
|
|
control_id => $self->control_id, |
|
123
|
|
|
|
|
|
|
volume => $vol, |
|
124
|
|
|
|
|
|
|
}); |
|
125
|
|
|
|
|
|
|
} |
|
126
|
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
# --- RecordAction --- |
|
128
|
|
|
|
|
|
|
package SignalWire::Agents::Relay::Action::Record; |
|
129
|
4
|
|
|
4
|
|
2726
|
use Moo; |
|
|
4
|
|
|
|
|
11
|
|
|
|
4
|
|
|
|
|
21
|
|
|
130
|
|
|
|
|
|
|
extends 'SignalWire::Agents::Relay::Action'; |
|
131
|
|
|
|
|
|
|
|
|
132
|
1
|
|
|
1
|
|
333
|
sub _stop_method { 'calling.record.stop' } |
|
133
|
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
sub pause { |
|
135
|
0
|
|
|
0
|
0
|
0
|
my ($self, %opts) = @_; |
|
136
|
0
|
|
|
|
|
0
|
my $client = $self->_client; |
|
137
|
0
|
0
|
|
|
|
0
|
return unless $client; |
|
138
|
0
|
|
|
|
|
0
|
my $params = { |
|
139
|
|
|
|
|
|
|
node_id => $self->node_id, |
|
140
|
|
|
|
|
|
|
call_id => $self->call_id, |
|
141
|
|
|
|
|
|
|
control_id => $self->control_id, |
|
142
|
|
|
|
|
|
|
}; |
|
143
|
0
|
0
|
|
|
|
0
|
$params->{behavior} = $opts{behavior} if $opts{behavior}; |
|
144
|
0
|
|
|
|
|
0
|
return $client->execute('calling.record.pause', $params); |
|
145
|
|
|
|
|
|
|
} |
|
146
|
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
sub resume { |
|
148
|
0
|
|
|
0
|
0
|
0
|
my ($self) = @_; |
|
149
|
0
|
|
|
|
|
0
|
return $self->_execute_subcommand('calling.record.resume'); |
|
150
|
|
|
|
|
|
|
} |
|
151
|
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
# Result accessors |
|
153
|
0
|
|
0
|
0
|
0
|
0
|
sub url { $_[0]->payload->{url} // '' } |
|
154
|
0
|
|
0
|
0
|
0
|
0
|
sub duration { $_[0]->payload->{duration} // 0 } |
|
155
|
0
|
|
0
|
0
|
0
|
0
|
sub size { $_[0]->payload->{size} // 0 } |
|
156
|
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
# --- DetectAction --- |
|
158
|
|
|
|
|
|
|
package SignalWire::Agents::Relay::Action::Detect; |
|
159
|
4
|
|
|
4
|
|
3215
|
use Moo; |
|
|
4
|
|
|
|
|
10
|
|
|
|
4
|
|
|
|
|
23
|
|
|
160
|
|
|
|
|
|
|
extends 'SignalWire::Agents::Relay::Action'; |
|
161
|
|
|
|
|
|
|
|
|
162
|
1
|
|
|
1
|
|
6
|
sub _stop_method { 'calling.detect.stop' } |
|
163
|
|
|
|
|
|
|
|
|
164
|
0
|
|
0
|
0
|
0
|
0
|
sub detect_result { $_[0]->payload->{detect} // {} } |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
# --- CollectAction --- |
|
167
|
|
|
|
|
|
|
package SignalWire::Agents::Relay::Action::Collect; |
|
168
|
4
|
|
|
4
|
|
2292
|
use Moo; |
|
|
4
|
|
|
|
|
28
|
|
|
|
4
|
|
|
|
|
35
|
|
|
169
|
|
|
|
|
|
|
extends 'SignalWire::Agents::Relay::Action'; |
|
170
|
|
|
|
|
|
|
|
|
171
|
1
|
|
|
1
|
|
6
|
sub _stop_method { 'calling.collect.stop' } |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
sub start_input_timers { |
|
174
|
0
|
|
|
0
|
0
|
0
|
my ($self) = @_; |
|
175
|
0
|
|
|
|
|
0
|
return $self->_execute_subcommand('calling.collect.start_input_timers'); |
|
176
|
|
|
|
|
|
|
} |
|
177
|
|
|
|
|
|
|
|
|
178
|
0
|
|
0
|
0
|
0
|
0
|
sub collect_result { $_[0]->payload->{result} // {} } |
|
179
|
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
# Override event handling: for play_and_collect, ignore play events |
|
181
|
|
|
|
|
|
|
sub _handle_event { |
|
182
|
1
|
|
|
1
|
|
6
|
my ($self, $event) = @_; |
|
183
|
|
|
|
|
|
|
# If this is a play_and_collect action, only resolve on collect events |
|
184
|
1
|
50
|
|
|
|
9
|
if ($event->event_type eq 'calling.call.play') { |
|
185
|
|
|
|
|
|
|
# Ignore play events for collect actions (play_and_collect gotcha) |
|
186
|
1
|
|
|
|
|
2
|
return; |
|
187
|
|
|
|
|
|
|
} |
|
188
|
0
|
|
|
|
|
0
|
$self->SUPER::_handle_event($event); |
|
189
|
|
|
|
|
|
|
} |
|
190
|
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
# --- FaxAction --- |
|
192
|
|
|
|
|
|
|
package SignalWire::Agents::Relay::Action::Fax; |
|
193
|
4
|
|
|
4
|
|
2609
|
use Moo; |
|
|
4
|
|
|
|
|
12
|
|
|
|
4
|
|
|
|
|
18
|
|
|
194
|
|
|
|
|
|
|
extends 'SignalWire::Agents::Relay::Action'; |
|
195
|
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
has '_fax_type' => ( is => 'ro', default => sub { 'send' } ); |
|
197
|
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
sub _stop_method { |
|
199
|
2
|
|
|
2
|
|
8
|
my ($self) = @_; |
|
200
|
2
|
100
|
|
|
|
12
|
return $self->_fax_type eq 'receive' |
|
201
|
|
|
|
|
|
|
? 'calling.receive_fax.stop' |
|
202
|
|
|
|
|
|
|
: 'calling.send_fax.stop'; |
|
203
|
|
|
|
|
|
|
} |
|
204
|
|
|
|
|
|
|
|
|
205
|
0
|
|
0
|
0
|
0
|
0
|
sub fax_result { $_[0]->payload->{fax} // {} } |
|
206
|
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
# --- TapAction --- |
|
208
|
|
|
|
|
|
|
package SignalWire::Agents::Relay::Action::Tap; |
|
209
|
4
|
|
|
4
|
|
2424
|
use Moo; |
|
|
4
|
|
|
|
|
8
|
|
|
|
4
|
|
|
|
|
19
|
|
|
210
|
|
|
|
|
|
|
extends 'SignalWire::Agents::Relay::Action'; |
|
211
|
|
|
|
|
|
|
|
|
212
|
1
|
|
|
1
|
|
6
|
sub _stop_method { 'calling.tap.stop' } |
|
213
|
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
# --- StreamAction --- |
|
215
|
|
|
|
|
|
|
package SignalWire::Agents::Relay::Action::Stream; |
|
216
|
4
|
|
|
4
|
|
1574
|
use Moo; |
|
|
4
|
|
|
|
|
8
|
|
|
|
4
|
|
|
|
|
14
|
|
|
217
|
|
|
|
|
|
|
extends 'SignalWire::Agents::Relay::Action'; |
|
218
|
|
|
|
|
|
|
|
|
219
|
1
|
|
|
1
|
|
6
|
sub _stop_method { 'calling.stream.stop' } |
|
220
|
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
# --- PayAction --- |
|
222
|
|
|
|
|
|
|
package SignalWire::Agents::Relay::Action::Pay; |
|
223
|
4
|
|
|
4
|
|
1651
|
use Moo; |
|
|
4
|
|
|
|
|
23
|
|
|
|
4
|
|
|
|
|
36
|
|
|
224
|
|
|
|
|
|
|
extends 'SignalWire::Agents::Relay::Action'; |
|
225
|
|
|
|
|
|
|
|
|
226
|
1
|
|
|
1
|
|
6
|
sub _stop_method { 'calling.pay.stop' } |
|
227
|
|
|
|
|
|
|
|
|
228
|
0
|
|
0
|
0
|
0
|
0
|
sub pay_result { $_[0]->payload->{result} // {} } |
|
229
|
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
# --- TranscribeAction --- |
|
231
|
|
|
|
|
|
|
package SignalWire::Agents::Relay::Action::Transcribe; |
|
232
|
4
|
|
|
4
|
|
1849
|
use Moo; |
|
|
4
|
|
|
|
|
15
|
|
|
|
4
|
|
|
|
|
17
|
|
|
233
|
|
|
|
|
|
|
extends 'SignalWire::Agents::Relay::Action'; |
|
234
|
|
|
|
|
|
|
|
|
235
|
1
|
|
|
1
|
|
7
|
sub _stop_method { 'calling.transcribe.stop' } |
|
236
|
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
# --- AIAction --- |
|
238
|
|
|
|
|
|
|
package SignalWire::Agents::Relay::Action::AI; |
|
239
|
4
|
|
|
4
|
|
1779
|
use Moo; |
|
|
4
|
|
|
|
|
2173
|
|
|
|
4
|
|
|
|
|
22
|
|
|
240
|
|
|
|
|
|
|
extends 'SignalWire::Agents::Relay::Action'; |
|
241
|
|
|
|
|
|
|
|
|
242
|
1
|
|
|
1
|
|
8
|
sub _stop_method { 'calling.ai.stop' } |
|
243
|
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
1; |