Packages

A wrapper around Ngrok providing a secure tunnel to localhost for demoing your Elixir/Phoenix web application or testing webhook integrations.

Current section

Files

Jump to
ex_ngrok lib api.ex
Raw

lib/api.ex

defmodule Ngrok.Api do
@moduledoc """
Provides the ability to fetch the Ngrok settings from the Ngrok API
- See: https://ngrok.com/docs#client-api-base
"""
@type error :: {:error, String.t}
@type successful_parse :: {:ok, map}
@type successful_get :: {:ok, String.t}
@spec tunnel_settings() :: error | successful_parse
def tunnel_settings do
with api_url = Application.get_env(:ex_ngrok, :api_url),
{:ok, body} <- get(api_url),
{:ok, parsed} <- parse(body) do
find_tunnel(parsed)
end
end
@spec get(String.t) :: error | successful_get
defp get(api_url) do
case HTTPoison.get(api_url) do
{:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
{:ok, body}
{:ok, %HTTPoison.Response{status_code: _, body: body}} ->
{:error, "Could not find Ngrok API on #{api_url}, data: #{body}"}
{:error, %HTTPoison.Error{reason: reason}} ->
{:error, "Could not connect to Ngrok API on #{api_url}, reason: #{reason}"}
end
end
@spec parse(String.t) :: error | successful_parse
defp parse(body) do
case Poison.Parser.parse(body) do
{:ok, parsed} ->
{:ok, parsed}
_ ->
{:error, "Could not parse data from Ngrok API, data: #{body}"}
end
end
@spec find_tunnel(map) :: error | successful_parse
defp find_tunnel(parsed) do
tunnels = Map.fetch!(parsed, "tunnels")
protocol = Application.get_env(:ex_ngrok, :protocol)
case Enum.find(tunnels, &tunnel_for_protocol(&1, protocol)) do
nil ->
{:error, "No Ngrok tunnels found for protocol: #{protocol}"}
tunnel ->
{:ok, tunnel}
end
end
@spec tunnel_for_protocol(map, String.t) :: boolean
defp tunnel_for_protocol(tunnel, protocol) do
Map.fetch!(tunnel, "proto") == protocol
end
end