salesforce

package module
v0.0.0-...-e321a4e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 10, 2026 License: MIT Imports: 21 Imported by: 0

README

go-salesforce

A REST API wrapper for interacting with Salesforce using the Go programming language.

GoDoc Go Report Card codecov MIT License Mentioned in Awesome Go

Table of Contents

Installation

go get github.com/k-capehart/go-salesforce/v3

Types

type Salesforce struct {
    auth   *authentication
    config configuration
}

type configuration struct {
    compressionHeaders           bool
    apiVersion                   string
    batchSizeMax                 int
    bulkBatchSizeMax             int
    httpClient                   *http.Client
    roundTripper                 http.RoundTripper
    shouldValidateAuthentication bool
    httpTimeout                  time.Duration
}

type Creds struct {
    Domain         string
    Username       string
    Password       string
    SecurityToken  string
    ConsumerKey    string
    ConsumerSecret string
    ConsumerRSAPem string
    AccessToken    string
}

type SalesforceResults struct {
    Results             []SalesforceResult
    HasSalesforceErrors bool
}

type SalesforceResult struct {
    Id      string
    Errors  []SalesforceErrorMessage
    Success bool
}

type SalesforceErrorMessage struct {
    Message    string
    StatusCode string
    Fields     []string
}

type BulkJobResults struct {
    Id                  string
    State               string
    NumberRecordsFailed int
    ErrorMessage        string
    SuccessfulRecords   []map[string]any
    FailedRecords       []map[string]any
}
Salesforce tag
  • tag struct fields with the salesforce tag to decode them into their Salesforce API field names
type Account struct {
    ExternalID string `salesforce:"ExternalId__c"`
    Name       string
}

Authentication

Init

func Init(creds Creds, options ...Option) *Salesforce

Returns a new Salesforce instance given a user's credentials.

  • creds: a struct containing the necessary credentials to authenticate into a Salesforce org
  • options: optional configuration - see Configuration
  • If an operation fails with the Error Code INVALID_SESSION_ID, go-salesforce will attempt to refresh the session by resubmitting the same credentials used during initialization
  • Configuration values are set to the defaults if not specified

Client Credentials Flow

sf, err := salesforce.Init(salesforce.Creds{
    Domain:         DOMAIN, // ex: https://myslug.my.salesforce.com
    ConsumerKey:    CONSUMER_KEY,
    ConsumerSecret: CONSUMER_SECRET,
})

Username-Password Flow

sf, err := salesforce.Init(salesforce.Creds{
    Domain:         DOMAIN,
    Username:       USERNAME,
    Password:       PASSWORD,
    SecurityToken:  SECURITY_TOKEN,
    ConsumerKey:    CONSUMER_KEY,
    ConsumerSecret: CONSUMER_SECRET,
})

JWT Bearer Flow

sf, err := salesforce.Init(salesforce.Creds{
    Domain:         DOMAIN,
    Username:       USERNAME,
    ConsumerKey:    CONSUMER_KEY,
    ConsumerRSAPem: CONSUMER_RSA_PEM,
})

Authenticate with an Access Token

  • Implement your own OAuth flow and use the resulting access_token from the response to initialize go-salesforce
sf, err := salesforce.Init(salesforce.Creds{
    Domain:      DOMAIN,
    AccessToken: ACCESS_TOKEN,
})
GetAccessToken

func (sf *Salesforce) GetAccessToken() string

Returns the current session's Access Token as a string.

token := sf.GetAccessToken()
GetInstanceUrl

func (sf *Salesforce) GetInstanceUrl() string

Returns the current session's Instance URL as a string.

url := sf.GetInstanceUrl()
GetAuthFlow

func (sf *Salesforce) GetAuthFlow() AuthFlowType

Returns the auth flow used for authentication.

authType := sf.GetAuthFlow()

Configuration

Configure optional parameters for your Salesforce instance

Optional configuration:

  • func WithCompressionHeaders(compression bool) Option - see docs
  • func WithAPIVersion(version string) Option - set API version manually instead of using default
  • func WithBatchSizeMax(size int) - for collections API
  • func WithBulkBatchSizeMax(size int) Option - for Bulk API
  • func WithBulkPollTimeout(timeout time.Duration) Option - set max wait when polling bulk results with waitForResults=true
  • func WithRoundTripper(rt http.RoundTripper) Option - for http requests
  • func WithHTTPTimeout(timeout time.Duration) Option - set custom timeout
  • func WithValidateAuthentication(validate bool) Option - optionally skip validation during certain auth flows

Get configuration:

  • func (sf *Salesforce) GetAPIVersion() string
  • func (sf *Salesforce) GetBatchSizeMax() int
  • func (sf *Salesforce) GetBulkBatchSizeMax() int
  • func (sf *Salesforce) GetCompressionHeaders() bool
  • func (sf *Salesforce) GetHTTPClient() *http.Client

See HTTP_CLIENT_CONFIG for additional documentation on round trippers

See examples/functional-config and examples/http-config for usage

See WithHeader for custom header options

SOQL

Query Salesforce records

Query

func (sf *Salesforce) Query(query string, sObject any) error

Performs a SOQL query given a query string and decodes the response into the given struct

  • query: a SOQL query
  • sObject: a slice of a custom struct type representing a Salesforce Object
type Contact struct {
    Id       string
    LastName string
}
contacts := []Contact{}
err := sf.Query("SELECT Id, LastName FROM Contact WHERE LastName = 'Lee'", &contacts)
QueryStruct

func (sf *Salesforce) QueryStruct(soqlStruct any, sObject any) error

Performs a SOQL query given a go-soql struct and decodes the response into the given struct

  • soqlStruct: a custom struct using soql tags
  • sObject: a slice of a custom struct type representing a Salesforce Object
  • Review forcedotcom/go-soql
    • Eliminates need to separately maintain query string and struct
    • Helps prevent SOQL injection
type Contact struct {
    Id       string `soql:"selectColumn,fieldName=Id" json:"Id"`
    LastName string `soql:"selectColumn,fieldName=LastName" json:"LastName"`
}

type ContactQueryCriteria struct {
    LastName string `soql:"equalsOperator,fieldName=LastName"`
}

type ContactSoqlQuery struct {
    SelectClause Contact              `soql:"selectClause,tableName=Contact"`
    WhereClause  ContactQueryCriteria `soql:"whereClause"`
}
soqlStruct := ContactSoqlQuery{
    SelectClause: Contact{},
    WhereClause: ContactQueryCriteria{
        LastName: "Lee",
    },
}
contacts := []Contact{}
err := sf.QueryStruct(soqlStruct, &contacts)
Handling Relationship Queries

When querying Salesforce objects, it's common to access fields that are related through parent-child or lookup relationships. For instance, querying Account.Name with related Contact might look like this:

type Account struct {
    Name string
}

type Contact struct {
    Id       string
    Account Account
}

contacts := []Contact{}
sf.Query("SELECT Id, Account.Name FROM Contact", &contacts)

DML

Note that any DML operation that includes an uninitialized struct field, or 0 or null value, will effectively be treated as passing a null value to Salesforce.

type Contact struct {
    Id        string
    LastName  string
    FirstName string
}

contact := Contact{
    Id:       "003Dn00000pEYQSIA4",
    LastName: "Banner",
}
err = sf.UpdateOne("Contact", contact) // will update the FirstName of the contact to an empty string ""

SObject Single Record Operations

Insert, Update, Upsert, or Delete one record at a time

InsertOne

func (sf *Salesforce) InsertOne(sObjectName string, record any) (SalesforceResult, error)

InsertOne inserts one salesforce record of the given type

  • sObjectName: API name of Salesforce object
  • record: a Salesforce object record
type Contact struct {
    LastName string
}
contact := Contact{
    LastName: "Stark",
}
result, err := sf.InsertOne("Contact", contact)
UpdateOne

func (sf *Salesforce) UpdateOne(sObjectName string, record any) error

Updates one salesforce record of the given type

  • sObjectName: API name of Salesforce object
  • record: a Salesforce object record
    • An Id is required
type Contact struct {
    Id       string
    LastName string
}
contact := Contact{
    Id:       "003Dn00000pEYQSIA4",
    LastName: "Banner",
}
err := sf.UpdateOne("Contact", contact)
UpsertOne

func (sf *Salesforce) UpsertOne(sObjectName string, externalIdFieldName string, record any) (SalesforceResult, error)

Updates (or inserts) one salesforce record using the given external Id

  • sObjectName: API name of Salesforce object
  • externalIdFieldName: field API name for an external Id that exists on the given object
  • record: a Salesforce object record
    • A value for the External Id is required
type Contact struct {
    ContactExternalId__c string
    LastName             string
}
contact := Contact{
    ContactExternalId__c: "Avng0",
    LastName:             "Rogers",
}
result, err := sf.UpsertOne("Contact", "ContactExternalId__c", contact)
DeleteOne

func (sf *Salesforce) DeleteOne(sObjectName string, record any) error

Deletes a Salesforce record

  • sObjectName: API name of Salesforce object
  • record: a Salesforce object record
    • Should only contain an Id
type Contact struct {
    Id       string
}
contact := Contact{
    Id: "003Dn00000pEYQSIA4",
}
err := sf.DeleteOne("Contact", contact)

SObject Collections

Insert, Update, Upsert, or Delete collections of records

  • Review Salesforce REST API resources for working with collections
  • Perform operations in batches of up to 200 records at a time
  • Consider making a Bulk request for very large operations
  • Partial successes are enabled
    • If a record fails then successes are still committed to the database
  • Will return an instance of SalesforceResults which contains information on each affected record and whether DML errors were encountered
InsertCollection

func (sf *Salesforce) InsertCollection(sObjectName string, records any, batchSize int) (SalesforceResults, error)

Inserts a list of salesforce records of the given type

  • sObjectName: API name of Salesforce object
  • records: a slice of salesforce records
  • batchSize: 1 <= batchSize <= 200
type Contact struct {
    LastName string
}
contacts := []Contact{
    {
        LastName: "Barton",
    },
    {
        LastName: "Romanoff",
    },
}
results, err := sf.InsertCollection("Contact", contacts, 200)
UpdateCollection

func (sf *Salesforce) UpdateCollection(sObjectName string, records any, batchSize int) (SalesforceResults, error)

Updates a list of salesforce records of the given type

  • sObjectName: API name of Salesforce object
  • records: a slice of salesforce records
    • An Id is required
  • batchSize: 1 <= batchSize <= 200
type Contact struct {
    Id       string
    LastName string
}
contacts := []Contact{
    {
        Id:       "003Dn00000pEfyAIAS",
        LastName: "Fury",
    },
    {
        Id:       "003Dn00000pEfy9IAC",
        LastName: "Odinson",
    },
}
results, err := sf.UpdateCollection("Contact", contacts, 200)
UpsertCollection

func (sf *Salesforce) UpsertCollection(sObjectName string, externalIdFieldName string, records any, batchSize int) (SalesforceResults, error)

Updates (or inserts) a list of salesforce records using the given ExternalId

  • sObjectName: API name of Salesforce object
  • externalIdFieldName: field API name for an external Id that exists on the given object
  • records: a slice of salesforce records
    • A value for the External Id is required
  • batchSize: 1 <= batchSize <= 200
type Contact struct {
    ContactExternalId__c string
    LastName             string
}
contacts := []Contact{
    {
        ContactExternalId__c: "Avng1",
        LastName:             "Danvers",
    },
    {
        ContactExternalId__c: "Avng2",
        LastName:             "Pym",
    },
}
results, err := sf.UpsertCollection("Contact", "ContactExternalId__c", contacts, 200)
DeleteCollection

func (sf *Salesforce) DeleteCollection(sObjectName string, records any, batchSize int) (SalesforceResults, error)

Deletes a list of salesforce records

  • sObjectName: API name of Salesforce object
  • records: a slice of salesforce records
    • Should only contain Ids
  • batchSize: 1 <= batchSize <= 200
type Contact struct {
    Id       string
}
contacts := []Contact{
    {
        Id: "003Dn00000pEfyAIAS",
    },
    {
        Id: "003Dn00000pEfy9IAC",
    },
}
results, err := sf.DeleteCollection("Contact", contacts, 200)

Composite Requests

Make numerous 'subrequests' contained within a single 'composite request', reducing the overall number of calls to Salesforce

  • Review Salesforce REST API resources for making composite requests
  • Up to 25 subrequests may be included in a single composite request
    • For DML operations, max number of records to be processed is determined by batch size (25 * (batch size))
    • So if batch size is 1, then max number of records to be included in request is 25
    • If batch size is 200, then max is 5000
  • If allOrNone is true, then records are only committed to database if everything succeeds
  • Will return an instance of SalesforceResults which contains information on each affected record and whether DML errors were encountered
InsertComposite

func (sf *Salesforce) InsertComposite(sObjectName string, records any, batchSize int, allOrNone bool) (SalesforceResults, error)

Inserts a list of salesforce records in a single request

  • sObjectName: API name of Salesforce object
  • records: a slice of salesforce records
  • batchSize: 1 <= batchSize <= 200
  • allOrNone: denotes whether to roll back entire operation if a record fails
type Contact struct {
    LastName string
}
contacts := []Contact{
    {
        LastName: "Parker",
    },
    {
        LastName: "Murdock",
    },
}
results, err := sf.InsertComposite("Contact", contacts, 200, true)
UpdateComposite

func (sf *Salesforce) UpdateComposite(sObjectName string, records any, batchSize int, allOrNone bool) (SalesforceResults, error)

Updates a list of salesforce records in a single request

  • sObjectName: API name of Salesforce object
  • records: a slice of salesforce records
    • An Id is required
  • batchSize: 1 <= batchSize <= 200
  • allOrNone: denotes whether to roll back entire operation if a record fails
type Contact struct {
    Id       string
    LastName string
}
contacts := []Contact{
    {
        Id:       "003Dn00000pEi32IAC",
        LastName: "Richards",
    },
    {
        Id:       "003Dn00000pEi31IAC",
        LastName: "Storm",
    },
}
results, err := sf.UpdateComposite("Contact", contacts, 200, true)
UpsertComposite

func (sf *Salesforce) UpsertComposite(sObjectName string, externalIdFieldName string, records any, batchSize int, allOrNone bool) (SalesforceResults, error)

Updates (or inserts) a list of salesforce records using the given ExternalId in a single request

  • sObjectName: API name of Salesforce object
  • externalIdFieldName: field API name for an external Id that exists on the given object
  • records: a slice of salesforce records
    • A value for the External Id is required
  • batchSize: 1 <= batchSize <= 200
  • allOrNone: denotes whether to roll back entire operation if a record fails
type Contact struct {
    ContactExternalId__c string
    LastName             string
}
contacts := []Contact{
    {
        ContactExternalId__c: "Avng3",
        LastName:             "Maximoff",
    },
    {
        ContactExternalId__c: "Avng4",
        LastName:             "Wilson",
    },
}
results, err := sf.UpsertComposite("Contact", "ContactExternalId__c", contacts, 200, true)
DeleteComposite

func (sf *Salesforce) DeleteComposite(sObjectName string, records any, batchSize int, allOrNone bool) (SalesforceResults, error)

Deletes a list of salesforce records in a single request

  • sObjectName: API name of Salesforce object
  • records: a slice of salesforce records
    • Should only contain Ids
  • batchSize: 1 <= batchSize <= 200
  • allOrNone: denotes whether to roll back entire operation if a record fails
type Contact struct {
    Id       string
}
contacts := []Contact{
    {
        Id: "003Dn00000pEi0OIAS",
    },
    {
        Id: "003Dn00000pEi0NIAS",
    },
}
results, err := sf.DeleteComposite("Contact", contacts, 200, true)

Bulk v2

Create Bulk API Jobs to query, insert, update, upsert, and delete large collections of records

QueryBulkExport

func (sf *Salesforce) QueryBulkExport(query string, filePath string) error

Performs a query and exports the data to a csv file

  • filePath: name and path of a csv file to be created
  • query: a SOQL query
err := sf.QueryBulkExport("SELECT Id, FirstName, LastName FROM Contact", "data/export.csv")
QueryStructBulkExport

func (sf *Salesforce) QueryStructBulkExport(soqlStruct any, filePath string) error

Performs a SOQL query given a go-soql struct and decodes the response into the given struct

  • filePath: name and path of a csv file to be created
  • soqlStruct: a custom struct using soql tags
  • Review forcedotcom/go-soql
    • Eliminates need to separately maintain query string and struct
    • Helps prevent SOQL injection
type ContactSoql struct {
    Id        string `soql:"selectColumn,fieldName=Id" json:"Id"`
    FirstName string `soql:"selectColumn,fieldName=FirstName" json:"FirstName"`
    LastName  string `soql:"selectColumn,fieldName=LastName" json:"LastName"`
}

type ContactSoqlQuery struct {
    SelectClause ContactSoql          `soql:"selectClause,tableName=Contact"`
}
soqlStruct := ContactSoqlQuery{
    SelectClause: ContactSoql{},
}
err := sf.QueryStructBulkExport(soqlStruct, "data/export2.csv")
QueryBulkIterator

func (sf *Salesforce) QueryBulkIterator(query string) (IteratorJob, error)

Performs a query and return a IteratorJob to decode data

  • query: a SOQL query
type Contact struct {
    Id        string `json:"Id" csv:"Id"`
    FirstName string `json:"FirstName" csv:"FirstName"`
    LastName  string `json:"LastName" csv:"LastName"`
}

it, err := sf.QueryBulkIterator("SELECT Id, FirstName, LastName FROM Contact")
if err != nil {
    panic(err)
}

for it.Next() {
    var data []Contact
    if err := it.Decode(&data); err != nil {
        panic(err)
    }
    fmt.Println(data)
}

if err := it.Error(); err != nil {
    panic(err)
}
Bulk with nested objects
  • Nested objects are supported using the csv tag
  • The csv tag should be formatted as csv:"APIFieldName.,inline"
type ContactWithAltOwner struct {
    Id                 string
    AlternateOwnerName User `csv:"Alternate_Owner__r.,inline"`
}

it, err = sf.QueryBulkIterator("SELECT Id, Alternate_Owner__r.Name FROM Contact")
if err != nil {
    panic(err)
}

for it.Next() {
    var data []Contact
    if err := it.Decode(&data); err != nil {
        panic(err)
    }
    fmt.Println(data)
}

if err := it.Error(); err != nil {
    panic(err)
}
InsertBulk

func (sf *Salesforce) InsertBulk(sObjectName string, records any, batchSize int, waitForResults bool) ([]string, error)

Inserts a list of salesforce records using Bulk API v2, returning a list of Job IDs

  • sObjectName: API name of Salesforce object
  • records: a slice of salesforce records
  • batchSize: 1 <= batchSize <= 10000
  • waitForResults: denotes whether to wait for jobs to finish
type Contact struct {
    LastName string
}
contacts := []Contact{
    {
        LastName: "Lang",
    },
    {
        LastName: "Van Dyne",
    },
}
jobIds, err := sf.InsertBulk("Contact", contacts, 1000, false)
InsertBulkFile

func (sf *Salesforce) InsertBulkFile(sObjectName string, filePath string, batchSize int, waitForResults bool) ([]string, error)

Inserts a collection of salesforce records from a csv file using Bulk API v2, returning a list of Job IDs

  • sObjectName: API name of Salesforce object
  • filePath: path to a csv file containing salesforce data
  • batchSize: 1 <= batchSize <= 10000
  • waitForResults: denotes whether to wait for jobs to finish

data/avengers.csv

FirstName,LastName
Tony,Stark
Steve,Rogers
Bruce,Banner
jobIds, err := sf.InsertBulkFile("Contact", "data/avengers.csv", 1000, false)
InsertBulkAssign

func (sf *Salesforce) InsertBulkAssign(sObjectName string, records any, batchSize int, waitForResults bool, assignmentRuleId string) ([]string, error)

Inserts a list of Lead or Case records to be assigned via an Assignment rule, using Bulk API v2, returning a list of Job IDs

  • sObjectName: API name of Salesforce object (must be Lead or Case)
  • records: a slice of Lead or Case records
  • batchSize: 1 <= batchSize <= 10000
  • waitForResults: denotes whether to wait for jobs to finish
  • assignmentRuleId: the Salesforce Id of a Lead or Case Assignment Rule
type Lead struct {
    LastName string
    Company string
}
leads := []Lead{
    {
        LastName: "Spector",
        Company:  "The Avengers",
    },
}
jobIds, err := sf.InsertBulkAssign("Lead", leads, 100, true, "01QDn00000112FHMAY")
InsertBulkFileAssign

func (sf *Salesforce) InsertBulkFileAssign(sObjectName string, filePath string, batchSize int, waitForResults bool, assignmentRuleId string) ([]string, error)

Inserts a list of Lead or Case records to be assigned via an Assignment rule, from a csv file using Bulk API v2, returning a list of Job IDs

  • sObjectName: API name of Salesforce object (must be Lead or Case)
  • filePath: path to a csv file containing Lead or Case data
  • batchSize: 1 <= batchSize <= 10000
  • waitForResults: denotes whether to wait for jobs to finish
  • assignmentRuleId: the Salesforce Id of a Lead or Case Assignment Rule

data/avengers.csv

FirstName,LastName,Company
Tony,Stark,The Avengers
Steve,Rogers,The Avengers
Bruce,Banner,The Avengers
jobIds, err := sf.InsertBulkFileAssign("Lead", "data/avengers.csv", 1000, false, "01QDn00000112FHMAY")
UpdateBulk

func (sf *Salesforce) UpdateBulk(sObjectName string, records any, batchSize int, waitForResults bool) ([]string, error)

Updates a list of salesforce records using Bulk API v2, returning a list of Job IDs

  • sObjectName: API name of Salesforce object
  • records: a slice of salesforce records
    • An Id is required
  • batchSize: 1 <= batchSize <= 10000
  • waitForResults: denotes whether to wait for jobs to finish
type Contact struct {
    Id       string
    LastName string
}
contacts := []Contact{
    {
        Id:       "003Dn00000pEsoRIAS",
        LastName: "Strange",
    },
    {
        Id:       "003Dn00000pEsoSIAS",
        LastName: "T'Challa",
    },
}
jobIds, err := sf.UpdateBulk("Contact", contacts, 1000, false)
UpdateBulkFile

func (sf *Salesforce) UpdateBulkFile(sObjectName string, filePath string, batchSize int, waitForResults bool) ([]string, error)

Updates a collection of salesforce records from a csv file using Bulk API v2, returning a list of Job IDs

  • sObjectName: API name of Salesforce object
  • filePath: path to a csv file containing salesforce data
    • An Id is required within csv data
  • batchSize: 1 <= batchSize <= 10000
  • waitForResults: denotes whether to wait for jobs to finish

data/update_avengers.csv

Id,FirstName,LastName
003Dn00000pEwRuIAK,Rocket,Raccoon
003Dn00000pEwQxIAK,Drax,The Destroyer
003Dn00000pEwQyIAK,Peter,Quill
003Dn00000pEwQzIAK,I Am,Groot
003Dn00000pEwR0IAK,Gamora,Zen Whoberi Ben Titan
003Dn00000pEwR1IAK,Mantis,Mantis
jobIds, err := sf.UpdateBulkFile("Contact", "data/update_avengers.csv", 1000, false)
UpdateBulkAssign

func (sf *Salesforce) UpdateBulkAssign(sObjectName string, records any, batchSize int, waitForResults bool, assignmentRuleId string) ([]string, error)

Updates a list of Lead or Case records to be assigned via an Assignment rule, using Bulk API v2, returning a list of Job IDs

  • sObjectName: API name of Salesforce object (must be Lead or Case)
  • records: a slice of Lead or Case records
  • batchSize: 1 <= batchSize <= 10000
  • waitForResults: denotes whether to wait for jobs to finish
  • assignmentRuleId: the Salesforce Id of a Lead or Case Assignment Rule
type Lead struct {
    Id        string
    LastName  string
    Company   string
}
leads := []Lead{
    {
        Id:       "00QDn0000024r6FMAQ",
        LastName: "Grant",
        Company:  "The Avengers",
    },
}
jobIds, err := sf.UpdateBulkAssign("Lead", leads, 100, true, "01QDn00000112FHMAY")
UpdateBulkFileAssign

func (sf *Salesforce) UpdateBulkFileAssign(sObjectName string, filePath string, batchSize int, waitForResults bool, assignmentRuleId string) ([]string, error)

Updates a list of Lead or Case records to be assigned via an Assignment rule, from a csv file using Bulk API v2, returning a list of Job IDs

  • sObjectName: API name of Salesforce object (must be Lead or Case)
  • filePath: path to a csv file containing Lead or Case data
  • batchSize: 1 <= batchSize <= 10000
  • waitForResults: denotes whether to wait for jobs to finish
  • assignmentRuleId: the Salesforce Id of a Lead or Case Assignment Rule

data/update_avengers.csv

Id,FirstName,LastName,Company
00QDn0000024r6WMAQ,Clint,Barton,The Avengers
00QDn0000024r6VMAQ,Natasha,Romanoff,The Avengers
00QDn0000024r6UMAQ,Hank,Pym,The Avengers
jobIds, err := sf.UpdateBulkFileAssign("Lead", "data/update_avengers.csv", 100, true, "01QDn00000112FHMAY")
UpsertBulk

func (sf *Salesforce) UpsertBulk(sObjectName string, externalIdFieldName string, records any, batchSize int, waitForResults bool) ([]string, error)

Updates (or inserts) a list of salesforce records using Bulk API v2, returning a list of Job IDs

  • sObjectName: API name of Salesforce object
  • externalIdFieldName: field API name for an external Id that exists on the given object
  • records: a slice of salesforce records
    • A value for the External Id is required
  • batchSize: 1 <= batchSize <= 10000
  • waitForResults: denotes whether to wait for jobs to finish
type Contact struct {
    ContactExternalId__c string
    LastName             string
}
contacts := []Contact{
    {
        ContactExternalId__c: "Avng5",
        LastName:             "Rhodes",
    },
    {
        ContactExternalId__c: "Avng6",
        LastName:             "Quill",
    },
}
jobIds, err := sf.UpsertBulk("Contact", "ContactExternalId__c", contacts, 1000, false)
UpsertBulkFile

func (sf *Salesforce) UpsertBulkFile(sObjectName string, externalIdFieldName string, filePath string, batchSize int, waitForResults bool) ([]string, error)

Updates (or inserts) a collection of salesforce records from a csv file using Bulk API v2, returning a list of Job IDs

  • sObjectName: API name of Salesforce object
  • externalIdFieldName: field API name for an external Id that exists on the given object
  • filePath: path to a csv file containing salesforce data
    • A value for the External Id is required within csv data
  • batchSize: 1 <= batchSize <= 10000
  • waitForResults: denotes whether to wait for jobs to finish

data/upsert_avengers.csv

ContactExternalId__c,FirstName,LastName
Avng7,Matt,Murdock
Avng8,Luke,Cage
Avng9,Jessica,Jones
Avng10,Danny,Rand
jobIds, err := sf.UpsertBulkFile("Contact", "ContactExternalId__c", "data/upsert_avengers.csv", 1000, false)
UpsertBulkAssign

func (sf *Salesforce) UpsertBulkAssign(sObjectName string, externalIdFieldName string, records any, batchSize int, waitForResults bool, assignmentRuleId string) ([]string, error)

Updates (or inserts) a list of Lead or Case records to be assigned via an Assignment rule, using Bulk API v2, returning a list of Job IDs

  • sObjectName: API name of Salesforce object (must be Lead or Case)
  • externalIdFieldName: field API name for an external Id that exists on the given object
  • records: a slice of Lead or Case records
  • batchSize: 1 <= batchSize <= 10000
  • waitForResults: denotes whether to wait for jobs to finish
  • assignmentRuleId: the Salesforce Id of a Lead or Case Assignment Rule
type Lead struct {
    LeadExternalId__c string
    LastName          string
    Company           string
}
leads := []Lead{
    {
        LeadExternalId__c: "MK3",
        LastName:          "Lockley",
        Company:           "The Avengers",
    },
}
jobIds, err := sf.UpsertBulkAssign("Lead", "LeadExternalId__c", leads, 100, true, "00QDn0000024r6FMAQ")
UpsertBulkFileAssign

func (sf *Salesforce) UpsertBulkFileAssign(sObjectName string, externalIdFieldName string, filePath string, batchSize int, waitForResults bool, assignmentRuleId string) ([]string, error)

Updates (or inserts) a list of Lead or Case records to be assigned via an Assignment rule, from a csv file using Bulk API v2, returning a list of Job IDs

  • sObjectName: API name of Salesforce object (must be Lead or Case)
  • externalIdFieldName: field API name for an external Id that exists on the given object
  • filePath: path to a csv file containing salesforce data
    • A value for the External Id is required within csv data
  • batchSize: 1 <= batchSize <= 10000
  • waitForResults: denotes whether to wait for jobs to finish
  • assignmentRuleId: the Salesforce Id of a Lead or Case Assignment Rule

data/upsert_avengers

LeadExternalId__c,FirstName,LastName,Company
Avng11,Nick,Fury,The Avengers
Avng12,Maria,Hill,The Avengers
Avng13,Howard,Stark,The Avengers
jobIds, err := sf.UpsertBulkFileAssign("Lead", "LeadExternalId__c", "data/upsert_avengers.csv", 100, true, "01QDn00000112FHMAY")
DeleteBulk

func (sf *Salesforce) DeleteBulk(sObjectName string, records any, batchSize int, waitForResults bool) ([]string, error)

Deletes a list of salesforce records using Bulk API v2, returning a list of Job IDs

  • sObjectName: API name of Salesforce object
  • records: a slice of salesforce records
    • should only contain Ids
  • batchSize: 1 <= batchSize <= 10000
  • waitForResults: denotes whether to wait for jobs to finish
type Contact struct {
    Id       string
}
contacts := []ContactIds{
    {
        Id: "003Dn00000pEsoRIAS",
    },
    {
        Id: "003Dn00000pEsoSIAS",
    },
}
jobIds, err := sf.DeleteBulk("Contact", contacts, 1000, false)
DeleteBulkFile

func (sf *Salesforce) DeleteBulkFile(sObjectName string, filePath string, batchSize int, waitForResults bool) ([]string, error)

Deletes a collection of salesforce records from a csv file using Bulk API v2, returning a list of Job IDs

  • sObjectName: API name of Salesforce object
  • filePath: path to a csv file containing salesforce data
    • should only contain Ids
  • batchSize: 1 <= batchSize <= 10000
  • waitForResults: denotes whether to wait for jobs to finish

data/delete_avengers.csv

Id
003Dn00000pEwRuIAK
003Dn00000pEwQxIAK
003Dn00000pEwQyIAK
003Dn00000pEwQzIAK
003Dn00000pEwR0IAK
003Dn00000pEwR1IAK
jobIds, err := sf.DeleteBulkFile("Contact", "data/delete_avengers.csv", 1000, false)
GetJobResults

func (sf *Salesforce) GetJobResults(bulkJobId string) (BulkJobResults, error)

Returns an instance of BulkJobResults given a Job Id

  • bulkJobId: the Id for a bulk API job
  • Use to check results of Bulk Job, including successful and failed records
type Contact struct {
    LastName string
}
contacts := []Contact{
    {
        LastName: "Grimm",
    },
}
jobIds, err := sf.InsertBulk("Contact", contacts, 1000, true)
if err != nil {
    panic(err)
}
for _, id := range jobIds {
    results, err := sf.GetJobResults(id) // returns an instance of BulkJobResults
    if err != nil {
        panic(err)
    }
    fmt.Println(results)
}

Other

DoRequest

func (sf *Salesforce) DoRequest(method string, uri string, body []byte, opts ...RequestOption) (*http.Response, error)

Make a http call to Salesforce, returning a response to be parsed by the client

  • method: request method ("GET", "POST", "PUT", "PATCH", "DELETE")
  • uri: uniform resource identifier (include everything after /services/data/apiVersion)
  • body: json encoded body to be included in request
  • opts: optional request options (currently supports custom headers via WithHeader)

Example to call the /limits endpoint

resp, err := sf.DoRequest(http.MethodGet, "/limits", nil)
if err != nil {
    panic(err)
}
respBody, err := io.ReadAll(resp.Body)
if err != nil {
    panic(err)
}
fmt.Println(string(respBody))
WithHeader

func WithHeader(key, value string) RequestOption

Creates a request option that sets a custom header on the HTTP request

  • key: the header name
  • value: the header value
// Use If-Modified-Since for efficient caching
resp, err := sf.DoRequest("GET", "/sobjects/Account/describe", nil,
    salesforce.WithHeader("If-Modified-Since", "Wed, 21 Oct 2015 07:28:00 GMT"))
if err != nil {
    panic(err)
}

if resp.StatusCode == 304 {
    fmt.Println("Data not modified, using cached version")
}
// Multiple custom headers
resp, err := sf.DoRequest("GET", "/sobjects", nil,
    salesforce.WithHeader("If-Modified-Since", "Wed, 21 Oct 2015 07:28:00 GMT"),
    salesforce.WithHeader("Accept-Language", "en-US"))

Documentation

Index

Constants

View Source
const JwtExpirationTime = 5 * time.Minute

Variables

This section is empty.

Functions

This section is empty.

Types

type AuthFlowType

type AuthFlowType int

AuthFlowType represents the type of authentication flow used

const (
	AuthFlowUnknown AuthFlowType = iota
	AuthFlowUsernamePassword
	AuthFlowClientCredentials
	AuthFlowAccessToken
	AuthFlowJWT
)

func (AuthFlowType) String

func (a AuthFlowType) String() string

type BulkJobResults

type BulkJobResults struct {
	Id                  string `json:"id"`
	State               string `json:"state"`
	NumberRecordsFailed int    `json:"numberRecordsFailed"`
	ErrorMessage        string `json:"errorMessage"`
	SuccessfulRecords   []map[string]any
	FailedRecords       []map[string]any
}

type Creds

type Creds struct {
	Domain         string
	Username       string
	Password       string
	SecurityToken  string
	ConsumerKey    string
	ConsumerSecret string
	ConsumerRSAPem string
	AccessToken    string
}

type IteratorJob

type IteratorJob interface {
	Next() bool
	Error() error
	Decode(any) error
}

type Option

type Option func(*configuration) error

Option is a functional configuration option that can return an error

func WithAPIVersion

func WithAPIVersion(version string) Option

WithAPIVersion sets the Salesforce API version to use

func WithBatchSizeMax

func WithBatchSizeMax(size int) Option

WithBatchSizeMax sets the maximum batch size for collections

func WithBulkBatchSizeMax

func WithBulkBatchSizeMax(size int) Option

WithBulkBatchSizeMax sets the maximum batch size for bulk operations

func WithBulkPollTimeout

func WithBulkPollTimeout(timeout time.Duration) Option

WithBulkPollTimeout sets the timeout for polling bulk job results.

func WithBulkQueryMaxRecords

func WithBulkQueryMaxRecords(maxRecords int) Option

WithBulkQueryMaxRecords caps the number of records Salesforce returns per bulk-query result page (the maxRecords query parameter). Bounding this keeps the streaming iterator's per-page memory in check on large result sets; the default (-1) leaves it to the server.

func WithCompressionHeaders

func WithCompressionHeaders(compression bool) Option

WithCompressionHeaders sets whether to compress request and response headers

func WithHTTPTimeout

func WithHTTPTimeout(timeout time.Duration) Option

WithHTTPTimeout sets the HTTP client timeout duration

func WithRoundTripper

func WithRoundTripper(rt http.RoundTripper) Option

WithRoundTripper sets a custom round tripper for HTTP requests

func WithValidateAuthentication

func WithValidateAuthentication(validate bool) Option

WithValidateAuthentication sets whether to validate the authentication session on client creation

type RequestOption

type RequestOption func(*http.Request)

RequestOption represents a functional option for configuring HTTP requests

func WithHeader

func WithHeader(key, value string) RequestOption

WithHeader sets a custom header on the HTTP request

type Salesforce

type Salesforce struct {
	AuthFlow AuthFlowType
	// contains filtered or unexported fields
}

func Init

func Init(creds Creds, options ...Option) (*Salesforce, error)

func (*Salesforce) DeleteBulk

func (sf *Salesforce) DeleteBulk(
	sObjectName string,
	records any,
	batchSize int,
	waitForResults bool,
) ([]string, error)

func (*Salesforce) DeleteBulkFile

func (sf *Salesforce) DeleteBulkFile(
	sObjectName string,
	filePath string,
	batchSize int,
	waitForResults bool,
) ([]string, error)

func (*Salesforce) DeleteCollection

func (sf *Salesforce) DeleteCollection(
	sObjectName string,
	records any,
	batchSize int,
) (SalesforceResults, error)

func (*Salesforce) DeleteComposite

func (sf *Salesforce) DeleteComposite(
	sObjectName string,
	records any,
	batchSize int,
	allOrNone bool,
) (SalesforceResults, error)

func (*Salesforce) DeleteOne

func (sf *Salesforce) DeleteOne(sObjectName string, record any) error

func (*Salesforce) DoApexRequest

func (sf *Salesforce) DoApexRequest(
	method string,
	uri string,
	body []byte,
	opts ...RequestOption,
) (*http.Response, error)

func (*Salesforce) DoRequest

func (sf *Salesforce) DoRequest(
	method string,
	uri string,
	body []byte,
	opts ...RequestOption,
) (*http.Response, error)

func (*Salesforce) GetAPIVersion

func (sf *Salesforce) GetAPIVersion() string

GetAPIVersion returns the configured API version

func (*Salesforce) GetAccessToken

func (sf *Salesforce) GetAccessToken() string

func (*Salesforce) GetAuthFlow

func (sf *Salesforce) GetAuthFlow() AuthFlowType

GetAuthFlow returns the authentication flow type used

func (*Salesforce) GetBatchSizeMax

func (sf *Salesforce) GetBatchSizeMax() int

GetBatchSizeMax returns the configured maximum batch size for collections

func (*Salesforce) GetBulkBatchSizeMax

func (sf *Salesforce) GetBulkBatchSizeMax() int

GetBulkBatchSizeMax returns the configured maximum batch size for bulk operations

func (*Salesforce) GetCompressionHeaders

func (sf *Salesforce) GetCompressionHeaders() bool

GetCompressionHeaders returns whether compression headers are enabled

func (*Salesforce) GetHTTPClient

func (sf *Salesforce) GetHTTPClient() *http.Client

GetHTTPClient returns the configured HTTP client

func (*Salesforce) GetInstanceUrl

func (sf *Salesforce) GetInstanceUrl() string

func (*Salesforce) GetJobResults

func (sf *Salesforce) GetJobResults(bulkJobId string) (BulkJobResults, error)

func (*Salesforce) InsertBulk

func (sf *Salesforce) InsertBulk(
	sObjectName string,
	records any,
	batchSize int,
	waitForResults bool,
) ([]string, error)

func (*Salesforce) InsertBulkAssign

func (sf *Salesforce) InsertBulkAssign(
	sObjectName string,
	records any,
	batchSize int,
	waitForResults bool,
	assignmentRuleId string,
) ([]string, error)

func (*Salesforce) InsertBulkFile

func (sf *Salesforce) InsertBulkFile(
	sObjectName string,
	filePath string,
	batchSize int,
	waitForResults bool,
) ([]string, error)

func (*Salesforce) InsertBulkFileAssign

func (sf *Salesforce) InsertBulkFileAssign(
	sObjectName string,
	filePath string,
	batchSize int,
	waitForResults bool,
	assignmentRuleId string,
) ([]string, error)

func (*Salesforce) InsertCollection

func (sf *Salesforce) InsertCollection(
	sObjectName string,
	records any,
	batchSize int,
) (SalesforceResults, error)

func (*Salesforce) InsertComposite

func (sf *Salesforce) InsertComposite(
	sObjectName string,
	records any,
	batchSize int,
	allOrNone bool,
) (SalesforceResults, error)

func (*Salesforce) InsertOne

func (sf *Salesforce) InsertOne(sObjectName string, record any) (SalesforceResult, error)

func (*Salesforce) Query

func (sf *Salesforce) Query(query string, sObject any) error

func (*Salesforce) QueryBulkExport

func (sf *Salesforce) QueryBulkExport(query string, filePath string) error

func (*Salesforce) QueryBulkIterator

func (sf *Salesforce) QueryBulkIterator(query string) (IteratorJob, error)

func (*Salesforce) QueryStruct

func (sf *Salesforce) QueryStruct(soqlStruct any, sObject any) error

func (*Salesforce) QueryStructBulkExport

func (sf *Salesforce) QueryStructBulkExport(soqlStruct any, filePath string) error

func (*Salesforce) UpdateBulk

func (sf *Salesforce) UpdateBulk(
	sObjectName string,
	records any,
	batchSize int,
	waitForResults bool,
) ([]string, error)

func (*Salesforce) UpdateBulkAssign

func (sf *Salesforce) UpdateBulkAssign(
	sObjectName string,
	records any,
	batchSize int,
	waitForResults bool,
	assignmentRuleId string,
) ([]string, error)

func (*Salesforce) UpdateBulkFile

func (sf *Salesforce) UpdateBulkFile(
	sObjectName string,
	filePath string,
	batchSize int,
	waitForResults bool,
) ([]string, error)

func (*Salesforce) UpdateBulkFileAssign

func (sf *Salesforce) UpdateBulkFileAssign(
	sObjectName string,
	filePath string,
	batchSize int,
	waitForResults bool,
	assignmentRuleId string,
) ([]string, error)

func (*Salesforce) UpdateCollection

func (sf *Salesforce) UpdateCollection(
	sObjectName string,
	records any,
	batchSize int,
) (SalesforceResults, error)

func (*Salesforce) UpdateComposite

func (sf *Salesforce) UpdateComposite(
	sObjectName string,
	records any,
	batchSize int,
	allOrNone bool,
) (SalesforceResults, error)

func (*Salesforce) UpdateOne

func (sf *Salesforce) UpdateOne(sObjectName string, record any) error

func (*Salesforce) UpsertBulk

func (sf *Salesforce) UpsertBulk(
	sObjectName string,
	externalIdFieldName string,
	records any,
	batchSize int,
	waitForResults bool,
) ([]string, error)

func (*Salesforce) UpsertBulkAssign

func (sf *Salesforce) UpsertBulkAssign(
	sObjectName string,
	externalIdFieldName string,
	records any,
	batchSize int,
	waitForResults bool,
	assignmentRuleId string,
) ([]string, error)

func (*Salesforce) UpsertBulkFile

func (sf *Salesforce) UpsertBulkFile(
	sObjectName string,
	externalIdFieldName string,
	filePath string,
	batchSize int,
	waitForResults bool,
) ([]string, error)

func (*Salesforce) UpsertBulkFileAssign

func (sf *Salesforce) UpsertBulkFileAssign(
	sObjectName string,
	externalIdFieldName string,
	filePath string,
	batchSize int,
	waitForResults bool,
	assignmentRuleId string,
) ([]string, error)

func (*Salesforce) UpsertCollection

func (sf *Salesforce) UpsertCollection(
	sObjectName string,
	externalIdFieldName string,
	records any,
	batchSize int,
) (SalesforceResults, error)

func (*Salesforce) UpsertComposite

func (sf *Salesforce) UpsertComposite(
	sObjectName string,
	externalIdFieldName string,
	records any,
	batchSize int,
	allOrNone bool,
) (SalesforceResults, error)

func (*Salesforce) UpsertOne

func (sf *Salesforce) UpsertOne(
	sObjectName string,
	externalIdFieldName string,
	record any,
) (SalesforceResult, error)

type SalesforceErrorMessage

type SalesforceErrorMessage struct {
	Message    string   `json:"message"`
	StatusCode string   `json:"statusCode"`
	Fields     []string `json:"fields"`
	ErrorCode  string   `json:"errorCode"`
}

type SalesforceResult

type SalesforceResult struct {
	Id      string                   `json:"id"`
	Errors  []SalesforceErrorMessage `json:"errors"`
	Success bool                     `json:"success"`
}

type SalesforceResults

type SalesforceResults struct {
	Results             []SalesforceResult
	HasSalesforceErrors bool
}

Directories

Path Synopsis
examples
http-config command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL