SFDCQuery

Query Salesforce data easily formatting and viewing the data as you want!

Installation

def deps do
  [
    {:sdfc_query, "~> 0.1.0"}
  ]
end

Using

For querying Salesforce using SFDCQuery library, you will need to define a Client and later, you can parse or print the query response

Default Client

SFDCQuery implements SFDCQuery.Client.Default which allow to your application pass the follow args:

  • instance_url
  • access_token
  • version
  • logs

In case of any of those args are not passed to the function create/1, it'll get the values from the environment variables:

  • SFDC_QUERY_INSTANCE_URL
  • SFDC_QUERY_ACCESS_TOKEN
  • SFDC_QUERY_VERSION
  • SFDC_QUERY_LOGS_ENABLED

SFDCQuery.Client.Default.create(%{
  instance_url: "https://sfdc_query.my.salesforce.com",
  access_token: "MY ACCESS TOKEN",
  version: "60.0",
  logs: true
})

%SFDCQuery.Config{
  instance_url: "https://sfdc_query.my.salesforce.com",
  access_token: "MY ACCESS TOKEN",
  version: "60.0",
  logs: true
}

Building your own Client

SFDCQuery defines the behaviour SFDCQuery.Client.Behaviour allowing you to implement your own Client. It allows you build the Client config following the requirements of your project

defmodule MyApp.CustomerSFDCClient do
  @behaviour SFDCQuery.Client.Behaviour

  alias SFDCQuery.Config

  alias MyApp.Ecto

  import Ecto.Query

  @impl true
  def create(customer_id) do
    credentials = from(c in Credentials, where: c.customer_id == ^customer_id) |> Repo.one()

    Config.new(%{
      instance_url: credentials.salesforce_instance_url,
      access_token: credentials.salesforce_access_token,
      version: credentials.salesforce_version,
      logs: false
    })
  end
end

Querying Salesforce

Having a Client, now you need to write the SOQL to query the Salesforce

SFDCQuery.Client.Default.create(args)
|> SFDCQuery.query("SELECT Id, Name, Website From Account LIMIT 3")

{:ok,
 %SFDCQuery.Query{
   soql: "SELECT Id, Name, Website From Account LIMIT 3",
   fields: ["Id", "Name", "Website"],
   records: [
     %{
       attributes: %{
         "type" => "Account",
         "url" => "/services/data/v60.0/sobjects/Account/001U8000005CeutIAC"
       },
       Name: "Page",
       Id: "001U8000005CeutIAC",
       Website: nil
     },
     %{
       attributes: %{
         "type" => "Account",
         "url" => "/services/data/v60.0/sobjects/Account/001U8000005cJN0IAM"
       },
       Name: "Nike",
       Id: "001U8000005cJN0IAM",
       Website: "https://www.nike.com/"
     },
     %{
       attributes: %{
         "type" => "Account",
         "url" => "/services/data/v60.0/sobjects/Account/001U8000005cRAnIAM"
       },
       Name: "Google",
       Id: "001U8000005cRAnIAM",
       Website: "google.com"
     }
   ]
 }}

Parsing the response

Map

SFDCQuery.Client.Default.create(args)
|> SFDCQuery.query("SELECT Id, Name, Website From Account LIMIT 3")
|> SFDCQuery.Parser.Map.parse()

{:ok,
 [
    %{
      attributes: %{
        "type" => "Account",
        "url" => "/services/data/v60.0/sobjects/Account/001U8000005CeutIAC"
      },
      Name: "Page",
      Id: "001U8000005CeutIAC",
      Website: nil
    },
    %{
      attributes: %{
        "type" => "Account",
        "url" => "/services/data/v60.0/sobjects/Account/001U8000005cJN0IAM"
      },
      Name: "Nike",
      Id: "001U8000005cJN0IAM",
      Website: "https://www.nike.com/"
    },
    %{
      attributes: %{
        "type" => "Account",
        "url" => "/services/data/v60.0/sobjects/Account/001U8000005cRAnIAM"
      },
      Name: "Google",
      Id: "001U8000005cRAnIAM",
      Website: "google.com"
    }
  ]
}

JSON

SFDCQuery.Client.Default.create(args)
|> SFDCQuery.query("SELECT Id, Name, Website From Account LIMIT 3")
|> SFDCQuery.Parser.JSON.parse()

{:ok, "[{\"attributes\":{\"type\":\"Account\",\"url\":\"/services/data/v60.0/sobjects/Account/001U8000005CeutIAC\"},\"Name\":\"Page\",\"Id\":\"001U8000005CeutIAC\",\"Website\":null},{\"attributes\":{\"type\":\"Account\",\"url\":\"/services/data/v60.0/sobjects/Account/001U8000005cJN0IAM\"},\"Name\":\"Nike\",\"Id\":\"001U8000005cJN0IAM\",\"Website\":\"https://www.nike.com/\"},{\"attributes\":{\"type\":\"Account\",\"url\":\"/services/data/v60.0/sobjects/Account/001U8000005cRAnIAM\"},\"Name\":\"Google\",\"Id\":\"001U8000005cRAnIAM\",\"Website\":\"google.com\"}]"}

CSV

SFDCQuery.Client.Default.create(args)
|> SFDCQuery.query("SELECT Id, Name, Website From Account LIMIT 3")
|> SFDCQuery.Parser.CSV.parse()

{:ok, "Id,Name,Website\n001U8000005CeutIAC,Page,\n001U8000005cJN0IAM,Nike,https://www.nike.com/\n001U8000005cRAnIAM,Google,google.com"}

Building your own Parser

You can build your own parser using the behaviour SFDCQuery.Parser.Behaviour

defmodule MyApp.SFDCParser do
  @behaviour SFDCQuery.Parser.Behaviour

  alias SFDCQuery.Query

  @impl true
  def parse({:error, _} = error), do: error
  def parse({:ok, %Query{records: records}}), do: {:ok, parse_records(records)}
end

Viewing the response

When debugging an Salesforce instance, it's useful to see the data in a view. To allow this, SFDCQuery allow to see the response in the terminal.

Table

SFDCQuery.Client.Default.create(args)
|> SFDCQuery.query("SELECT Id, Name, Website From Account LIMIT 3")
|> SFDCQuery.View.Table.show()

SELECT Id, Name, Website From Account LIMIT 3
-------------------------------------------------------
| Id                 | Name   | Website               |
-------------------------------------------------------
| 001U8000005CeutIAC | Page   |                       |
| 001U8000005cJN0IAM | Nike   | https://www.nike.com/ |
| 001U8000005cRAnIAM | Google | google.com            |

JSON

SFDCQuery.Client.Default.create(args)
|> SFDCQuery.query("SELECT Id, Name, Website From Account LIMIT 3")
|> SFDCQuery.View.JSON.show()

SELECT Id, Name, Website From Account LIMIT 3
-------------------------------------------------------
[
  {
    "attributes": {
      "type": "Account",
      "url": "/services/data/v60.0/sobjects/Account/001U8000005CeutIAC"
    },
    "Name": "Page",
    "Id": "001U8000005CeutIAC",
    "Website": null
  },
  {
    "attributes": {
      "type": "Account",
      "url": "/services/data/v60.0/sobjects/Account/001U8000005cJN0IAM"
    },
    "Name": "Nike",
    "Id": "001U8000005cJN0IAM",
    "Website": "https://www.nike.com/"
  },
  {
    "attributes": {
      "type": "Account",
      "url": "/services/data/v60.0/sobjects/Account/001U8000005cRAnIAM"
    },
    "Name": "Google",
    "Id": "001U8000005cRAnIAM",
    "Website": "google.com"
  }
]

CSV

SFDCQuery.Client.Default.create(args)
|> SFDCQuery.query("SELECT Id, Name, Website From Account LIMIT 3")
|> SFDCQuery.View.CSV.show()

SELECT Id, Name, Website From Account LIMIT 3
-------------------------------------------------------
Id,Name,Website
001U8000005CeutIAC,Page,
001U8000005cJN0IAM,Nike,https://www.nike.com/
001U8000005cRAnIAM,Google,google.com

Building your own View

You can build your own view using the behaviour SFDCQuery.View.Behaviour

defmodule MyApp.SFDCHTMLView do
  @behaviour SFDCQuery.View.Behaviour

  alias SFDCQuery.Query

  @impl true
  def show({:error, _} = error), do: error

  def show({:ok, %Query{records: records}}) do
    build_records_html(records)

    :ok
  end
end