In the previous episode, we saw how to handle an inbound call to an Asterisk extension from Elixir. However, the actual module that was used to handle the call was written in Erlang. Today we're going to write an AGI module in Elixir. Let's get started.
Project
I'm in the same project that we ended the last episode with. In the meantime, I've written an API client for a friend's API for getting contact information when all you have is a phone number, called EveryoneAPI.
First, let's have a look at the everyoneapi client library.
((( vim ~/elixir/everyoneapi/lib/everyoneapi.ex )))
defmodule Everyoneapi do
use HTTPoison.Base
require Logger
# We just set up the base url
@base_url "https://api.everyoneapi.com"
# Here's our nicer public api for getting the info for a phone number
def info!(number) do
get! "/v1/phone/+12052153957"
end
# We prefix the url with the base url so we don't have to type out the whole
# url every time we talk to the API
def process_url(url) do
@base_url <> url
end
# For every outbound request, we add our basic auth header
def process_request_headers(headers) do
Enum.into(headers, [{"Authorization", "Basic #{encoded_basic}"}])
end
# The basic auth header consists of getting the username and password out of #
# the application's configuration, concatenating them separated by a colon, and
# then Base64 encoding the resulting string
defp encoded_basic do
account_sid = Application.get_env :everyoneapi, :account_sid
auth_token = Application.get_env :everyoneapi, :auth_token
combined = "#{account_sid}:#{auth_token}"
Base.encode64(combined)
end
# Finally, the body JSON is decoded
def process_response_body(body) do
Logger.warn body
Poison.decode!(body)
end
end
So this wasn't the point of the episode, but I wanted to look at it because it took me a few minutes to figure out how to inject that header into the request.
Next, we're going to modify an Asterisk extension such that we can dial in, and it will make an API call for a hardcoded number, presently. It will then read out the contact name associated with that number in EveryoneAPI.
We'll open up lib/everyoneapi_demo.ex
:
defmodule EveryoneapiDemo do
require Logger
# The erlagi interface expects a handler module that responds to `new_call/1`
# and calls it with an agicall record
def new_call(call) do
# We start our API client up every call. This is stupid and inefficient,
# but it works for now.
Everyoneapi.start
result = Everyoneapi.info! "+12052153957"
# We'll extract the name out of the response from the API
name = result.body["data"]["name"]
# Then we just answer the call
:erlagi.answer(call)
# And read out the characters in the name.
:erlagi.say_alpha(call, String.to_char_list(name), '#')
end
end
Next, we need to modify our configuration to use this module for the callback
instead of the erlagi_demo
module. Open up config/config.exs
{:localhost, host: '127.0.0.1', port: 20000, backlog: 5, callback: EveryoneapiDemo}
Restart the app by launching iex.
Finally, we'll just try it out by dialing in to our extension.
((( dial extension 2601 )))
Summary
In today's episode, we built on the previous episode by building our own Asterisk AGI handler module in Elixir, and we looked at building an http api client using basic auth. See you soon!
Comments for Asterisk AGI with Elixir