Skip to content

Commit

Permalink
Merge pull request #13 from SeatedInc/replace-ex-twilio
Browse files Browse the repository at this point in the history
Replace ex_twilio, make hackney configurable
  • Loading branch information
john-griffin authored May 21, 2018
2 parents 46aadda + ae5a4ee commit e28be80
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 23 deletions.
4 changes: 0 additions & 4 deletions config/test.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
use Mix.Config

config :logger, level: :warn

config :ex_twilio,
account_sid: "fake-account-sid",
auth_token: "fake-auth-token"
53 changes: 46 additions & 7 deletions lib/apus/adapters/twilio_adapter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,55 @@ defmodule Apus.TwilioAdapter do

@behaviour Apus.Adapter

alias ExTwilio.Message

def deliver(message, config) do
params = message |> convert_to_twilio_params(config) |> to_query_string()

case :hackney.post(uri(config), headers(config), params, options(config)) do
{:ok, status, _headers, response} when status > 299 ->
{:ok, body} = :hackney.body(response)
body = Poison.decode!(body)
{:error, body["message"]}

{:ok, _status, _headers, response} ->
{:ok, body} = :hackney.body(response)
Poison.decode(body, as: %Apus.Message{})

error ->
error
end
end

def handle_config(config), do: config

defp uri(config) do
"https://api.twilio.com/2010-04-01/Accounts/#{config.account_sid}/Messages.json"
end

defp headers(config) do
auth = Base.encode64("#{config.account_sid}:#{config.auth_token}")

[
Authorization: "Basic #{auth}",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
]
end

defp convert_to_twilio_params(message, config) do
message
|> Map.from_struct()
|> maybe_put_service_sid(config)
|> Message.create()
|> format_response
|> Map.to_list()
end

def handle_config(config), do: config
defp to_query_string(list) do
list
|> Enum.flat_map(fn {key, value} -> [{camelize(key), value}] end)
|> URI.encode_query()
end

defp camelize(name) do
name |> to_string |> Macro.camelize()
end

defp maybe_put_service_sid(%{from: from} = message, %{messaging_service_sid: sid})
when from in [nil, ""] do
Expand All @@ -23,6 +61,7 @@ defmodule Apus.TwilioAdapter do

defp maybe_put_service_sid(message, _config), do: message

defp format_response({:error, message, _}), do: {:error, message}
defp format_response(response), do: response
defp options(config) do
config[:request_options] || []
end
end
5 changes: 3 additions & 2 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ defmodule Apus.MixProject do

defp deps do
[
{:ex_twilio, "~> 0.6.0"},
{:excoveralls, "~> 0.8.1", [only: :test]},
{:exvcr, "~> 0.10.2", only: :test},
{:ex_doc, "~> 0.18.3", only: :dev}
{:ex_doc, "~> 0.18.3", only: :dev},
{:hackney, "~> 1.12"},
{:poison, "~> 3.1"}
]
end

Expand Down
6 changes: 0 additions & 6 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
%{
"base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm"},
"certifi": {:hex, :certifi, "2.3.1", "d0f424232390bf47d82da8478022301c561cf6445b5b5fb6a84d49a9e76d2639", [:rebar3], [{:parse_trans, "3.2.0", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
"earmark": {:hex, :earmark, "1.2.5", "4d21980d5d2862a2e13ec3c49ad9ad783ffc7ca5769cf6ff891a4553fbaae761", [:mix], [], "hexpm"},
"ex_doc": {:hex, :ex_doc, "0.18.3", "f4b0e4a2ec6f333dccf761838a4b253d75e11f714b85ae271c9ae361367897b7", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"},
"ex_twilio": {:hex, :ex_twilio, "0.6.0", "62873a6b37b0daee363120cfb1860f176b89e38b6dc221ff766911236bceab3a", [:mix], [{:httpoison, ">= 0.9.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:inflex, "~> 1.0", [hex: :inflex, repo: "hexpm", optional: false]}, {:joken, "~> 1.5", [hex: :joken, repo: "hexpm", optional: false]}, {:poison, "~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
"exactor": {:hex, :exactor, "2.2.4", "5efb4ddeb2c48d9a1d7c9b465a6fffdd82300eb9618ece5d34c3334d5d7245b1", [:mix], [], "hexpm"},
"excoveralls": {:hex, :excoveralls, "0.8.2", "b941a08a1842d7aa629e0bbc969186a4cefdd035bad9fe15d43aaaaaeb8fae36", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"},
"exvcr": {:hex, :exvcr, "0.10.2", "a66a0fa86d03153e5c21e38b1320d10b537038d7bc7b10dcc1ab7f0343569822", [:mix], [{:exactor, "~> 2.2", [hex: :exactor, repo: "hexpm", optional: false]}, {:exjsx, "~> 4.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: true]}, {:httpotion, "~> 3.1", [hex: :httpotion, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:meck, "~> 0.8", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"},
"hackney": {:hex, :hackney, "1.12.1", "8bf2d0e11e722e533903fe126e14d6e7e94d9b7983ced595b75f532e04b7fdc7", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"httpoison": {:hex, :httpoison, "1.1.1", "96ed7ab79f78a31081bb523eefec205fd2900a02cda6dbc2300e7a1226219566", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "5.1.1", "cbc3b2fa1645113267cc59c760bafa64b2ea0334635ef06dbac8801e42f7279c", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
"inflex": {:hex, :inflex, "1.10.0", "8366a7696e70e1813aca102e61274addf85d99f4a072b2f9c7984054ea1b9d29", [:mix], [], "hexpm"},
"joken": {:hex, :joken, "1.5.0", "42a0953e80bd933fc98a0874e156771f78bf0e92abe6c3a9c22feb6da28efb0b", [:mix], [{:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}, {:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"},
"jose": {:hex, :jose, "1.8.4", "7946d1e5c03a76ac9ef42a6e6a20001d35987afd68c2107bcd8f01a84e75aa73", [:mix, :rebar3], [{:base64url, "~> 0.0.1", [hex: :base64url, repo: "hexpm", optional: false]}], "hexpm"},
"jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"},
"meck": {:hex, :meck, "0.8.9", "64c5c0bd8bcca3a180b44196265c8ed7594e16bcc845d0698ec6b4e577f48188", [:rebar3], [], "hexpm"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
Expand Down
34 changes: 30 additions & 4 deletions test/lib/apus/adapters/twilio_adapter_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,45 @@ defmodule Apus.TwilioAdapterTest do

describe "message delivery" do
test "deliver/2 should deliver a message" do
config = %{
account_sid: "fake-account-sid",
auth_token: "fake-auth-token"
}

message = Message.new(from: "+15551234567", to: "+15557654321", body: "Hello there")

use_cassette "twilio_sms_from_success", match_requests_on: [:request_body] do
{:ok, %ExTwilio.Message{} = tw_message} = TwilioAdapter.deliver(message, %{})
{:ok, %{} = tw_message} = TwilioAdapter.deliver(message, config)

assert tw_message.from == "+15551234567"
assert tw_message.to == "+15557654321"
assert tw_message.body == "Hello there"
end
end

test "deliver/2 passes request_options to hackney" do
config = %{
request_options: [recv_timeout: 0],
account_sid: "fake-account-sid",
auth_token: "fake-auth-token"
}

message = Message.new(from: "+15551234567", to: "+15557654321", body: "Hello there")

assert {:error, :timeout} == TwilioAdapter.deliver(message, config)
end

test "deliver/2 should deliver a message with the messaging service sid set" do
config = %{
account_sid: "fake-account-sid",
auth_token: "fake-auth-token",
messaging_service_sid: "fake-mssid"
}

message = Message.new(to: "+15557654321", body: "Hello there")

use_cassette "twilio_sms_mssid_success", match_requests_on: [:request_body] do
{:ok, %ExTwilio.Message{} = tw_message} = TwilioAdapter.deliver(message, config)
{:ok, %{} = tw_message} = TwilioAdapter.deliver(message, config)

assert tw_message.from == nil
assert tw_message.to == "+15557654321"
Expand All @@ -36,13 +55,15 @@ defmodule Apus.TwilioAdapterTest do

test "deliver/2 should override messaging service sid if from is set" do
config = %{
account_sid: "fake-account-sid",
auth_token: "fake-auth-token",
messaging_service_sid: "fake-mssid"
}

message = Message.new(from: "+15551234567", to: "+15557654321", body: "Hello there")

use_cassette "twilio_sms_from_success", match_requests_on: [:request_body] do
{:ok, %ExTwilio.Message{} = tw_message} = TwilioAdapter.deliver(message, config)
{:ok, %{} = tw_message} = TwilioAdapter.deliver(message, config)

assert tw_message.from == "+15551234567"
assert tw_message.to == "+15557654321"
Expand All @@ -51,10 +72,15 @@ defmodule Apus.TwilioAdapterTest do
end

test "deliver/2 should return the twilio error message" do
config = %{
account_sid: "fake-account-sid",
auth_token: "fake-auth-token"
}

message = Message.new(from: "+15551234567", to: "+15557654321", body: "Hello there")

use_cassette "twilio_sms_failure", match_requests_on: [:request_body] do
{:error, message} = TwilioAdapter.deliver(message, %{})
{:error, message} = TwilioAdapter.deliver(message, config)

assert message == "Some server error occurred"
end
Expand Down

0 comments on commit e28be80

Please sign in to comment.