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

I’d also be curious if you were able to integrate with salesforce streaming API.

Based on this discussion ending in April 2019, their aren’t many options. In that thread, they reference two libraries, both of which appear unmaintained. I bet with a week of love, either of those libraries could be made current and be fine.

What was your mileage?

2 Likes

Anyone has any solution that works as of summer 2023? :slight_smile:

1 Like

What’s the difficulty? Rolling your own API client in Elixir is a matter of a day or two of work (well, excluding tests).

usually yes, but I somehow struggle with SF in particular right now, which I want to query from a livebook (it contains _part of _ important business information). this multifactor and token exchange thingy is driving me nuts right now

Oh I see, there are multiple steps before authentication. Yeah, that can be nasty.

Well… might be a good opportunity for you to devise and open-source it then!

2 Likes