bougyman-freeswitcher 0.0.9 → 0.1.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/README +45 -4
- data/{bin → examples/bin}/cmd_demo.rb +0 -0
- data/examples/bin/dtmf_test.rb +38 -0
- data/{bin → examples/bin}/ies_demo.rb +0 -0
- data/{bin → examples/bin}/ies_demo_with_hook.rb +0 -2
- data/{bin → examples/bin}/oes_demo.rb +0 -0
- data/examples/dtmf_test.rb +35 -0
- data/examples/ies_demo.rb +19 -0
- data/examples/ies_demo_with_hook.rb +25 -0
- data/examples/oes_demo.rb +21 -0
- data/examples/play_and_get_test.rb +35 -0
- data/lib/fsr.rb +1 -1
- data/lib/fsr/app/hangup.rb +3 -3
- data/lib/fsr/app/play_and_get_digits.rb +30 -0
- data/lib/fsr/app/playback.rb +2 -3
- data/lib/fsr/app/read.rb +22 -0
- data/lib/fsr/app/transfer.rb +2 -2
- data/lib/fsr/app/uuid_dump.rb +22 -0
- data/lib/fsr/app/uuid_getvar.rb +23 -0
- data/lib/fsr/app/uuid_setvar.rb +24 -0
- data/lib/fsr/cmd/calls.rb +46 -0
- data/lib/fsr/listener/outbound.rb +65 -25
- data/lib/fsr/listener/outbound.rb.orig +131 -0
- data/lib/fsr/model/call.rb +48 -0
- data/spec/fsr/app/hangup.rb +16 -0
- data/spec/fsr/app/log.rb +11 -0
- data/spec/fsr/app/play_and_get_digits.rb +12 -0
- data/spec/fsr/app/playback.rb +11 -0
- data/spec/fsr/app/set.rb +12 -0
- data/spec/fsr/app/transfer.rb +11 -0
- data/spec/fsr/cmd/calls.rb +13 -0
- data/spec/fsr/listener/inbound.rb +7 -0
- data/spec/fsr/loading.rb +2 -2
- metadata +74 -15
data/README
CHANGED
@@ -44,11 +44,11 @@ Example of creating an Outbound Eventsocket listener:
|
|
44
44
|
|
45
45
|
class OesDemo < FSR::Listener::Outbound
|
46
46
|
|
47
|
-
def session_initiated
|
48
|
-
number = session.headers[:caller_caller_id_number] # Grab the inbound caller id
|
47
|
+
def session_initiated
|
48
|
+
number = @session.headers[:caller_caller_id_number] # Grab the inbound caller id
|
49
49
|
FSR::Log.info "*** Answering incoming call from #{number}"
|
50
50
|
answer # Answer the call
|
51
|
-
set "
|
51
|
+
set("hangup_after_bridge", "true")# Set a variable
|
52
52
|
speak 'Hello, This is your phone switch. Have a great day' # use mod_flite to speak
|
53
53
|
hangup # Hangup the call
|
54
54
|
end
|
@@ -59,12 +59,53 @@ Example of creating an Outbound Eventsocket listener:
|
|
59
59
|
|
60
60
|
|
61
61
|
|
62
|
+
Example of creating an Outbound Eventsocket listener that can read DTMF input and keep state:
|
63
|
+
|
64
|
+
#!/usr/bin/env ruby
|
65
|
+
|
66
|
+
require 'fsr'
|
67
|
+
require 'fsr/listener/outbound'
|
68
|
+
|
69
|
+
FSR.load_all_applications
|
70
|
+
FSR.load_all_commands
|
71
|
+
|
72
|
+
class DtmfDemo < FSR::Listener::Outbound
|
73
|
+
|
74
|
+
def session_initiated
|
75
|
+
exten = @session.headers[:caller_caller_id_number]
|
76
|
+
FSR::Log.info "*** Answering incoming call from #{exten}"
|
77
|
+
answer # Answer the call
|
78
|
+
end
|
79
|
+
|
80
|
+
def receive_reply(reply)
|
81
|
+
exten = @session.headers[:caller_caller_id_number]
|
82
|
+
case @step
|
83
|
+
when 1
|
84
|
+
FSR::Log.info "*** Reading dtmf for #{exten}"
|
85
|
+
read "/home/freeswitch/freeswitch/sounds/music/8000/sweet.wav",4,10,"test",15000 # read test
|
86
|
+
when 2
|
87
|
+
FSR::Log.info "*** updating session for #{exten}"
|
88
|
+
update_session
|
89
|
+
when 3
|
90
|
+
FSR::Log.info "** Success, grabbed #{@session.headers[:variable_test].strip} from #{exten}"
|
91
|
+
FSR::Log.info "*** Hanging up call"
|
92
|
+
hangup # Hangup the call
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
FSR.start_oes! DtmfDemo, :port => 8084, :host => "127.0.0.1"
|
99
|
+
|
100
|
+
|
101
|
+
|
62
102
|
Example of creating an Inbound Eventsocket listener:
|
63
103
|
|
64
104
|
#!/usr/bin/env ruby
|
65
105
|
|
66
106
|
require 'fsr'
|
67
|
-
require
|
107
|
+
require 'fsr/listener/inbound'
|
108
|
+
require 'pp'
|
68
109
|
|
69
110
|
class IesDemo < FSR::Listener::Inbound
|
70
111
|
|
File without changes
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.join(File.dirname(__FILE__), "..", 'start_common')
|
3
|
+
require 'eventmachine'
|
4
|
+
require "fsr/listener/outbound"
|
5
|
+
require 'pp'
|
6
|
+
$stdout.flush
|
7
|
+
FSR.load_all_applications
|
8
|
+
FSR.load_all_commands
|
9
|
+
class ConsumerLogin < FSR::Listener::Outbound
|
10
|
+
|
11
|
+
def session_initiated(session, step = 0)
|
12
|
+
@step ||= step
|
13
|
+
exten = session.headers[:channel_caller_id_number]
|
14
|
+
pp session.headers
|
15
|
+
FSR::Log.info "*** Answering incoming call from #{exten}"
|
16
|
+
answer # Answer the call
|
17
|
+
end
|
18
|
+
|
19
|
+
def receive_reply(reply)
|
20
|
+
exten = @session.headers[:channel_caller_id_number]
|
21
|
+
@step += 1
|
22
|
+
case @step
|
23
|
+
when 1
|
24
|
+
FSR::Log.info "*** Reading dtmf for #{exten}"
|
25
|
+
read "/home/freeswitch/freeswitch/sounds/music/8000/sweet.wav",4,10,"test",15000 # read test
|
26
|
+
when 2
|
27
|
+
FSR::Log.info "*** updating session for #{exten}"
|
28
|
+
update_session
|
29
|
+
when 3
|
30
|
+
FSR::Log.info "** Success, grabbed #{reply.content[:variable_test].strip} from #{exten}"
|
31
|
+
FSR::Log.info "*** Hanging up call"
|
32
|
+
hangup # Hangup the call
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
FSR.start_oes! ConsumerLogin, :port => 8084, :host => "127.0.0.1"
|
File without changes
|
File without changes
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), "..", 'lib', 'fsr')
|
4
|
+
require "fsr/listener/outbound"
|
5
|
+
$stdout.flush
|
6
|
+
|
7
|
+
FSR.load_all_applications
|
8
|
+
FSR.load_all_commands
|
9
|
+
class DtmfDemo < FSR::Listener::Outbound
|
10
|
+
|
11
|
+
def session_initiated
|
12
|
+
exten = @session.headers[:caller_caller_id_number]
|
13
|
+
FSR::Log.info "*** Answering incoming call from #{exten}"
|
14
|
+
answer # Answer the call
|
15
|
+
end
|
16
|
+
|
17
|
+
def receive_reply(reply)
|
18
|
+
exten = @session.headers[:caller_caller_id_number]
|
19
|
+
case @step
|
20
|
+
when 1
|
21
|
+
FSR::Log.info "*** Reading dtmf for #{exten}"
|
22
|
+
read "/home/freeswitch/freeswitch/sounds/music/8000/sweet.wav",4,10,"test",15000 # read test
|
23
|
+
when 2
|
24
|
+
FSR::Log.info "*** updating session for #{exten}"
|
25
|
+
update_session
|
26
|
+
when 3
|
27
|
+
FSR::Log.info "** Success, grabbed #{@session.headers[:variable_test].strip} from #{exten}"
|
28
|
+
FSR::Log.info "*** Hanging up call"
|
29
|
+
hangup # Hangup the call
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
FSR.start_oes! DtmfDemo, :port => 8084, :host => "127.0.0.1"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'pp'
|
4
|
+
require File.join(File.dirname(__FILE__), "..", 'lib', 'fsr')
|
5
|
+
puts $LOAD_PATH.inspect
|
6
|
+
$stdout.flush
|
7
|
+
require "fsr/listener/inbound"
|
8
|
+
|
9
|
+
|
10
|
+
class IesDemo < FSR::Listener::Inbound
|
11
|
+
|
12
|
+
def on_event(event)
|
13
|
+
pp event.headers
|
14
|
+
pp event.content[:event_name]
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
FSR.start_ies!(IesDemo, :host => "localhost", :port => 8021)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'pp'
|
4
|
+
require File.join(File.dirname(__FILE__), "..", 'lib', 'fsr')
|
5
|
+
puts $LOAD_PATH.inspect
|
6
|
+
$stdout.flush
|
7
|
+
require "fsr/listener/inbound"
|
8
|
+
|
9
|
+
# EXAMPLE 1
|
10
|
+
# This adds a hook on CHANNEL_CREATE events. You can also create a method to handle the event you're after. See the next example
|
11
|
+
FSL::Inbound.add_event_hook(:CHANNEL_CREATE) {|event| FSR::Log.info "*** [#{event.content[:unique_id]}] Channel created - greetings from the hook!" }
|
12
|
+
|
13
|
+
# EXAMPLE 2
|
14
|
+
# Define a method to handle CHANNEL_HANGUP events.
|
15
|
+
def custom_channel_hangup_handler(event)
|
16
|
+
FSR::Log.info "*** [#{event.content[:unique_id]}] Channel hangup. The event:"
|
17
|
+
pp event
|
18
|
+
end
|
19
|
+
# This adds a hook for EXAMPLE 2
|
20
|
+
FSL::Inbound.add_event_hook(:CHANNEL_HANGUP) {|event| custom_channel_hangup_handler(event) }
|
21
|
+
|
22
|
+
|
23
|
+
# Start FSR Inbound Listener
|
24
|
+
FSR.start_ies!(FSL::Inbound, :host => "localhost", :port => 8021)
|
25
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), "..", 'lib', 'fsr')
|
4
|
+
$stdout.flush
|
5
|
+
require "fsr/listener/outbound"
|
6
|
+
|
7
|
+
class OesDemo < FSR::Listener::Outbound
|
8
|
+
|
9
|
+
def session_initiated
|
10
|
+
number = @session.headers[:caller_caller_id_number] # Grab the inbound caller id
|
11
|
+
FSR::Log.info "*** Answering incoming call from #{number}"
|
12
|
+
answer # Answer the call
|
13
|
+
log("1", "Pong from the FSR event socket!")
|
14
|
+
set("hangup_after_bridge", "true") # Set a variable
|
15
|
+
speak 'Hello, This is your phone switch. Have a great day' # use mod_flite to speak
|
16
|
+
hangup # Hangup the call
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
FSR.start_oes!(OesDemo, :port => 1888, :host => "localhost")
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), "..", 'lib', 'fsr')
|
4
|
+
require "fsr/listener/outbound"
|
5
|
+
$stdout.flush
|
6
|
+
|
7
|
+
FSR.load_all_applications
|
8
|
+
FSR.load_all_commands
|
9
|
+
class PlayAndGetTest < FSR::Listener::Outbound
|
10
|
+
|
11
|
+
def session_initiated
|
12
|
+
exten = @session.headers[:caller_caller_id_number]
|
13
|
+
FSR::Log.info "*** Answering incoming call from #{exten}"
|
14
|
+
answer # Answer the call
|
15
|
+
end
|
16
|
+
|
17
|
+
def receive_reply(reply)
|
18
|
+
exten = @session.headers[:caller_caller_id_number]
|
19
|
+
case @step
|
20
|
+
when 1
|
21
|
+
FSR::Log.info "*** Reading dtmf for #{exten}"
|
22
|
+
play_and_get_digits "tone_stream://%(10000,0,350,440)","/home/freeswitch/freeswitch/sounds/en/us/callie/misc/8000/error.wav",2,10,3,7000,["#"],"test", "\d+" # play_and_get_digits test
|
23
|
+
when 2
|
24
|
+
FSR::Log.info "*** updating session for #{exten}"
|
25
|
+
update_session
|
26
|
+
when 3
|
27
|
+
FSR::Log.info "** Success, grabbed #{@session.headers[:variable_test]} from #{exten}"
|
28
|
+
FSR::Log.info "*** Hanging up call"
|
29
|
+
hangup # Hangup the call
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
FSR.start_oes! PlayAndGetTest, :port => 8084, :host => "127.0.0.1"
|
data/lib/fsr.rb
CHANGED
data/lib/fsr/app/hangup.rb
CHANGED
@@ -3,12 +3,12 @@ module FSR
|
|
3
3
|
module App
|
4
4
|
# http://wiki.freeswitch.org/wiki/Misc._Dialplan_Tools_hangup
|
5
5
|
class Hangup < Application
|
6
|
-
def initialize(
|
7
|
-
@
|
6
|
+
def initialize(cause = nil)
|
7
|
+
@cause = cause
|
8
8
|
end
|
9
9
|
|
10
10
|
def arguments
|
11
|
-
@
|
11
|
+
@cause
|
12
12
|
end
|
13
13
|
|
14
14
|
def sendmsg
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "fsr/app"
|
2
|
+
module FSR
|
3
|
+
#http://wiki.freeswitch.org/wiki/Misc._Dialplan_Tools_play_and_get_digits
|
4
|
+
module App
|
5
|
+
class PlayAndGetDigits < Application
|
6
|
+
def initialize(sound_file, invalid_file, min = 0, max = 10, tries = 3, timeout = 7000, terminators = ["#"], chan_var = "fsr_read_dtmf", regexp = "\d")
|
7
|
+
@sound_file = sound_file
|
8
|
+
@invalid_file = invalid_file
|
9
|
+
@min = min
|
10
|
+
@max = max
|
11
|
+
@tries = tries
|
12
|
+
@timeout = timeout
|
13
|
+
@chan_var = chan_var
|
14
|
+
@terminators = terminators
|
15
|
+
@regexp = regexp
|
16
|
+
end
|
17
|
+
|
18
|
+
def arguments
|
19
|
+
[@min, @max, @tries, @timeout, @terminators.join(","), @sound_file, @invalid_file, @chan_var, @regexp]
|
20
|
+
end
|
21
|
+
|
22
|
+
def sendmsg
|
23
|
+
"call-command: execute\nexecute-app-name: %s\nexecute-app-arg: %s\nevent-lock:true\n\n" % ["play_and_get_digits", arguments.join(" ")]
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
register(:play_and_get_digits, PlayAndGetDigits)
|
29
|
+
end
|
30
|
+
end
|
data/lib/fsr/app/playback.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require "fsr/app"
|
3
2
|
module FSR
|
4
3
|
module App
|
@@ -10,11 +9,11 @@ module FSR
|
|
10
9
|
@wavfile = wavfile
|
11
10
|
end
|
12
11
|
def arguments
|
13
|
-
|
12
|
+
@wavfile
|
14
13
|
end
|
15
14
|
|
16
15
|
def sendmsg
|
17
|
-
"call-command: execute\nexecute-app-name: %s\nexecute-app-arg: %s\nevent-lock:true\n\n" % [app_name, arguments
|
16
|
+
"call-command: execute\nexecute-app-name: %s\nexecute-app-arg: %s\nevent-lock:true\n\n" % [app_name, arguments]
|
18
17
|
end
|
19
18
|
end
|
20
19
|
|
data/lib/fsr/app/read.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "fsr/app"
|
2
|
+
module FSR
|
3
|
+
# http://wiki.freeswitch.org/wiki/Misc._Dialplan_Tools_read
|
4
|
+
module App
|
5
|
+
class Read < Application
|
6
|
+
def initialize(sound_file, min = 0, max = 10, chan_var = "fsr_read_dtmf", timeout = 10000, terminators = ["#"])
|
7
|
+
@sound_file, @min, @max, @chan_var, @timeout, @terminators = sound_file, min, max, chan_var, timeout, terminators
|
8
|
+
end
|
9
|
+
|
10
|
+
def arguments
|
11
|
+
[@min, @max, @sound_file, @chan_var, @timeout, @terminators.join(",")]
|
12
|
+
end
|
13
|
+
|
14
|
+
def sendmsg
|
15
|
+
"call-command: execute\nexecute-app-name: %s\nexecute-app-arg: %s\nevent-lock:true\n\n" % [app_name, arguments.join(" ")]
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
register(:read, Read)
|
21
|
+
end
|
22
|
+
end
|
data/lib/fsr/app/transfer.rb
CHANGED
@@ -6,8 +6,8 @@ module FSR
|
|
6
6
|
|
7
7
|
def initialize(destination_number, dialplan = nil, context = nil)
|
8
8
|
@destination_number = destination_number
|
9
|
-
@dialplan = dialplan
|
10
|
-
@context = context
|
9
|
+
@dialplan = dialplan
|
10
|
+
@context = context
|
11
11
|
end
|
12
12
|
|
13
13
|
def arguments
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "fsr/app"
|
2
|
+
module FSR
|
3
|
+
#http://wiki.freeswitch.org/wiki/Mod_commands#uuid_dump
|
4
|
+
module App
|
5
|
+
class UuidDump < Application
|
6
|
+
def initialize(uuid)
|
7
|
+
@uuid = uuid # Unique channel ID
|
8
|
+
end
|
9
|
+
|
10
|
+
def arguments
|
11
|
+
[@uuid]
|
12
|
+
end
|
13
|
+
|
14
|
+
def sendmsg
|
15
|
+
"call-command: execute\nexecute-app-name: %s\nexecute-app-arg: %s\nevent-lock:true\n\n" % [app_name, arguments.join(" ")]
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
register(:uuid_dump, UuidDump)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "fsr/app"
|
2
|
+
module FSR
|
3
|
+
#http://wiki.freeswitch.org/wiki/Mod_commands#uuid_getvar
|
4
|
+
module App
|
5
|
+
class UuidGetVar < Application
|
6
|
+
def initialize(uuid, var)
|
7
|
+
@uuid = uuid # Unique channel ID
|
8
|
+
@var = var # Channel variable you wish to 'get'
|
9
|
+
end
|
10
|
+
|
11
|
+
def arguments
|
12
|
+
[@uuid, @var]
|
13
|
+
end
|
14
|
+
|
15
|
+
def sendmsg
|
16
|
+
"call-command: execute\nexecute-app-name: %s\nexecute-app-arg: %s\nevent-lock:true\n\n" % [app_name, arguments.join(" ")]
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
register(:uuid_getvar, UuidGetVar)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "fsr/app"
|
2
|
+
module FSR
|
3
|
+
#http://wiki.freeswitch.org/wiki/Mod_commands#uuid_setvar
|
4
|
+
module App
|
5
|
+
class UuidSetVar < Application
|
6
|
+
def initialize(uuid, var, assignment)
|
7
|
+
@uuid = uuid # Unique channel ID
|
8
|
+
@var = var # Channel variable you wish to 'set'
|
9
|
+
@assignment
|
10
|
+
end
|
11
|
+
|
12
|
+
def arguments
|
13
|
+
[@uuid, @var, @assignment]
|
14
|
+
end
|
15
|
+
|
16
|
+
def sendmsg
|
17
|
+
"call-command: execute\nexecute-app-name: %s\nexecute-app-arg: %s\nevent-lock:true\n\n" % [app_name, arguments.join(" ")]
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
register(:uuid_setvar, UuidSetVar)
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "fsr/app"
|
2
|
+
module FSR
|
3
|
+
module Cmd
|
4
|
+
class Calls < Command
|
5
|
+
|
6
|
+
include Enumerable
|
7
|
+
def each(&block)
|
8
|
+
@calls ||= run
|
9
|
+
if @calls
|
10
|
+
@calls.each { |call| yield call }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(fs_socket = nil)
|
15
|
+
@fs_socket = fs_socket # FSR::CommandSocket obj
|
16
|
+
end
|
17
|
+
|
18
|
+
# Send the command to the event socket, using bgapi by default.
|
19
|
+
def run(api_method = :api)
|
20
|
+
orig_command = "%s %s" % [api_method, raw]
|
21
|
+
Log.debug "saying #{orig_command}"
|
22
|
+
resp = @fs_socket.say(orig_command)
|
23
|
+
unless resp["body"] == "0 total."
|
24
|
+
call_info, count = resp["body"].split("\n\n")
|
25
|
+
require "fsr/model/call"
|
26
|
+
begin
|
27
|
+
require "fastercsv"
|
28
|
+
calls = FCSV.parse(call_info)
|
29
|
+
rescue LoadError
|
30
|
+
require "csv"
|
31
|
+
calls = CSV.parse(call_info)
|
32
|
+
end
|
33
|
+
return calls[1 .. -1].map { |c| FSR::Model::Call.new(*c) }
|
34
|
+
end
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
|
38
|
+
# This method builds the API command to send to the freeswitch event socket
|
39
|
+
def raw
|
40
|
+
orig_command = "show calls"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
register(:calls, Calls)
|
45
|
+
end
|
46
|
+
end
|
@@ -7,6 +7,7 @@ module FSR
|
|
7
7
|
load_all_applications
|
8
8
|
module Listener
|
9
9
|
class Outbound < EventMachine::Protocols::HeaderAndContentProtocol
|
10
|
+
attr_reader :session
|
10
11
|
|
11
12
|
# Include FSR::App to get all the applications defined as methods
|
12
13
|
include FSR::App
|
@@ -15,33 +16,23 @@ module FSR
|
|
15
16
|
SENDMSG_METHOD_DEFINITION = "def %s(*args, &block); sendmsg super; end"
|
16
17
|
APPLICATIONS.each { |app, obj| module_eval(SENDMSG_METHOD_DEFINITION % app.to_s) }
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
# session_initiated is called when a @session is first created.
|
20
|
+
# Overwrite this in your worker class with the call/channel
|
21
|
+
# handling logic you desire
|
22
|
+
def session_initiated
|
23
|
+
FSR::Log.warn "#{self.class.name}#session_initiated not overwritten"
|
24
|
+
FSR::Log.debug session_data.inspect
|
22
25
|
end
|
23
26
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# Received data dispatches the data received by the EM socket,
|
37
|
-
# Either as a Session, a continuation of a Session, or as a Session's last CommandReply
|
38
|
-
|
39
|
-
def session_initiated(session)
|
40
|
-
session
|
41
|
-
end
|
42
|
-
|
43
|
-
def receive_reply(session)
|
44
|
-
session
|
27
|
+
# receive_reply is called when a response is received.
|
28
|
+
# Overwrite this in your worker class with the call/channel
|
29
|
+
# handling logic you desire, taking @step into account for
|
30
|
+
# state management between commands
|
31
|
+
# @param reply This HeaderAndContent instance will have the channel variables
|
32
|
+
# in #content, if the session has been updated
|
33
|
+
def receive_reply(reply)
|
34
|
+
FSR::Log.warn "#{self.class.name}#receive_reply not overwritten"
|
35
|
+
FSR::Log.debug reply.inspect
|
45
36
|
end
|
46
37
|
|
47
38
|
# sendmsg sends data to the EM app socket via #send_data, or
|
@@ -56,7 +47,56 @@ module FSR
|
|
56
47
|
self.respond_to?(:send_data) ? send_data(message) : message
|
57
48
|
end
|
58
49
|
|
50
|
+
# Update_session
|
51
|
+
|
52
|
+
def update_session
|
53
|
+
send_data("api uuid_dump #{@session.headers[:unique_id]}\n\n")
|
54
|
+
end
|
55
|
+
|
56
|
+
protected
|
57
|
+
def post_init
|
58
|
+
@session = nil # holds the session object
|
59
|
+
send_data("connect\n\n")
|
60
|
+
FSR::Log.debug "Accepting connections."
|
61
|
+
end
|
62
|
+
|
63
|
+
# receive_request is called each time data is received by the event machine
|
64
|
+
# it will manipulate the received data into either a new session or a reply,
|
65
|
+
# to be picked up by #session_initiated or #receive_reply.
|
66
|
+
# If your listener is listening for events, this will also renew your @session
|
67
|
+
# each time you receive a CHANNEL_DATA event.
|
68
|
+
# @param header The header of the request, as passed by HeaderAndContentProtocol
|
69
|
+
# @param content The content of the request, as passed by HeaderAndContentProtocol
|
70
|
+
#
|
71
|
+
# @returns HeaderAndContentResponse
|
72
|
+
def receive_request(header, content)
|
73
|
+
hash_header = headers_2_hash(header)
|
74
|
+
hash_content = headers_2_hash(content)
|
75
|
+
session_header_and_content = HeaderAndContentResponse.new({:headers => hash_header, :content => hash_content})
|
76
|
+
# If we're a new session, call session initiate
|
77
|
+
if @session.nil?
|
78
|
+
@session = session_header_and_content
|
79
|
+
@step = 0
|
80
|
+
session_initiated
|
81
|
+
elsif session_header_and_content.content[:event_name] # If content includes an event_name, it must be a response from an api command
|
82
|
+
if session_header_and_content.content[:event_name].to_s.match(/CHANNEL_DATA/i) # Anytime we see CHANNEL_DATA event, we want to update our @session
|
83
|
+
session_header_and_content = HeaderAndContentResponse.new({:headers => hash_header.merge(hash_content.strip_value_newlines), :content => {}})
|
84
|
+
@session = session_header_and_content
|
85
|
+
@step += 1
|
86
|
+
receive_reply(hash_header)
|
87
|
+
end
|
88
|
+
else
|
89
|
+
@step += 1
|
90
|
+
receive_reply(session_header_and_content)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
59
94
|
end
|
95
|
+
end
|
96
|
+
end
|
60
97
|
|
98
|
+
class Hash
|
99
|
+
def strip_value_newlines
|
100
|
+
Hash[*(self.map { |k,v| v.respond_to?(:to_s) ? [k, v.to_s.strip] : [k, v] }.flatten)]
|
61
101
|
end
|
62
102
|
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "fsr/listener"
|
3
|
+
module FSR
|
4
|
+
load_all_applications
|
5
|
+
module Listener
|
6
|
+
module Outbound
|
7
|
+
include FSR::Listener
|
8
|
+
|
9
|
+
# Include FSR::App to get all the applications defined as methods
|
10
|
+
include FSR::App
|
11
|
+
|
12
|
+
# Redefine the FSR::App methods to wrap sendmsg around them
|
13
|
+
SENDMSG_METHOD_DEFINITION = "def %s(*args, &block); sendmsg super; end"
|
14
|
+
APPLICATIONS.each { |app, obj| module_eval(SENDMSG_METHOD_DEFINITION % app.to_s) }
|
15
|
+
|
16
|
+
def post_init
|
17
|
+
@session = nil # holds the session object
|
18
|
+
send_data("connect\n\n")
|
19
|
+
FSR::Log.debug "Accepting connections."
|
20
|
+
end
|
21
|
+
|
22
|
+
# Received data dispatches the data received by the EM socket,
|
23
|
+
# Either as a Session, a continuation of a Session, or as a Session's last CommandReply
|
24
|
+
def receive_data(data)
|
25
|
+
FSR::Log.debug("received #{data}")
|
26
|
+
if @session.nil? # if @session is nil, create a new Session object
|
27
|
+
@session = Session.new(data)
|
28
|
+
session_initiated(@session) if @session.initiated?
|
29
|
+
else
|
30
|
+
# If it's not nil, we add the data to this session, Session knows whether
|
31
|
+
# or not to create a CommandReply, complete a CommandReply, or simply add to
|
32
|
+
# its own @data array and @headers/@body structures
|
33
|
+
if @session.initiated?
|
34
|
+
@session << data
|
35
|
+
reply_received(@session.replies.last) if @session.replies.last.complete?
|
36
|
+
else
|
37
|
+
@session << data
|
38
|
+
session_initiated(@session) if @session.initiated?
|
39
|
+
end
|
40
|
+
end
|
41
|
+
@session
|
42
|
+
end
|
43
|
+
|
44
|
+
def session_initiated(session)
|
45
|
+
session
|
46
|
+
end
|
47
|
+
|
48
|
+
def reply_received(command_reply)
|
49
|
+
command_reply
|
50
|
+
end
|
51
|
+
|
52
|
+
alias :receive_response :reply_received
|
53
|
+
# sendmsg sends data to the EM app socket via #send_data, or
|
54
|
+
# returns the string it would send if #send_data is not defined.
|
55
|
+
# It expects an object which responds to either #sendmsg or #to_s,
|
56
|
+
# which should return a EM Outbound Event Socket formatted instruction
|
57
|
+
def sendmsg(message)
|
58
|
+
text = message.respond_to?(:sendmsg) ? message.sendmsg : message.to_s
|
59
|
+
FSR::Log.debug "sending #{text}"
|
60
|
+
message = "sendmsg\n%s\n" % text
|
61
|
+
self.respond_to?(:send_data) ? send_data(message) : message
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
class SocketResponse
|
66
|
+
attr_accessor :headers, :body, :data
|
67
|
+
def initialize(data = "")
|
68
|
+
@data = [data]
|
69
|
+
@headers = {}
|
70
|
+
if data.match(/\n$/)
|
71
|
+
headers, @body = data.split("\n\n")
|
72
|
+
headers.each_line do |line|
|
73
|
+
key, value = line.split(":")
|
74
|
+
@headers[key] = value.to_s.strip
|
75
|
+
end
|
76
|
+
end
|
77
|
+
@body ||= ""
|
78
|
+
FSR::Log.debug("New #{self.class.name} created: #{self}")
|
79
|
+
end
|
80
|
+
|
81
|
+
def <<(data)
|
82
|
+
if data.match(/\n$/)
|
83
|
+
@data.last.match(/\n$/) ? @data << data : @data.last << data
|
84
|
+
extra_headers, more_body = @data.last.split("\n\n")
|
85
|
+
extra_headers.each_line do |line|
|
86
|
+
key, value = line.split(":")
|
87
|
+
@headers[key] = value.to_s.strip
|
88
|
+
end
|
89
|
+
@body << more_body unless more_body.nil?
|
90
|
+
else
|
91
|
+
@data.last.match(/\n$/) ? @data << data : @data.last << data
|
92
|
+
end
|
93
|
+
self
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
class Session < SocketResponse
|
98
|
+
attr_accessor :replies
|
99
|
+
def initialize(data = "")
|
100
|
+
super
|
101
|
+
@replies = []
|
102
|
+
end
|
103
|
+
|
104
|
+
def <<(data)
|
105
|
+
if initiated?
|
106
|
+
if @replies.empty? or @replies.last.complete?
|
107
|
+
@replies << CommandReply.new(data)
|
108
|
+
else
|
109
|
+
@replies.last << data
|
110
|
+
end
|
111
|
+
else
|
112
|
+
super
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def initiated?
|
117
|
+
@headers.keys.include?("Control")
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
class CommandReply < SocketResponse
|
123
|
+
# Set this to true for now, fill it in when we know what completed a reply
|
124
|
+
def complete?
|
125
|
+
true
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module FSR
|
2
|
+
module Model
|
3
|
+
class Call
|
4
|
+
attr_reader :created, :created_epoch, :function, :caller_id_name, :caller_id_number,
|
5
|
+
:caller_destination, :caller_channel_name, :caller_uuid, :callee_id_name,
|
6
|
+
:callee_id_number, :callee_destination, :callee_channel_name, :callee_uuid
|
7
|
+
def initialize(created,
|
8
|
+
created_epoch,
|
9
|
+
function,
|
10
|
+
caller_cid_name,
|
11
|
+
caller_cid_num,
|
12
|
+
caller_dest_num,
|
13
|
+
caller_chan_name,
|
14
|
+
caller_uuid,
|
15
|
+
callee_cid_name,
|
16
|
+
callee_cid_num,
|
17
|
+
callee_dest_num,
|
18
|
+
callee_chan_name,
|
19
|
+
callee_uuid)
|
20
|
+
@created,
|
21
|
+
@created_epoch,
|
22
|
+
@function,
|
23
|
+
@caller_id_name,
|
24
|
+
@caller_id_number,
|
25
|
+
@caller_destination,
|
26
|
+
@caller_chan_name,
|
27
|
+
@caller_uuid,
|
28
|
+
@callee_id_name,
|
29
|
+
@callee_id_number,
|
30
|
+
@callee_destination,
|
31
|
+
@callee_channel_name,
|
32
|
+
@callee_uuid = created,
|
33
|
+
created_epoch,
|
34
|
+
function,
|
35
|
+
caller_cid_name,
|
36
|
+
caller_cid_num,
|
37
|
+
caller_dest_num,
|
38
|
+
caller_chan_name,
|
39
|
+
caller_uuid,
|
40
|
+
callee_cid_name,
|
41
|
+
callee_cid_num,
|
42
|
+
callee_dest_num,
|
43
|
+
callee_chan_name,
|
44
|
+
callee_uuid
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec/helper'
|
2
|
+
require "fsr/app"
|
3
|
+
FSR::App.load_application("hangup")
|
4
|
+
|
5
|
+
describe "Testing FSR::App::Hangup" do
|
6
|
+
it "Hangs up the channel" do
|
7
|
+
hangup = FSR::App::Hangup.new
|
8
|
+
hangup.sendmsg.should == "call-command: execute\nexecute-app-name: hangup\nexecute-app-arg: \n\n"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "Hangs up the channel using a hangup cause" do
|
12
|
+
hangup = FSR::App::Hangup.new("USER_BUSY")
|
13
|
+
hangup.sendmsg.should == "call-command: execute\nexecute-app-name: hangup\nexecute-app-arg: USER_BUSY\n\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
data/spec/fsr/app/log.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec/helper'
|
2
|
+
require "fsr/app"
|
3
|
+
FSR::App.load_application("log")
|
4
|
+
|
5
|
+
describe "Testing FSR::App::Log" do
|
6
|
+
it "Logs to the console" do
|
7
|
+
log = FSR::App::Log.new(1, "This is a test! :-)")
|
8
|
+
log.sendmsg.should == "call-command: execute\nexecute-app-name: log\nexecute-app-arg: 1 This is a test! :-)\nevent-lock:true\n\n"
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec/helper'
|
2
|
+
require "fsr/app"
|
3
|
+
FSR::App.load_application("play_and_get_digits")
|
4
|
+
|
5
|
+
describe "Testing FSR::App::PlayAndGetDigits" do
|
6
|
+
# Utilize the [] shortcut to start a conference
|
7
|
+
it "Send a play_and_gets_digits command" do
|
8
|
+
tmp = FSR::App::PlayAndGetDigits.new("soundfile.wav", "invalid.wav")
|
9
|
+
tmp.sendmsg.should == "call-command: execute\nexecute-app-name: play_and_get_digits\nexecute-app-arg: 0 10 3 7000 # soundfile.wav invalid.wav fsr_read_dtmf d\nevent-lock:true\n\n"
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec/helper'
|
2
|
+
require "fsr/app"
|
3
|
+
FSR::App.load_application("playback")
|
4
|
+
|
5
|
+
describe "Testing FSR::App::Playback" do
|
6
|
+
it "Plays a file or stream" do
|
7
|
+
playback = FSR::App::Playback.new("shout://scfire-ntc-aa01.stream.aol.com/stream/1035")
|
8
|
+
playback.sendmsg.should == "call-command: execute\nexecute-app-name: playback\nexecute-app-arg: shout://scfire-ntc-aa01.stream.aol.com/stream/1035\nevent-lock:true\n\n"
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
data/spec/fsr/app/set.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec/helper'
|
2
|
+
require "fsr/app"
|
3
|
+
FSR::App.load_application("set")
|
4
|
+
|
5
|
+
describe "Testing FSR::App::Set" do
|
6
|
+
# Utilize the [] shortcut to start a conference
|
7
|
+
it "Sets a single variable" do
|
8
|
+
set = FSR::App::Set.new("hangup_after_bridge", true)
|
9
|
+
set.sendmsg.should == "call-command: execute\nexecute-app-name: set\nexecute-app-arg: hangup_after_bridge=true\nevent-lock:true\n\n"
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec/helper'
|
2
|
+
require "fsr/app"
|
3
|
+
FSR::App.load_application("transfer")
|
4
|
+
|
5
|
+
describe "Testing FSR::App::Transfer" do
|
6
|
+
it "Transfers the call" do
|
7
|
+
transfer = FSR::App::Transfer.new("500", "XML", "default")
|
8
|
+
transfer.sendmsg.should == "call-command: execute\nexecute-app-name: transfer\nexecute-app-arg: 500 XML default\nevent-lock:true\n\n"
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec/helper'
|
2
|
+
require "fsr/cmd"
|
3
|
+
FSR::Cmd.load_command("calls")
|
4
|
+
|
5
|
+
describe "Testing FSR::Cmd::Calls" do
|
6
|
+
## Calls ##
|
7
|
+
# Interface to calls
|
8
|
+
it "FSR::Cmd::Calls should send show calls" do
|
9
|
+
sofia = FSR::Cmd::Calls.new
|
10
|
+
sofia.raw.should == "show calls"
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -16,4 +16,11 @@ describe "Testing FSR::Listener::Inbound" do
|
|
16
16
|
FSR::Listener::Inbound.method_defined?(:post_init).should == true
|
17
17
|
end
|
18
18
|
|
19
|
+
it "adds and deletes hooks" do
|
20
|
+
FSL::Inbound.add_event_hook(:CHANNEL_CREATE) {|event| puts event.inspect }
|
21
|
+
FSL::Inbound::HOOKS.size.should == 1
|
22
|
+
FSL::Inbound.del_event_hook(:CHANNEL_CREATE)
|
23
|
+
FSL::Inbound::HOOKS.size.should == 0
|
24
|
+
end
|
25
|
+
|
19
26
|
end
|
data/spec/fsr/loading.rb
CHANGED
@@ -4,7 +4,7 @@ require 'spec/helper'
|
|
4
4
|
describe "Testing FSR module loading methods" do
|
5
5
|
# When you add applications you must modify the expected apps_loaded behavior
|
6
6
|
it "Loads all applications" do
|
7
|
-
all_apps = [:set, :transfer, :speak, :fs_sleep, :playback, :answer, :fifo, :bridge, :hangup, :conference, :fs_break, :log]
|
7
|
+
all_apps = [:play_and_get_digits, :uuid_dump, :uuid_setvar, :uuid_getvar, :read, :set, :transfer, :speak, :fs_sleep, :playback, :answer, :fifo, :bridge, :hangup, :conference, :fs_break, :log]
|
8
8
|
# Add any apps which will load to this set
|
9
9
|
apps_loaded = FSR.load_all_applications
|
10
10
|
apps_loaded.kind_of?(Array).should == true
|
@@ -16,7 +16,7 @@ describe "Testing FSR module loading methods" do
|
|
16
16
|
|
17
17
|
# When you add commands you must modify the expected cmds_loaded behavior
|
18
18
|
it "Loads all commands" do
|
19
|
-
all_commands = [:originate, :sofia, :fsctl, :sofia_contact, :status] # If you add a command add it to this set
|
19
|
+
all_commands = [:originate, :sofia, :fsctl, :sofia_contact, :status, :calls] # If you add a command add it to this set
|
20
20
|
cmds_loaded = FSR.load_all_commands
|
21
21
|
cmds_loaded.kind_of?(Array).should == true
|
22
22
|
all_commands.each do |cmd|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bougyman-freeswitcher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jayson Vaughn
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: "0"
|
27
27
|
version:
|
28
|
-
description: "========================================================= FreeSWITCHeR Copyright (c) 2009 The Rubyists (Jayson Vaughn, Tj Vanderpoel, Michael Fellinger, Kevin Berry) Distributed under the terms of the MIT License. ========================================================== About ----- *** STILL UNDER HEAVY DEVELOPMENT *** A ruby library for interacting with the \"FreeSWITCH\" (http://www.freeswitch.org) opensource telephony platform *** STILL UNDER HEAVY DEVELOPMENT *** Requirements ------------ - ruby (>= 1.8) - eventmachine (If you wish to use Outbound and Inbound listener) Usage ----- Example of originating a new call in 'irb' using FSR::CommandSocket#originate: irb(main):001:0> require 'fsr' => true irb(main):002:0> FSR.load_all_commands => [:sofia, :originate] irb(main):003:0> sock = FSR::CommandSocket.new => #<FSR::CommandSocket:0xb7a89104 @server=\"127.0.0.1\", @socket=#<TCPSocket:0xb7a8908c>, @port=\"8021\", @auth=\"ClueCon\"> irb(main):007:0> sock.originate(:target => 'sofia/gateway/carlos/8179395222', :endpoint => FSR::App::Bridge.new(\"user/bougyman\")).run => {\"Job-UUID\"=>\"732075a4-7dd5-4258-b124-6284a82a5ae7\", \"body\"=>\"\", \"Content-Type\"=>\"command/reply\", \"Reply-Text\"=>\"+OK Job-UUID: 732075a4-7dd5-4258-b124-6284a82a5ae7\"} Example of creating an Outbound Eventsocket listener: #!/usr/bin/env ruby require 'fsr' require \"fsr/listener/outbound\" class OesDemo < FSR::Listener::Outbound def session_initiated
|
28
|
+
description: "========================================================= FreeSWITCHeR Copyright (c) 2009 The Rubyists (Jayson Vaughn, Tj Vanderpoel, Michael Fellinger, Kevin Berry) Distributed under the terms of the MIT License. ========================================================== About ----- *** STILL UNDER HEAVY DEVELOPMENT *** A ruby library for interacting with the \"FreeSWITCH\" (http://www.freeswitch.org) opensource telephony platform *** STILL UNDER HEAVY DEVELOPMENT *** Requirements ------------ - ruby (>= 1.8) - eventmachine (If you wish to use Outbound and Inbound listener) Usage ----- Example of originating a new call in 'irb' using FSR::CommandSocket#originate: irb(main):001:0> require 'fsr' => true irb(main):002:0> FSR.load_all_commands => [:sofia, :originate] irb(main):003:0> sock = FSR::CommandSocket.new => #<FSR::CommandSocket:0xb7a89104 @server=\"127.0.0.1\", @socket=#<TCPSocket:0xb7a8908c>, @port=\"8021\", @auth=\"ClueCon\"> irb(main):007:0> sock.originate(:target => 'sofia/gateway/carlos/8179395222', :endpoint => FSR::App::Bridge.new(\"user/bougyman\")).run => {\"Job-UUID\"=>\"732075a4-7dd5-4258-b124-6284a82a5ae7\", \"body\"=>\"\", \"Content-Type\"=>\"command/reply\", \"Reply-Text\"=>\"+OK Job-UUID: 732075a4-7dd5-4258-b124-6284a82a5ae7\"} Example of creating an Outbound Eventsocket listener: #!/usr/bin/env ruby require 'fsr' require \"fsr/listener/outbound\" class OesDemo < FSR::Listener::Outbound def session_initiated number = @session.headers[:caller_caller_id_number] # Grab the inbound caller id FSR::Log.info \"*** Answering incoming call from #{number}\" answer # Answer the call set(\"hangup_after_bridge\", \"true\")# Set a variable speak 'Hello, This is your phone switch. Have a great day' # use mod_flite to speak hangup # Hangup the call end end FSR.start_oes!(OesDemo, :port => 1888, :host => \"localhost\") Example of creating an Outbound Eventsocket listener that can read DTMF input and keep state: #!/usr/bin/env ruby require 'fsr' require 'fsr/listener/outbound' FSR.load_all_applications FSR.load_all_commands class DtmfDemo < FSR::Listener::Outbound def session_initiated exten = @session.headers[:caller_caller_id_number] FSR::Log.info \"*** Answering incoming call from #{exten}\" answer # Answer the call end def receive_reply(reply) exten = @session.headers[:caller_caller_id_number] case @step when 1 FSR::Log.info \"*** Reading dtmf for #{exten}\" read \"/home/freeswitch/freeswitch/sounds/music/8000/sweet.wav\",4,10,\"test\",15000 # read test when 2 FSR::Log.info \"*** updating session for #{exten}\" update_session when 3 FSR::Log.info \"** Success, grabbed #{@session.headers[:variable_test].strip} from #{exten}\" FSR::Log.info \"*** Hanging up call\" hangup # Hangup the call end end end FSR.start_oes! DtmfDemo, :port => 8084, :host => \"127.0.0.1\" Example of creating an Inbound Eventsocket listener: #!/usr/bin/env ruby require 'fsr' require 'fsr/listener/inbound' require 'pp' class IesDemo < FSR::Listener::Inbound def on_event(event) pp event.headers pp event.content[:event_name] end end FSR.start_ies!(IesDemo, :host => \"localhost\", :port => 8021) Support ------- Home page at http://code.rubyists.com/projects/fs #rubyists on FreeNode"
|
29
29
|
email: FreeSWITCHeR@rubyists.com
|
30
30
|
executables: []
|
31
31
|
|
@@ -38,12 +38,18 @@ files:
|
|
38
38
|
- NEWS
|
39
39
|
- README
|
40
40
|
- Rakefile
|
41
|
-
-
|
42
|
-
- bin
|
43
|
-
- bin/
|
44
|
-
- bin/
|
45
|
-
- bin/
|
46
|
-
- bin/
|
41
|
+
- examples
|
42
|
+
- examples/bin
|
43
|
+
- examples/bin/cmd_demo.rb
|
44
|
+
- examples/bin/dtmf_test.rb
|
45
|
+
- examples/bin/ies_demo.rb
|
46
|
+
- examples/bin/ies_demo_with_hook.rb
|
47
|
+
- examples/bin/oes_demo.rb
|
48
|
+
- examples/dtmf_test.rb
|
49
|
+
- examples/ies_demo.rb
|
50
|
+
- examples/ies_demo_with_hook.rb
|
51
|
+
- examples/oes_demo.rb
|
52
|
+
- examples/play_and_get_test.rb
|
47
53
|
- lib
|
48
54
|
- lib/fsr
|
49
55
|
- lib/fsr/app
|
@@ -55,12 +61,18 @@ files:
|
|
55
61
|
- lib/fsr/app/fs_sleep.rb
|
56
62
|
- lib/fsr/app/hangup.rb
|
57
63
|
- lib/fsr/app/log.rb
|
64
|
+
- lib/fsr/app/play_and_get_digits.rb
|
58
65
|
- lib/fsr/app/playback.rb
|
66
|
+
- lib/fsr/app/read.rb
|
59
67
|
- lib/fsr/app/set.rb
|
60
68
|
- lib/fsr/app/speak.rb
|
61
69
|
- lib/fsr/app/transfer.rb
|
70
|
+
- lib/fsr/app/uuid_dump.rb
|
71
|
+
- lib/fsr/app/uuid_getvar.rb
|
72
|
+
- lib/fsr/app/uuid_setvar.rb
|
62
73
|
- lib/fsr/app.rb
|
63
74
|
- lib/fsr/cmd
|
75
|
+
- lib/fsr/cmd/calls.rb
|
64
76
|
- lib/fsr/cmd/fsctl.rb
|
65
77
|
- lib/fsr/cmd/originate.rb
|
66
78
|
- lib/fsr/cmd/sofia
|
@@ -88,13 +100,12 @@ files:
|
|
88
100
|
- lib/fsr/listener/outbound.rb
|
89
101
|
- lib/fsr/listener/outbound.rb.orig
|
90
102
|
- lib/fsr/listener.rb
|
103
|
+
- lib/fsr/model
|
104
|
+
- lib/fsr/model/call.rb
|
91
105
|
- lib/fsr.rb
|
92
106
|
- tasks
|
93
107
|
- tasks/package.rake
|
94
|
-
- tasks/ride.rake
|
95
|
-
- tasks/rspec.rake
|
96
108
|
- tasks/spec.rake
|
97
|
-
- tmp
|
98
109
|
has_rdoc: false
|
99
110
|
homepage: http://code.rubyists.com/projects/fs
|
100
111
|
post_install_message: |
|
@@ -144,11 +155,11 @@ post_install_message: |
|
|
144
155
|
|
145
156
|
class OesDemo < FSR::Listener::Outbound
|
146
157
|
|
147
|
-
def session_initiated
|
148
|
-
number = session.headers[:caller_caller_id_number] # Grab the inbound caller id
|
158
|
+
def session_initiated
|
159
|
+
number = @session.headers[:caller_caller_id_number] # Grab the inbound caller id
|
149
160
|
FSR::Log.info "*** Answering incoming call from #{number}"
|
150
161
|
answer # Answer the call
|
151
|
-
set "
|
162
|
+
set("hangup_after_bridge", "true")# Set a variable
|
152
163
|
speak 'Hello, This is your phone switch. Have a great day' # use mod_flite to speak
|
153
164
|
hangup # Hangup the call
|
154
165
|
end
|
@@ -159,12 +170,53 @@ post_install_message: |
|
|
159
170
|
|
160
171
|
|
161
172
|
|
173
|
+
Example of creating an Outbound Eventsocket listener that can read DTMF input and keep state:
|
174
|
+
|
175
|
+
#!/usr/bin/env ruby
|
176
|
+
|
177
|
+
require 'fsr'
|
178
|
+
require 'fsr/listener/outbound'
|
179
|
+
|
180
|
+
FSR.load_all_applications
|
181
|
+
FSR.load_all_commands
|
182
|
+
|
183
|
+
class DtmfDemo < FSR::Listener::Outbound
|
184
|
+
|
185
|
+
def session_initiated
|
186
|
+
exten = @session.headers[:caller_caller_id_number]
|
187
|
+
FSR::Log.info "*** Answering incoming call from #{exten}"
|
188
|
+
answer # Answer the call
|
189
|
+
end
|
190
|
+
|
191
|
+
def receive_reply(reply)
|
192
|
+
exten = @session.headers[:caller_caller_id_number]
|
193
|
+
case @step
|
194
|
+
when 1
|
195
|
+
FSR::Log.info "*** Reading dtmf for #{exten}"
|
196
|
+
read "/home/freeswitch/freeswitch/sounds/music/8000/sweet.wav",4,10,"test",15000 # read test
|
197
|
+
when 2
|
198
|
+
FSR::Log.info "*** updating session for #{exten}"
|
199
|
+
update_session
|
200
|
+
when 3
|
201
|
+
FSR::Log.info "** Success, grabbed #{@session.headers[:variable_test].strip} from #{exten}"
|
202
|
+
FSR::Log.info "*** Hanging up call"
|
203
|
+
hangup # Hangup the call
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
208
|
+
|
209
|
+
FSR.start_oes! DtmfDemo, :port => 8084, :host => "127.0.0.1"
|
210
|
+
|
211
|
+
|
212
|
+
|
162
213
|
Example of creating an Inbound Eventsocket listener:
|
163
214
|
|
164
215
|
#!/usr/bin/env ruby
|
165
216
|
|
166
217
|
require 'fsr'
|
167
|
-
require
|
218
|
+
require 'fsr/listener/inbound'
|
219
|
+
require 'pp'
|
168
220
|
|
169
221
|
class IesDemo < FSR::Listener::Inbound
|
170
222
|
|
@@ -214,8 +266,15 @@ test_files:
|
|
214
266
|
- spec/fsr/app/bridge.rb
|
215
267
|
- spec/fsr/app/conference.rb
|
216
268
|
- spec/fsr/app/fifo.rb
|
269
|
+
- spec/fsr/app/hangup.rb
|
270
|
+
- spec/fsr/app/log.rb
|
271
|
+
- spec/fsr/app/play_and_get_digits.rb
|
272
|
+
- spec/fsr/app/playback.rb
|
273
|
+
- spec/fsr/app/set.rb
|
274
|
+
- spec/fsr/app/transfer.rb
|
217
275
|
- spec/fsr/app.rb
|
218
276
|
- spec/fsr/cmd
|
277
|
+
- spec/fsr/cmd/calls.rb
|
219
278
|
- spec/fsr/cmd/originate.rb
|
220
279
|
- spec/fsr/cmd/sofia
|
221
280
|
- spec/fsr/cmd/sofia/profile.rb
|