Current section
Files
Jump to
Current section
Files
lib/epik/client.ex
defmodule Epik.Client do
@moduledoc """
API client for the Epik.com v2 API.
Interact with the API directly. It's usually better to use the `Epik` module
if such a function exists. Otherwise, this module can do everything else.
- The `path` parameter in each function is appended to the endpoint
set in your config. It should always begin with a forward slash,
for example: `/v2/domains/check`
- The `signature` included in your config is used automatically
to authenticate requests.
It uses `HTTPoison` to make requests and parses the response with `Jason`.
The API is slightly different than `HTTPoison` to make it more ergonomic
for use with Epik, but it does return `HTTPoison.Response` structs.
"""
@doc """
Send a GET request.
```elixir
iex(1)> Epik.Client.get("/v2/domains/check", %{"DOMAINS" => "tribes.host,fediverse.gold"})
{:ok,
%HTTPoison.Response{
status_code: 200,
body: %{
"code" => 1000,
"data" => %{
"FEDIVERSE.GOLD" => %{
"available" => 1,
"domain" => "FEDIVERSE.GOLD",
"premium" => 0,
"price" => 5.49,
"supported" => 1
},
"TRIBES.HOST" => %{
"available" => 0,
"available_reason" => "in use",
"domain" => "TRIBES.HOST",
"premium" => 0,
"supported" => 1
}
},
"message" => "Command completed successfully."
}
}}
```
"""
@spec get(path :: String.t(), params :: map()) ::
{:ok, HTTPoison.Response.t()} | {:error, any()}
def get(path, params \\ %{}) do
request(:get, path, params, "", [])
end
@doc """
Send a POST request.
```elixir
iex(1)> Epik.Client.post("/v2/domains/fedigold.xyz/create", %{"PERIOD" => 1})
{:ok,
%HTTPoison.Response{
status_code: 200,
body: %{
"code" => 1000,
"data" => %{
"FEDIGOLD.XYZ" => %{
"error" => 0,
"message" => "Successfully created",
"payment" => %{
"error" => 0,
"paymentStatus" => true,
"paymentValue" => 0.99,
"period" => "1",
"pricePerPeriod" => 0.99
},
"paymentStatus" => true,
"paymentValue" => 0.99,
"period" => "1",
"pricePerPeriod" => 0.99
}
},
"message" => "Command completed successfully.",
"period" => "1",
"total" => %{
"amount" => 0.99,
"message" => "Withdraw money successfully",
"method" => "Balance",
"success" => true
}
}
}}
```
"""
@spec post(path :: String.t(), body :: any()) ::
{:ok, HTTPoison.Response.t()} | {:error, any()}
def post(path, body \\ "") do
request(:post, path, %{}, body, [])
end
@doc """
General request function. If there's something the other functions in this
module can't do, you can use this instead.
```elixir
iex(1)> Epik.Client.request(:get, "/v2/domains/check", %{"DOMAINS" => "tribes.host,fediverse.gold"}, "", [{"user-agent", "Epik Elixir API Client <https://hex.pm/packages/epik>; Bot"}])
{:ok,
%HTTPoison.Response{
status_code: 200,
body: %{
"code" => 1000,
"data" => %{
"FEDIVERSE.GOLD" => %{
"available" => 1,
"domain" => "FEDIVERSE.GOLD",
"premium" => 0,
"price" => 5.49,
"supported" => 1
},
"TRIBES.HOST" => %{
"available" => 0,
"available_reason" => "in use",
"domain" => "TRIBES.HOST",
"premium" => 0,
"supported" => 1
}
},
"message" => "Command completed successfully."
}
}}
```
"""
@spec request(
method :: HTTPoison.Base.method(),
path :: String.t(),
params :: map(),
body :: any(),
headers :: HTTPoison.Base.headers(),
options :: Keyword.t()
) ::
{:ok, HTTPoison.Response.t()} | {:error, any()}
def request(method, path, params \\ %{}, body \\ "", headers \\ [], options \\ []) do
config = get_config()
params = Map.put_new(params, "SIGNATURE", config[:signature])
options = Keyword.put_new(options, :recv_timeout, config[:timeout])
request = %HTTPoison.Request{
method: method,
url: config[:endpoint] <> path,
body: body,
headers: headers,
options: options,
params: params
}
with {:ok, %HTTPoison.Response{} = response} <- config[:http_client].request(request) do
parse_response(response, config[:parser])
end
end
defp parse_response(%HTTPoison.Response{body: body} = response, parser) do
with {:ok, json} <- parser.decode(body) do
response = Map.put(response, :body, json)
{:ok, response}
end
end
defp get_config() do
%{
http_client: Application.get_env(:epik, :http_client, HTTPoison),
endpoint: Application.get_env(:epik, :endpoint),
signature: Application.get_env(:epik, :signature),
parser: Application.get_env(:epik, :json_parser, Jason),
timeout: Application.get_env(:epik, :timeout, 60_000)
}
end
end