defmodule BufferAPI do alias BufferApi.Client @doc """ Returns the authorized user ## Examples iex> BufferApi.get_user(%BufferApi.Client{...}) %BufferAPI.User{ ... } """ def get_user(%Client{api_url: api_url, access_token: access_token}) do case HTTPoison.get("#{api_url}/user.json?access_token=#{access_token}") do {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> user = body |> Jason.decode!() |> to_struct(BufferAPI.User) {:ok, user} {:ok, %HTTPoison.Response{body: body}} -> error = Jason.decode!(body) {:error, error["error"]} end end def get_user!(client = %Client{}) do {:ok, user} = get_user(client) user end @doc """ Returns an array of social media profiles connected to the authorized user's account ## Examples iex> BufferApi.get_profiles(%BufferApi.Client{...}) [ %BufferAPI.Profile{ ... } ] """ def get_profiles(%Client{api_url: api_url, access_token: access_token}) do case HTTPoison.get("#{api_url}/profiles.json?access_token=#{access_token}") |> IO.inspect() do {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> profiles = body |> Jason.decode!() |> Enum.map(fn profile -> to_struct(profile, BufferAPI.Profile) end) {:ok, profiles} {:ok, %HTTPoison.Response{body: body}} -> error = Jason.decode!(body) {:error, error["error"]} end end def get_profiles!(client = %Client{}) do {:ok, profiles} = get_profiles(client) profiles end @doc """ Returns a social media profile by it's ID ## Examples iex> BufferApi.get_profile(id, %BufferApi.Client{...}) %BufferAPI.Profile{ ... } """ def get_profile(id, %Client{api_url: api_url, access_token: access_token}) do case HTTPoison.get("#{api_url}/profiles/#{id}.json?access_token=#{access_token}") do {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> profile = body |> Jason.decode!() |> to_struct(BufferAPI.Profile) {:ok, profile} {:ok, %HTTPoison.Response{body: body}} -> error = Jason.decode!(body) {:error, error["error"]} end end def get_profile!(id, client = %Client{}) do {:ok, profile} = get_profile(id, client) profile end @doc """ Returns details of the posting schedules associated with a social media profile. ## Examples iex> BufferApi.get_schedules(profile_id, %BufferApi.Client{...}) [ %BufferAPI.Schedule{ days: ["fri", "sat", "sun"], times: ["12:00", "17:00"] } ] """ def get_schedules(profile_id, %Client{api_url: api_url, access_token: access_token}) do case HTTPoison.get( "#{api_url}/profiles/#{profile_id}/schedules.json?access_token=#{access_token}" ) do {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> schedules = body |> Jason.decode!() |> Enum.map(fn schedule -> to_struct(schedule, BufferAPI.Schedule) end) {:ok, schedules} {:ok, %HTTPoison.Response{body: body}} -> error = Jason.decode!(body) {:error, error["error"]} end end @doc """ Create a new status update for one or more profiles ## Examples iex> BufferApi.get_update("000000000000000000000000", %BufferApi.Client{...}) %BufferAPI.Update{ id: "000000000000000000000000", ... } """ def get_update(id, %Client{api_url: api_url, access_token: access_token}) do case HTTPoison.get("#{api_url}/#{id}.json?access_token=#{access_token}") do {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> update = Jason.decode!(body) {:ok, update} {:ok, %HTTPoison.Response{body: body}} -> error = Jason.decode!(body) {:error, error["error"]} end end def get_update!(id, client = %Client{}) do {:ok, update} = get_update(id, client) update end @doc """ Returns a single social media update. ## Params - profile_ids required [array] An array of Buffer profile id's that the status update should be sent to. Invalid profile_id's will be silently ignored - text optional string The status update text - attachment optional boolean In the absence of the media parameter, attachment controls whether a link the in `text` should automatically populate the `media` parameter. Defaults to `true` ## TODO Add optional buffering params ## Examples iex> BufferApi.create_update("000000000000000000000000", "1111111111111", %BufferApi.Client{...}) %BufferAPI.Update{ id: "000000000000000000000000", ... } """ def create_update(text, profile_ids, media_props \\ %{}, %Client{ api_url: api_url, access_token: access_token }) do media = media_props |> Enum.map(fn {key, value} -> {"media[#{key}]", value} end) |> Enum.into(%{}) body = %{ "access_token" => access_token, "attachment" => false, "now" => false, "profile_ids[]" => profile_ids, "shorten" => true, "text" => text, "top" => false } |> Map.merge(media) |> URI.encode_query() headers = [ {"Content-Type", "application/x-www-form-urlencoded"} ] case HTTPoison.post("#{api_url}/updates/create.json", body, headers) do {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> update = Jason.decode!(body) {:ok, update} {:ok, %HTTPoison.Response{body: body}} -> {:error, body} end end @doc """ Returns an array of updates that are currenlty in the buffer for an individual profile. ## Examples iex> BufferApi.get_pending_updates("000000000000000000000000", %BufferApi.Client{...}) [ %BufferAPI.Update{ id: "000000000000000000000000", ... }, ... ] """ def get_pending_updates(profile_id, %Client{api_url: api_url, access_token: access_token}) do case HTTPoison.get( "#{api_url}/profiles/#{profile_id}/updates/pending.json?access_token=#{access_token}" ) do {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> updates = body |> Jason.decode!() |> Enum.map(fn update -> to_struct(update, BufferAPI.Update) end) {:ok, updates} {:ok, %HTTPoison.Response{body: body}} -> error = Jason.decode!(body) {:error, error["error"]} end end @doc """ Returns an array of updates that have been sent from an individual profile. ## Examples iex> BufferApi.get_sent_updates("000000000000000000000000", %BufferApi.Client{...}) [ %BufferAPI.Update{ id: "000000000000000000000000", ... }, ... ] """ def get_sent_updates(profile_id, %Client{api_url: api_url, access_token: access_token}) do case HTTPoison.get( "#{api_url}/profiles/#{profile_id}/updates/sent.json?access_token=#{access_token}" ) do {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> updates = body |> Jason.decode!() |> Enum.map(fn update -> to_struct(update, BufferAPI.Update) end) {:ok, updates} {:ok, %HTTPoison.Response{body: body}} -> error = Jason.decode!(body) {:error, error["error"]} end end defp to_struct(attrs, kind) do struct = struct(kind) Enum.reduce(Map.to_list(struct), struct, fn {k, _}, acc -> case Map.fetch(attrs, Atom.to_string(k)) do {:ok, v} -> %{acc | k => v} :error -> acc end end) end end