Packages

Synapse API client for Elixir.

Current section

Files

Jump to
ex_synapse lib ex_synapse.ex
Raw

lib/ex_synapse.ex

defmodule ExSynapse do
@moduledoc false
alias ExSynapse.{ApiConnectionError,
ApiError,
AuthenticationError,
IncorrectValuesError,
InvalidRequestError,
RateLimitError,
RequestFailedError}
@base_url "https://uat-api.synapsefi.com/v3.1"
@missing_auth_info_message "The client_id and client_secret settings are required to use Synapse."
def request(action, endpoint, data, opts)
when action in [:get, :post, :delete, :patch] do
action
|> HTTPoison.request(Path.join(get_api_endpoint(), endpoint),
Poison.encode!(data),
create_headers(opts))
|> handle_response()
end
defp get_client_id do
from_env(:ex_synapse, :client_id) ||
raise(AuthenticationError, message: @missing_auth_info_message)
end
defp get_client_secret do
from_env(:ex_synapse, :client_secret) ||
raise(AuthenticationError, message: @missing_auth_info_message)
end
defp get_api_endpoint do
from_env(:ex_synapse, :api_endpoint) || @base_url
end
defp create_headers(opts) do
[
{"X-SP-GATEWAY", "#{get_client_id()}|#{get_client_secret()}"},
{"X-SP-LANG", "en"},
{"Content-Type", "application/json"},
{"Accept", "application/json"},
]
|> MapSet.new()
|> assign_user_ip(opts)
|> assign_user(opts)
|> assign_idempotency_key(opts)
end
defp assign_user_ip(headers, opts) do
case Keyword.get(opts, :user_ip) do
nil ->
headers
user_ip ->
MapSet.put headers, {"X-SP-USER-IP", user_ip}
end
end
defp assign_user(headers, opts) do
user_oauth_key = Keyword.get(opts, :user_oauth_key)
user_fingerprint = Keyword.get(opts, :user_fingerprint)
if user_oauth_key == nil and user_fingerprint == nil do
headers
else
user_header = create_user_header(user_oauth_key, user_fingerprint)
MapSet.put headers, user_header
end
end
defp assign_idempotency_key(headers, opts) do
case Keyword.get(opts, :idempotency_key) do
nil ->
headers
idempotency_key ->
MapSet.put headers, {"X-SP-IDEMPOTENCY-KEY", idempotency_key}
end
end
defp create_user_header(user_oauth_key, user_fingerprint)
defp create_user_header(nil, user_fingerprint) do
{"X-SP-USER", "|#{user_fingerprint}"}
end
defp create_user_header(user_oauth_key, user_fingerprint) do
{"X-SP-USER", "#{user_oauth_key}|#{user_fingerprint}"}
end
defp handle_response({:ok, %{body: body, status_code: 200}}) do
{:ok, process_response_body(body)}
end
defp handle_response({:ok, %{body: body, status_code: status_code}}) do
message =
body
|> process_response_body()
|> Map.fetch!("error")
|> Map.fetch!("en")
error_struct =
case status_code do
status_code when status_code in [400, 404] ->
%InvalidRequestError{message: message}
401 ->
%AuthenticationError{message: message}
402 ->
%RequestFailedError{message: message}
409 ->
%IncorrectValuesError{message: message}
429 ->
%RateLimitError{message: message}
_ ->
%ApiError{message: message}
end
{:error, error_struct}
end
defp handle_response({:error, %HTTPoison.Error{reason: reason}}) do
%ApiConnectionError{message: "Network Error: #{reason}"}
end
defp process_response_body(body) do
Poison.decode! body
end
defp from_env(otp_app, key, default \\ nil)
defp from_env(otp_app, key, default) do
otp_app
|> Application.get_env(key, default)
|> read_env_from_system(default)
end
defp read_env_from_system({:system, env}, default) do
System.get_env(env) || default
end
defp read_env_from_system(value, _default) do
value
end
end