Current section
Files
Jump to
Current section
Files
lib/astrox/bulk/client.ex
defmodule Astrox.Bulk.Client do
defstruct session_id: nil,
api_version: "43.0",
endpoint: "https://login.salesforce.com",
host: nil
require Logger
@doc """
Initially signs into Force.com Bulk API.
Login credentials may be supplied. Order for locating credentials:
1. Map supplied to `login/1`
2. Environment variables
3. Applications configuration
Supplying a Map of login credentials must be in the form of
%{
username: "...",
password: "...",
security_token: "..."
}
Environment variables
- `SALESFORCE_USERNAME`
- `SALESFORCE_PASSWORD`
- `SALESFORCE_SECURITY_TOKEN`
Application configuration
config :astrox, Astrox.Bulk.Client,
username: "user@example.com",
password: "my_super_secret_password",
security_token: "EMAILED_FROM_SALESFORCE"
Will require additional call to `locate_services/1` to identify which Force.com
services are availabe for your deployment.
client = Astrox.Bulk.Client.login
"""
def login(c \\ default_config()) do
login(c, %__MODULE__{})
end
def login(conf, starting_struct) do
envelope = """
<?xml version="1.0" encoding="utf-8" ?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Body>
<n1:login xmlns:n1="urn:partner.soap.sforce.com">
<n1:username>#{conf.username}</n1:username>
<n1:password>#{conf.password}#{conf.security_token}</n1:password>
</n1:login>
</env:Body>
</env:Envelope>
"""
headers = [
{"Content-Type", "text/xml; charset=UTF-8"},
{"SOAPAction", "login"}
]
HTTPoison.post!(
"#{starting_struct.endpoint}/services/Soap/u/#{starting_struct.api_version}",
envelope,
headers
)
|> parse_login_response
end
defp parse_login_response(%HTTPoison.Response{body: body, status_code: 200}) do
{:ok,
{'{http://schemas.xmlsoap.org/soap/envelope/}Envelope', _,
[
{'{http://schemas.xmlsoap.org/soap/envelope/}Body', _,
[
{'{urn:partner.soap.sforce.com}loginResponse', _,
[
{'{urn:partner.soap.sforce.com}result', _, login_parameters}
]}
]}
]}, _} = :erlsom.simple_form(body)
server_url = extract_from_parameters(login_parameters, :serverUrl)
session_id = extract_from_parameters(login_parameters, :sessionId)
%__MODULE__{session_id: session_id, host: server_url |> URI.parse() |> Map.get(:host)}
end
defp extract_from_parameters(params, key) do
compound_key = "{urn:partner.soap.sforce.com}#{key}" |> to_charlist
{^compound_key, _, [value]} = :lists.keyfind(compound_key, 1, params)
value |> to_string
end
def default_config() do
[:username, :password, :security_token]
|> Enum.map(&{&1, get_val_from_env(&1)})
|> Enum.into(%{})
end
defp get_val_from_env(key) do
key
|> env_var
|> System.get_env()
|> case do
nil ->
Application.get_env(:astrox, __MODULE__, [])
|> Keyword.get(key)
val ->
val
end
end
defp env_var(key), do: "SALESFORCE_#{key |> to_string |> String.upcase()}"
end