Each different type of step produces different step execution values that are added to the formula "context". The formula context is then passed from step-to-step, allowing you to use these values in any subsequent steps in your formula. Below are the different values that each different step type produces:
NOTE: Any step execution values that are added to the context are always name-spaced under
steps.<your-step-name>
.
elementRequest
or request
step:{
"my-step-name": {
"request": {
"query": "{}",
"body": "{\"Name\":\"New Account Name\"}",
"method": "POST",
"path": "{}",
"uri": "/elements/api-v2/hubs/crm/accounts",
"headers": "{\"authorization\":\"Element /ABC=, User DEF=, Organization GHI\",\"content-length\":\"14\",\"host\":\"anysite.io\",\"content-type\":\"application/json}"
},
"response": {
"code": "200",
"headers": "{\"Set-Cookie\": \"CESESSIONID=2CA15552EE56EAF65BF1102F6CACEACC;Path=/elements/;HttpOnly\"}",
"body": "{\"Id\": \"001tx3WcAAI\", \"Name\": \"New Account Name\"}"
}
}
}
httpRequest
step:{
"my-step-name": {
"request": {
"query": "{}",
"body": "{\"Name\":\"New Account Name\"}",
"method": "POST",
"url": "https://api.myservice.com:443/myresource",
"path": "{}",
"headers": "{\"authorization\":\"mysessionid\",\"content-type\":\"application/json}"
},
"response": {
"code": "200",
"headers": "{\"Set-Cookie\": \"CESESSIONID=2CA15552EE56EAF65BF1102F6CACEACC;Path=/elements/;HttpOnly\"}",
"body": "{\"id\": \"237648\", \"name\": \"My New Resource Name\"}"
}
}
}
NOTE: The
url
attribute is required, the value of which must be a validhttp
orhttps
URL.
elementRequestStream
step:{
"my-step-name": {
"download": {
"request": {
"query": "{}",
"method": "POST",
"uri": "/elements/api-v2/hubs/crm/accounts",
"headers": "{\"authorization\":\"Element /ABC=, User DEF=, Organization GHI\",\"content-length\":\"14\",\"host\":\"anysite.io\",\"content-type\":\"application/json}"
},
"response": {
"code": "200",
"headers": "{\"Set-Cookie\": \"CESESSIONID=2CA15552EE56EAF65BF1102F6CACEACC;Path=/elements/;HttpOnly\"}"
}
},
"upload": {
"request": {
"query": "{}",
"method": "POST",
"uri": "/elements/api-v2/hubs/crm/accounts",
"headers": "{\"authorization\":\"Element /ABC=, User DEF=, Organization GHI\",\"content-length\":\"14\",\"host\":\"anysite.io\",\"content-type\":\"application/json}"
,
"response": {
"code": "200",
"headers": "{\"Set-Cookie\": \"CESESSIONID=2CA15552EE56EAF65BF1102F6CACEACC;Path=/elements/;HttpOnly\"}",
"body": "{\"Id\": \"001tx3WcAAI\", \"Name\": \"New Account Name\"}"
}
}
}
}
amqpRequest
step:{
"my-step-name": {
"request": {
"body": "{\"message\":\"This is a test message.\"}",
"url": "amqp://otqaqsml:tPpXwTl7-iMtezRmyJmD-y2U_XbroYpW@jaguar.rmq.cloudamqp.com/otqaqsml",
"exchange": "main",
"queue": "myqueue"
}
}
}
NOTE: The
url
andqueue
attributes are required. The AMQP URL has to adhere to the conventions described in the following document - https://www.rabbitmq.com/uri-spec.html. If the AMQP request succeeds, the associatedonSuccess
step is executed, else theonFailure
step.
script
step:A script step adds whatever object is passed to the JS done
callback onto the formula "context". For example, if you have a step named my-script-step
that looks like:
done({
foo: 'bar',
object: {
someKey: 'someValue'
}
});
You could now reference steps.my-script-step.foo
, steps.my-script-step.object
or steps.my-script-step.object.someKey
in any subsequent steps when needed.
loop
step:A loop step makes available the current object being processed and the index to each step executed inside of that loop. For example, if we have a loop
step named looper
, any steps that are run inside of that loop would have access to looper.index
and looper.entry
.
filter
or notification
steps:These steps simply pass a boolean into the JS done
callback function. That boolean is made available under the key titled continue
, for example:
{
"my-step-name": {
"continue": "true"
}
}
NOTE: In the above example,
true
was passed to thedone
callback.
{
"my-step-name": {
"continue": "false"
}
}
NOTE: In the above example,
false
was passed to thedone
callback.
formula
step:These steps execute a sub-formula from the current formula. The values that are added to the formula context after a formula
step finishes executing are whatever the last step that executed in the sub-formula makes available. Therefore, it's common practice to have a specific step in the sub-formula that basically aggregates and "returns" whatever data is needed in the parent's formula context.
retryFormulaExecution
step:Steps of this type truncate the formula execution and schedule a retry execution for a later time based upon the retry attempt number. The equation used to determine the retry time is round(e^x)
, where x
is the retry attempt number. The result of this equation is used to schedule a retry in minutes. The step execution response value for this step, is a string
such as
{
"id": "53067",
"key": "retry.error",
"value": "Formula instance execution scheduled for retry at approximately 2016-12-05T08:52:37-07:00"
}
In the above example, the step name in the formula is retry
, and the value of the step execution indicates the time when the formula execution will be retried.
There are many step types that allow you to write your own custom Javascript. The function signature for all JS-related step types looks like:
/**
* @param trigger The trigger that started this execution
* @param steps The list of steps that have been executed up until this point for this execution and all of their step execution values
* @param info Metadata about this formula
* @param config The configuration values set on the formula instance (config variables)
* @param done The callback function that you will need to call at the end of your script step
*/
function (trigger, steps, info, config, done) {
// your Javascript will be executed here
}
PROTIP: For all scripts, Javascript
strict
mode is enforced.PROTIP: You can use
console.log
to log things in your formula and help debug.PROTIP: You can use
notify.email
to send an email notification.PROTIP: ES6 is supported.
PROTIP: The function parameters are immutable, meaning they cannot be assigned to directly. In order to change an object or value passed into the function, first copy it to your own local variable and then make the necessary changes.
Functions
console.log(str)
: Log something from the script. This logged value will be returned in an array called console
, which will be available to see as a step execution value. Takes a string
as a parameter.throw(str)
: Force a script to exit with an error message. The error message will be available to see as a step execution value. Takes a string
as a parameter.notify.email(to, subject, body)
: Send an email notification directly from a Javascript step. to
can be a single email or a comma separated list of emails, subject
is the subject of the email and body
is the body of the email. A value will be returned in an array called notify
, which will be available to see as a step execution value. Takes three string
parameters. You can reference anything from the context when passing in to
, subject
or body
in the same way you can access these variables elsewhere in the Javascript. For example:
notify.email(steps.previous-step.email, steps.previous-step.subject, steps.previous-step.emailPrefix + '<br>This is the main body.');
Libraries
require
this library, it is available by default.
CE.randomString()
: Generate a random string (approx. 10 characters long).CE.randomEmail()
: Generate a random email address.CE.md5(str)
: Create an MD5 hash from a string value. Takes a string
as a parameter. Returns a string
.CE.b64(str)
: Encode a string in base64. Takes a string
as a parameter. Returns a string
.CE.decode64(str)
: Decode a string from base64, using UTF-8 encoding. Takes a string
as a parameter. Returns a string
.CE.hmac(algo)(enc)(secret, str)
: HMAC hash a string (str) using the provided secret (secret), algorithm (algo), and encoding (enc). See https://nodejs.org/api/crypto.html#crypto_class_hmac for more information about the algorithm and encoding parameters.CE.hmac[algo][enc](secret, str)
: This is a set of convenience functions that allow HMAC hashing using some common algorithms and encodings. For example, CE.hmacSha1Hex(secret, str)
will create an HMAC SHA1 hash of the provided string, using the provided secret, and return a hex string. You can replace algo and enc with the following values:
algo: Sha1
, Sha256
, Md5
enc: Hex
, base64
lodash
library. To use this library, simply require
it in your script. It is possible to use the library modules, as well, such as lodash/fp
.util
library. To use, require
it in your script.Example trigger
object:
{
"eventId": 11211123,
"instanceId": 231232132,
"type": "event",
"event": {
"date": "2016-06-01T04:09:10Z",
"elementKey": "sfdc",
"eventType": "UPDATED",
"objectId": "n005i000003sgTd0AAE",
"objectType": "Contact"
}
}
NOTE: The above
trigger
example is for anevent
type trigger.
Example steps
object:
{
"PreviousStepName": {
"StepExecutionKey": "StepExecutionValue",
"AnotherStepExecutionKey": "AnotherStepExecutionValue"
},
"AnotherPreviousStepName": {
"StepExecutionKey": "StepExecutionValue"
}
}
NOTE: Each different step type has different step execution values that they will add to the formula "context". See above for what each type of step adds to this context.
Example info
object:
{
"formulaId": 123,
"formulaName": "my formula name",
"formulaInstanceId": 456,
"formulaInstanceName": "my formula instance name",
"formulaExecutionId": 789
}
The done
function is simply a callback function that should be called to terminate the given step. For script
type steps, this done
callback takes a Javascript object whereas for filter
or notification
steps, the done
callback just takes a boolean
.
script
step:done({
payload: {
subject: 'Frozen Yogurt',
to: 'joseph.pulaski@old-school.com',
from: 'frank.ricard@old-school.com',
message: 'Contact ' + trigger.event.objectId + ' was updated!'
}
});
NOTE: This is an example script step that is building a JSON payload in order to send an email in a later step.
filter
step:done(trigger.event.eventType === 'UPDATED' && trigger.event.objectType === 'Contact');
NOTE: This is an example
filter
step that will passtrue
to ourdone
callback if the event we received in our trigger is from a Contact that was updated in the service that we are listening for events.