Working with the Salesforce API

Anyone have experience using Salesforce API in Elixir? Am trying to integrate their REST API and streaming API. jeffweiss/forcex looks like a nice start on the REST API — are there others I’m not seeing? Open to just rolling something on my own.

Any tips/cautions would be greatly appreciated.

1 Like

Looks like a good start in that library. The only thing you should be aware that it’s not fully finished. There is a list with REST endpoints which are not implemented into library yet.

1 Like

I also found chulkilee/ex_force. It’s brand new which I guess is why it didn’t turn up in my initial web search. The code looks well written and tested — think I’m going to give it a try.

2 Likes

Hey! Care to share what you ended up using?

1 Like

I’m currently using ex_force for my Salesforce REST API integrations. It’s using an up to date version of Tesla (http client), works with Jason, and I’ve found it pretty straightforward to use. Currently have a separate module for Auth concerns and some basic caching using Cachex for tokens and metadata like record type ids.

4 Likes

do you have an example on how you set up your connected app, and Auth currently im trying to implement this and am getting an authentication failure im just trying to run a simple query from a module i created

defmodule Db.Sf do

  @moduledoc """

  Documentation for Db.

  """

  def connect(opts \\ []) do

    opts = build_opts(opts)

    IO.inspect(opts, label: "opts:")

    response =

      ExForce.OAuth.get_token(

        opts[:url],

        grant_type: opts[:grant_type],

        client_id: opts[:client_id],

        client_secret: opts[:client_secret],

        username: opts[:username],

        password: opts[:password]

      )

    case response do

      {:error, response} ->

        exit(response["error_description"])

      {:ok, oauth_response} ->

        %{instance_url: instance_url} = oauth_response

        {:ok, version_maps} = ExForce.versions(instance_url)

        latest_version = version_maps |> Enum.map(&Map.fetch!(&1, "version")) |> List.last()

        ExForce.build_client(oauth_response, api_version: latest_version)

    end

  end

  def fetch_appointments() do

    client = connect()

    ExForce.query_stream(

      client,

      "SELECT Name FROM xxx__c WHERE CreatedDate = TODAY"

    )

    |> Stream.map(&Map.fetch!(&1.data, "Name"))

    |> Stream.take(50)

    |> Enum.to_list()

  end

  defp build_opts(opts) do

    system_opts = [

      url: System.get_env("PLATFORM_SF_LOGIN_URL"),

      grant_type: System.get_env("PLATFORM_SF_GRANT_TYPE"),

      client_id: System.get_env("PLATFORM_SF_CLIENT_ID"),

      client_secret: System.get_env("PLATFORM_SF_CLIENT_SECRET"),

      password: System.get_env("PLATFORM_SF_PASSWORD"),

      username: System.get_env("PLATFORM_SF_USERNAME")

    ]

    system_opts

    |> remove_empty_opts()

    |> merge_opts(opts)

  end

  defp merge_opts(system_opts, opts) do

    Keyword.merge(opts, system_opts)

  end

  defp remove_empty_opts(system_opts) do

    Enum.reject(system_opts, fn {_k, value} -> is_nil(value) end)

  end

end