Current section
Files
Jump to
Current section
Files
lib/intercom/user.ex
defmodule Intercom.User do
@moduledoc """
Users are the primary way of interacting with the Intercom API. If you know a
user's ID you can easily fetch their data.
```elixir
{:ok, %Intercom.User{} = user} = Intercom.User.get("530370b477ad7120001d")
```
You can also look them up using the `user_id` your system assigned to them
when creating the user record, or alternatively, via their email address.
```elixir
{:ok, %Intercom.User{}} = Intercom.User.find({:user_id, 25})
{:ok, %Intercom.User{}} = Intercom.User.find({:email, "wash@serenity.io"})
```
If the user cannot be found you will get `{:error, :not_found}`. If your
token doesn't have sufficient permissions to access a resource the return
value will be `{:error, :not_authorised}`.
"""
use Ecto.Schema
import Ecto.Changeset
alias Intercom.{Location, Avatar, Company, SocialProfile, Segment,
Tag, Request, HTTP}
alias __MODULE__
@path "/users"
@primary_key false
embedded_schema do
field :type, :string
field :id, :string
field :user_id, :string
field :email, :string
field :phone, :string
field :name, :string
field :updated_at, :integer
field :last_seen_ip, :string
field :unsubscribed_from_emails, :boolean
field :last_request_at, :integer
field :signed_up_at, :integer
field :created_at, :integer
field :session_count, :integer
field :user_agent_data, :string
field :pseudonym, :string
field :anonymous, :boolean
embeds_one :location, Location
embeds_one :avatar, Avatar
embeds_many :companies, Company
embeds_many :social_profiles, SocialProfile
embeds_many :segments, Segment
embeds_many :tags, Tag
end
@type t :: %__MODULE__{}
@type result :: {:ok, User.t} | {:error, :not_found} |
{:error, :not_authorised} | {:error, any}
@doc """
Fetches a user by their Intercom ID.
"""
@spec get(String.t) :: result
def get(id) when is_binary(id) do
"#{@path}/#{id}"
|> Request.build
|> HTTP.get
|> case do
{:ok, map} -> parse(map)
{:error, {:http, 404}} -> {:error, :not_found}
{:error, {:http, 401}} -> {:error, :not_authorised}
{:error, _} = err -> err
end
end
@doc """
Look up a user by their assigned user ID or email address.
"""
@spec find({:user_id | :email, String.t}) :: result
def find({:user_id, user_id}) when is_binary(user_id) do
@path
|> Request.build(%{user_id: user_id})
|> HTTP.get
|> case do
{:ok, map} -> parse(map)
{:error, {:http, 404}} -> {:error, :not_found}
{:error, {:http, 401}} -> {:error, :not_authorised}
{:error, _} = err -> err
end
end
def find({:email, email}) do
@path
|> Request.build(%{email: email})
|> HTTP.get
|> case do
{:ok, map} -> parse(map)
{:error, {:http, 404}} -> {:error, :not_found}
{:error, {:http, 401}} -> {:error, :not_authorised}
{:error, _} = err -> err
end
end
@doc false
@spec changeset(User.t, map) :: Ecto.Changeset.t
def changeset(%User{} = user, %{} = changes) do
user
|> cast(changes, __schema__(:fields) -- __schema__(:embeds))
|> cast_embed(:location, with: &Location.changeset/2)
|> cast_embed(:avatar, with: &Avatar.changeset/2)
|> cast_embed(:social_profiles, with: &SocialProfile.changeset/2)
|> cast_embed(:companies, with: &Company.changeset/2)
|> cast_embed(:segments, with: &Segment.changeset/2)
|> cast_embed(:tags, with: &Tag.changeset/2)
end
@doc false
@spec parse(map) :: result
def parse(%{} = user) do
{loc, user} = Map.pop(user, :location_data)
{%{social_profiles: profs}, user} = Map.pop(user, :social_profiles)
{%{companies: comps}, user} = Map.pop(user, :companies)
{%{segments: segs}, user} = Map.pop(user, :segments)
{%{tags: tags}, user} = Map.pop(user, :tags)
user =
user
|> Map.put(:location, loc)
|> Map.put(:social_profiles, profs)
|> Map.put(:companies, comps)
|> Map.put(:segments, segs)
|> Map.put(:tags, tags)
case changeset(%User{}, user) do
%Ecto.Changeset{valid?: true} = changes ->
{:ok, apply_changes(changes)}
%Ecto.Changeset{valid?: false} = changes ->
{:error, changes}
end
end
end