Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export TWILIO_ACCOUNT_SID="<production account sid here>"
export TWILIO_AUTH_TOKEN="<production auth token here>"
export TWILIO_WORKSPACE_SID="<production workspace sid here>"
export TWILIO_PROXY_SERVICE_SID="<production proxy service sid here>"

export TWILIO_TEST_ACCOUNT_SID="<test account sid here>"
export TWILIO_TEST_AUTH_TOKEN="<test auth token here>"
Expand Down
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ You will need to set the following configuration variables in your
```elixir
use Mix.Config

config :ex_twilio, account_sid: {:system, "TWILIO_ACCOUNT_SID"},
auth_token: {:system, "TWILIO_AUTH_TOKEN"},
workspace_sid: {:system, "TWILIO_WORKSPACE_SID"} # optional
config :ex_twilio, account_sid: {:system, "TWILIO_ACCOUNT_SID"},
auth_token: {:system, "TWILIO_AUTH_TOKEN"},
workspace_sid: {:system, "TWILIO_WORKSPACE_SID"}, # optional
proxy_service_sid: {:system, "TWILIO_PROXY_SERVICE_SID"} # optional if using proxy API
```

For security, I recommend that you use environment variables rather than hard
Expand All @@ -53,6 +54,7 @@ following content:
export TWILIO_ACCOUNT_SID=<account sid here>
export TWILIO_AUTH_TOKEN=<auth token>
export TWILIO_WORKSPACE_SID=<workspace sid here> #optional
export TWILIO_PROXY_SERVICE_SID=<proxy service sid here> #optional
```

Then, just be sure to run `source .env` in your shell before compiling your
Expand Down Expand Up @@ -150,6 +152,17 @@ Twilio's TaskRouter API:
- [Workspaces](https://www.twilio.com/docs/api/taskrouter/workspaces)
- [Statistics](https://www.twilio.com/docs/api/taskrouter/workspace-statistics)

Twilio's Proxy API:

- [Overview](https://www.twilio.com/docs/proxy/api)
- [Service](https://www.twilio.com/docs/proxy/api/service)
- [Phone Number](https://www.twilio.com/docs/proxy/api/phone-number)
- [Short Code](https://www.twilio.com/docs/proxy/api/short-code)
- [Session Resource](https://www.twilio.com/docs/proxy/api/session)
- [Participant](https://www.twilio.com/docs/proxy/api/participant)
- [Interaction](https://www.twilio.com/docs/proxy/api/interaction)
- [Sending Messages](https://www.twilio.com/docs/proxy/api/sending-messages)

Twilio's ProgrammableChat API:

- [Overview](https://www.twilio.com/docs/api/chat/rest)
Expand Down
3 changes: 2 additions & 1 deletion config/dev.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ use Mix.Config
config :ex_twilio,
account_sid: {:system, "TWILIO_ACCOUNT_SID"},
auth_token: {:system, "TWILIO_AUTH_TOKEN"},
workspace_sid: {:system, "TWILIO_WORKSPACE_SID"}
workspace_sid: {:system, "TWILIO_WORKSPACE_SID"},
proxy_service_sid: {:system, "TWILIO_PROXY_SERVICE_SID"}
3 changes: 2 additions & 1 deletion config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use Mix.Config
config :ex_twilio,
account_sid: {:system, "TWILIO_TEST_ACCOUNT_SID"},
auth_token: {:system, "TWILIO_TEST_AUTH_TOKEN"},
workspace_sid: {:system, "TWILIO_TEST_WORKSPACE_SID"}
workspace_sid: {:system, "TWILIO_WORKSPACE_SID"},
proxy_service_sid: {:system, "TWILIO_PROXY_SERVICE_SID"}

config :logger, level: :info
4 changes: 4 additions & 0 deletions lib/ex_twilio/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ defmodule ExTwilio.Config do

def workspace_sid, do: Application.get_env(:ex_twilio, :workspace_sid) || "12345"

def proxy_service_sid, do: Application.get_env(:ex_twilio, :proxy_service_sid) || "12345"

@doc """
Return the combined base URL of the Twilio API, using the configuration
settings given.
Expand All @@ -69,6 +71,8 @@ defmodule ExTwilio.Config do

def video_url, do: "https://video.twilio.com/v1"

def proxy_url, do: "https://proxy.twilio.com/v1"

@doc """
A light wrapper around `Application.get_env/2`, providing automatic support for
`{:system, "VAR"}` tuples.
Expand Down
35 changes: 35 additions & 0 deletions lib/ex_twilio/resources/proxy/interaction.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
defmodule ExTwilio.Proxy.Interaction do
@moduledoc """
Represents an Interaction of a Session.

- [Twilio docs](https://www.twilio.com/docs/proxy/api/interaction)
"""

defstruct sid: nil,
account_sid: nil,
session_sid: nil,
service_sid: nil,
data: nil,
type: nil,
inbound_participant_sid: nil,
inbound_resource_sid: nil,
inbound_resource_status: nil,
inbound_resource_type: nil,
inbound_resource_url: nil,
outbound_participant_sid: nil,
outbound_resource_sid: nil,
outbound_resource_status: nil,
outbound_resource_type: nil,
outbound_resource_url: nil,
date_created: nil,
date_updated: nil,
url: nil

use ExTwilio.Resource, import: [:stream, :all, :find, :delete]

def parents,
do: [
%ExTwilio.Parent{module: ExTwilio.Proxy.Service, key: :service},
%ExTwilio.Parent{module: ExTwilio.Proxy.SessionResource, key: :session}
]
end
39 changes: 39 additions & 0 deletions lib/ex_twilio/resources/proxy/message.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
defmodule ExTwilio.Proxy.Message do
@moduledoc """
Represents a Message Interaction of a Session.

- [Twilio docs](https://www.twilio.com/docs/proxy/api/sending-messages)
"""

defstruct sid: nil,
account_sid: nil,
session_sid: nil,
service_sid: nil,
participant_sid: nil,
data: nil,
type: nil,
inbound_participant_sid: nil,
inbound_resource_sid: nil,
inbound_resource_status: nil,
inbound_resource_type: nil,
inbound_resource_url: nil,
outbound_participant_sid: nil,
outbound_resource_sid: nil,
outbound_resource_status: nil,
outbound_resource_type: nil,
outbound_resource_url: nil,
date_created: nil,
date_updated: nil,
url: nil

use ExTwilio.Resource, import: [:create]

def parents,
do: [
%ExTwilio.Parent{module: ExTwilio.Proxy.Service, key: :service},
%ExTwilio.Parent{module: ExTwilio.Proxy.SessionResource, key: :session},
%ExTwilio.Parent{module: ExTwilio.Proxy.Participant, key: :participant}
]

def resource_name, do: "MessageInteractions"
end
29 changes: 29 additions & 0 deletions lib/ex_twilio/resources/proxy/participant.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
defmodule ExTwilio.Proxy.Participant do
@moduledoc """
Represents a Participant attached to a Session.

- [Twilio docs](https://www.twilio.com/docs/proxy/api/participant)
"""

defstruct sid: nil,
account_sid: nil,
session_sid: nil,
service_sid: nil,
friendly_name: nil,
identifier: nil,
proxy_identifier: nil,
proxy_identifier_sid: nil,
date_deleted: nil,
date_created: nil,
date_updated: nil,
url: nil,
links: nil

use ExTwilio.Resource, import: [:stream, :all, :find, :create, :delete]

def parents,
do: [
%ExTwilio.Parent{module: ExTwilio.Proxy.Service, key: :service},
%ExTwilio.Parent{module: ExTwilio.Proxy.SessionResource, key: :session}
]
end
34 changes: 34 additions & 0 deletions lib/ex_twilio/resources/proxy/phone_number.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
defmodule ExTwilio.Proxy.PhoneNumber do
@moduledoc """
Represents a Phone Number attached to a Service.

- [Twilio docs](https://www.twilio.com/docs/proxy/api/phone-number)
"""

defstruct sid: nil,
account_sid: nil,
service_sid: nil,
date_created: nil,
date_updated: nil,
phone_number: nil,
friendly_name: nil,
iso_country: nil,
capabilities: nil,
url: nil,
is_reserved: nil,
in_use: nil

use ExTwilio.Resource, import: [:stream, :all, :find, :create, :update, :delete]

alias ExTwilio.Parser
alias ExTwilio.Api

@spec create_reserved(Api.data(), list) :: Parser.success() | Parser.error()
def create_reserved(data, options) when is_map(data),
do: data |> Map.to_list() |> create_reserved(options)

def create_reserved(data, options),
do: data |> Keyword.merge(is_reserved: true) |> create(options)

def parents, do: [%ExTwilio.Parent{module: ExTwilio.Proxy.Service, key: :service}]
end
25 changes: 25 additions & 0 deletions lib/ex_twilio/resources/proxy/service.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
defmodule ExTwilio.Proxy.Service do
@moduledoc """
A Service is a container for Proxy Sessions, Phone Numbers and Short Codes.
Each of these items exists within a single Service and will not be shared across Services.

- [Twilio docs](https://www.twilio.com/docs/proxy/api/service)
"""

defstruct sid: nil,
account_sid: nil,
unique_name: nil,
chat_instance_sid: nil,
callback_url: nil,
default_ttl: nil,
number_selection_behavior: nil,
geo_match_level: nil,
intercept_callback_url: nil,
out_of_session_callback_url: nil,
date_created: nil,
date_updated: nil,
url: nil,
links: nil

use ExTwilio.Resource, import: [:stream, :all, :find, :create, :update, :delete]
end
32 changes: 32 additions & 0 deletions lib/ex_twilio/resources/proxy/session_resource.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
defmodule ExTwilio.Proxy.SessionResource do
@moduledoc """
Represents an allocated Session containing Participants, an allocated Phone Number, and Interations.

- [Twilio docs](https://www.twilio.com/docs/proxy/api/session)
"""

defstruct sid: nil,
account_sid: nil,
service_sid: nil,
date_started: nil,
date_ended: nil,
date_last_interation: nil,
date_expirty: nil,
unique_name: nil,
status: nil,
closed_reason: nil,
ttl: nil,
mode: nil,
date_created: nil,
date_updated: nil,
url: nil,
links: nil

use ExTwilio.Resource, import: [:stream, :all, :find, :create, :update, :delete]

def parents, do: [%ExTwilio.Parent{module: ExTwilio.Proxy.Service, key: :service}]

def resource_name, do: "Sessions"

def resource_collection_name, do: "sessions"
end
22 changes: 22 additions & 0 deletions lib/ex_twilio/resources/proxy/short_code.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
defmodule ExTwilio.Proxy.ShortCode do
@moduledoc """
Represents a Short Code attached to a Service.

- [Twilio docs](https://www.twilio.com/docs/proxy/api/short-code)
"""

defstruct sid: nil,
account_sid: nil,
service_sid: nil,
date_created: nil,
date_updated: nil,
short_code: nil,
iso_country: nil,
capabilities: nil,
url: nil,
is_reserved: nil

use ExTwilio.Resource, import: [:stream, :all, :find, :create, :update, :delete]

def parents, do: [%ExTwilio.Parent{module: ExTwilio.Proxy.Service, key: :service}]
end
10 changes: 10 additions & 0 deletions lib/ex_twilio/url_generator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ defmodule ExTwilio.UrlGenerator do
url = add_segments(Config.video_url(), module, id, options)
{url, options}

["ExTwilio", "Proxy" | _] ->
options = add_proxy_service_to_options(module, options)
url = add_segments(Config.proxy_url(), module, id, options)
{url, options}

_ ->
# Add Account SID segment if not already present
options = add_account_to_options(module, options)
Expand Down Expand Up @@ -165,6 +170,11 @@ defmodule ExTwilio.UrlGenerator do
Keyword.put_new(options, :workspace, Config.workspace_sid())
end

@spec add_proxy_service_to_options(atom, list) :: list
defp add_proxy_service_to_options(_module, options) do
Keyword.put_new(options, :service, Config.proxy_service_sid())
end

@spec normalize_parents(list) :: list
defp normalize_parents(parents) do
parents
Expand Down
12 changes: 6 additions & 6 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
%{
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
"certifi": {:hex, :certifi, "2.5.2", "b7cfeae9d2ed395695dd8201c57a2d019c0c43ecaf8b8bcb9320b40d6662f340", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "3b3b5f36493004ac3455966991eaf6e768ce9884693d9968055aeeeb1e575040"},
"certifi": {:hex, :certifi, "2.5.3", "70bdd7e7188c804f3a30ee0e7c99655bc35d8ac41c23e12325f36ab449b70651", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "ed516acb3929b101208a9d700062d520f3953da3b6b918d866106ffa980e1c10"},
"dialyze": {:hex, :dialyze, "0.2.1", "9fb71767f96649020d769db7cbd7290059daff23707d6e851e206b1fdfa92f9d", [:mix], [], "hexpm", "f485181fa53229356621261a384963cb47511cccf1454e82ca4fde53274fcd48"},
"earmark_parser": {:hex, :earmark_parser, "1.4.10", "6603d7a603b9c18d3d20db69921527f82ef09990885ed7525003c7fe7dc86c56", [:mix], [], "hexpm", "8e2d5370b732385db2c9b22215c3f59c84ac7dda7ed7e544d7c459496ae519c0"},
"ex_doc": {:hex, :ex_doc, "0.23.0", "a069bc9b0bf8efe323ecde8c0d62afc13d308b1fa3d228b65bca5cf8703a529d", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "f5e2c4702468b2fd11b10d39416ddadd2fcdd173ba2a0285ebd92c39827a5a16"},
"hackney": {:hex, :hackney, "1.16.0", "5096ac8e823e3a441477b2d187e30dd3fff1a82991a806b2003845ce72ce2d84", [:rebar3], [{:certifi, "2.5.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.0", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3bf0bebbd5d3092a3543b783bf065165fa5d3ad4b899b836810e513064134e18"},
"httpoison": {:hex, :httpoison, "1.7.0", "abba7d086233c2d8574726227b6c2c4f6e53c4deae7fe5f6de531162ce9929a0", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "975cc87c845a103d3d1ea1ccfd68a2700c211a434d8428b10c323dc95dc5b980"},
"idna": {:hex, :idna, "6.0.1", "1d038fb2e7668ce41fbf681d2c45902e52b3cb9e9c77b55334353b222c2ee50c", [:rebar3], [{:unicode_util_compat, "0.5.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a02c8a1c4fd601215bb0b0324c8a6986749f807ce35f25449ec9e69758708122"},
"hackney": {:hex, :hackney, "1.17.0", "717ea195fd2f898d9fe9f1ce0afcc2621a41ecfe137fae57e7fe6e9484b9aa99", [:rebar3], [{:certifi, "~>2.5", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "64c22225f1ea8855f584720c0e5b3cd14095703af1c9fbc845ba042811dc671c"},
"httpoison": {:hex, :httpoison, "1.8.0", "6b85dea15820b7804ef607ff78406ab449dd78bed923a49c7160e1886e987a3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "28089eaa98cf90c66265b6b5ad87c59a3729bea2e74e9d08f9b51eb9729b3c3a"},
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
"inch_ex": {:hex, :inch_ex, "2.0.0", "24268a9284a1751f2ceda569cd978e1fa394c977c45c331bb52a405de544f4de", [:mix], [{:bunt, "~> 0.2", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "96d0ec5ecac8cf63142d02f16b7ab7152cf0f0f1a185a80161b758383c9399a8"},
"inflex": {:hex, :inflex, "2.1.0", "a365cf0821a9dacb65067abd95008ca1b0bb7dcdd85ae59965deef2aa062924c", [:mix], [], "hexpm", "14c17d05db4ee9b6d319b0bff1bdf22aa389a25398d1952c7a0b5f3d93162dd8"},
"jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
Expand All @@ -19,7 +19,7 @@
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"mock": {:hex, :mock, "0.3.6", "e810a91fabc7adf63ab5fdbec5d9d3b492413b8cda5131a2a8aa34b4185eb9b4", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "bcf1d0a6826fb5aee01bae3d74474669a3fa8b2df274d094af54a25266a1ebd2"},
"nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"},
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.5.0", "8516502659002cec19e244ebd90d312183064be95025a319a6c7e89f4bccd65b", [:rebar3], [], "hexpm", "d48d002e15f5cc105a696cf2f1bbb3fc72b4b770a184d8420c8db20da2674b38"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
}