punchblock 1.4.1 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +5 -0
- data/README.markdown +2 -1
- data/lib/punchblock.rb +0 -1
- data/lib/punchblock/command/accept.rb +1 -1
- data/lib/punchblock/command/answer.rb +1 -1
- data/lib/punchblock/command/dial.rb +1 -1
- data/lib/punchblock/command/hangup.rb +1 -1
- data/lib/punchblock/command/join.rb +1 -1
- data/lib/punchblock/command/redirect.rb +1 -1
- data/lib/punchblock/command/reject.rb +1 -1
- data/lib/punchblock/command/unjoin.rb +1 -1
- data/lib/punchblock/component/component_node.rb +3 -3
- data/lib/punchblock/component/input.rb +48 -94
- data/lib/punchblock/component/output.rb +54 -18
- data/lib/punchblock/component/record.rb +21 -32
- data/lib/punchblock/event/complete.rb +0 -4
- data/lib/punchblock/translator/asterisk/call.rb +1 -1
- data/lib/punchblock/version.rb +1 -1
- data/punchblock.gemspec +1 -1
- data/spec/punchblock/component/input_spec.rb +18 -16
- data/spec/punchblock/component/record_spec.rb +0 -4
- data/spec/punchblock/connection/xmpp_spec.rb +1 -1
- data/spec/punchblock/translator/asterisk/call_spec.rb +1 -0
- metadata +5 -7
- data/lib/punchblock/media_container.rb +0 -42
- data/lib/punchblock/media_node.rb +0 -19
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# [develop](https://github.com/adhearsion/punchblock)
|
2
2
|
|
3
|
+
# [v1.5.0](https://github.com/adhearsion/punchblock/compare/v1.4.1...v1.5.0) - [2012-10-01](https://rubygems.org/gems/punchblock/versions/1.5.0)
|
4
|
+
* Feature: Input component now supports grammar URLs
|
5
|
+
* Bugfix: Hanging up Asterisk calls now correctly specifies normal clearing cause
|
6
|
+
* Doc: Fix a bunch of API documentation
|
7
|
+
|
3
8
|
# [v1.4.1](https://github.com/adhearsion/punchblock/compare/v1.4.0...v1.4.1) - [2012-09-06](https://rubygems.org/gems/punchblock/versions/1.4.1)
|
4
9
|
* Bugfix: Cleaning up DTMF handlers for input components with a dead call should not crash on FreeSWITCH
|
5
10
|
* Bugfix: Reduced a race condition on FreeSWITCH when dispatching events from calls to dead components
|
data/README.markdown
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Punchblock
|
2
2
|
Punchblock is a middleware library for telephony applications. Like Rack is to Rails and Sinatra, Punchblock provides a consistent API on top of several underlying third-party call control protocols.
|
3
3
|
|
4
|
-
In the same spirit that inspired Rack, the Punchblock library is envisioned to be the single library for call control wiring. Frameworks and applications may take advantage of Punchblock's single API to write powerful code for managing calls. Punchblock is not and will not be an application framework; rather it only surfaces the various protocols and presents a consistent interface to its consumers.
|
4
|
+
In the same spirit that inspired Rack, the Punchblock library is envisioned to be the single library for call control wiring. Frameworks and applications may take advantage of Punchblock's single API to write powerful code for managing calls. Punchblock is not and will not be an application framework; rather it only surfaces the various protocols and presents a consistent interface to its consumers. NB: If you're looking to develop an application, you should take a look at the [Adhearsion](http://adhearsion.com) framework first. This library is much lower level.
|
5
5
|
|
6
6
|
## Installation
|
7
7
|
gem install punchblock
|
@@ -14,6 +14,7 @@ The best available usage documentation available for Punchblock is by example, i
|
|
14
14
|
|
15
15
|
* Rayo
|
16
16
|
* Asterisk (AMI & AsyncAGI)
|
17
|
+
* FreeSWITCH (Inbound Event Socket)
|
17
18
|
|
18
19
|
## Links:
|
19
20
|
* [Source](https://github.com/adhearsion/punchblock)
|
data/lib/punchblock.rb
CHANGED
@@ -8,7 +8,7 @@ module Punchblock
|
|
8
8
|
include HasHeaders
|
9
9
|
|
10
10
|
##
|
11
|
-
# Create
|
11
|
+
# Create a Rayo accept command. This is equivalent to a SIP "180 Trying"
|
12
12
|
#
|
13
13
|
# @param [Hash] options
|
14
14
|
# @option options [Array[Header], Hash, Optional] :headers SIP headers to attach to
|
@@ -8,7 +8,7 @@ module Punchblock
|
|
8
8
|
include HasHeaders
|
9
9
|
|
10
10
|
##
|
11
|
-
# Create
|
11
|
+
# Create a Rayo answer command. This is equivalent to a SIP "200 OK"
|
12
12
|
#
|
13
13
|
# @param [Hash] options
|
14
14
|
# @option options [Array[Header], Hash, Optional] :headers SIP headers to attach to
|
@@ -10,7 +10,7 @@ module Punchblock
|
|
10
10
|
VALID_REASONS = [:busy, :decline, :error].freeze
|
11
11
|
|
12
12
|
##
|
13
|
-
# Create
|
13
|
+
# Create a Rayo reject command
|
14
14
|
#
|
15
15
|
# @param [Hash] options
|
16
16
|
# @option options [Symbol] :reason for rejecting the call. Can be any one of VALID_REASONS. Defaults to :decline
|
@@ -54,16 +54,16 @@ module Punchblock
|
|
54
54
|
end
|
55
55
|
|
56
56
|
##
|
57
|
-
# Create
|
57
|
+
# Create a Rayo stop message
|
58
58
|
#
|
59
|
-
# @return [Stop]
|
59
|
+
# @return [Stop] a Rayo stop message
|
60
60
|
#
|
61
61
|
def stop_action
|
62
62
|
Stop.new :component_id => component_id, :target_call_id => target_call_id
|
63
63
|
end
|
64
64
|
|
65
65
|
##
|
66
|
-
# Sends
|
66
|
+
# Sends a Rayo stop message for the current component
|
67
67
|
#
|
68
68
|
def stop!(options = {})
|
69
69
|
raise InvalidActionError, "Cannot stop a #{self.class.name.split("::").last} that is not executing" unless executing?
|
@@ -6,30 +6,29 @@ module Punchblock
|
|
6
6
|
register :input, :input
|
7
7
|
|
8
8
|
##
|
9
|
-
# Create
|
9
|
+
# Create a input command
|
10
10
|
#
|
11
|
-
# @param [Hash] options
|
12
|
-
# @option options [
|
13
|
-
# @option options [
|
14
|
-
# @option options [
|
15
|
-
# @option options [
|
16
|
-
# @option options [
|
17
|
-
# @option options [String,
|
18
|
-
# @option options [
|
19
|
-
# @option options [
|
11
|
+
# @param [Hash] options
|
12
|
+
# @option options [Grammar, Hash] :grammar the grammar to activate
|
13
|
+
# @option options [Integer, optional] :max_silence the amount of time in milliseconds that an input command will wait until considered that a silence becomes a NO-MATCH
|
14
|
+
# @option options [Float, optional] :min_confidence with which to consider a response acceptable
|
15
|
+
# @option options [Symbol, optional] :mode by which to accept input. Can be :speech, :dtmf or :any
|
16
|
+
# @option options [String, optional] :recognizer to use for speech recognition
|
17
|
+
# @option options [String, optional] :terminator by which to signal the end of input
|
18
|
+
# @option options [Float, optional] :sensitivity Indicates how sensitive the interpreter should be to loud versus quiet input. Higher values represent greater sensitivity.
|
19
|
+
# @option options [Integer, optional] :initial_timeout Indicates the amount of time preceding input which may expire before a timeout is triggered.
|
20
|
+
# @option options [Integer, optional] :inter_digit_timeout Indicates (in the case of DTMF input) the amount of time between input digits which may expire before a timeout is triggered.
|
20
21
|
#
|
21
22
|
# @return [Command::Input] a formatted Rayo input command
|
22
23
|
#
|
23
24
|
# @example
|
24
|
-
# input :
|
25
|
-
# :
|
26
|
-
# :timeout => 30,
|
25
|
+
# input :grammar => {:value => '[5 DIGITS]', :content_type => 'application/grammar+voxeo'},
|
26
|
+
# :mode => :speech,
|
27
27
|
# :recognizer => 'es-es'
|
28
28
|
#
|
29
29
|
# returns:
|
30
|
-
# <input xmlns="urn:xmpp:
|
31
|
-
# <
|
32
|
-
# <choices content-type="application/grammar+voxeo">[5 DIGITS]</choices>
|
30
|
+
# <input xmlns="urn:xmpp:rayo:input:1" mode="speech" recognizer="es-es">
|
31
|
+
# <grammar content-type="application/grammar+voxeo">[5 DIGITS]</choices>
|
33
32
|
# </input>
|
34
33
|
#
|
35
34
|
def self.new(options = {})
|
@@ -38,20 +37,6 @@ module Punchblock
|
|
38
37
|
end
|
39
38
|
end
|
40
39
|
|
41
|
-
##
|
42
|
-
# @return [Boolean] wether or not to allow the caller to begin their response before the prompt finishes
|
43
|
-
#
|
44
|
-
def max_digits
|
45
|
-
read_attr :'max-digits', :to_i
|
46
|
-
end
|
47
|
-
|
48
|
-
##
|
49
|
-
# @param [Boolean] bargein wether or not to allow the caller to begin their response before the prompt finishes
|
50
|
-
#
|
51
|
-
def max_digits=(other)
|
52
|
-
write_attr :'max-digits', other
|
53
|
-
end
|
54
|
-
|
55
40
|
##
|
56
41
|
# @return [Integer] the amount of time in milliseconds that an input command will wait until considered that a silence becomes a NO-MATCH
|
57
42
|
#
|
@@ -123,91 +108,49 @@ module Punchblock
|
|
123
108
|
end
|
124
109
|
|
125
110
|
##
|
126
|
-
# @return [
|
111
|
+
# @return [Float] Indicates how sensitive the interpreter should be to loud versus quiet input. Higher values represent greater sensitivity.
|
127
112
|
#
|
128
113
|
def sensitivity
|
129
114
|
read_attr :sensitivity, :to_f
|
130
115
|
end
|
131
116
|
|
132
117
|
##
|
133
|
-
# @param [
|
118
|
+
# @param [Float] other Indicates how sensitive the interpreter should be to loud versus quiet input. Higher values represent greater sensitivity.
|
134
119
|
#
|
135
120
|
def sensitivity=(other)
|
136
121
|
write_attr :sensitivity, other
|
137
122
|
end
|
138
123
|
|
139
124
|
##
|
140
|
-
# @return [Integer]
|
125
|
+
# @return [Integer] Indicates the amount of time preceding input which may expire before a timeout is triggered.
|
141
126
|
#
|
142
127
|
def initial_timeout
|
143
128
|
read_attr :'initial-timeout', :to_i
|
144
129
|
end
|
145
130
|
|
146
131
|
##
|
147
|
-
# @param [Integer] timeout
|
132
|
+
# @param [Integer] timeout Indicates the amount of time preceding input which may expire before a timeout is triggered.
|
148
133
|
#
|
149
134
|
def initial_timeout=(other)
|
150
135
|
write_attr :'initial-timeout', other
|
151
136
|
end
|
152
137
|
|
153
138
|
##
|
154
|
-
# @return [Integer]
|
139
|
+
# @return [Integer] Indicates (in the case of DTMF input) the amount of time between input digits which may expire before a timeout is triggered.
|
155
140
|
#
|
156
141
|
def inter_digit_timeout
|
157
142
|
read_attr :'inter-digit-timeout', :to_i
|
158
143
|
end
|
159
144
|
|
160
145
|
##
|
161
|
-
# @param [Integer] timeout
|
146
|
+
# @param [Integer] timeout Indicates (in the case of DTMF input) the amount of time between input digits which may expire before a timeout is triggered.
|
162
147
|
#
|
163
148
|
def inter_digit_timeout=(other)
|
164
149
|
write_attr :'inter-digit-timeout', other
|
165
150
|
end
|
166
151
|
|
167
152
|
##
|
168
|
-
# @return [
|
169
|
-
#
|
170
|
-
def term_timeout
|
171
|
-
read_attr :'term-timeout', :to_i
|
172
|
-
end
|
173
|
-
|
174
|
-
##
|
175
|
-
# @param [Integer] timeout to wait for user input
|
176
|
-
#
|
177
|
-
def term_timeout=(other)
|
178
|
-
write_attr :'term-timeout', other
|
179
|
-
end
|
180
|
-
|
181
|
-
##
|
182
|
-
# @return [Integer] timeout to wait for user input
|
183
|
-
#
|
184
|
-
def complete_timeout
|
185
|
-
read_attr :'complete-timeout', :to_i
|
186
|
-
end
|
187
|
-
|
188
|
-
##
|
189
|
-
# @param [Integer] timeout to wait for user input
|
190
|
-
#
|
191
|
-
def complete_timeout=(other)
|
192
|
-
write_attr :'complete-timeout', other
|
193
|
-
end
|
194
|
-
|
195
|
-
##
|
196
|
-
# @return [Integer] timeout to wait for user input
|
197
|
-
#
|
198
|
-
def incomplete_timeout
|
199
|
-
read_attr :'incomplete-timeout', :to_i
|
200
|
-
end
|
201
|
-
|
202
|
-
##
|
203
|
-
# @param [Integer] timeout to wait for user input
|
204
|
-
#
|
205
|
-
def incomplete_timeout=(other)
|
206
|
-
write_attr :'incomplete-timeout', other
|
207
|
-
end
|
208
|
-
|
209
|
-
##
|
210
|
-
# @return [Choices] the choices available
|
153
|
+
# @return [Grammar] the grammar to activate
|
211
154
|
#
|
212
155
|
def grammar
|
213
156
|
node = find_first 'ns:grammar', :ns => self.class.registered_ns
|
@@ -215,9 +158,10 @@ module Punchblock
|
|
215
158
|
end
|
216
159
|
|
217
160
|
##
|
218
|
-
# @param [Hash]
|
219
|
-
# @option
|
220
|
-
# @option
|
161
|
+
# @param [Hash] other
|
162
|
+
# @option other [String] :content_type the document content type
|
163
|
+
# @option other [String] :value the grammar doucment
|
164
|
+
# @option other [String] :url the url from which to fetch the grammar
|
221
165
|
#
|
222
166
|
def grammar=(other)
|
223
167
|
return unless other
|
@@ -227,14 +171,15 @@ module Punchblock
|
|
227
171
|
end
|
228
172
|
|
229
173
|
def inspect_attributes # :nodoc:
|
230
|
-
[:mode, :terminator, :
|
174
|
+
[:mode, :terminator, :recognizer, :initial_timeout, :inter_digit_timeout, :sensitivity, :min_confidence, :grammar] + super
|
231
175
|
end
|
232
176
|
|
233
177
|
class Grammar < RayoNode
|
234
178
|
##
|
235
179
|
# @param [Hash] options
|
236
|
-
# @option options [String] :content_type
|
237
|
-
# @option options [String] :value the
|
180
|
+
# @option options [String] :content_type the document content type
|
181
|
+
# @option options [String] :value the grammar document
|
182
|
+
# @option options [String] :url the url from which to fetch the grammar
|
238
183
|
#
|
239
184
|
def self.new(options = {})
|
240
185
|
super(:grammar).tap do |new_node|
|
@@ -244,12 +189,13 @@ module Punchblock
|
|
244
189
|
when Hash
|
245
190
|
new_node.content_type = options[:content_type]
|
246
191
|
new_node.value = options[:value]
|
192
|
+
new_node.url = options[:url]
|
247
193
|
end
|
248
194
|
end
|
249
195
|
end
|
250
196
|
|
251
197
|
##
|
252
|
-
# @return [String] the
|
198
|
+
# @return [String] the document content type
|
253
199
|
#
|
254
200
|
def content_type
|
255
201
|
read_attr 'content-type'
|
@@ -263,8 +209,9 @@ module Punchblock
|
|
263
209
|
end
|
264
210
|
|
265
211
|
##
|
266
|
-
# @return [String] the
|
212
|
+
# @return [String, RubySpeech::GRXML::Grammar] the grammar document
|
267
213
|
def value
|
214
|
+
return nil unless content.present?
|
268
215
|
if grxml?
|
269
216
|
RubySpeech::GRXML.import content
|
270
217
|
else
|
@@ -273,7 +220,7 @@ module Punchblock
|
|
273
220
|
end
|
274
221
|
|
275
222
|
##
|
276
|
-
# @param [String] value the
|
223
|
+
# @param [String, RubySpeech::GRXML::Grammar] value the grammar document
|
277
224
|
def value=(value)
|
278
225
|
return unless value
|
279
226
|
if grxml? && !value.is_a?(RubySpeech::GRXML::Element)
|
@@ -284,15 +231,22 @@ module Punchblock
|
|
284
231
|
end
|
285
232
|
end
|
286
233
|
|
287
|
-
|
288
|
-
# @
|
289
|
-
#
|
290
|
-
def
|
291
|
-
|
234
|
+
##
|
235
|
+
# @return [String] the URL from which the fetch the grammar
|
236
|
+
#
|
237
|
+
def url
|
238
|
+
read_attr 'url'
|
239
|
+
end
|
240
|
+
|
241
|
+
##
|
242
|
+
# @param [String] other the URL from which the fetch the grammar
|
243
|
+
#
|
244
|
+
def url=(other)
|
245
|
+
write_attr 'url', other
|
292
246
|
end
|
293
247
|
|
294
248
|
def inspect_attributes # :nodoc:
|
295
|
-
[:content_type, :value] + super
|
249
|
+
[:content_type, :value, :url] + super
|
296
250
|
end
|
297
251
|
|
298
252
|
private
|
@@ -5,8 +5,6 @@ module Punchblock
|
|
5
5
|
class Output < ComponentNode
|
6
6
|
register :output, :output
|
7
7
|
|
8
|
-
include MediaContainer
|
9
|
-
|
10
8
|
##
|
11
9
|
# Creates an Rayo Output command
|
12
10
|
#
|
@@ -14,6 +12,12 @@ module Punchblock
|
|
14
12
|
# @option options [String, Optional] :text to speak back
|
15
13
|
# @option options [String, Optional] :voice with which to render TTS
|
16
14
|
# @option options [String, Optional] :ssml document to render TTS
|
15
|
+
# @option options [Symbol] :interrupt_on input type on which to interrupt output. May be :speech, :dtmf or :any
|
16
|
+
# @option options [Integer] :start_offset Indicates some offset through which the output should be skipped before rendering begins.
|
17
|
+
# @option options [true, false] :start_paused Indicates wether or not the component should be started in a paused state to be resumed at a later time.
|
18
|
+
# @option options [Integer] :repeat_interval Indicates the duration of silence that should space repeats of the rendered document.
|
19
|
+
# @option options [Integer] :repeat_times Indicates the number of times the output should be played.
|
20
|
+
# @option options [Integer] :max_time Indicates the maximum amount of time for which the output should be allowed to run before being terminated. Includes repeats.
|
17
21
|
#
|
18
22
|
# @return [Command::Output] an Rayo "output" command
|
19
23
|
#
|
@@ -21,13 +25,12 @@ module Punchblock
|
|
21
25
|
# output :text => 'Hello brown cow.'
|
22
26
|
#
|
23
27
|
# returns:
|
24
|
-
# <output xmlns="urn:xmpp:
|
28
|
+
# <output xmlns="urn:xmpp:rayo:output:1">Hello brown cow.</output>
|
25
29
|
#
|
26
30
|
def self.new(options = {})
|
27
31
|
super().tap do |new_node|
|
28
32
|
case options
|
29
33
|
when Hash
|
30
|
-
new_node.voice = options.delete(:voice) if options[:voice]
|
31
34
|
new_node.ssml = options.delete(:ssml) if options[:ssml]
|
32
35
|
new_node << options.delete(:text) if options[:text]
|
33
36
|
options.each_pair { |k,v| new_node.send :"#{k}=", v }
|
@@ -40,89 +43,122 @@ module Punchblock
|
|
40
43
|
##
|
41
44
|
# @return [String] the TTS voice to use
|
42
45
|
#
|
46
|
+
def voice
|
47
|
+
read_attr :voice
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# @param [String] voice to use when rendering TTS
|
52
|
+
#
|
53
|
+
def voice=(voice)
|
54
|
+
write_attr :voice, voice
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# @return [String] the SSML document to render TTS
|
59
|
+
#
|
60
|
+
def ssml
|
61
|
+
node = children.first
|
62
|
+
RubySpeech::SSML.import node if node
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# @param [String] ssml the SSML document to render TTS
|
67
|
+
#
|
68
|
+
def ssml=(ssml)
|
69
|
+
return unless ssml
|
70
|
+
unless ssml.is_a?(RubySpeech::SSML::Element)
|
71
|
+
ssml = RubySpeech::SSML.import ssml
|
72
|
+
end
|
73
|
+
self << ssml
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# @return [Symbol] input type on which to interrupt output
|
78
|
+
#
|
43
79
|
def interrupt_on
|
44
80
|
read_attr :'interrupt-on', :to_sym
|
45
81
|
end
|
46
82
|
|
47
83
|
##
|
48
|
-
# @param [
|
84
|
+
# @param [Symbol] other input type on which to interrupt output. May be :speech, :dtmf or :any
|
49
85
|
#
|
50
86
|
def interrupt_on=(other)
|
51
87
|
write_attr :'interrupt-on', other
|
52
88
|
end
|
53
89
|
|
54
90
|
##
|
55
|
-
# @return [
|
91
|
+
# @return [Integer] Indicates some offset through which the output should be skipped before rendering begins.
|
56
92
|
#
|
57
93
|
def start_offset
|
58
94
|
read_attr :'start-offset', :to_i
|
59
95
|
end
|
60
96
|
|
61
97
|
##
|
62
|
-
# @param [
|
98
|
+
# @param [Integer] other Indicates some offset through which the output should be skipped before rendering begins.
|
63
99
|
#
|
64
100
|
def start_offset=(other)
|
65
101
|
write_attr :'start-offset', other
|
66
102
|
end
|
67
103
|
|
68
104
|
##
|
69
|
-
# @return [
|
105
|
+
# @return [true, false] Indicates wether or not the component should be started in a paused state to be resumed at a later time.
|
70
106
|
#
|
71
107
|
def start_paused
|
72
108
|
read_attr(:'start-paused') == 'true'
|
73
109
|
end
|
74
110
|
|
75
111
|
##
|
76
|
-
# @param [
|
112
|
+
# @param [true, false] other Indicates wether or not the component should be started in a paused state to be resumed at a later time.
|
77
113
|
#
|
78
114
|
def start_paused=(other)
|
79
115
|
write_attr :'start-paused', other.to_s
|
80
116
|
end
|
81
117
|
|
82
118
|
##
|
83
|
-
# @return [
|
119
|
+
# @return [Integer] Indicates the duration of silence that should space repeats of the rendered document.
|
84
120
|
#
|
85
121
|
def repeat_interval
|
86
122
|
read_attr :'repeat-interval', :to_i
|
87
123
|
end
|
88
124
|
|
89
125
|
##
|
90
|
-
# @param [
|
126
|
+
# @param [Integer] other Indicates the duration of silence that should space repeats of the rendered document.
|
91
127
|
#
|
92
128
|
def repeat_interval=(other)
|
93
129
|
write_attr :'repeat-interval', other
|
94
130
|
end
|
95
131
|
|
96
132
|
##
|
97
|
-
# @return [
|
133
|
+
# @return [Integer] Indicates the number of times the output should be played.
|
98
134
|
#
|
99
135
|
def repeat_times
|
100
136
|
read_attr :'repeat-times', :to_i
|
101
137
|
end
|
102
138
|
|
103
139
|
##
|
104
|
-
# @param [
|
140
|
+
# @param [Integer] other Indicates the number of times the output should be played.
|
105
141
|
#
|
106
142
|
def repeat_times=(other)
|
107
143
|
write_attr :'repeat-times', other
|
108
144
|
end
|
109
145
|
|
110
146
|
##
|
111
|
-
# @return [
|
147
|
+
# @return [Integer] Indicates the maximum amount of time for which the output should be allowed to run before being terminated. Includes repeats.
|
112
148
|
#
|
113
149
|
def max_time
|
114
150
|
read_attr :'max-time', :to_i
|
115
151
|
end
|
116
152
|
|
117
153
|
##
|
118
|
-
# @param [
|
154
|
+
# @param [Integer] other Indicates the maximum amount of time for which the output should be allowed to run before being terminated. Includes repeats.
|
119
155
|
#
|
120
156
|
def max_time=(other)
|
121
157
|
write_attr :'max-time', other
|
122
158
|
end
|
123
159
|
|
124
160
|
def inspect_attributes
|
125
|
-
super + [:interrupt_on, :start_offset, :start_paused, :repeat_interval, :repeat_times, :max_time]
|
161
|
+
super + [:voice, :ssml, :interrupt_on, :start_offset, :start_paused, :repeat_interval, :repeat_times, :max_time]
|
126
162
|
end
|
127
163
|
|
128
164
|
state_machine :state do
|
@@ -143,7 +179,7 @@ module Punchblock
|
|
143
179
|
# output_obj.pause_action.to_xml
|
144
180
|
#
|
145
181
|
# returns:
|
146
|
-
# <pause xmlns="urn:xmpp:
|
182
|
+
# <pause xmlns="urn:xmpp:rayo:output:1"/>
|
147
183
|
def pause_action
|
148
184
|
Pause.new :component_id => component_id, :target_call_id => target_call_id
|
149
185
|
end
|
@@ -168,7 +204,7 @@ module Punchblock
|
|
168
204
|
# output_obj.resume_action.to_xml
|
169
205
|
#
|
170
206
|
# returns:
|
171
|
-
# <resume xmlns="urn:xmpp:
|
207
|
+
# <resume xmlns="urn:xmpp:rayo:output:1"/>
|
172
208
|
def resume_action
|
173
209
|
Resume.new :component_id => component_id, :target_call_id => target_call_id
|
174
210
|
end
|
@@ -9,11 +9,14 @@ module Punchblock
|
|
9
9
|
# Creates an Rayo Record command
|
10
10
|
#
|
11
11
|
# @param [Hash] options
|
12
|
-
# @option options [String
|
13
|
-
# @option options [
|
14
|
-
# @option options [
|
12
|
+
# @option options [String] :format to use for recording
|
13
|
+
# @option options [Integer] :initial_timeout Controls how long the recognizer should wait after the end of the prompt for the caller to speak before sending a Recorder event.
|
14
|
+
# @option options [Integer] :final_timeout Controls the length of a period of silence after callers have spoken to conclude they finished.
|
15
|
+
# @option options [Integer] :max_duration Indicates the maximum duration for the recording.
|
16
|
+
# @option options [true, false] :start_beep Indicates whether subsequent record will be preceded with a beep.
|
17
|
+
# @option options [true, false] :start_paused Whether subsequent record will start in PAUSE mode.
|
15
18
|
#
|
16
|
-
# @return [Command::Record]
|
19
|
+
# @return [Command::Record] a Rayo "record" command
|
17
20
|
#
|
18
21
|
# @example
|
19
22
|
# record :text => 'Hello brown cow.'
|
@@ -28,14 +31,14 @@ module Punchblock
|
|
28
31
|
end
|
29
32
|
|
30
33
|
##
|
31
|
-
# @return [
|
34
|
+
# @return [Integer] Controls the length of a period of silence after callers have spoken to conclude they finished.
|
32
35
|
#
|
33
36
|
def final_timeout
|
34
37
|
read_attr :'final-timeout', :to_i
|
35
38
|
end
|
36
39
|
|
37
40
|
##
|
38
|
-
# @param [
|
41
|
+
# @param [Integer] timeout Controls the length of a period of silence after callers have spoken to conclude they finished.
|
39
42
|
#
|
40
43
|
def final_timeout=(timeout)
|
41
44
|
write_attr :'final-timeout', timeout
|
@@ -56,77 +59,63 @@ module Punchblock
|
|
56
59
|
end
|
57
60
|
|
58
61
|
##
|
59
|
-
# @return [
|
62
|
+
# @return [Integer] Controls how long the recognizer should wait after the end of the prompt for the caller to speak before sending a Recorder event.
|
60
63
|
#
|
61
64
|
def initial_timeout
|
62
65
|
read_attr :'initial-timeout', :to_i
|
63
66
|
end
|
64
67
|
|
65
68
|
##
|
66
|
-
# @param [
|
69
|
+
# @param [Integer] timeout Controls how long the recognizer should wait after the end of the prompt for the caller to speak before sending a Recorder event.
|
67
70
|
#
|
68
71
|
def initial_timeout=(timeout)
|
69
72
|
write_attr :'initial-timeout', timeout
|
70
73
|
end
|
71
74
|
|
72
75
|
##
|
73
|
-
# @return [
|
76
|
+
# @return [Integer] Indicates the maximum duration for the recording.
|
74
77
|
#
|
75
78
|
def max_duration
|
76
79
|
read_attr :'max-duration', :to_i
|
77
80
|
end
|
78
81
|
|
79
82
|
##
|
80
|
-
# @param [
|
83
|
+
# @param [Integer] other Indicates the maximum duration for the recording.
|
81
84
|
#
|
82
85
|
def max_duration=(other)
|
83
86
|
write_attr :'max-duration', other
|
84
87
|
end
|
85
88
|
|
86
89
|
##
|
87
|
-
# @return [
|
90
|
+
# @return [true, false] Indicates whether subsequent record will be preceded with a beep.
|
88
91
|
#
|
89
92
|
def start_beep
|
90
93
|
read_attr(:'start-beep') == 'true'
|
91
94
|
end
|
92
95
|
|
93
96
|
##
|
94
|
-
# @param [
|
97
|
+
# @param [true, false] sb Indicates whether subsequent record will be preceded with a beep.
|
95
98
|
#
|
96
99
|
def start_beep=(sb)
|
97
100
|
write_attr :'start-beep', sb
|
98
101
|
end
|
99
102
|
|
100
103
|
##
|
101
|
-
# @return [
|
102
|
-
#
|
103
|
-
def stop_beep
|
104
|
-
read_attr(:'stop-beep') == 'true'
|
105
|
-
end
|
106
|
-
|
107
|
-
##
|
108
|
-
# @param [String] codec to use for recording
|
109
|
-
#
|
110
|
-
def stop_beep=(sb)
|
111
|
-
write_attr :'stop-beep', sb
|
112
|
-
end
|
113
|
-
|
114
|
-
##
|
115
|
-
# @return [String] the codec to use for recording
|
104
|
+
# @return [true, false] Whether subsequent record will start in PAUSE mode.
|
116
105
|
#
|
117
106
|
def start_paused
|
118
107
|
read_attr(:'start-paused') == 'true'
|
119
108
|
end
|
120
109
|
|
121
110
|
##
|
122
|
-
# @param [
|
111
|
+
# @param [true, false] other Whether subsequent record will start in PAUSE mode.
|
123
112
|
#
|
124
113
|
def start_paused=(other)
|
125
114
|
write_attr :'start-paused', other
|
126
115
|
end
|
127
116
|
|
128
117
|
def inspect_attributes # :nodoc:
|
129
|
-
[:final_timeout, :format, :initial_timeout, :max_duration, :start_beep, :start_paused
|
118
|
+
[:final_timeout, :format, :initial_timeout, :max_duration, :start_beep, :start_paused] + super
|
130
119
|
end
|
131
120
|
|
132
121
|
state_machine :state do
|
@@ -191,15 +180,15 @@ module Punchblock
|
|
191
180
|
##
|
192
181
|
# Directly returns the recording for the component
|
193
182
|
# @return [Punchblock::Component::Record::Recording] The recording object
|
194
|
-
#
|
183
|
+
#
|
195
184
|
def recording
|
196
185
|
complete_event.recording
|
197
186
|
end
|
198
|
-
|
187
|
+
|
199
188
|
##
|
200
189
|
# Directly returns the recording URI for the component
|
201
190
|
# @return [String] The recording URI
|
202
|
-
#
|
191
|
+
#
|
203
192
|
def recording_uri
|
204
193
|
recording.uri
|
205
194
|
end
|
@@ -175,7 +175,7 @@ module Punchblock
|
|
175
175
|
command.response = true
|
176
176
|
end
|
177
177
|
when Command::Hangup
|
178
|
-
send_ami_action 'Hangup', 'Channel' => channel do |response|
|
178
|
+
send_ami_action 'Hangup', 'Channel' => channel, 'Cause' => 16 do |response|
|
179
179
|
command.response = true
|
180
180
|
end
|
181
181
|
when Command::Join
|
data/lib/punchblock/version.rb
CHANGED
data/punchblock.gemspec
CHANGED
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
|
|
28
28
|
s.add_runtime_dependency %q<state_machine>, ["~> 1.0"]
|
29
29
|
s.add_runtime_dependency %q<future-resource>, ["~> 1.0"]
|
30
30
|
s.add_runtime_dependency %q<has-guarded-handlers>, ["~> 1.3"]
|
31
|
-
s.add_runtime_dependency %q<celluloid>, ["
|
31
|
+
s.add_runtime_dependency %q<celluloid>, ["~> 0.11.1"]
|
32
32
|
s.add_runtime_dependency %q<ruby_ami>, ["~> 1.2", ">= 1.2.1", "< 1.2.2"]
|
33
33
|
s.add_runtime_dependency %q<ruby_fs>, ["~> 1.0", "< 1.0.1"]
|
34
34
|
s.add_runtime_dependency %q<ruby_speech>, ["~> 1.0"]
|
@@ -14,14 +14,10 @@ module Punchblock
|
|
14
14
|
Input.new :grammar => {:value => '[5 DIGITS]', :content_type => 'application/grammar+custom'},
|
15
15
|
:mode => :speech,
|
16
16
|
:terminator => '#',
|
17
|
-
:max_digits => 10,
|
18
17
|
:max_silence => 1000,
|
19
18
|
:recognizer => 'en-US',
|
20
19
|
:initial_timeout => 2000,
|
21
20
|
:inter_digit_timeout => 2000,
|
22
|
-
:term_timeout => 2000,
|
23
|
-
:complete_timeout => 2000,
|
24
|
-
:incomplete_timeout => 2000,
|
25
21
|
:sensitivity => 0.5,
|
26
22
|
:min_confidence => 0.5
|
27
23
|
end
|
@@ -29,14 +25,10 @@ module Punchblock
|
|
29
25
|
its(:grammar) { should be == Input::Grammar.new(:value => '[5 DIGITS]', :content_type => 'application/grammar+custom') }
|
30
26
|
its(:mode) { should be == :speech }
|
31
27
|
its(:terminator) { should be == '#' }
|
32
|
-
its(:max_digits) { should be == 10 }
|
33
28
|
its(:max_silence) { should be == 1000 }
|
34
29
|
its(:recognizer) { should be == 'en-US' }
|
35
30
|
its(:initial_timeout) { should be == 2000 }
|
36
31
|
its(:inter_digit_timeout) { should be == 2000 }
|
37
|
-
its(:term_timeout) { should be == 2000 }
|
38
|
-
its(:complete_timeout) { should be == 2000 }
|
39
|
-
its(:incomplete_timeout) { should be == 2000 }
|
40
32
|
its(:sensitivity) { should be == 0.5 }
|
41
33
|
its(:min_confidence) { should be == 0.5 }
|
42
34
|
end
|
@@ -47,14 +39,10 @@ module Punchblock
|
|
47
39
|
<input xmlns="urn:xmpp:rayo:input:1"
|
48
40
|
mode="speech"
|
49
41
|
terminator="#"
|
50
|
-
max-digits="10"
|
51
42
|
max-silence="1000"
|
52
43
|
recognizer="en-US"
|
53
44
|
initial-timeout="2000"
|
54
45
|
inter-digit-timeout="2000"
|
55
|
-
term-timeout="2000"
|
56
|
-
complete-timeout="2000"
|
57
|
-
incomplete-timeout="2000"
|
58
46
|
sensitivity="0.5"
|
59
47
|
min-confidence="0.5">
|
60
48
|
<grammar content-type="application/grammar+custom">
|
@@ -71,14 +59,10 @@ module Punchblock
|
|
71
59
|
its(:grammar) { should be == Input::Grammar.new(:value => '[5 DIGITS]', :content_type => 'application/grammar+custom') }
|
72
60
|
its(:mode) { should be == :speech }
|
73
61
|
its(:terminator) { should be == '#' }
|
74
|
-
its(:max_digits) { should be == 10 }
|
75
62
|
its(:max_silence) { should be == 1000 }
|
76
63
|
its(:recognizer) { should be == 'en-US' }
|
77
64
|
its(:initial_timeout) { should be == 2000 }
|
78
65
|
its(:inter_digit_timeout) { should be == 2000 }
|
79
|
-
its(:term_timeout) { should be == 2000 }
|
80
|
-
its(:complete_timeout) { should be == 2000 }
|
81
|
-
its(:incomplete_timeout) { should be == 2000 }
|
82
66
|
its(:sensitivity) { should be == 0.5 }
|
83
67
|
its(:min_confidence) { should be == 0.5 }
|
84
68
|
end
|
@@ -132,6 +116,24 @@ module Punchblock
|
|
132
116
|
it { should_not be == grammar4 }
|
133
117
|
end
|
134
118
|
end
|
119
|
+
|
120
|
+
describe 'with a grammar reference by URL' do
|
121
|
+
let(:url) { 'http://foo.com/bar.grxml' }
|
122
|
+
|
123
|
+
subject { Input::Grammar.new :url => url }
|
124
|
+
|
125
|
+
its(:url) { should be == url }
|
126
|
+
|
127
|
+
describe "comparison" do
|
128
|
+
it "should be the same with the same url" do
|
129
|
+
Input::Grammar.new(:url => url).should be == Input::Grammar.new(:url => url)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should be different with a different url" do
|
133
|
+
Input::Grammar.new(:url => url).should_not be == Input::Grammar.new(:url => 'http://doo.com/dah')
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
135
137
|
end
|
136
138
|
|
137
139
|
describe "actions" do
|
@@ -14,7 +14,6 @@ module Punchblock
|
|
14
14
|
Record.new :format => 'WAV',
|
15
15
|
:start_beep => true,
|
16
16
|
:start_paused => false,
|
17
|
-
:stop_beep => true,
|
18
17
|
:max_duration => 500000,
|
19
18
|
:initial_timeout => 10000,
|
20
19
|
:final_timeout => 30000
|
@@ -23,7 +22,6 @@ module Punchblock
|
|
23
22
|
its(:format) { should be == 'WAV' }
|
24
23
|
its(:start_beep) { should be == true }
|
25
24
|
its(:start_paused) { should be == false }
|
26
|
-
its(:stop_beep) { should be == true }
|
27
25
|
its(:max_duration) { should be == 500000 }
|
28
26
|
its(:initial_timeout) { should be == 10000 }
|
29
27
|
its(:final_timeout) { should be == 30000 }
|
@@ -36,7 +34,6 @@ module Punchblock
|
|
36
34
|
format="WAV"
|
37
35
|
start-beep="true"
|
38
36
|
start-paused="false"
|
39
|
-
stop-beep="true"
|
40
37
|
max-duration="500000"
|
41
38
|
initial-timeout="10000"
|
42
39
|
final-timeout="30000"/>
|
@@ -50,7 +47,6 @@ module Punchblock
|
|
50
47
|
its(:format) { should be == 'WAV' }
|
51
48
|
its(:start_beep) { should be == true }
|
52
49
|
its(:start_paused) { should be == false }
|
53
|
-
its(:stop_beep) { should be == true }
|
54
50
|
its(:max_duration) { should be == 500000 }
|
55
51
|
its(:initial_timeout) { should be == 10000 }
|
56
52
|
its(:final_timeout) { should be == 30000 }
|
@@ -76,7 +76,7 @@ module Punchblock
|
|
76
76
|
offer.call_id = '9f00061'
|
77
77
|
offer.to = 'sip:whatever@127.0.0.1'
|
78
78
|
output = <<-MSG
|
79
|
-
<output xmlns='urn:xmpp:
|
79
|
+
<output xmlns='urn:xmpp:rayo:output:1'>
|
80
80
|
<audio url='http://acme.com/greeting.mp3'>
|
81
81
|
Thanks for calling ACME company
|
82
82
|
</audio>
|
@@ -827,6 +827,7 @@ module Punchblock
|
|
827
827
|
subject.execute_command command
|
828
828
|
ami_action = subject.wrapped_object.instance_variable_get(:'@current_ami_action')
|
829
829
|
ami_action.name.should be == "hangup"
|
830
|
+
ami_action.headers['Cause'].should be == 16
|
830
831
|
ami_action << RubyAMI::Response.new
|
831
832
|
command.response(0.5).should be true
|
832
833
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: punchblock
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-
|
14
|
+
date: 2012-10-01 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: niceogiri
|
@@ -114,7 +114,7 @@ dependencies:
|
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
115
115
|
none: false
|
116
116
|
requirements:
|
117
|
-
- -
|
117
|
+
- - ~>
|
118
118
|
- !ruby/object:Gem::Version
|
119
119
|
version: 0.11.1
|
120
120
|
type: :runtime
|
@@ -122,7 +122,7 @@ dependencies:
|
|
122
122
|
version_requirements: !ruby/object:Gem::Requirement
|
123
123
|
none: false
|
124
124
|
requirements:
|
125
|
-
- -
|
125
|
+
- - ~>
|
126
126
|
- !ruby/object:Gem::Version
|
127
127
|
version: 0.11.1
|
128
128
|
- !ruby/object:Gem::Dependency
|
@@ -423,8 +423,6 @@ files:
|
|
423
423
|
- lib/punchblock/has_headers.rb
|
424
424
|
- lib/punchblock/header.rb
|
425
425
|
- lib/punchblock/key_value_pair_node.rb
|
426
|
-
- lib/punchblock/media_container.rb
|
427
|
-
- lib/punchblock/media_node.rb
|
428
426
|
- lib/punchblock/protocol_error.rb
|
429
427
|
- lib/punchblock/rayo_node.rb
|
430
428
|
- lib/punchblock/ref.rb
|
@@ -523,7 +521,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
523
521
|
version: '0'
|
524
522
|
segments:
|
525
523
|
- 0
|
526
|
-
hash:
|
524
|
+
hash: -689196999409732364
|
527
525
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
528
526
|
none: false
|
529
527
|
requirements:
|
@@ -1,42 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Punchblock
|
4
|
-
module MediaContainer
|
5
|
-
##
|
6
|
-
# @return [String] the TTS voice to use
|
7
|
-
#
|
8
|
-
def voice
|
9
|
-
read_attr :voice
|
10
|
-
end
|
11
|
-
|
12
|
-
##
|
13
|
-
# @param [String] voice to use when rendering TTS
|
14
|
-
#
|
15
|
-
def voice=(voice)
|
16
|
-
write_attr :voice, voice
|
17
|
-
end
|
18
|
-
|
19
|
-
##
|
20
|
-
# @return [String] the SSML document to render TTS
|
21
|
-
#
|
22
|
-
def ssml
|
23
|
-
node = children.first
|
24
|
-
RubySpeech::SSML.import node if node
|
25
|
-
end
|
26
|
-
|
27
|
-
##
|
28
|
-
# @param [String] ssml the SSML document to render TTS
|
29
|
-
#
|
30
|
-
def ssml=(ssml)
|
31
|
-
return unless ssml
|
32
|
-
unless ssml.is_a?(RubySpeech::SSML::Element)
|
33
|
-
ssml = RubySpeech::SSML.import ssml
|
34
|
-
end
|
35
|
-
self << ssml
|
36
|
-
end
|
37
|
-
|
38
|
-
def inspect_attributes # :nodoc:
|
39
|
-
[:voice, :ssml] + super
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Punchblock
|
4
|
-
class MediaNode < RayoNode
|
5
|
-
include MediaContainer
|
6
|
-
|
7
|
-
def self.new(options = {})
|
8
|
-
super().tap do |new_node|
|
9
|
-
case options
|
10
|
-
when Hash
|
11
|
-
new_node << options.delete(:text) if options[:text]
|
12
|
-
options.each_pair { |k,v| new_node.send :"#{k}=", v }
|
13
|
-
when Nokogiri::XML::Element
|
14
|
-
new_node.inherit options
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|