ExTwiml

Build StatusHex VersionInline docs

Generate TwiML for your Twilio integration, right inside Elixir! This is the first step toward a comprehensive Twilio integration library I'm writing for Elixir, but it can be used entirely on its own.

Installation

ExTwiml can be installed through mix as a hex package. First, update your dependencies in mix.exs.

defp deps
[{:ex_twiml, "~> 1.1.3"}]
end

If you prefer, you can depend on the latest version from Github:

defp deps
[{:ex_twiml, github: "danielberkompas/ex_twiml"}]
end

Then run mix deps.get, and ExTwiml will be installed.

Usage

Import the ExTwiml module into your module, and then use the twiml macro to generate your TwiML, like so:

defmodule YourModule do
import ExTwiml
def render do
twiml do
play "/assets/welcome.mp3"
gather digits: 4, finish_on_key: "#" do
say """
Please enter the last four digits of your credit card number, followed
by the pound sign.
""", voice: "woman"
end
end
end
end

You can then render the TwiML by calling YourModule.render/0. The output will be a binary in this format:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Play>/assets/welcome.mp3</Play>
<Gather digits="4" finishOnKey="#">
<Say voice="woman">
Please enter the last four digits of your credit card number, followed by
the pound sign.
</Say>
</Gather>
</Response>

The twiml macro simply returns a binary (or string), so you're not limited to the pattern above. Just use twiml wherever you need a TwiML string.

Options

If you are integrating ExTwilio into a state machine for handling your call flows, you might find the option macro useful. It helps you dry up your code by recording a user's option at the same time as you Say it to the user.

extensions = ... # load from database
{opts, _xml} = twiml do
Enum.each extensions, fn ext ->
option ext.code, "Press #{ext.number} for #{ext.name}", [menu: :call_person], [voice: "woman"]
end
end
opts # => [{301, [menu: :call_person]}, ...]

The option macro is really just an enhanced say macro under the hood, so the twiml generated by the above will look like this:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say voice="woman">
Press 301 for Engineering Department
</Say>
</Response>

Supported Verbs and Nouns

See the Twilio Documentation for a complete list of verbs supported by Twilio. ExTwiml has built in macros for the following verbs and nouns:

Supported verbs can be called in three forms:

# Verbs that support nesting, like <Gather> and <Dial>:
verb option_1: "value", option_2: "value" do
# Nested verbs here
end
# => "<Verb option1="value" option2="value">Nested verbs here</Verb>":
# Verbs that don't support nesting, like <Say>
twiml do
verb "Inner text", option_1: "value", option_2: "value"
end
# => "<Verb option1="value" option2="value">Inner text</Verb>"
# Verbs that have no inner content, like <Reject>:
reject reason: "busy"
# => "<Reject reason="busy" />"

To maximize compatibility with future versions of the TwiML spec, ExTwiml does not validate the attributes passed to the various verbs to ensure that they are supported by Twilio. You'll need to do this yourself.

Unsupported Verbs?

If the Twilio API adds a verb and I haven't yet created a macro for it, you can do two things:

  1. Submit a PR to add it
  2. Use the tag macro in the meantime while the PR is reviewed

The tag macro can be used to create arbitrary XML tags in the output, like this:

tag :custom, option_1: "value" do
tag :speak, do: "Whatever you say, boss!"
end
# => "<Custom option1="value"><Speak>Whatever you say, boss!</Speak></Custom>"

Contributing

Contributions are welcome!

  1. Fork the repository
  2. Code up your changes
  3. Submit a PR back here with your fix.