punchblock 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +20 -0
- data/README.markdown +31 -0
- data/Rakefile +23 -0
- data/assets/ozone/ask-1.0.xsd +56 -0
- data/assets/ozone/conference-1.0.xsd +17 -0
- data/assets/ozone/ozone-1.0.xsd +127 -0
- data/assets/ozone/say-1.0.xsd +24 -0
- data/assets/ozone/transfer-1.0.xsd +32 -0
- data/bin/punchblock-console +125 -0
- data/lib/punchblock/command/accept.rb +30 -0
- data/lib/punchblock/command/answer.rb +30 -0
- data/lib/punchblock/command/dial.rb +88 -0
- data/lib/punchblock/command/hangup.rb +25 -0
- data/lib/punchblock/command/join.rb +81 -0
- data/lib/punchblock/command/mute.rb +7 -0
- data/lib/punchblock/command/redirect.rb +49 -0
- data/lib/punchblock/command/reject.rb +61 -0
- data/lib/punchblock/command/unjoin.rb +50 -0
- data/lib/punchblock/command/unmute.rb +7 -0
- data/lib/punchblock/command.rb +16 -0
- data/lib/punchblock/command_node.rb +46 -0
- data/lib/punchblock/component/input.rb +320 -0
- data/lib/punchblock/component/output.rb +449 -0
- data/lib/punchblock/component/record.rb +216 -0
- data/lib/punchblock/component/tropo/ask.rb +197 -0
- data/lib/punchblock/component/tropo/conference.rb +328 -0
- data/lib/punchblock/component/tropo/say.rb +113 -0
- data/lib/punchblock/component/tropo/transfer.rb +178 -0
- data/lib/punchblock/component/tropo.rb +12 -0
- data/lib/punchblock/component.rb +73 -0
- data/lib/punchblock/connection.rb +209 -0
- data/lib/punchblock/core_ext/blather/stanza/presence.rb +11 -0
- data/lib/punchblock/core_ext/blather/stanza.rb +26 -0
- data/lib/punchblock/dsl.rb +46 -0
- data/lib/punchblock/event/answered.rb +7 -0
- data/lib/punchblock/event/complete.rb +65 -0
- data/lib/punchblock/event/dtmf.rb +19 -0
- data/lib/punchblock/event/end.rb +15 -0
- data/lib/punchblock/event/info.rb +15 -0
- data/lib/punchblock/event/joined.rb +50 -0
- data/lib/punchblock/event/offer.rb +29 -0
- data/lib/punchblock/event/ringing.rb +7 -0
- data/lib/punchblock/event/unjoined.rb +50 -0
- data/lib/punchblock/event.rb +16 -0
- data/lib/punchblock/generic_connection.rb +18 -0
- data/lib/punchblock/has_headers.rb +34 -0
- data/lib/punchblock/header.rb +47 -0
- data/lib/punchblock/media_container.rb +39 -0
- data/lib/punchblock/media_node.rb +17 -0
- data/lib/punchblock/protocol_error.rb +16 -0
- data/lib/punchblock/rayo_node.rb +88 -0
- data/lib/punchblock/ref.rb +26 -0
- data/lib/punchblock/version.rb +3 -0
- data/lib/punchblock.rb +42 -0
- data/log/.gitkeep +0 -0
- data/punchblock.gemspec +42 -0
- data/spec/punchblock/command/accept_spec.rb +13 -0
- data/spec/punchblock/command/answer_spec.rb +13 -0
- data/spec/punchblock/command/dial_spec.rb +54 -0
- data/spec/punchblock/command/hangup_spec.rb +13 -0
- data/spec/punchblock/command/join_spec.rb +21 -0
- data/spec/punchblock/command/mute_spec.rb +11 -0
- data/spec/punchblock/command/redirect_spec.rb +19 -0
- data/spec/punchblock/command/reject_spec.rb +43 -0
- data/spec/punchblock/command/unjoin_spec.rb +19 -0
- data/spec/punchblock/command/unmute_spec.rb +11 -0
- data/spec/punchblock/command_node_spec.rb +80 -0
- data/spec/punchblock/component/input_spec.rb +188 -0
- data/spec/punchblock/component/output_spec.rb +531 -0
- data/spec/punchblock/component/record_spec.rb +235 -0
- data/spec/punchblock/component/tropo/ask_spec.rb +183 -0
- data/spec/punchblock/component/tropo/conference_spec.rb +360 -0
- data/spec/punchblock/component/tropo/say_spec.rb +171 -0
- data/spec/punchblock/component/tropo/transfer_spec.rb +153 -0
- data/spec/punchblock/component_spec.rb +126 -0
- data/spec/punchblock/connection_spec.rb +194 -0
- data/spec/punchblock/event/answered_spec.rb +23 -0
- data/spec/punchblock/event/complete_spec.rb +80 -0
- data/spec/punchblock/event/dtmf_spec.rb +24 -0
- data/spec/punchblock/event/end_spec.rb +30 -0
- data/spec/punchblock/event/info_spec.rb +30 -0
- data/spec/punchblock/event/joined_spec.rb +32 -0
- data/spec/punchblock/event/offer_spec.rb +35 -0
- data/spec/punchblock/event/ringing_spec.rb +23 -0
- data/spec/punchblock/event/unjoined_spec.rb +32 -0
- data/spec/punchblock/header_spec.rb +44 -0
- data/spec/punchblock/protocol_error_spec.rb +9 -0
- data/spec/punchblock/ref_spec.rb +21 -0
- data/spec/spec_helper.rb +43 -0
- metadata +353 -0
@@ -0,0 +1,81 @@
|
|
1
|
+
module Punchblock
|
2
|
+
module Command
|
3
|
+
class Join < CommandNode
|
4
|
+
register :join, :core
|
5
|
+
|
6
|
+
##
|
7
|
+
# Create a join message
|
8
|
+
#
|
9
|
+
# @param [Hash] options
|
10
|
+
# @option options [String, Optional] :other_call_id the call ID to join
|
11
|
+
# @option options [String, Optional] :mixer_id the mixer name to join
|
12
|
+
# @option options [Symbol, Optional] :direction the direction in which media should flow
|
13
|
+
# @option options [Symbol, Optional] :media the method by which to negotiate media
|
14
|
+
#
|
15
|
+
# @return [Command::Join] a formatted Rayo join command
|
16
|
+
#
|
17
|
+
def self.new(options = {})
|
18
|
+
super().tap do |new_node|
|
19
|
+
case options
|
20
|
+
when Nokogiri::XML::Node
|
21
|
+
new_node.inherit options
|
22
|
+
when Hash
|
23
|
+
options.each_pair { |k,v| new_node.send :"#{k}=", v }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# @return [String] the call ID to join
|
30
|
+
def other_call_id
|
31
|
+
read_attr :'call-id'
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# @param [String] other the call ID to join
|
36
|
+
def other_call_id=(other)
|
37
|
+
write_attr :'call-id', other
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# @return [String] the mixer name to join
|
42
|
+
def mixer_id
|
43
|
+
read_attr :'mixer-id'
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# @param [String] other the mixer name to join
|
48
|
+
def mixer_id=(other)
|
49
|
+
write_attr :'mixer-id', other
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# @return [String] the direction in which media should flow
|
54
|
+
def direction
|
55
|
+
read_attr :direction, :to_sym
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# @param [String] other the direction in which media should flow. Can be :duplex, :recv or :send
|
60
|
+
def direction=(other)
|
61
|
+
write_attr :direction, other
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# @return [String] the method by which to negotiate media
|
66
|
+
def media
|
67
|
+
read_attr :media, :to_sym
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# @param [String] other the method by which to negotiate media. Can be :direct or :bridge
|
72
|
+
def media=(other)
|
73
|
+
write_attr :media, other
|
74
|
+
end
|
75
|
+
|
76
|
+
def inspect_attributes # :nodoc:
|
77
|
+
[:other_call_id, :mixer_id, :direction, :media] + super
|
78
|
+
end
|
79
|
+
end # Join
|
80
|
+
end # Command
|
81
|
+
end # Punchblock
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Punchblock
|
2
|
+
module Command
|
3
|
+
class Redirect < CommandNode
|
4
|
+
register :redirect, :core
|
5
|
+
|
6
|
+
include HasHeaders
|
7
|
+
|
8
|
+
##
|
9
|
+
# Create an Rayo redirect message
|
10
|
+
#
|
11
|
+
# @param [Hash] options
|
12
|
+
# @option options [String] :to redirect target
|
13
|
+
# @option options [Array[Header], Hash, Optional] :headers SIP headers to attach to
|
14
|
+
# the new call. Can be either a hash of key-value pairs, or an array of
|
15
|
+
# Header objects.
|
16
|
+
#
|
17
|
+
# @return [Command::Redirect] a formatted Rayo redirect command
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# Redirect.new(:to => 'tel:+14045551234').to_xml
|
21
|
+
#
|
22
|
+
# returns:
|
23
|
+
# <redirect to="tel:+14045551234" xmlns="urn:xmpp:rayo:1"/>
|
24
|
+
#
|
25
|
+
def self.new(options = {})
|
26
|
+
super().tap do |new_node|
|
27
|
+
new_node.to = options[:to]
|
28
|
+
new_node.headers = options[:headers]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# @return [String] the redirect target
|
34
|
+
def to
|
35
|
+
read_attr :to
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# @param [String] redirect_to redirect target
|
40
|
+
def to=(redirect_to)
|
41
|
+
write_attr :to, redirect_to
|
42
|
+
end
|
43
|
+
|
44
|
+
def inspect_attributes # :nodoc:
|
45
|
+
[:to] + super
|
46
|
+
end
|
47
|
+
end # Redirect
|
48
|
+
end # Command
|
49
|
+
end # Punchblock
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Punchblock
|
2
|
+
module Command
|
3
|
+
class Reject < CommandNode
|
4
|
+
register :reject, :core
|
5
|
+
|
6
|
+
include HasHeaders
|
7
|
+
|
8
|
+
VALID_REASONS = [:busy, :decline, :error].freeze
|
9
|
+
|
10
|
+
##
|
11
|
+
# Create an Rayo reject message
|
12
|
+
#
|
13
|
+
# @param [Hash] options
|
14
|
+
# @option options [Symbol] :reason for rejecting the call. Can be any one of VALID_REASONS. Defaults to :decline
|
15
|
+
# @option options [Array[Header], Hash, Optional] :headers SIP headers to attach to
|
16
|
+
# the call. Can be either a hash of key-value pairs, or an array of
|
17
|
+
# Header objects.
|
18
|
+
#
|
19
|
+
# @return [Command::Reject] a formatted Rayo reject command
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# Reject.new(:reason => :busy).to_xml
|
23
|
+
#
|
24
|
+
# returns:
|
25
|
+
# <reject xmlns="urn:xmpp:rayo:1"><busy/></reject
|
26
|
+
#
|
27
|
+
def self.new(options = {})
|
28
|
+
super().tap do |new_node|
|
29
|
+
new_node.reason = options[:reason] || :decline
|
30
|
+
new_node.headers = options[:headers]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# @return [Symbol] the reason type for rejecting a call
|
36
|
+
#
|
37
|
+
def reason
|
38
|
+
children.select { |c| c.is_a? Nokogiri::XML::Element }.first.name.to_sym
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Set the reason for rejecting the call
|
43
|
+
#
|
44
|
+
# @param [Symbol] reject_reason Can be any one of :busy, :dclined or :error.
|
45
|
+
#
|
46
|
+
# @raises ArgumentError if reject_reason is not one of the allowed reasons
|
47
|
+
#
|
48
|
+
def reason=(reject_reason)
|
49
|
+
if reject_reason && !VALID_REASONS.include?(reject_reason.to_sym)
|
50
|
+
raise ArgumentError, "Invalid Reason (#{reject_reason}), use: #{VALID_REASONS*' '}"
|
51
|
+
end
|
52
|
+
children.each &:remove
|
53
|
+
self << RayoNode.new(reject_reason)
|
54
|
+
end
|
55
|
+
|
56
|
+
def inspect_attributes # :nodoc:
|
57
|
+
[:reason] + super
|
58
|
+
end
|
59
|
+
end # Reject
|
60
|
+
end # Command
|
61
|
+
end # Punchblock
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Punchblock
|
2
|
+
module Command
|
3
|
+
class Unjoin < CommandNode
|
4
|
+
register :unjoin, :core
|
5
|
+
|
6
|
+
##
|
7
|
+
# Create an ujoin message
|
8
|
+
#
|
9
|
+
# @param [Hash] options
|
10
|
+
# @option options [String, Optional] :other_call_id the call ID to unjoin
|
11
|
+
# @option options [String, Optional] :mixer_id the mixer name to unjoin
|
12
|
+
#
|
13
|
+
# @return [Command::Unjoin] a formatted Rayo unjoin command
|
14
|
+
#
|
15
|
+
def self.new(options = {})
|
16
|
+
super().tap do |new_node|
|
17
|
+
options.each_pair { |k,v| new_node.send :"#{k}=", v }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# @return [String] the call ID to unjoin
|
23
|
+
def other_call_id
|
24
|
+
read_attr :'call-id'
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# @param [String] other the call ID to unjoin
|
29
|
+
def other_call_id=(other)
|
30
|
+
write_attr :'call-id', other
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# @return [String] the mixer name to unjoin
|
35
|
+
def mixer_id
|
36
|
+
read_attr :'mixer-id'
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# @param [String] other the mixer name to unjoin
|
41
|
+
def mixer_id=(other)
|
42
|
+
write_attr :'mixer-id', other
|
43
|
+
end
|
44
|
+
|
45
|
+
def inspect_attributes # :nodoc:
|
46
|
+
[:other_call_id, :mixer_id] + super
|
47
|
+
end
|
48
|
+
end # Unjoin
|
49
|
+
end # Command
|
50
|
+
end # Punchblock
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Punchblock
|
2
|
+
module Command
|
3
|
+
extend ActiveSupport::Autoload
|
4
|
+
|
5
|
+
autoload :Accept
|
6
|
+
autoload :Answer
|
7
|
+
autoload :Dial
|
8
|
+
autoload :Hangup
|
9
|
+
autoload :Join
|
10
|
+
autoload :Mute
|
11
|
+
autoload :Redirect
|
12
|
+
autoload :Reject
|
13
|
+
autoload :Unjoin
|
14
|
+
autoload :Unmute
|
15
|
+
end # Command
|
16
|
+
end # Punchblock
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'state_machine'
|
2
|
+
|
3
|
+
module Punchblock
|
4
|
+
class CommandNode < RayoNode
|
5
|
+
def self.new(options = {})
|
6
|
+
super().tap do |new_node|
|
7
|
+
new_node.call_id = options[:call_id]
|
8
|
+
new_node.component_id = options[:component_id]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(*args)
|
13
|
+
super
|
14
|
+
@response = FutureResource.new
|
15
|
+
end
|
16
|
+
|
17
|
+
state_machine :state, :initial => :new do
|
18
|
+
event :request do
|
19
|
+
transition :new => :requested
|
20
|
+
end
|
21
|
+
|
22
|
+
event :execute do
|
23
|
+
transition :requested => :executing
|
24
|
+
end
|
25
|
+
|
26
|
+
event :complete do
|
27
|
+
transition :executing => :complete
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def write_attr(*args)
|
32
|
+
raise StandardError, "Cannot alter attributes of a requested command" unless new?
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
36
|
+
def response(timeout = nil)
|
37
|
+
@response.resource timeout
|
38
|
+
end
|
39
|
+
|
40
|
+
def response=(other)
|
41
|
+
return if @response.set_yet?
|
42
|
+
@response.resource = other
|
43
|
+
execute!
|
44
|
+
end
|
45
|
+
end # CommandNode
|
46
|
+
end # Punchblock
|
@@ -0,0 +1,320 @@
|
|
1
|
+
module Punchblock
|
2
|
+
module Component
|
3
|
+
class Input < ComponentNode
|
4
|
+
register :input, :input
|
5
|
+
|
6
|
+
##
|
7
|
+
# Create an input message
|
8
|
+
#
|
9
|
+
# @param [Hash] options for inputing/prompting a specific call
|
10
|
+
# @option options [Choices, Hash] :choices to allow the user to input
|
11
|
+
# @option options [Prompt, Hash, Optional] :prompt to play/read to the caller as the question
|
12
|
+
# @option options [Symbol, Optional] :mode by which to accept input. Can be :speech, :dtmf or :any
|
13
|
+
# @option options [Integer, Optional] :timeout to wait for user input
|
14
|
+
# @option options [Boolean, Optional] :bargein wether or not to allow the caller to begin their response before the prompt finishes
|
15
|
+
# @option options [String, Optional] :recognizer to use for speech recognition
|
16
|
+
# @option options [String, Optional] :terminator by which to signal the end of input
|
17
|
+
# @option options [Float, Optional] :min_confidence with which to consider a response acceptable
|
18
|
+
#
|
19
|
+
# @return [Command::Input] a formatted Rayo input command
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# input :prompt => {:text => 'Please enter your postal code.', :voice => 'simon'},
|
23
|
+
# :choices => {:value => '[5 DIGITS]'},
|
24
|
+
# :timeout => 30,
|
25
|
+
# :recognizer => 'es-es'
|
26
|
+
#
|
27
|
+
# returns:
|
28
|
+
# <input xmlns="urn:xmpp:tropo:input:1" timeout="30" recognizer="es-es">
|
29
|
+
# <prompt voice='simon'>Please enter your postal code.</prompt>
|
30
|
+
# <choices content-type="application/grammar+voxeo">[5 DIGITS]</choices>
|
31
|
+
# </input>
|
32
|
+
#
|
33
|
+
def self.new(options = {})
|
34
|
+
super().tap do |new_node|
|
35
|
+
options.each_pair { |k,v| new_node.send :"#{k}=", v }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# @return [Boolean] wether or not to allow the caller to begin their response before the prompt finishes
|
41
|
+
#
|
42
|
+
def max_digits
|
43
|
+
read_attr :'max-digits', :to_i
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# @param [Boolean] bargein wether or not to allow the caller to begin their response before the prompt finishes
|
48
|
+
#
|
49
|
+
def max_digits=(other)
|
50
|
+
write_attr :'max-digits', other
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# @return [Float] Confidence with which to consider a response acceptable
|
55
|
+
#
|
56
|
+
def min_confidence
|
57
|
+
read_attr 'min-confidence', :to_f
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# @param [Float] min_confidence with which to consider a response acceptable
|
62
|
+
#
|
63
|
+
def min_confidence=(min_confidence)
|
64
|
+
write_attr 'min-confidence', min_confidence
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# @return [Symbol] mode by which to accept input. Can be :speech, :dtmf or :any
|
69
|
+
#
|
70
|
+
def mode
|
71
|
+
read_attr :mode, :to_sym
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# @param [Symbol] mode by which to accept input. Can be :speech, :dtmf or :any
|
76
|
+
#
|
77
|
+
def mode=(mode)
|
78
|
+
write_attr :mode, mode
|
79
|
+
end
|
80
|
+
|
81
|
+
##
|
82
|
+
# @return [String] recognizer to use for speech recognition
|
83
|
+
#
|
84
|
+
def recognizer
|
85
|
+
read_attr :recognizer
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# @param [String] recognizer to use for speech recognition
|
90
|
+
#
|
91
|
+
def recognizer=(recognizer)
|
92
|
+
write_attr :recognizer, recognizer
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# @return [String] terminator by which to signal the end of input
|
97
|
+
#
|
98
|
+
def terminator
|
99
|
+
read_attr :terminator
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
# @param [String] terminator by which to signal the end of input
|
104
|
+
#
|
105
|
+
def terminator=(terminator)
|
106
|
+
write_attr :terminator, terminator
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# @return [Integer] timeout to wait for user input
|
111
|
+
#
|
112
|
+
def sensitivity
|
113
|
+
read_attr :sensitivity, :to_f
|
114
|
+
end
|
115
|
+
|
116
|
+
##
|
117
|
+
# @param [Integer] timeout to wait for user input
|
118
|
+
#
|
119
|
+
def sensitivity=(other)
|
120
|
+
write_attr :sensitivity, other
|
121
|
+
end
|
122
|
+
|
123
|
+
##
|
124
|
+
# @return [Integer] timeout to wait for user input
|
125
|
+
#
|
126
|
+
def initial_timeout
|
127
|
+
read_attr :'initial-timeout', :to_i
|
128
|
+
end
|
129
|
+
|
130
|
+
##
|
131
|
+
# @param [Integer] timeout to wait for user input
|
132
|
+
#
|
133
|
+
def initial_timeout=(other)
|
134
|
+
write_attr :'initial-timeout', other
|
135
|
+
end
|
136
|
+
|
137
|
+
##
|
138
|
+
# @return [Integer] timeout to wait for user input
|
139
|
+
#
|
140
|
+
def inter_digit_timeout
|
141
|
+
read_attr :'inter-digit-timeout', :to_i
|
142
|
+
end
|
143
|
+
|
144
|
+
##
|
145
|
+
# @param [Integer] timeout to wait for user input
|
146
|
+
#
|
147
|
+
def inter_digit_timeout=(other)
|
148
|
+
write_attr :'inter-digit-timeout', other
|
149
|
+
end
|
150
|
+
|
151
|
+
##
|
152
|
+
# @return [Integer] timeout to wait for user input
|
153
|
+
#
|
154
|
+
def term_timeout
|
155
|
+
read_attr :'term-timeout', :to_i
|
156
|
+
end
|
157
|
+
|
158
|
+
##
|
159
|
+
# @param [Integer] timeout to wait for user input
|
160
|
+
#
|
161
|
+
def term_timeout=(other)
|
162
|
+
write_attr :'term-timeout', other
|
163
|
+
end
|
164
|
+
|
165
|
+
##
|
166
|
+
# @return [Integer] timeout to wait for user input
|
167
|
+
#
|
168
|
+
def complete_timeout
|
169
|
+
read_attr :'complete-timeout', :to_i
|
170
|
+
end
|
171
|
+
|
172
|
+
##
|
173
|
+
# @param [Integer] timeout to wait for user input
|
174
|
+
#
|
175
|
+
def complete_timeout=(other)
|
176
|
+
write_attr :'complete-timeout', other
|
177
|
+
end
|
178
|
+
|
179
|
+
##
|
180
|
+
# @return [Integer] timeout to wait for user input
|
181
|
+
#
|
182
|
+
def incomplete_timeout
|
183
|
+
read_attr :'incomplete-timeout', :to_i
|
184
|
+
end
|
185
|
+
|
186
|
+
##
|
187
|
+
# @param [Integer] timeout to wait for user input
|
188
|
+
#
|
189
|
+
def incomplete_timeout=(other)
|
190
|
+
write_attr :'incomplete-timeout', other
|
191
|
+
end
|
192
|
+
|
193
|
+
##
|
194
|
+
# @return [Choices] the choices available
|
195
|
+
#
|
196
|
+
def grammar
|
197
|
+
Grammar.new find_first('ns:grammar', :ns => self.class.registered_ns)
|
198
|
+
end
|
199
|
+
|
200
|
+
##
|
201
|
+
# @param [Hash] choices
|
202
|
+
# @option choices [String] :content_type
|
203
|
+
# @option choices [String] :value the choices available
|
204
|
+
#
|
205
|
+
def grammar=(other)
|
206
|
+
remove_children :grammar
|
207
|
+
grammar = Grammar.new(other) unless other.is_a?(Grammar)
|
208
|
+
self << grammar
|
209
|
+
end
|
210
|
+
|
211
|
+
def inspect_attributes # :nodoc:
|
212
|
+
[:mode, :terminator, :max_digits, :recognizer, :initial_timeout, :inter_digit_timeout, :term_timeout, :complete_timeout, :incomplete_timeout, :sensitivity, :min_confidence, :choices] + super
|
213
|
+
end
|
214
|
+
|
215
|
+
class Grammar < RayoNode
|
216
|
+
##
|
217
|
+
# @param [Hash] options
|
218
|
+
# @option options [String] :content_type
|
219
|
+
# @option options [String] :value the choices available
|
220
|
+
#
|
221
|
+
def self.new(options = {})
|
222
|
+
super(:grammar).tap do |new_node|
|
223
|
+
case options
|
224
|
+
when Nokogiri::XML::Node
|
225
|
+
new_node.inherit options
|
226
|
+
when Hash
|
227
|
+
new_node.content_type = options[:content_type]
|
228
|
+
new_node.value = options[:value]
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
##
|
234
|
+
# @return [String] the choice content type
|
235
|
+
#
|
236
|
+
def content_type
|
237
|
+
read_attr 'content-type'
|
238
|
+
end
|
239
|
+
|
240
|
+
##
|
241
|
+
# @param [String] content_type Defaults to the Voxeo Simple Grammar
|
242
|
+
#
|
243
|
+
def content_type=(content_type)
|
244
|
+
write_attr 'content-type', content_type || 'application/grammar+grxml'
|
245
|
+
end
|
246
|
+
|
247
|
+
##
|
248
|
+
# @return [String] the choices available
|
249
|
+
def value
|
250
|
+
content
|
251
|
+
end
|
252
|
+
|
253
|
+
##
|
254
|
+
# @param [String] value the choices available
|
255
|
+
def value=(value)
|
256
|
+
Nokogiri::XML::Builder.with(self) do |xml|
|
257
|
+
xml.cdata " #{value} "
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
# Compare two Choices objects by content type, and value
|
262
|
+
# @param [Header] o the Choices object to compare against
|
263
|
+
# @return [true, false]
|
264
|
+
def eql?(o, *fields)
|
265
|
+
super o, *(fields + [:content_type, :value])
|
266
|
+
end
|
267
|
+
|
268
|
+
def inspect_attributes # :nodoc:
|
269
|
+
[:content_type, :value] + super
|
270
|
+
end
|
271
|
+
end # Choices
|
272
|
+
|
273
|
+
class Complete
|
274
|
+
class Success < Event::Complete::Reason
|
275
|
+
register :success, :input_complete
|
276
|
+
|
277
|
+
##
|
278
|
+
# @return [Symbol] the mode by which the question was answered. May be :speech or :dtmf
|
279
|
+
#
|
280
|
+
def mode
|
281
|
+
read_attr :mode, :to_sym
|
282
|
+
end
|
283
|
+
|
284
|
+
##
|
285
|
+
# @return [Float] A measure of the confidence of the result, between 0-1
|
286
|
+
#
|
287
|
+
def confidence
|
288
|
+
read_attr :confidence, :to_f
|
289
|
+
end
|
290
|
+
|
291
|
+
##
|
292
|
+
# @return [String] An intelligent interpretation of the meaning of the response.
|
293
|
+
#
|
294
|
+
def interpretation
|
295
|
+
find_first('//ns:interpretation', :ns => self.registered_ns).text
|
296
|
+
end
|
297
|
+
|
298
|
+
##
|
299
|
+
# @return [String] The exact response gained
|
300
|
+
#
|
301
|
+
def utterance
|
302
|
+
find_first('//ns:utterance', :ns => self.registered_ns).text
|
303
|
+
end
|
304
|
+
|
305
|
+
def inspect_attributes # :nodoc:
|
306
|
+
[:mode, :confidence, :interpretation, :utterance] + super
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
class NoMatch < Event::Complete::Reason
|
311
|
+
register :nomatch, :input_complete
|
312
|
+
end
|
313
|
+
|
314
|
+
class NoInput < Event::Complete::Reason
|
315
|
+
register :noinput, :input_complete
|
316
|
+
end
|
317
|
+
end # Complete
|
318
|
+
end # Input
|
319
|
+
end # Command
|
320
|
+
end # Punchblock
|