diff --git a/.github/banner.svg b/.github/banner.svg deleted file mode 100644 index 6a883da..0000000 --- a/.github/banner.svg +++ /dev/null @@ -1,283 +0,0 @@ - diff --git a/README.md b/README.md index c377f6b..793c43f 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,9 @@ -
-
-
A Ruby library for interacting with FreeSWITCH through + mod_event_socket, using async I/O.
+ + + +You should be familiar with + mod_event_socket + and the differences between inbound and outbound event sockets before getting started.
+Requires Ruby 3.0+.
+ +Add to your Gemfile:
gem "librevox"
+
+ Subclass Librevox::Listener::Inbound to create an inbound listener. It connects to
+ FreeSWITCH and subscribes to events.
React to events in two ways:
+on_event, called for every event.event hooks for specific event names.class MyInbound < Librevox::Listener::Inbound
+ def on_event(e)
+ puts "Got event: #{e.content[:event_name]}"
+ end
+
+ event :channel_hangup do
+ do_something
+ end
+
+ # The hook block receives a Response when it takes an argument:
+ event :channel_bridge do |e|
+ puts e.content[:caller_caller_id_number]
+ end
+
+ def do_something
+ # ...
+ end
+end
+
+ By default, inbound listeners subscribe to all events. Use events to limit which events
+ are received, and filters to filter by header values:
class MyInbound < Librevox::Listener::Inbound
+ events ['CHANNEL_EXECUTE', 'CUSTOM foo']
+ filters 'Caller-Context' => ['default', 'example'],
+ 'Caller-Privacy-Hide-Name' => 'no'
+end
+ Note on CUSTOM events: FreeSWITCH custom events have a subclass name (e.g.
+ CUSTOM conference::maintenance). You must include both the event name and subclass —
+ events ['CUSTOM conference::maintenance']. Using just events ['CUSTOM']
+ will not match any custom events.
Subclass Librevox::Listener::Outbound to create an outbound listener. FreeSWITCH
+ connects to it when a call hits a socket application in the dialplan.
Outbound listeners have the same event functionality as inbound, but scoped to the session.
+ +When FreeSWITCH connects, session_initiated is called. Build your dialplan here.
Each application call blocks until FreeSWITCH signals completion
+ (CHANNEL_EXECUTE_COMPLETE), so applications execute sequentially:
class MyOutbound < Librevox::Listener::Outbound
+ def session_initiated
+ answer
+ digit = play_and_get_digits "enter-digit.wav", "bad-digit.wav"
+ bridge "sofia/gateway/trunk/#{digit}"
+ end
+end
+ Applications that read input (like play_and_get_digits and read) return the
+ collected value directly.
def session_initiated
+ answer
+ set "foo", "bar"
+ multiset "baz" => "1", "qux" => "2"
+ playback "welcome.wav"
+ hangup
+end
+ For apps not yet wrapped by a named helper, call application directly:
application "park"
+ Channel variables are available through session (a hash) and variable:
def session_initiated
+ answer
+ number = variable(:destination_number)
+ playback "greeting-#{number}.wav"
+end
+
+ To avoid name clashes between applications and commands, commands are accessed through
+ api:
def session_initiated
+ answer
+ api.status
+ api.originate 'sofia/user/coltrane', extension: "1234"
+end
+
+ Start a single listener:
+Librevox.start MyInbound
+ With connection options:
+Librevox.start MyInbound, host: "1.2.3.4", port: 8021, auth: "secret"
+ Start multiple listeners:
+Librevox.start do
+ run MyInbound
+ run MyOutbound, port: 8084
+end
+ Default ports are 8021 for inbound and 8084 for outbound.
+ +After a session ends (e.g. the caller hangs up), the outbound socket connection to FreeSWITCH + remains open for post-session events. Close it manually when done to avoid lingering sessions:
+class MyOutbound < Librevox::Listener::Outbound
+ event :channel_hangup do
+ disconnect
+ end
+end
+
+ Librevox::CommandSocket connects to the FreeSWITCH management console for one-off
+ commands:
require "librevox/command_socket"
+
+socket = Librevox::CommandSocket.new(server: "127.0.0.1", port: 8021, auth: "ClueCon")
+
+socket.originate 'sofia/user/coltrane', extension: "1234"
+#=> #<Librevox::Protocol::Response ...>
+
+socket.status
+#=> #<Librevox::Protocol::Response ...>
+
+socket.close
+
+ Librevox.options[:log_file] = "librevox.log" # default: STDOUT
+Librevox.options[:log_level] = Logger::DEBUG # default: Logger::INFO
+
+