Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 32 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ Start the Segment agent with your write_key from Segment for a HTTP API Server S
Segment.start_link("YOUR_WRITE_KEY")
```

You can optionally start the Segment agent to be able to send events to multiple sources. In that case, just provide a write key for each source name:

```elixir
Segment.start_link(source_1: "YOUR_WRITE_KEY_S1", source_2: "YOUR_WRITE_KEY_S2")
```

There are then two ways to call the different methods on the API.
A basic way through `Segment.Analytics` functions with either the full event Struct
or some helper methods (also allowing Context and Integrations to be set manually).
Expand All @@ -43,79 +49,79 @@ The other way is to drop down lower and use `Segment.Http` `send` and `batch` di
### Track

```elixir
Segment.Analytics.track(user_id, event, %{property1: "", property2: ""})
Segment.Analytics.track(source, user_id, event, %{property1: "", property2: ""})
```

or the full way using a struct with all the possible options for the track call

```elixir
%Segment.Analytics.Track{userId: "sdsds", event: "eventname", properties: %{property1: "", property2: ""}}
|> Segment.Analytics.track
|> Segment.Analytics.track(source)
```

### Identify

```elixir
Segment.Analytics.identify(user_id, %{trait1: "", trait2: ""})
Segment.Analytics.identify(source, user_id, %{trait1: "", trait2: ""})
```

Or the full way using a struct with all the possible options for the identify call.

```elixir
%Segment.Analytics.Identify{userId: "sdsds", traits: %{trait1: "", trait2: ""}}
|> Segment.Analytics.identify
|> Segment.Analytics.identify(source)
```

### Screen

```elixir
Segment.Analytics.screen(user_id, name)
Segment.Analytics.screen(source, user_id, name)
```

Or the full way using a struct with all the possible options for the screen call.

```elixir
%Segment.Analytics.Screen{userId: "sdsds", name: "dssd"}
|> Segment.Analytics.screen
|> Segment.Analytics.screen(source)
```

### Alias

```elixir
Segment.Analytics.alias(user_id, previous_id)
Segment.Analytics.alias(source, user_id, previous_id)
```

Or the full way using a struct with all the possible options for the alias call.

```elixir
%Segment.Analytics.Alias{userId: "sdsds", previousId: "dssd"}
|> Segment.Analytics.alias
|> Segment.Analytics.alias(source)
```

### Group

```elixir
Segment.Analytics.group(user_id, group_id)
Segment.Analytics.group(source, user_id, group_id)
```

Or the full way using a struct with all the possible options for the group call.

```elixir
%Segment.Analytics.Group{userId: "sdsds", groupId: "dssd"}
|> Segment.Analytics.group
|> Segment.Analytics.group(source)
```

### Page

```elixir
Segment.Analytics.page(user_id, name)
Segment.Analytics.page(source, user_id, name)
```

Or the full way using a struct with all the possible options for the page call.

```elixir
%Segment.Analytics.Page{userId: "sdsds", name: "dssd"}
|> Segment.Analytics.page
|> Segment.Analytics.page(source)
```

### Using the Segment Context
Expand All @@ -124,7 +130,7 @@ If you want to set the Context manually you should create a `Segment.Analytics.C

```elixir
context = Segment.Analytics.Context.new(%{active: false})
Segment.Analytics.track(user_id, event, %{property1: "", property2: ""}, context)
Segment.Analytics.track(:default, user_id, event, %{property1: "", property2: ""}, context)
```

## Configuration
Expand Down Expand Up @@ -155,12 +161,25 @@ This is how I add to a Phoenix project (may not be your preferred way)
write_key: "2iFFnRsCfi"
```

or

```elixir
config :segment,
write_keys: [source_1: "2iFFnRsCfi". source_2: "AakdKAsds"]
```

3. Start the Segment GenServer in the supervised children list. In `application.ex` add to the children list:

```elixir
{Segment, Application.get_env(:segment, :write_key)}
```

or with multiple sources

```elixir
{Segment, Application.get_env(:segment, :write_keys)}
```

## Running tests

There are not many tests at the moment. if you want to run live tests on your account you need to change the config in `test.exs` to `config :segment, :send_to_http, true` and then provide your key as an environment variable.
Expand Down
84 changes: 42 additions & 42 deletions lib/segment/analytics.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ defmodule Segment.Analytics do
@doc """
Make a call to Segment with an event. Should be of type `Track, Identify, Screen, Alias, Group or Page`
"""
@spec send(Segment.segment_event()) :: :ok
def send(%{__struct__: mod} = event)
@spec send(atom(), Segment.segment_event()) :: :ok
def send(source_name, %{__struct__: mod} = event)
when mod in [Track, Identify, Screen, Alias, Group, Page] do
call(event)
call(event, source_name)
end

@doc """
Expand All @@ -27,9 +27,9 @@ defmodule Segment.Analytics do

See [https://segment.com/docs/spec/track/](https://segment.com/docs/spec/track/)
"""
@spec track(Segment.Analytics.Track.t()) :: :ok
def track(t = %Track{}) do
call(t)
@spec track(atom(), Segment.Analytics.Track.t()) :: :ok
def track(source_name, t = %Track{}) do
call(t, source_name)
end

@doc """
Expand All @@ -38,15 +38,15 @@ defmodule Segment.Analytics do

See [https://segment.com/docs/spec/track/](https://segment.com/docs/spec/track/)
"""
@spec track(segment_id(), String.t(), map(), Segment.Analytics.Context.t()) :: :ok
def track(user_id, event_name, properties \\ %{}, context \\ Context.new()) do
@spec track(atom(), segment_id(), String.t(), map(), Segment.Analytics.Context.t()) :: :ok
def track(source_name, user_id, event_name, properties \\ %{}, context \\ Context.new()) do
%Track{
userId: user_id,
event: event_name,
properties: properties,
context: context
}
|> call
|> call(source_name)
end

@doc """
Expand All @@ -55,20 +55,20 @@ defmodule Segment.Analytics do

See [https://segment.com/docs/spec/identify/](https://segment.com/docs/spec/identify/)
"""
@spec identify(Segment.Analytics.Identify.t()) :: :ok
def identify(i = %Identify{}) do
call(i)
@spec identify(atom(), Segment.Analytics.Identify.t()) :: :ok
def identify(source_name, i = %Identify{}) do
call(i, source_name)
end

@doc """
`identify` lets you tie a user to their actions and record traits about them. `identify/3` takes a `user_id`, optional additional `traits` and an optional `Segment.Analytics.Context` struct.

See [https://segment.com/docs/spec/identify/](https://segment.com/docs/spec/identify/)
"""
@spec identify(segment_id(), map(), Segment.Analytics.Context.t()) :: :ok
def identify(user_id, traits \\ %{}, context \\ Context.new()) do
@spec identify(atom(), segment_id(), map(), Segment.Analytics.Context.t()) :: :ok
def identify(source_name, user_id, traits \\ %{}, context \\ Context.new()) do
%Identify{userId: user_id, traits: traits, context: context}
|> call
|> call(source_name)
end

@doc """
Expand All @@ -77,56 +77,56 @@ defmodule Segment.Analytics do

See [https://segment.com/docs/spec/screen/](https://segment.com/docs/spec/screen/)
"""
@spec screen(Segment.Analytics.Screen.t()) :: :ok
def screen(s = %Screen{}) do
call(s)
@spec screen(atom(), Segment.Analytics.Screen.t()) :: :ok
def screen(source_name, s = %Screen{}) do
call(s, source_name)
end

@doc """
`screen` let you record whenever a user sees a screen of your mobile app. `screen/4` takes a `user_id`, an optional `screen_name`, optional `properties` and an optional `Segment.Analytics.Context` struct.

See [https://segment.com/docs/spec/screen/](https://segment.com/docs/spec/screen/)
"""
@spec screen(segment_id(), String.t(), map(), Segment.Analytics.Context.t()) :: :ok
def screen(user_id, screen_name \\ "", properties \\ %{}, context \\ Context.new()) do
@spec screen(atom(), segment_id(), String.t(), map(), Segment.Analytics.Context.t()) :: :ok
def screen(source_name, user_id, screen_name \\ "", properties \\ %{}, context \\ Context.new()) do
%Screen{
userId: user_id,
name: screen_name,
properties: properties,
context: context
}
|> call
|> call(source_name)
end

@doc """
`alias` is how you associate one identity with another with properties defined in the `Segment.Analytics.Alias` struct

See [https://segment.com/docs/spec/alias/](https://segment.com/docs/spec/alias/)
"""
@spec alias(Segment.Analytics.Alias.t()) :: :ok
def alias(a = %Alias{}) do
call(a)
@spec alias(atom(), Segment.Analytics.Alias.t()) :: :ok
def alias(source_name, a = %Alias{}) do
call(a, source_name)
end

@doc """
`alias` is how you associate one identity with another. `alias/3` takes a `user_id` and a `previous_id` to map from. It also takes an optional `Segment.Analytics.Context` struct.

See [https://segment.com/docs/spec/alias/](https://segment.com/docs/spec/alias/)
"""
@spec alias(segment_id(), segment_id(), Segment.Analytics.Context.t()) :: :ok
def alias(user_id, previous_id, context \\ Context.new()) do
@spec alias(atom(), segment_id(), segment_id(), Segment.Analytics.Context.t()) :: :ok
def alias(source_name, user_id, previous_id, context \\ Context.new()) do
%Alias{userId: user_id, previousId: previous_id, context: context}
|> call
|> call(source_name)
end

@doc """
The `group` call is how you associate an individual user with a group with the properties in the defined in the `Segment.Analytics.Group` struct

See [https://segment.com/docs/spec/group/](https://segment.com/docs/spec/group/)
"""
@spec group(Segment.Analytics.Group.t()) :: :ok
def group(g = %Group{}) do
call(g)
@spec group(atom(), Segment.Analytics.Group.t()) :: :ok
def group(source_name, g = %Group{}) do
call(g, source_name)
end

@doc """
Expand All @@ -135,35 +135,35 @@ defmodule Segment.Analytics do

See [https://segment.com/docs/spec/group/](https://segment.com/docs/spec/group/)
"""
@spec group(segment_id(), segment_id(), map(), Segment.Analytics.Context.t()) :: :ok
def group(user_id, group_id, traits \\ %{}, context \\ Context.new()) do
@spec group(atom(), segment_id(), segment_id(), map(), Segment.Analytics.Context.t()) :: :ok
def group(source_name, user_id, group_id, traits \\ %{}, context \\ Context.new()) do
%Group{userId: user_id, groupId: group_id, traits: traits, context: context}
|> call
|> call(source_name)
end

@doc """
The `page` call lets you record whenever a user sees a page of your website with the properties defined in the `Segment.Analytics.Page` struct

See [https://segment.com/docs/spec/page/](https://segment.com/docs/spec/page/)
"""
@spec page(Segment.Analytics.Page.t()) :: :ok
def page(p = %Page{}) do
call(p)
@spec page(atom(), Segment.Analytics.Page.t()) :: :ok
def page(source_name, p = %Page{}) do
call(p, source_name)
end

@doc """
The `page` call lets you record whenever a user sees a page of your website. `page/4` takes a `user_id` and an optional `page_name`, optional `properties` and an optional `Segment.Analytics.Context` struct.

See [https://segment.com/docs/spec/page/](https://segment.com/docs/spec/page/)
"""
@spec page(segment_id(), String.t(), map(), Segment.Analytics.Context.t()) :: :ok
def page(user_id, page_name \\ "", properties \\ %{}, context \\ Context.new()) do
@spec page(atom(), segment_id(), String.t(), map(), Segment.Analytics.Context.t()) :: :ok
def page(source_name, user_id, page_name \\ "", properties \\ %{}, context \\ Context.new()) do
%Page{userId: user_id, name: page_name, properties: properties, context: context}
|> call
|> call(source_name)
end

@spec call(Segment.segment_event()) :: :ok
def call(event) do
Segment.Config.service().call(event)
@spec call(Segment.segment_event(), atom()) :: :ok
def call(event, source_name) do
Segment.Config.service().call(event, source_name)
end
end
Loading