elixir_mod_event
Elixir client for the FreeSWITCH mod_event_socket.
It also supports the mod_erlang_event.
Using it with Mix
To use it in your Mix projects, first add it as a dependency:
def deps do
[{:elixir_mod_event, "~> 0.0.6"}]
endThen run mix deps.get to install it.
Documentation
Feel free to take a look at the documentation served by hex.pm or the source itself to find more.
Inbound Mode (TCP connection)
Starting a TCP connection
To connect to FreeSWITCH just start a Connection, which is just a GenServer that you can plug into your own supervisor tree.
> alias FSModEvent.Connection, as: C
> C.start :connection_name, fs_host, fs_port, fs_password
{:ok, #PID<0.158.0>}You can also start and link the connection:
> C.start :connection_name, fs_host, fs_port, fs_password
{:ok, #PID<0.159.0>}Results
When executing a command (either in foreground or background) or receiving events, the result will be a Packet, with a structure with some fields of interest:
- success: Boolean. When executing foreground commands will be true if the command was executed successfuly.
- type: String. The type of the packet (e.g: "text/event-plain", "command/reply", etc).
- payload: Map or String. Depends on the type of the packet.
- length: Payload length, useful when the payload is a string.
- job_id: String. May contain a job id, related to a response or an event.
- headers: Map. Packet headers.
- custom_payload: String. May contain additional payload, depends on the packet and command sent/received.
Receiving events
To receive events register processes with a filter function like this:
> C.start_listening :fs1The default filter function will let all events pass through to the process, but you can specify a custom filter function:
> C.start_listening :fs1, fn(pkt) -> pkt.payload["event-name"] === "HEARTBEAT" endTo unregister the listener process:
> C.stop_listening :fs1NOTE: The caller process will be monitored and auto-unregister when the registered process dies.
Examples
api
Sends a command.
> C.api :fs1, "host_lookup", "google.com"
%FSModEvent.Packet{
payload: '173.194.42.78',
...
}bgapi
Like api but runs the command without blocking the process. The calling process will
receive a message with the result of the command. Be sure to subscribe to the
BACKGROUND_JOB event.
> C.event :fs1, "BACKGROUND_JOB"
> C.bgapi :fs1, "md5", "some_data"
"b857e1dd-e4de-424e-9ff6-8e05e9a076d9"
> flush
{:fs_job_result, "b857e1dd-e4de-424e-9ff6-8e05e9a076d9", %FSModEvent.Packet{
custom_payload: '0d9247cbce34aba4aca8d5c887a0f0a4',
...
}}linger
> C.linger :fs1nolinger
> C.nolinger :fs1event
> C.event :fs1, "all"
> C.event :fs1, "CUSTOM", "conference::maintenance"myevents
> C.myevents :fs1, "e96b78d8-1dc2-4634-84c4-58366f1a92b1"divert_events
> C.enable_divert_events :fs1
> C.disable_divert_events :fs1filter
> C.filter :fs1, "Event-Name", "CHANNEL_EXECUTE"filter_delete
> C.filter_delete :fs1, "Event-Name", "CHANNEL_EXECUTE"sendevent
> C.sendevent :fs1, "custom_event", [{"header1", "value1"}], "custom payload"sendmsg
> C.sendmsg_exec :fs1, "e96b78d8-1dc2-4634-84c4-58366f1a92b1", "uuid_answer", "e96b78d8-1dc2-4634-84c4-58366f1a92b1"
> C.sendmsg_hangup :fs1, "e96b78d8-1dc2-4634-84c4-58366f1a92b1", 16
> C.sendmsg_unicast :fs1, "e96b78d8-1dc2-4634-84c4-58366f1a92b1", "tcp", "native", "127.0.0.1", 8025, "127.0.0.1", 8026
> C.sendmsg_nomedia :fs1, "e96b78d8-1dc2-4634-84c4-58366f1a92b1", "info"exit
> C.exit :fs1log
> C.log :fs1, "debug"nolog
> C.nolog :fs1nixevent
> C.nixevent :fs1, "all"noevents
> C.noevents :fs1Inbound Mode (Erlang node connection)
To "talk" to the FreeSWITCH erlang node, use the Erlang module:
> alias FSModEvent.Erlang, as: E
> node = :"freeswitch@host.local"api
Sends a command.
> E.api node, "host_lookup", "google.com"
"173.194.42.82"bgapi
Like api but runs the command without blocking the process. The caller process will
receive a message with a tuple like this:
{:fs_job_result, job_id, status, result}Where:
job_id :: String.t
status :: :ok | :error
result :: :timeout | String.t> E.bgapi node, "md5", "some_data"
"4a41cfc1-d9b7-4966-95d0-5de5ec690a07"
> flush
{:fs_job_result, "4a41cfc1-d9b7-4966-95d0-5de5ec690a07", :ok,
"0d9247cbce34aba4aca8d5c887a0f0a4"}register_event_handler
> E.register_event_handler nodeevent
> E.event node, "all"
> E.event node, "CUSTOM", "conference::maintenance"nixevent
> E.nixevent node, "all"noevents
> E.noevents noderegister_log_handler
> E.register_log_handler nodeset_log_level
> E.set_log_level node, "debug"nolog
> E.nolog nodeexit
> E.exit nodesendmsg
> E.sendmsg_exec node, "e96b78d8-1dc2-4634-84c4-58366f1a92b1", "uuid_answer", "e96b78d8-1dc2-4634-84c4-58366f1a92b1"
> E.sendmsg_hangup node, "e96b78d8-1dc2-4634-84c4-58366f1a92b1", 16
> E.sendmsg_unicast node, "e96b78d8-1dc2-4634-84c4-58366f1a92b1", "tcp", "native", "127.0.0.1", 8025, "127.0.0.1", 8026
> E.sendmsg_nomedia node, "e96b78d8-1dc2-4634-84c4-58366f1a92b1", "info"pid
> E.pid nodehandlecall
> E.handlecall node, "e96b78d8-1dc2-4634-84c4-58366f1a92b1"
> E.handlecall node, "e96b78d8-1dc2-4634-84c4-58366f1a92b1", :my_call_handlerConfiguration hooks
You can also configure FreeSWITCH by sending and receiving regular erlang messages by binding to the needed configuration sections. See XML Search Bindings.
The format and sections correspond to the ones supported by mod_xml_curl.
# Bind to the "directory" section
> E.config_bind node, "directory"
# Sample XML text
> xml = "<?xml version='1.0' en ... "
# After a configuration message is received, a reply can be sent.
> receive do
{:fetch, :directory, "domain", "name", domain_name, uuid, headers} ->
E.config_reply node, uuid, xml
after 10 -> :ok
endLicense
The source code is released under Apache 2 License.
Check LICENSE file for more information.