If you’re inserting records from R you may want to turn off the
assignment rules or even bypass duplicate rules and alerts to save
records. Beginning in Version 0.1.3 of the {salesforcer} package many
functions have a control
argument that will allow you to
fine tune the behavior of calls to the Salesforce APIs. This vignette
will introduce the different options you can control and how to pass
them into the {salesforcer} functions you’re already familiar with.
This new feature can be seen in the sf_create
(and many
other functions) as control=list(...)
. The dots mean that
you can pass any number of controls directly into the function.
First, authenticate and load any required packages for your analysis.
In the example below, we demonstrate how to create a record, but use
the control arguments to prevent its creation from showing up in the
Chatter feeds by setting the DisableFeedTrackingHeader
.
new_contact <- c(FirstName = "Jenny",
LastName = "Williams",
Email = "jennyw@gmail.com")
record1 <- sf_create(new_contact,
object_name = "Contact",
DisableFeedTrackingHeader = list(disableFeedTracking = TRUE))
record1
#> # A tibble: 1 × 2
#> success errors
#> <lgl> <list>
#> 1 FALSE <list [1]>
You will notice that the argument
DisableFeedTrackingHeader
can be included right into the
function without any documentation existing for it in the
sf_create
function. This is because the dots
(...
) allow you to pass over a dozen different control
parameters and that documentation would be tedious to create and
maintain over multiple functions in the package. However, you will
notice in the documentation entry for the control
argument
there is a link to a function called sf_control
which you
can use to directly to pass into control
or simply to
review its documentation of all the possible control parameters and
their defaults. This is where you can review the various control options
in more detail before trying to set them.
You may have also noticed that the argument
DisableFeedTrackingHeader
was formatted as a list with an element inside called
disableFeedTracking
set to TRUE
. This may seem
redundant but there are two reasons for this. First, this is exactly how
the Salesforce APIs documents these options, which are typically
referred to as “headers” because they are passed as a named header of
the HTTP request and then the header fields and values are provided for
that header. Second, some headers have multiple fields and values so a
list is the only way to provide multiple named fields and values under a
single header entity.
DuplicateRuleHeader
The DuplicateRuleHeader
that controls whether the
duplicate rules are followed when inserting records from the API, has
three fields:
allowSave
- For a duplicate rule, when the Alert
option is enabled, bypass alerts and save duplicate records by setting
this property to true. Prevent duplicate records from being saved by
setting this property to false.
includeRecordDetails
- Get fields and values for
records detected as duplicates by setting this property to true. Get
only record IDs for records detected as duplicates by setting this
property to false.
runAsCurrentUser
- Make sure that sharing rules for
the current user are enforced when duplicate rules run by setting this
property to true. Use the sharing rules specified in the class for the
request by setting this property to false. If no sharing rules are
specified, Apex code runs in system context and sharing rules for the
current user are not enforced.
Specifying these arguments requires a list
structure in
R, which may seem redundant in some cases, but is necessary to follow in
order to build the API request correctly.
# override the duplicate rules ...
record2 <- sf_create(new_contact,
object_name = "Contact",
DuplicateRuleHeader = list(allowSave = TRUE,
includeRecordDetails = FALSE,
runAsCurrentUser = TRUE))
record2
#> # A tibble: 1 × 2
#> id success
#> <chr> <lgl>
#> 1 003Kg000002Ac4BIAS TRUE
# ... or succumb to the duplicate rules
record3 <- sf_create(new_contact,
object_name = "Contact",
DuplicateRuleHeader = list(allowSave = FALSE,
includeRecordDetails = FALSE,
runAsCurrentUser = TRUE))
record3
#> # A tibble: 1 × 2
#> success errors
#> <lgl> <list>
#> 1 FALSE <list [1]>
Per the description above, note that setting
allowSave=TRUE
will not override rules where the “Action on
Create” for a rule is set to “Block”. If the duplicate rule’s action is
“Allow” with an alert, then setting allowSave=TRUE
means
the record will be created with no warning message. If
allowSave=FALSE
, then the record will be prevented from
being created. For additional information on the
DuplicateRuleHeader
, please see the Salesforce
documentation at:
https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_header_duplicateruleheader.htm
Finally, you may notice during your use that only certain control
arguments are permitted based on the API. For example, the
DuplicateRuleHeader
is not implemented in the REST API like
it is in the SOAP API. In the example below you should take note of two
things:
When using the REST API and setting the
DuplicateRuleHeader
, then you will notice a warning that
the header was ignored. You will receive warnings when trying to set any
control parameters for an API or operation that does not recognize that
particular control.
In this example, you cannot bypass the duplicate rule alert to create the record if using the REST API like you can with the SOAP API.
record4 <- sf_create(new_contact,
object_name = "Contact",
DuplicateRuleHeader = list(allowSave = FALSE,
includeRecordDetails = FALSE,
runAsCurrentUser = TRUE),
api_type = "REST")
#> Warning: Ignoring the following controls which are not used in the REST API:
#> DuplicateRuleHeader
record4
#> # A tibble: 1 × 2
#> success errors
#> <lgl> <list>
#> 1 FALSE <list [1]>
If this type of control structure is new to you, take a look at the
documentation for the glm
and glm.control
functions. The way these two functions behave is exactly how functions
like sf_create
and sf_control
work with each
other. As demonstrated above you can pass any number of arbitrary
controls into the function and they are all gathered up into the control
by control = list(...)
. However, you can specify the
control directly like this:
sf_query("SELECT Id, Name FROM Account LIMIT 1000",
object_name = "Account",
control = sf_control(QueryOptions = list(batchSize = 200)))
#> # A tibble: 16 × 2
#> Id Name
#> <chr> <chr>
#> 1 0013s00000zFgA6AAK KEEP Test Account With Child Records
#> 2 0013s00000zFdugAAC KEEP Test Account With Child Records
#> 3 0013s000014jF2HAAU Test Account For Performance Test
#> 4 0016A0000035mJEQAY GenePoint
#> 5 0016A0000035mJCQAY United Oil & Gas, UK
#> # ℹ 11 more rows
You may already be taking advantage of the all_or_none
or line_ending
arguments which are control arguments that
were explicity included in functions. These argument essentially hard
coded values to pass the AllOrNoneHeader
and
LineEndingHeader
control parameters. Starting with the
0.1.3 release it is no longer necessary and preferable not to have an
argument like all_or_none
listed explicity as an argument
since it can be provided in the control
argument. Note: the
all_or_none
argument and other explicit control arguments
will still be available in {salesforcer} 0.1.3 but will provide a
deprecated warning. They will be removed in the next CRAN release of the
package so it will be important to update your code now if you are
explicitly passing these arguments and see a deprecation warning.
Below is a list of links that go directly to the control arguments
(a.k.a headers) for the different APIs. I highly recommend reading this
documentation before setting a control parameter in R so you know
exactly what the behavior will be and how to specify it in R. You may
notice that some controls are not included in the R package. Some may be
added in the future if requested and some will not be added given the
scope of the package. One final note is that some arguments in the REST
API, like the “All or None” behavior is not a header, but a parameter in
the API call. For this reason you will not see it listed in the REST API
Headers section, but it is set in this R package using the
AllOrNoneHeader
argument in sf_control
just to
provide consistency between the SOAP and REST APIs. It would be
confusing to have two arguments named differently, one for each API, but
to do the exact same thing from R. For this reason, many of the control
arguments match exactly as they are listed in the SOAP API, but can be
used across other APIs even if not exactly written that way in the
Salesforce documentation referenced below.
SOAP API Headers:
REST API Headers:
Bulk 1.0 API Headers:
Metadata API Headers:
Bulk 2.0 API Headers: None
Reports and Dashboards REST API Headers: None