freec 0.2.6 → 0.2.8

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: df2fa8a96256734d308ad216676ff07f879d6266
4
+ data.tar.gz: 7408f1183efa35c140a83515a9d8e40078823980
5
+ SHA512:
6
+ metadata.gz: 4d6ade697846f0b75566dedf0c0ccc3d0ea78895e8ffe4f42265544c6a8d5620678563717ad22fdf387b18dcfbefa859d4dc1ca674e892d85ec5612b43ff3472
7
+ data.tar.gz: 4283bc10510063f7a100a5a7bb7025f18b7932506e9b6bc978b1962192b49bd6b10a0cea97c42a595caf6a79d88411b07ab2c99869cd15221e10762412f922a5
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ pkg
2
+ doc
3
+ Manifest
4
+ *gem
5
+ .rspec_status
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in freec.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,39 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ freec (0.2.8)
5
+ daemons (~> 1.2.4)
6
+ gserver (~> 0.0.1)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ daemons (1.2.4)
12
+ diff-lcs (1.3)
13
+ gserver (0.0.1)
14
+ rake (10.5.0)
15
+ rspec (3.5.0)
16
+ rspec-core (~> 3.5.0)
17
+ rspec-expectations (~> 3.5.0)
18
+ rspec-mocks (~> 3.5.0)
19
+ rspec-core (3.5.4)
20
+ rspec-support (~> 3.5.0)
21
+ rspec-expectations (3.5.0)
22
+ diff-lcs (>= 1.2.0, < 2.0)
23
+ rspec-support (~> 3.5.0)
24
+ rspec-mocks (3.5.0)
25
+ diff-lcs (>= 1.2.0, < 2.0)
26
+ rspec-support (~> 3.5.0)
27
+ rspec-support (3.5.0)
28
+
29
+ PLATFORMS
30
+ ruby
31
+
32
+ DEPENDENCIES
33
+ bundler (~> 1.14)
34
+ freec!
35
+ rake (~> 10.0)
36
+ rspec (~> 3.0)
37
+
38
+ BUNDLED WITH
39
+ 1.14.4
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Jan Kubr
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.rdoc CHANGED
@@ -6,20 +6,20 @@ Freec is a framework you can build voice applications on top of. It makes use of
6
6
 
7
7
  = Usage
8
8
  1. Install Freeswitch and point a chosen extension to the IP where your app will run:
9
-
9
+
10
10
  <extension name="telfa">
11
11
  <condition field="destination_number" expression="^.*$">
12
12
  <action application="socket" data="127.0.0.1:8084 async full" />
13
13
  </condition>
14
14
  </extension>
15
-
15
+
16
16
  2. Create a file with the main class of your application (e.g. Jukebox) and make it a subclass of Freec. Name the file according to the class name (e.g. jukebox.rb). Implement
17
17
  a step method instructions for which will follow. Simple example:
18
-
18
+
19
19
  #jukebox.rb
20
20
  require 'rubygems'
21
21
  require 'freec'
22
- class Jukebox < Freec
22
+ class Jukebox < FreecBase
23
23
  def step
24
24
  @step ||= 1
25
25
  case @step
@@ -34,10 +34,12 @@ Freec is a framework you can build voice applications on top of. It makes use of
34
34
  end
35
35
  end
36
36
 
37
+ start
38
+
37
39
  3. Run it with:
38
40
  ruby jukebox.rb
39
41
 
40
- = How does it work
42
+ = How does it work
41
43
  The step method is called after each even is finished (e.g. file is played, recording is finished). Here is what you can do:
42
44
  * read call variables from the hash in call_vars
43
45
  * call one of the following methods (Freeswitch apps):
@@ -49,25 +51,16 @@ The step method is called after each even is finished (e.g. file is played, reco
49
51
  * set_variable(name, value)
50
52
  * any other via execute_app(app_name, params)
51
53
  If you return nil or false from the step method, the call will be hungup.
52
-
54
+
53
55
  = Cool stuff
54
56
  * Your application's main file as well as everything you might have in the lib directory will be reloaded on each step in development mode.
55
- * Passing -d will daemonize the application and automatically implies production mode.
57
+ * Passing -d will daemonize the application and automatically implies production mode.
56
58
  * The log directory contains the log file and the pid file.
57
59
  * There is a hidden feature.
58
60
 
59
61
  = Stinks?
60
62
  What Freec can do at the moment was enough for me to implement Telfa (http://telfapbx.com). If it doesn't fit your needs, you can:
61
- 1. Complain to hi@jankubr.com .
63
+ 1. Complain to mail@jankubr.com .
62
64
  2. Fork it and change yourself.
63
65
  3. Check Liverpie (http://www.liverpie.com/) or Telegraph (http://code.google.com/p/telegraph/), Freec is inspired by them.
64
66
  4. Write yours :-)
65
-
66
- = License
67
- Copyright © 2009 Jan Kubr
68
-
69
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
70
-
71
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
72
-
73
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -1,42 +1,6 @@
1
- require 'rubygems'
2
- require 'rake'
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
3
 
4
- desc 'Clean up files.'
5
- task :clean do |t|
6
- FileUtils.rm_rf "tmp"
7
- FileUtils.rm_rf "pkg"
8
- end
4
+ RSpec::Core::RakeTask.new(:spec)
9
5
 
10
- spec = Gem::Specification.new do |s|
11
- s.name = "freec"
12
- s.version = '0.2.6'
13
- s.author = "Jan Kubr"
14
- s.email = "mail@jankubr.com"
15
- s.homepage = "http://github.com/jankubr/freec"
16
- s.platform = Gem::Platform::RUBY
17
- s.summary = "The layer between your Ruby voice app and FreeSWITCH."
18
- s.files = FileList["README*",
19
- "Rakefile",
20
- "{lib,spec}/**/*"].to_a
21
- s.require_path = "lib"
22
- s.rubyforge_project = "freec"
23
- s.has_rdoc = false
24
- s.extra_rdoc_files = FileList["README*"].to_a
25
- s.rdoc_options << '--line-numbers' << '--inline-source'
26
- s.add_dependency "daemons"
27
- s.add_development_dependency 'rspec', '> 2.0.1'
28
- end
29
-
30
- desc "Generate a gemspec file"
31
- task :gemspec do
32
- File.open("#{spec.name}.gemspec", 'w') do |f|
33
- f.write spec.to_ruby
34
- end
35
- end
36
-
37
- require 'rspec/core/rake_task'
38
-
39
- desc "Run all specs"
40
- RSpec::Core::RakeTask.new(:spec) do |t|
41
- t.pattern = FileList['spec/**/*.rb']
42
- end
6
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "freec"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/freec.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'freec/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "freec"
8
+ spec.version = Freec::VERSION
9
+ spec.authors = ["Jan Kubr"]
10
+ spec.email = ["mail@jankubr.com"]
11
+
12
+ spec.summary = "The layer between your Ruby voice app and FreeSWITCH."
13
+ spec.description = "The layer between your Ruby voice app and FreeSWITCH."
14
+ spec.homepage = "http://github.com/jankubr/freec"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_runtime_dependency 'gserver', '~> 0.0.1'
25
+ spec.add_runtime_dependency 'daemons', '~> 1.2.4'
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.14"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_development_dependency "rspec", "~> 3.0"
30
+ end
@@ -0,0 +1,3 @@
1
+ module Freec
2
+ VERSION = "0.2.8"
3
+ end
data/lib/freec.rb CHANGED
@@ -1,6 +1,8 @@
1
+ require 'freec/version'
1
2
  lib_dir = File.dirname(__FILE__)
2
3
  $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
3
- require "freec_base"
4
+ require 'gserver'
5
+ require 'freec_base'
4
6
  require 'listener'
5
7
 
6
8
  require 'fileutils'
@@ -9,7 +11,7 @@ require 'daemons/daemonize'
9
11
  include Daemonize
10
12
 
11
13
  def freec_app_file_name
12
- $0.sub(/\.[^\.]*$/, '')
14
+ $0.sub(/\.[^\.]*$/, '')
13
15
  end
14
16
 
15
17
  def freec_app_class_name
@@ -21,7 +23,7 @@ def freec_app_log_dir
21
23
  end
22
24
 
23
25
  def create_freec_app_log_dir
24
- FileUtils.mkdir_p(freec_app_log_dir)
26
+ FileUtils.mkdir_p(freec_app_log_dir)
25
27
  end
26
28
 
27
29
  def freec_app_log_file
@@ -44,9 +46,9 @@ def freec_app_configuration_file
44
46
  "#{ROOT}/config/config.yml"
45
47
  end
46
48
 
47
- unless defined?(TEST)
48
- ROOT = File.expand_path(File.dirname($0))
49
- ENVIRONMENT = ARGV[0] == '-d' ? 'production' : 'development'
49
+ ROOT = File.expand_path(File.dirname($0))
50
+ ENVIRONMENT = ARGV[0] == '-d' ? 'production' : 'development'
51
+ def start
50
52
  create_freec_app_log_dir
51
53
  load_freec_app_config
52
54
  if ARGV[0] == '-d'
@@ -59,9 +61,6 @@ unless defined?(TEST)
59
61
  server = Listener.new(freec_app_class_name, @@config)
60
62
  server.audit = true
61
63
  server.start
62
- loop do
63
- break if server.stopped?
64
- sleep(1)
65
- end
64
+ server.join
66
65
  end
67
66
  end
data/lib/freec_base.rb CHANGED
@@ -1,28 +1,27 @@
1
1
  require 'gserver'
2
- require 'rubygems'
3
2
  require 'uri'
4
3
 
5
4
  require 'tools'
6
- require "freeswitch_applications"
7
- require "call_variables"
5
+ require 'freeswitch_applications'
6
+ require 'call_variables'
8
7
 
9
- class Freec
8
+ class FreecBase
10
9
  include FreeswitchApplications
11
10
  include CallVariables
12
-
11
+
13
12
  attr_reader :call_vars, :event_body, :log, :config
14
-
13
+
15
14
  def initialize(io, log, config) #:nodoc:
16
15
  @call_vars = {}
17
16
  @want_events_from = []
18
17
  @last_app_executed = 'initial_step'
19
- @io = io
18
+ @io = io
20
19
  @log = log
21
20
  @config = config
22
21
  end
23
-
22
+
24
23
  def handle_call #:nodoc:
25
- call_initialization
24
+ call_initialization
26
25
  loop do
27
26
  subscribe_to_new_channel_events
28
27
  if last_event_dtmf? && respond_to?(:on_dtmf)
@@ -38,7 +37,7 @@ class Freec
38
37
  hangup unless @io.closed?
39
38
  send_and_read('exit') unless @io.closed?
40
39
  end
41
-
40
+
42
41
  def wait_for(key, value)
43
42
  @waiting_for_key = key && key.to_sym
44
43
  @waiting_for_value = value
@@ -46,13 +45,13 @@ class Freec
46
45
 
47
46
  def reset_wait_for
48
47
  wait_for(nil, nil)
49
- true
50
- end
51
-
48
+ true
49
+ end
50
+
52
51
  def execute_completed?
53
52
  channel_execute_complete? || channel_destroyed_after_bridge? || disconnect_notice?
54
53
  end
55
-
54
+
56
55
  private
57
56
 
58
57
  def call_initialization
@@ -62,17 +61,17 @@ private
62
61
 
63
62
  def channel_execute_complete?
64
63
  return true if @last_app_executed == 'initial_step'
65
- complete = call_vars[:content_type] == 'text/event-plain' &&
64
+ complete = call_vars[:content_type] == 'text/event-plain' &&
66
65
  call_vars[:event_name] == 'CHANNEL_EXECUTE_COMPLETE' &&
67
66
  @last_app_executed == call_vars[:application]
68
67
  @last_app_executed = nil if complete
69
68
  complete
70
69
  end
71
-
70
+
72
71
  def channel_destroyed_after_bridge?
73
72
  call_vars[:application] == 'bridge' && call_vars[:event_name] == 'CHANNEL_DESTROY'
74
73
  end
75
-
74
+
76
75
  def disconnect_notice?
77
76
  @io.closed? || call_vars[:content_type] == 'text/disconnect-notice'
78
77
  end
@@ -81,7 +80,7 @@ private
81
80
  send(callback_name, *args) if respond_to?(callback_name)
82
81
  rescue StandardError => e
83
82
  log.error e.message
84
- e.backtrace.each {|trace_line| log.error(trace_line)}
83
+ e.backtrace.each {|trace_line| log.error(trace_line)}
85
84
  end
86
85
 
87
86
  def reload_application_code
@@ -89,7 +88,7 @@ private
89
88
  load($0)
90
89
  lib_dir = "#{ROOT}/lib"
91
90
  return unless File.exist?(lib_dir)
92
- Dir.open(lib_dir).each do |file|
91
+ Dir.open(lib_dir).each do |file|
93
92
  full_file_name = File.join(lib_dir, file)
94
93
  next unless File.file?(full_file_name)
95
94
  load(full_file_name)
@@ -100,62 +99,62 @@ private
100
99
  send_and_read('connect')
101
100
  parse_response
102
101
  end
103
-
102
+
104
103
  def subscribe_to_events
105
104
  send_and_read('events plain all')
106
- parse_response
107
- send_and_read("filter Unique-ID #{@unique_id}")
108
- parse_response
109
- send_and_read("divert_events on")
105
+ parse_response
106
+ send_and_read("filter Unique-ID #{@unique_id}")
107
+ parse_response
108
+ send_and_read("divert_events on")
110
109
  parse_response
111
110
  end
112
-
111
+
113
112
  def subscribe_to_new_channel_events
114
113
  return unless call_vars[:event_name] == 'CHANNEL_BRIDGE'
115
114
  @want_events_from << call_vars[:other_leg_unique_id]
116
115
  send_and_read("filter Unique-ID #{call_vars[:other_leg_unique_id]}")
117
116
  end
118
-
117
+
119
118
  def waiting_for_this_response?
120
119
  @waiting_for_key && @waiting_for_value && call_vars[@waiting_for_key] == @waiting_for_value
121
120
  end
122
-
121
+
123
122
  def last_event_dtmf?
124
123
  call_vars[:content_type] == 'text/event-plain' && call_vars[:event_name] == 'DTMF'
125
124
  end
126
-
125
+
127
126
  def send_data(data)
128
127
  log.debug "Sending: #{data}"
129
128
  @io.write("#{data}\n\n") unless disconnect_notice?
130
129
  end
131
-
130
+
132
131
  def send_and_read(data)
133
132
  send_data(data)
134
133
  read_response
135
134
  end
136
-
135
+
137
136
  def read_and_parse_response
138
137
  my_event = false
139
138
  until my_event
140
139
  read_response
141
140
  my_event = parse_response
142
- end
141
+ end
143
142
  end
144
-
143
+
145
144
  def read_response
146
145
  return if disconnect_notice?
147
146
  read_response_info
148
147
  read_event_header
149
148
  read_event_body
150
149
  end
151
-
150
+
152
151
  def read_response_info
153
152
  @response = ''
154
153
  begin
155
154
  @response += read_line_from_io
156
- end until @response[-2..-1] == "\n\n"
155
+ end until @response[-2..-1] == "\n\n"
157
156
  end
158
-
157
+
159
158
  def read_event_header
160
159
  header_length = @response.sub(/^Content-Length: ([0-9]+)$.*/m, '\1').to_i
161
160
  return if header_length == 0
@@ -163,23 +162,23 @@ private
163
162
  begin
164
163
  header += read_line_from_io
165
164
  end until header[-2..-1] == "\n\n"
166
- @response += header
165
+ @response += header
167
166
  end
168
-
167
+
169
168
  def read_event_body
170
169
  body_length = @response.sub(/^Content-Length.*^Content-Length: ([0-9]+)$.*/m, '\1').to_i
171
170
  return if body_length == 0
172
171
  body = ''
173
- begin
172
+ begin
174
173
  body += read_block_from_io(body_length)
175
174
  end until body.length == body_length
176
- @response += body
175
+ @response += body
177
176
  end
178
-
177
+
179
178
  def parse_response
180
179
  hash = {}
181
180
  if @response =~ /^Content-Length.*^Content-Length/m
182
- @event_body = @response.sub(/.*\n\n.*\n\n(.*)/m, '\1').strip
181
+ @event_body = @response.sub(/.*\n\n.*\n\n(.*)/m, '\1').strip
183
182
  else
184
183
  @event_body = nil
185
184
  end
@@ -198,21 +197,21 @@ private
198
197
  @response = ''
199
198
  true
200
199
  end
201
-
200
+
202
201
  def read_line_from_io
203
202
  line = @io.gets
204
203
  raise io_disconnected_message unless line
205
204
  line
206
205
  end
207
-
206
+
208
207
  def read_block_from_io(length)
209
208
  block = @io.read(length)
210
209
  raise io_disconnected_message unless block
211
210
  block
212
211
  end
213
-
212
+
214
213
  def io_disconnected_message
215
214
  "IO disconnected - FreeSWITCH crashed?"
216
215
  end
217
-
218
- end
216
+
217
+ end
@@ -1,12 +1,12 @@
1
1
  module FreeswitchApplications
2
-
2
+
3
3
  # Answers the call.
4
4
  def answer
5
5
  execute_app('answer')
6
6
  end
7
7
 
8
8
  # Plays the file in file_name
9
- # file_name is either an absolute path or path relative
9
+ # file_name is either an absolute path or path relative
10
10
  # to the sound_prefix variable set in Freeswitch's vars.xml configuration file.
11
11
  def playback(file_name)
12
12
  execute_app('playback', file_name)
@@ -16,36 +16,36 @@ module FreeswitchApplications
16
16
  def spell(string)
17
17
  execute_app('phrase', "spell,#{string}")
18
18
  end
19
-
19
+
20
20
  # Says the given string
21
21
  # Don't forget to set up your TTS engine and set variables tts_engine and tts_voice accordingly
22
22
  # See e.g.: http://wiki.freeswitch.org/wiki/Mod_flite
23
23
  def speak(string)
24
24
  execute_app('speak', string)
25
25
  end
26
-
26
+
27
27
  # Bridges the call to the given number or numbers (this param can be a number or an array of numbers).
28
28
  def bridge(number_or_numbers, options = {})
29
29
  number_or_numbers = number_or_numbers.join(",") if number_or_numbers.is_a?(Array)
30
30
  execute_app("bridge", "#{number_or_numbers}")
31
31
  end
32
-
32
+
33
33
  # Transfers the call to the given extension
34
34
  def transfer(extension)
35
35
  execute_app("transfer", "#{extension}")
36
36
  end
37
-
37
+
38
38
  # Records the call to a file with the given file_name
39
- # file_name is either an absolute path or path relative
39
+ # file_name is either an absolute path or path relative
40
40
  # to the sound_prefix variable set in Freeswitch's vars.xml configuration file.
41
41
  #
42
42
  # Options:
43
43
  # * <tt>:time_limit_secs</tt> overrides the default timeout, which is 600 seconds
44
44
  def record(file_name, options = {})
45
- options = {:time_limit_secs => 600}.merge(options) #no reverse_merge, no fun :-)
45
+ options = {time_limit_secs: 600}.merge(options) #no reverse_merge, no fun :-)
46
46
  execute_app("record", "#{file_name} #{options[:time_limit_secs]}")
47
47
  end
48
-
48
+
49
49
  # Plays the file in file_name and reads input (key presses) from the user.
50
50
  #
51
51
  # Options:
@@ -55,10 +55,10 @@ module FreeswitchApplications
55
55
  # * <tt>:min and :max</tt> options to override the default maximum and minimum of characters that will be read (both default to 1)
56
56
  def read(file_name, options = {})
57
57
  options[:terminators] = [options[:terminators]] if options[:terminators].is_a?(String)
58
- options = {:timeout => 10, :variable => 'input', :min => 1, :max => 1, :terminators => ['#']}.merge(options)
58
+ options = {timeout: 10, variable: 'input', min: 1, max: 1, terminators: ['#']}.merge(options)
59
59
  execute_app("read", "#{options[:min]} #{options[:max]} #{file_name} #{options[:variable]} #{options[:timeout] * 1000} #{options[:terminators].join(',')}")
60
60
  end
61
-
61
+
62
62
  # Starts recording the call in file in file_name
63
63
  #
64
64
  def start_recording(file_name)
@@ -66,11 +66,11 @@ module FreeswitchApplications
66
66
  end
67
67
 
68
68
  # Stops recording the call in file in file_name
69
- #
69
+ #
70
70
  def stop_recording(file_name)
71
71
  execute_app('stop_record_session', file_name)
72
72
  end
73
-
73
+
74
74
  # Sets a variable with the give name to the given value.
75
75
  def set_variable(name, value)
76
76
  execute_app('set', "#{name}=#{value}")
@@ -78,9 +78,9 @@ module FreeswitchApplications
78
78
 
79
79
  # Hangs up the call.
80
80
  def hangup
81
- execute_app('hangup')
82
- end
83
-
81
+ execute_app('hangup', 'USER_BUSY')
82
+ end
83
+
84
84
  # Executes an app using the sendmsg command of Freeswitch.
85
85
  # Use this if there is no method for the application you want to run.
86
86
  #
@@ -88,7 +88,7 @@ module FreeswitchApplications
88
88
  # * <tt>app</tt> is the application name
89
89
  # * <tt>pars</tt> is a string of arguments of the app
90
90
  # * <tt>lock</tt> can be set to false so Freeswitch won't wait for this app to finish before running the next one
91
- def execute_app(app, pars = '', lock = true, unique_id = nil)
91
+ def execute_app(app, pars = '', lock = true, unique_id = nil)
92
92
  @last_app_executed = app
93
93
  unique_id = @unique_id unless unique_id
94
94
  cmd = "sendmsg #{unique_id}"
@@ -97,5 +97,5 @@ module FreeswitchApplications
97
97
  cmd << "\nexecute-app-arg: #{pars}" unless pars.blank?
98
98
  cmd << "\nevent-lock:#{lock}"
99
99
  send_data cmd
100
- end
101
- end
100
+ end
101
+ end