Paragraph workflows are TypeScript or JavaScript files that define a workflow, including its step configuration and control flow.
Workflows authored in Paragraph are fully compatible with the Paragon dashboard, for viewing in Task History and the Workflow Editor.
Creating a workflow
You can create a new workflow by running the following CLI command:
para new workflow --integration [integration name, e.g. salesforce]
The CLI will prompt you to title your workflow. Once you have completed this prompt, the CLI will create a new TypeScript file in the workflows/ folder of your selected integration:
An example of a simple workflow to sync contacts from Salesforce is below:
This is equivalent to the following workflow structure in the workflow dashboard:
Defining steps
In the define function of a workflow, steps can be created and configured. A step can be created in one of the following ways:
// Constructing a new standard Stepconstrequest=newRequestStep({...});// Calling an Integration Action or Integration TriggerconstgetRecords=integration.actions.searchRecords({...}, {})
Standard stepsand triggers (App Event Trigger, Request Trigger, Cron Trigger, Function, Request, Response, Conditional, Fan Out, and Integration Request) must be imported from the @useparagon/core library and configured to include the parameters that are required to run the step.
Integration-specific Actions or Triggers are available in the integration parameter passed to the define function.
All steps can use the following options in the constructor (or the second parameter for Integration Actions):
{// If true, this step will use Auto-Retry on failures autoRetry:true,// If true, this step will allow the workflow to continue if it fails,// emitting the error as output continueWorkflowOnError:true,// The step title, as displayed in the Workflow Editor description:"Step Title for Workflow Editor"}
For a full reference of steps, see our API documentation for the @useparagon/core package: @useparagon/core.
Referencing step outputs
Steps can be declared and configured in the define() function in any order. You will define an explicit flow/ordering for the steps using orchestration functions: see Orchestrating steps.
To reference step output in another step, simply access the .output property of a step or trigger:
For convenience, you can interpolate step outputs into strings with the template string format as in the example above. This mirrors the {{1.output.contact.email}} syntax of the Workflow Editor. For more advanced transformations on outputs, use a Function step.
Referencing User Settings and Environment Secrets
To reference User Settings or Environment Secrets as inputs, use the context parameter of the define() function.
The .getEnvironmentSecret function will use the Environment Secret value stored at a specified key.
The .getInput function will get the value of a User Setting. You can reference integration-level User Settings by importing from the integration's inputs.ts file or workflow-level User Settings with this.inputs.
// Import integration-level User Settingsimport inputs from'../inputs';//...constsearchRecordsStep=integration.actions.searchRecords({// Reference integration-level User Settings recordType:context.getInput(inputs.fieldMapping).objectName, filterFormula:Operators.StringContains("OpportunityStage",// Reference workflow-level User Settingscontext.getInput(this.inputs.opportunityStage) )}, {});
Referencing User Metadata or IDs
To reference User Metadata or your Connected User ID, use the connectUser parameter of the define() function.
The type for User Metadata comes from the persona.meta.ts file at the root of your Paragraph src/ folder. You can export an example metadata object from that file to expose available fields.
Conditional logic
Some steps will require you to define ConditionInput parameters, such as the Conditional Step or Stop Condition for Request Step Pagination.
When you need to define a condition, start by importing the Operators from @useparagon/core:
Operators contain conditions (like "string equals" or "number greater than") that can be chained together with AND or OR conditions. Paragon requires conditions to be in "disjunctive normal form" when chained, meaning that all conditions are "ORs of ANDs."
For example:
constshouldUpdateCondition=newConditionalStep({ if:Operators.Or(Operators.And(Operators.ArrayIsNotEmpty(requestStep.output.response.body.data), ), ), description:'Update or Create',});
Orchestrating steps
After defining or importing steps, the workflow requires an orchestration that describes how the steps are connected in the control flow.
The basic way to orchestrate step is to use the .next() function, available for every step. For example:
// Request -> Function -> ResponserequestStep.next(functionStep).next(responseStep);
Conditional branches
Conditional steps have additional functions, .whenTrue() and .whenFalse() for creating execution branches when a condition is True or False.
You can reuse steps or configuration by creating a shared top-level directory in your project src/ folder (the name can be anything exceptintegrations).
For example, you can create a common/ folder within src/:
You can export step definitions from common files as in the example below. To access execution data, you can import the static Execution class from the @useparagon/workflow library: