adzap-voice_form 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,6 @@
1
+ == 0.2.0 2009-01-16
2
+ * Updated to work with Adhearsion 0.8.0 release. Examples updated to match new usage.
3
+
1
4
  == 0.1.1 2008-11-12
2
5
  * refactored to auto include voice_form method in components, no more 'include VoiceForm'
3
6
 
@@ -33,7 +33,6 @@ command to play your sound files.
33
33
 
34
34
  class MyComponent
35
35
  include VoiceForm
36
- add_call_context :as => :call_context
37
36
 
38
37
  voice_form do
39
38
 
@@ -53,6 +52,10 @@ command to play your sound files.
53
52
  @age.to_i <= @max_age
54
53
  end
55
54
 
55
+ confirm(:accept => 1, :reject => 2, :timeout => 3, :attempts => 3) do
56
+ "You entered #{@age}. Press 1 to continue or 2 to try again."
57
+ end
58
+
56
59
  invalid do
57
60
  call_context.speak "Your age must be less than #{@max_age}. Try again."
58
61
  end
@@ -72,8 +75,7 @@ command to play your sound files.
72
75
  In your dialplan:
73
76
 
74
77
  general {
75
- my_component = new_my_component
76
- my_component.start_voice_form
78
+ MyComponent.new.start_voice_form(self)
77
79
  }
78
80
 
79
81
  That covers most of the functionality, and hopefully it makes sense pretty much straight
@@ -82,11 +84,14 @@ away.
82
84
  You don't have to start the form from the dialplan, but it makes it simple. You could start it from
83
85
  within a component method.
84
86
 
85
- All blocks (setup, validate, do_block etc.) are evaluated in the component scope so you can use
86
- component methods and instance variables in them and they will work.
87
+ All callback blocks (setup, validate, timeout etc.) are evaluated in the component scope so you can use
88
+ component methods and instance variables in them and they will work. You don't have to define any
89
+ callbacks if the field is straight forward and only depends on its length.
87
90
 
88
91
  For a more complete example see the examples folder.
89
92
 
93
+ ## Commands
94
+
90
95
  ### voice_form
91
96
 
92
97
  The flow of the form works like a stack. So each field and do_block are executed in order until the
@@ -137,8 +142,72 @@ There can only be one `prompt` but you can have multiple `reprompt`s. When you a
137
142
  what the prompt is if there is input the first time or the input is invalid.
138
143
 
139
144
 
140
- TODO: Add specific info for callback and option.
145
+ ### Callbacks
146
+
147
+ The available callbacks that can be defined for a field are as follows
148
+
149
+ - setup
150
+ - timeout
151
+ - validate
152
+ - invalid
153
+ - confirm
154
+ - success
155
+ - failure
156
+
157
+ Each of them takes a block which is executed as a specific point in the process of getting form input.
158
+ All of them are optional. The block for a callback is evaluated in the scope of the component so any
159
+ instance variables and component methods are available to use including the call context.
160
+
161
+ The details of each callback are as follows
162
+
163
+ ### setup
164
+
165
+ This is run once only for a field if defined before any prompts
166
+
167
+ ### timeout
168
+
169
+ This is run if no input is received.
170
+
171
+ ### validate
172
+
173
+ This is run after input of a valid length. The validate block is where you put validation logic of the
174
+ value just input by the user. The block should return `true` if the value is valid or `false` otherwise.
175
+ If the validate callback returns false then the invalid callback will be called next.
176
+
177
+ ### invalid
178
+
179
+ The invalid callback is called if the input value is not of a valid length or the validate block returns
180
+ false.
181
+
182
+ ### confirm
183
+
184
+ The confirm callback is called after the input has been validated. The confirm callback is a little different
185
+ from the others. Idea is that you return either an array or string of the audio files or TTS text, respectively,
186
+ you want to play as the prompt for confirming the value entered. The confirm block also takes a few options:
187
+
188
+ - :accept - the number to press to accept the field value entered. Default is 1.
189
+ - :reject - the number to press the reject the field value entered and try again. Default is 2.
190
+ - :attempts - the number of attempts to try to get a confirmation response. Default is 3
191
+ - :timeout - the number of seconds to wait for input after the confirmation response. Default is 3.
192
+
193
+ The value returned from the block should form the complete list of audio files or TTS text to prompt the user
194
+ including the values to accept of reject the value.
195
+
196
+ For example, in a field called my_field:
197
+
198
+ confirm(:accept => 1, :reject => 2, :attempts => 3) do
199
+ ['you-entered', @my_field.scan(/\d/), 'is-this-correct', 'press-1-accept-2-try-again'].flatten
200
+ end
201
+
202
+ The above will `play` the array of audo files as the prompt for confirmation.
203
+
204
+ confirm(:accept => 1, :reject => 2, :attempts => 3) do
205
+ "You entered #{@my_field}. Is this correct? Press 1 to accept or 2 try again."
206
+ end
207
+
208
+ The above will `speak` the string as the prompt for confirmation.
141
209
 
210
+ If no valid input is entered for the confirmation
142
211
 
143
212
  TODO: More docs
144
213
 
data/Rakefile CHANGED
@@ -5,11 +5,11 @@ require 'date'
5
5
  require 'spec/rake/spectask'
6
6
 
7
7
  GEM = "voice_form"
8
- GEM_VERSION = "0.1.0"
8
+ GEM_VERSION = "0.2.0"
9
9
  AUTHOR = "Adam Meehan"
10
10
  EMAIL = "adam.meehan@gmail.com"
11
11
  HOMEPAGE = "http://github.com/adzap/voice_form"
12
- SUMMARY = "A DSL for Adhearsion to create forms in the style of the VoiceXML form element."
12
+ SUMMARY = "A plugin for Adhearsion to create forms in the style of the VoiceXML form element."
13
13
 
14
14
  spec = Gem::Specification.new do |s|
15
15
  s.name = GEM
@@ -1,6 +1,7 @@
1
1
  class MyComponent
2
2
  include VoiceForm
3
- add_call_context :as => :call_context
3
+
4
+ delegate :play, :speak, :to => :call_context
4
5
 
5
6
  voice_form do
6
7
  field(:age, :max_length => 3, :attempts => 3) do
@@ -12,20 +13,20 @@ class MyComponent
12
13
  validate { @age.to_i < @max_age }
13
14
 
14
15
  invalid do
15
- call_context.speak "Your age must be less than #{@max_age}. Try again."
16
+ speak "Your age must be less than #{@max_age}. Try again."
16
17
  end
17
18
 
18
19
  success do
19
- call_context.speak "You are #{@age} years old."
20
+ speak "You are #{@age} years old."
20
21
  end
21
22
 
22
23
  failure do
23
- call_context.speak "You could not enter your age. Thats a bad sign."
24
+ speak "You could not enter your age. Thats a bad sign."
24
25
  end
25
26
  end
26
27
 
27
28
  do_block do
28
- call_context.speak "Get ready for the next question."
29
+ speak "Get ready for the next question."
29
30
  end
30
31
 
31
32
  field(:postcode, :length => 4, :attempts => 5) do
@@ -35,19 +36,19 @@ class MyComponent
35
36
 
36
37
  invalid do
37
38
  if @postcode.size < 4
38
- call_context.speak "Your postcode must 4 digits."
39
+ speak "Your postcode must 4 digits."
39
40
  else
40
- call_context.speak "Your postcode cannot start with a 0."
41
+ speak "Your postcode cannot start with a 0."
41
42
  end
42
43
  end
43
44
 
44
45
  success do
45
- call_context.speak "Your postcode is #{@postcode.scan(/\d/).join(', ')}."
46
+ speak "Your postcode is #{@postcode.scan(/\d/).join(', ')}."
46
47
  end
47
48
 
48
49
  failure do
49
50
  if @age.empty?
50
- call_context.speak "Lets start over shall we."
51
+ speak "Lets start over shall we."
51
52
  form.restart
52
53
  end
53
54
  end
@@ -1,11 +1,3 @@
1
1
  require 'voice_form/form_methods'
2
2
  require 'voice_form/form'
3
3
  require 'voice_form/form_field'
4
-
5
- Adhearsion::Components::Behavior.module_eval do
6
- include VoiceForm::FormMethods
7
- end
8
-
9
- Adhearsion::Components::Behavior::ClassMethods.module_eval do
10
- include VoiceForm::MacroMethods
11
- end
@@ -6,22 +6,18 @@ module VoiceForm
6
6
  attr_accessor :form_stack
7
7
  attr_reader :current_field
8
8
 
9
- def initialize(options={})
9
+ def initialize(options={}, &block)
10
10
  @options = options
11
-
12
11
  @form_stack = []
13
12
  @stack_index = 0
13
+ self.instance_eval(&block)
14
14
  end
15
15
 
16
16
  def run(component)
17
17
  @component = component
18
18
 
19
- alias_call_context
20
-
21
19
  add_field_accessors
22
-
23
20
  run_setup
24
-
25
21
  run_form_stack
26
22
  end
27
23
 
@@ -92,15 +88,6 @@ module VoiceForm
92
88
  slot.is_a?(VoiceForm::FormField)
93
89
  end
94
90
 
95
- def alias_call_context
96
- # hack to avoid setting the call_context in each field for different context name
97
- if context_name = @options[:call_context] && !@component.respond_to?(:call_context)
98
- @component.class_eval do
99
- alias_method :call_context, context_name
100
- end
101
- end
102
- end
103
-
104
91
  end
105
92
 
106
93
  end
@@ -4,11 +4,12 @@ module VoiceForm
4
4
  attr_reader :name
5
5
  attr_accessor :prompts
6
6
 
7
- def initialize(name, options, component)
7
+ def initialize(name, options, component, &block)
8
8
  @name, @options, @component = name, options, component
9
9
  @options.reverse_merge!(:attempts => 5, :call_context => 'call_context')
10
10
  @callbacks = {}
11
11
  @prompts = []
12
+ self.instance_eval(&block)
12
13
  end
13
14
 
14
15
  def prompt(options)
@@ -16,7 +16,7 @@ module VoiceForm
16
16
  include InstanceMethods
17
17
 
18
18
  cattr_accessor :voice_form_options
19
- attr_accessor :form
19
+ attr_accessor :form, :call_context
20
20
  end
21
21
 
22
22
  self.voice_form_options = [options, block]
@@ -26,10 +26,11 @@ module VoiceForm
26
26
 
27
27
  module InstanceMethods
28
28
 
29
- def start_voice_form
29
+ def start_voice_form(call)
30
30
  raise "No voice form defined" unless self.voice_form_options
31
- self.form = VoiceForm::Form.new(self.class.voice_form_options[0])
32
- self.form.instance_eval(&self.class.voice_form_options[1])
31
+ options, block = *self.class.voice_form_options
32
+ @call_context = call
33
+ self.form = VoiceForm::Form.new(options, &block)
33
34
  self.form.run(self)
34
35
  end
35
36
 
@@ -39,12 +40,11 @@ module VoiceForm
39
40
 
40
41
  # Can be used in a form or stand-alone in a component method
41
42
  def field(field_name, options={}, &block)
42
- raise 'Field require a block' unless block_given?
43
+ raise "A field requires a block" unless block_given?
43
44
 
44
- form_field = VoiceForm::FormField.new(field_name, options, self)
45
+ form_field = VoiceForm::FormField.new(field_name, options, self, &block)
45
46
 
46
- form_field.instance_eval(&block)
47
- raise 'At least one prompt is required' if form_field.prompts.empty?
47
+ raise 'A field requires a prompt to be defined' if form_field.prompts.empty?
48
48
 
49
49
  if self.class == VoiceForm::Form
50
50
  self.form_stack << form_field
@@ -267,9 +267,7 @@ describe VoiceForm::FormField do
267
267
 
268
268
  def form_field(field, options={}, &block)
269
269
  self.class.class_eval { attr_accessor field }
270
- item = VoiceForm::FormField.new(field, {:attempts => 3}.merge(options), self )
271
-
272
- item.instance_eval(&block)
270
+ item = VoiceForm::FormField.new(field, {:attempts => 3}.merge(options), self, &block)
273
271
  item
274
272
  end
275
273
  end
@@ -16,7 +16,7 @@ describe VoiceForm::Form do
16
16
 
17
17
  self.class.voice_form &call_me
18
18
 
19
- start_voice_form
19
+ start_voice_form(@call_context)
20
20
  end
21
21
 
22
22
  it "should call setup block" do
@@ -203,8 +203,8 @@ describe VoiceForm::Form do
203
203
 
204
204
  def new_voice_form
205
205
  self.class.voice_form { }
206
- self.form = VoiceForm::Form.new(self.class.voice_form_options[0])
207
- self.form.instance_eval(&self.class.voice_form_options[1])
206
+ options, block = *self.class.voice_form_options
207
+ self.form = VoiceForm::Form.new(options, &block)
208
208
  end
209
209
 
210
210
  def run_form
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adzap-voice_form
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Meehan
@@ -9,11 +9,11 @@ autorequire: voice_form
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-11-11 00:00:00 -08:00
12
+ date: 2009-01-16 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
16
- description: A DSL for Adhearsion to create forms in the style of the VoiceXML form element.
16
+ description: A plugin for Adhearsion to create forms in the style of the VoiceXML form element.
17
17
  email: adam.meehan@gmail.com
18
18
  executables: []
19
19
 
@@ -27,10 +27,12 @@ files:
27
27
  - Rakefile
28
28
  - lib/voice_form.rb
29
29
  - lib/voice_form
30
+ - lib/voice_form/simple_menu.rb
30
31
  - lib/voice_form/form.rb
31
32
  - lib/voice_form/form_field.rb
32
33
  - lib/voice_form/form_methods.rb
33
34
  - spec/form_field_spec.rb
35
+ - spec/simple_menu_spec.rb
34
36
  - spec/spec_helper.rb
35
37
  - spec/form_spec.rb
36
38
  - examples/my_component.rb
@@ -60,6 +62,6 @@ rubyforge_project:
60
62
  rubygems_version: 1.2.0
61
63
  signing_key:
62
64
  specification_version: 2
63
- summary: A DSL for Adhearsion to create forms in the style of the VoiceXML form element.
65
+ summary: A plugin for Adhearsion to create forms in the style of the VoiceXML form element.
64
66
  test_files: []
65
67