An Elixir Library for interfacing with Asterisk the Open Source Communications Software using ARI the Asterisk REST Interface.

Documentation is available on Hexdocs

An example application to get you started is available here. The example app also provides a lot of documentation on configuring Asterisk and setting up a local VOIP client.

This library has been tested against Asterisk version 15 and 16. The use of the ARI.Router module, which allows dynamic routing handled by your Elixir application, requires Asterisk 16 or above.

ARI provides a REST interface for controlling Asterisk resources as well as a WebSocket based event stream, for reacting to events. This library has full support for the REST interface as well as the WebSocket interface.

It's highly recommended that you read the full ARI documentation to get a full understanding of the capabilities.

The end goal of this library is to be able to completely configure and control an Asterisk node, essentially making Asterisk a "dumb" VOIP/SIP frontend.

This library does not provide a supervisor by default, it is up to the user to decide what functionality is needed by their application. An example application that handles some basic functionality like audio playback and reacting to touch tone events might look something like this.

  defmodule ExARIExample.Application do
    use Application

    def start(_, _) do
      un = System.get_env("ASTERISK_USERNAME")
      pw = System.get_env("ASTERISK_PASSWORD")
      ws_host = System.get_env("ASTERISK_WS_HOST")
      rest_host = System.get_env("ASTERISK_REST_HOST")
      rest_port = System.get_env("ASTERISK_REST_PORT") |> String.to_integer()
      name = System.get_env("ASTERISK_NAME")
      transport = System.get_env("ASTERISK_TRANSPORT")
      context = System.get_env("ASTERISK_CONTEXT")
      channel_supervisor = ExARIExample.ChannelSupervisor

      children = [
        {DynamicSupervisor, strategy: :one_for_one, name: channel_supervisor},
        {ARI.ChannelRegistrar, []},
        {ARI.HTTP.Asterisk, [rest_host, rest_port, un, pw]},
        {ARI.HTTP.Channels, [rest_host, rest_port, un, pw]},
        {ARI.HTTP.Playbacks, [rest_host, rest_port, un, pw]},
        {ARI.Stasis, [channel_supervisor, %{
          name: "ex_ari", 
          module: ExARIExample.Client
        }, ws_host, un, pw]},
        {ARI.Stasis, [channel_supervisor, %{
          name: "router", 
          module: ARI.Router, 
          extensions: %{
            "ex_ari" => "ex_ari",
            "+15555550101" => "ex_ari"
        }, ws_host, un, pw]},
        {ARI.Configurator, [name, transport, context, ExARIExample.Config]},

      opts = [strategy: :one_for_one, name: ExARIExample.Supervisor]
      Supervisor.start_link(children, opts)

The full example application is available here

Be sure to read over the ARI.Stasis and the ARI.Router documentation

It may also be useful to review the tests, which implements a pseudo Asterisk WebSocket server for testing purposes.

Recording calls, transferring a call to another number and routing calls to their respective applications can be a bit tricky to manage with Asterisk. The ex_ari library provides some default Stasis applications to help make that easier. ARI.RecordCall, ARI.Transfer and ARI.Router. When working on other complex workflows that involve joining multiple channels or snooping, these can be a good reference to refer to. These modules are all registered using an ARI.Stasis application like the ARI.Router registration in the application example above.