Packages

Elixir SDK for TalkJS

Current section

Files

Jump to
talkjs lib talkjs.ex
Raw

lib/talkjs.ex

defmodule TalkJS do
@external_resource "./README.md"
@moduledoc """
#{File.read!(@external_resource) |> String.split("---", parts: 2) |> List.last()}
"""
@typedoc "TalkJS config"
@type t :: %__MODULE__{
api_key: binary(),
app_id: binary(),
base_url: binary(),
http_client: term
}
defstruct [
:api_key,
:app_id,
base_url: "https://api.talkjs.com/v1/",
http_client: TalkJS.HTTPClient.HTTPC
]
@doc """
Create a new TalkJS client
Options for the TalkJS client:application
* `:api_key` - the API key provided by TalkJS (YOUR_SECRET_KEY)
* `:app_id` - the app id provided by TalkJS (YOUR_APP_ID)
* `:base_url` - the base URL for the API (default: "https://api.talkjs.com/v1/")
* `:http_client` - the HTTP client to use (default: TalkJS.HTTPClient.HTTPC).
Must adhere to `TalkJS.HTTPClient` behaviour
Example usage:
```elixir
client = TalkJS.new(api_key: "...", app_id: "...")
```
"""
@spec new(opts :: Keyword.t()) :: TalkJS.t()
def new(opts) do
client = struct!(__MODULE__, opts)
client.http_client.init()
validate!(opts, :api_key)
validate!(opts, :app_id)
client
end
defp validate!(opts, key) do
case Keyword.fetch(opts, key) do
{:ok, _} -> :ok
:error -> raise ArgumentError, "missing required option: #{key}"
end
end
@doc """
Perform a request to TalkJS
Example usage:
```elixir
client = TalkJS.new(api_key: "...", app_id: "...")
TalkJS.request(:get, "$app_id/users/#id", client, %{})
```
"""
@spec request(
method :: :get | :delete | :post | :put,
path :: String.t(),
client :: TalkJS.t(),
params :: map(),
opts :: Keyword.t()
) ::
{:ok, term()} | {:error, term()}
def request(method, path, client, params, opts \\ [])
def request(method, path, client, _params, opts) when method in [:get, :delete] do
url = URI.parse(client.base_url <> path) |> URI.to_string()
headers = build_headers(client)
do_request(client, method, url, headers, "", opts)
end
def request(method, path, client, params, opts) when method in [:post, :put] do
url = client.base_url <> path
headers = build_headers(client)
body = (params || %{}) |> Jason.encode!(params)
do_request(client, method, url, headers, body, opts)
end
defp do_request(client, method, url, headers, body, opts) do
http_opts = opts[:http_opts] || []
case client.http_client.request(method, url, headers, body, http_opts) do
{:ok, %{status: status} = resp} when status >= 200 and status < 300 ->
decoded_body = Jason.decode!(resp.body)
{:ok, decoded_body}
{:ok, resp} ->
# IO.inspect(resp)
decoded_body = Jason.decode!(resp.body)
{:error, decoded_body}
{:error, error} ->
{:error, error}
end
end
defp build_headers(client) do
[
{"authorization", "Bearer #{client.api_key}"}
]
end
end