punchblock 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|