Elixir client for the FreeSWITCH mod_event_socket.
It also supports the mod_erlang_event.
To use it in your Mix projects, first add it as a dependency:
def deps do
[{:elixir_mod_event, "~> 0.0.6"}]
end
Then run mix deps.get to install it.
Feel free to take a look at the documentation served by hex.pm or the source itself to find more.
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>}
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.
To receive events register processes with a filter function like this:
> C.start_listening :fs1
The 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" end
To unregister the listener process:
> C.stop_listening :fs1
NOTE: The caller process will be monitored and auto-unregister when the registered process dies.
Sends a command.
> C.api :fs1, "host_lookup", "google.com"
%FSModEvent.Packet{
payload: '173.194.42.78',
...
}
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',
...
}}
> C.linger :fs1
> C.nolinger :fs1
> C.event :fs1, "all"
> C.event :fs1, "CUSTOM", "conference::maintenance"
> C.myevents :fs1, "e96b78d8-1dc2-4634-84c4-58366f1a92b1"
> C.enable_divert_events :fs1
> C.disable_divert_events :fs1
> C.filter :fs1, "Event-Name", "CHANNEL_EXECUTE"
> C.filter_delete :fs1, "Event-Name", "CHANNEL_EXECUTE"
> C.sendevent :fs1, "custom_event", [{"header1", "value1"}], "custom payload"
> 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"
> C.exit :fs1
> C.log :fs1, "debug"
> C.nolog :fs1
> C.nixevent :fs1, "all"
> C.noevents :fs1
To "talk" to the FreeSWITCH erlang node, use the Erlang module:
> alias FSModEvent.Erlang, as: E
> node = :"freeswitch@host.local"
Sends a command.
> E.api node, "host_lookup", "google.com"
"173.194.42.82"
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"}
> E.register_event_handler node
> E.event node, "all"
> E.event node, "CUSTOM", "conference::maintenance"
> E.nixevent node, "all"
> E.noevents node
> E.register_log_handler node
> E.set_log_level node, "debug"
> E.nolog node
> E.exit node
> 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"
> E.pid node
> E.handlecall node, "e96b78d8-1dc2-4634-84c4-58366f1a92b1"
> E.handlecall node, "e96b78d8-1dc2-4634-84c4-58366f1a92b1", :my_call_handler
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
end
The source code is released under Apache 2 License.
Check LICENSE file for more information.