diff --git a/lib/punchblock/translator/asterisk.rb b/lib/punchblock/translator/asterisk.rb index de6009f1..f07f746d 100644 --- a/lib/punchblock/translator/asterisk.rb +++ b/lib/punchblock/translator/asterisk.rb @@ -1,6 +1,6 @@ # encoding: utf-8 -require 'celluloid' +require 'celluloid/autostart' require 'ruby_ami' module Punchblock diff --git a/lib/punchblock/translator/asterisk/call.rb b/lib/punchblock/translator/asterisk/call.rb index 829b4995..4e289e1f 100644 --- a/lib/punchblock/translator/asterisk/call.rb +++ b/lib/punchblock/translator/asterisk/call.rb @@ -293,7 +293,7 @@ def execute_agi_command(command, *params) agi = AGICommand.new Punchblock.new_uuid, channel, command, *params response = Celluloid::Future.new register_tmp_handler :ami, [{name: 'AsyncAGI', [:[], 'SubEvent'] => 'Exec'}, {name: 'AsyncAGIExec'}], [{[:[], 'CommandID'] => agi.id}, {[:[], 'CommandId'] => agi.id}] do |event| - response.signal Celluloid::SuccessResponse.new(nil, event) + response.signal Celluloid::Internals::Response::Success.new(nil, event) end agi.execute @ami_client event = response.value diff --git a/lib/punchblock/translator/asterisk/component/output.rb b/lib/punchblock/translator/asterisk/component/output.rb index a9525d7c..bec27318 100644 --- a/lib/punchblock/translator/asterisk/component/output.rb +++ b/lib/punchblock/translator/asterisk/component/output.rb @@ -31,12 +31,12 @@ def execute case rendering_engine.to_sym when :asterisk - validate_audio_only + validate_audio_or_number_only setup_for_native repeat_times.times do render_docs.each do |doc| - playback(filenames(doc).values) || raise(PlaybackError) + play_doc_asterisk(doc) end end when :native_or_unimrcp @@ -119,9 +119,13 @@ def send_progress_if_necessary @call.send_progress if @early end - def validate_audio_only + # Validates if the input document contains only audio files, or numbers. Raises UnrendernableDocError if the document isn't valid. + def validate_audio_or_number_only render_docs.each do |doc| - filenames doc, -> { raise UnrenderableDocError, 'The provided document could not be rendered. See http://adhearsion.com/docs/common_problems#unrenderable-document-error for details.' } + doc.value.children.each do |node| + next if RubySpeech::SSML::Audio === node || (RubySpeech::SSML::SayAs === node && all_numbers?(node.text) ) || (String === node && !node.include?(' ')) + raise UnrenderableDocError, 'The provided document could not be rendered. When using Asterisk rendering the document must contain either numbers, or links to audio files. See http://adhearsion.com/docs/common_problems#unrenderable-document-error for details' + end end end @@ -136,20 +140,27 @@ def path_for_audio_node(node) end end - def filenames(doc, check_audio_only_policy = -> {}) - names = {} + def play_doc_asterisk(doc) doc.value.children.each do |node| case node when RubySpeech::SSML::Audio - names[node] = path_for_audio_node node + playback([path_for_audio_node(node)]) || raise(PlaybackError) when String - check_audio_only_policy.call if node.include?(' ') - names[nil] = node - else - check_audio_only_policy.call + playback([node]) || raise(PlaybackError) + when RubySpeech::SSML::SayAs + if all_numbers?(node.text) + say_number(node.text) + else + raise UnrenderableDocError, 'The provided document could not be rendered. When using Asterisk rendering the document must contain either numbers, or links to audio files. See http://adhearsion.com/docs/common_problems#unrenderable-document-error for details' + end + else + raise UnrenderableDocError, 'The provided document could not be rendered. When using Asterisk rendering the document must contain either numbers, or links to audio files. See http://adhearsion.com/docs/common_problems#unrenderable-document-error for details' end end - names + end + + def all_numbers?(input) + !!(/^[0-9]+$/ =~ input) end def playback_options(paths) @@ -164,6 +175,11 @@ def playback(paths) @call.channel_var('PLAYBACKSTATUS') != 'FAILED' end + def say_number(number) + return true if @stopped + @call.execute_agi_command 'EXEC SayNumber', number + end + def fallback_doc(original, failed_audio_node) children = failed_audio_node.nokogiri_children copied_doc original, children @@ -229,4 +245,4 @@ def finish_reason end end end -end +end \ No newline at end of file diff --git a/lib/punchblock/version.rb b/lib/punchblock/version.rb index 3fa60280..62ae79e5 100644 --- a/lib/punchblock/version.rb +++ b/lib/punchblock/version.rb @@ -1,5 +1,5 @@ # encoding: utf-8 module Punchblock - VERSION = "2.7.5" + VERSION = "2.7.12" end diff --git a/punchblock.gemspec b/punchblock.gemspec index 41f82d44..b40399c3 100644 --- a/punchblock.gemspec +++ b/punchblock.gemspec @@ -22,15 +22,15 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 1.3.7") if s.respond_to? :required_rubygems_version= - s.add_runtime_dependency %q, ["~> 1.5", ">= 1.5.6"] - s.add_runtime_dependency %q, ["~> 1.0"] - s.add_runtime_dependency %q, [">= 3.0.0", "< 5.0.0"] + s.add_runtime_dependency %q + s.add_runtime_dependency %q + s.add_runtime_dependency %q, [">= 3.0.0", "<= 6.1"] s.add_runtime_dependency %q, ["~> 1.0"] s.add_runtime_dependency %q, ["~> 1.0"] s.add_runtime_dependency %q, ["~> 1.5"] - s.add_runtime_dependency %q, ["~> 0.15.2"] - s.add_runtime_dependency %q, ["~> 2.2"] - s.add_runtime_dependency %q, ["~> 2.3"] + s.add_runtime_dependency %q + s.add_runtime_dependency %q + s.add_runtime_dependency %q, ["~> 3.0"] s.add_runtime_dependency %q, ["~> 1.0"] s.add_runtime_dependency %q, ["~> 1.0"] diff --git a/spec/punchblock/translator/asterisk/component/composed_prompt_spec.rb b/spec/punchblock/translator/asterisk/component/composed_prompt_spec.rb index 0c814b6c..71c1353a 100644 --- a/spec/punchblock/translator/asterisk/component/composed_prompt_spec.rb +++ b/spec/punchblock/translator/asterisk/component/composed_prompt_spec.rb @@ -129,7 +129,7 @@ def send_ami_events_for_dtmf(digit) end context "if output fails to start" do - let(:output_response) { ProtocolError.new.setup 'unrenderable document error', 'The provided document could not be rendered. See http://adhearsion.com/docs/common_problems#unrenderable-document-error for details.' } + let(:output_response) { ProtocolError.new.setup 'unrenderable document error', 'The provided document could not be rendered. When using Asterisk rendering the document must contain either numbers, or links to audio files. See http://adhearsion.com/docs/common_problems#unrenderable-document-error for details' } let :ssml_doc do RubySpeech::SSML.draw do diff --git a/spec/punchblock/translator/asterisk/component/output_spec.rb b/spec/punchblock/translator/asterisk/component/output_spec.rb index bb8507a1..821c7c2d 100644 --- a/spec/punchblock/translator/asterisk/component/output_spec.rb +++ b/spec/punchblock/translator/asterisk/component/output_spec.rb @@ -503,6 +503,10 @@ def expect_playback_noanswer expect(mock_call).to receive(:execute_agi_command).once.with('EXEC Playback', audio_filename + ',noanswer').and_return code: 200 end + def expect_say_number(number) + expect(mock_call).to receive(:execute_agi_command).once.with('EXEC SayNumber', number).and_return code: 200 + end + let(:audio_filename) { 'tt-monkeys' } let :ssml_doc do @@ -703,7 +707,8 @@ def mock_call.answered? it 'should playback all audio files using Playback' do latch = CountDownLatch.new 2 - expect_playback [audio_filename1, audio_filename2].join('&') + expect_playback audio_filename1 + expect_playback audio_filename2 expect_answered subject.execute latch.wait 2 @@ -712,7 +717,8 @@ def mock_call.answered? it 'should send a complete event after the final file has finished playback' do expect_answered - expect_playback [audio_filename1, audio_filename2].join('&') + expect_playback audio_filename1 + expect_playback audio_filename2 latch = CountDownLatch.new 1 expect(original_command).to receive(:add_event).once { |e| expect(e.reason).to be_a Punchblock::Component::Output::Complete::Finish @@ -723,6 +729,41 @@ def mock_call.answered? end end + context 'with an audio file and a number' do + let(:audio_filename) { 'filename' } + let :ssml_doc do + RubySpeech::SSML.draw do + audio :src => audio_filename + say_as(:interpret_as => :cardinal) { '1234' } + end + end + + it 'should playback an audio file, and say a number' do + expect_answered + expect_playback audio_filename + expect_say_number '1234' + subject.execute + end + end + + context 'with an audio file and a number+text' do + let(:audio_filename) { 'filename' } + let :ssml_doc do + RubySpeech::SSML.draw do + audio :src => audio_filename + say_as(:interpret_as => :cardinal) { '1234X5' } + end + end + + it "should return an unrenderable document error" do + subject.execute + error = ProtocolError.new.setup 'unrenderable document error', 'The provided document could not be rendered. When using Asterisk rendering the document must contain either numbers, or links to audio files. See http://adhearsion.com/docs/common_problems#unrenderable-document-error for details' + expect(original_command.response(0.1)).to eq(error) + end + end + + + context "with an SSML document containing elements other than