Current section
Files
Jump to
Current section
Files
lib/hedgex/api.ex
defmodule Hedgex.Api do
@moduledoc """
Low-level operations for the Posthog API. This module is meant to be 1:1 with Posthog endpoints:
https://posthog.com/docs/api
## Options
Common options
* `:hedgex` - a `Hedgex.Env` containing API configuration. Defaults to a context constructed by application config.
"""
alias Hedgex.Env
@doc """
Send a single event to Posthog. See https://posthog.com/docs/api/capture#single-event for more details
## Examples
iex> Hedgex.Api.capture(%{event: "foo_created", distinct_id: "user_12345", properties: %{}})
:ok
"""
@spec capture(event :: Hedgex.event(), opts :: Keyword.t()) :: :ok | {:error, Exception.t()}
def capture(event, opts \\ []) do
env = opts[:hedgex] || Env.new()
event_body =
event
|> Map.take([:event, :distinct_id, :properties, :timestamp])
|> add_lib_props()
Env.public_req(env)
|> Req.post(url: "/capture", json: Map.merge(event_body, %{api_key: env.project_api_key}))
|> map_req_response(fn _ -> :ok end)
end
@doc """
Send a batch of events to Posthog. See https://posthog.com/docs/api/capture#batch-events for more details
## Options
* `:historical_migration` - defaults to false
## Examples
iex> Hedgex.Api.batch([%{event: "foo_created", distinct_id: "user_12345", properties: %{}}])
:ok
"""
@spec batch(batch :: [Hedgex.event()], opts :: Keyword.t()) :: :ok | {:error, Exception.t()}
def batch(batch, opts \\ []) do
env = opts[:hedgex] || Env.new()
historical_migration = opts[:historical_migration] || false
request_body = %{
api_key: env.project_api_key,
historical_migration: historical_migration,
batch: Enum.map(batch, &add_lib_props/1)
}
Env.public_req(env)
|> Req.post(url: "/batch", json: request_body)
|> map_req_response(fn _ -> :ok end)
end
@doc """
Call the public `decide` endpoint used to evaluate feature flag state for a given user. See
https://posthog.com/docs/api/decide for more details.
## Options
* `:groups` - (optional) Group config used to evaluate the feature flag
## Examples
iex> Hedgex.Api.decide("user_12345", groups: %{company: "Acme, Inc."}}])
{:ok, %{"featureFlags" => %{"my-awesome-flag" => true}}}
"""
@spec decide(distinct_id :: any(), opts :: Keyword.t()) ::
{:ok, map()} | {:error, Exception.t()}
def decide(distinct_id, opts \\ []) do
env = opts[:hedgex] || Env.new()
request_body = %{
api_key: env.project_api_key,
distinct_id: distinct_id,
groups: opts[:groups]
}
Env.public_req(env)
|> Req.post(url: "/decide", json: request_body)
|> map_req_response(fn response -> {:ok, response.body} end)
end
def map_req_response(response, success_fun) do
case response do
{:ok, %{status: 200} = resp} ->
success_fun.(resp)
{:ok, %{status: status, body: body}} ->
{:error, %Hedgex.PosthogError{status: status, body: body}}
{:error, err} ->
{:error, %Hedgex.ReqError{error: err}}
end
end
defp add_lib_props(event) do
event
|> Map.put_new(:properties, %{})
|> Map.update!(:properties, &Map.put(&1, "$lib", "hedgex"))
end
end