-
Notifications
You must be signed in to change notification settings - Fork 1
Advanced workflows
While the standard workflow actions in data-primals-engine cover many common use cases, the ExecuteScript action provides ultimate flexibility by allowing you to run custom server-side JavaScript code as part of any workflow. This enables complex data transformations, conditional logic, and dynamic interactions that go beyond pre-defined actions.
The ExecuteScript action type within a workflowAction document lets you write and execute a JavaScript snippet in a secure, sandboxed environment.
- Full JavaScript Support: Write modern JavaScript (async/await) to implement your logic.
-
Access to Workflow Context: Your script can read from and write to the
contextDataobject, allowing you to pass data between workflow steps. -
Database Interaction: Use a sandboxed
dbobject to perform CRUD operations. -
Error Handling: Throwing an error in your script will fail the current workflow step and can trigger the
onFailureStep.
When creating a workflowAction of type ExecuteScript, the most important field is script:
-
script(code - JavaScript): The JavaScript code to be executed.
Example workflowAction document:
{
"name": "Calculate Order Discount",
"type": "ExecuteScript",
"script": "const orderTotal = contextData.triggerData.totalAmount;\nif (orderTotal > 100) {\n contextData.discountAmount = orderTotal * 0.1;\n contextData.needsManagerApproval = false;\n} else if (orderTotal > 500) {\n contextData.discountAmount = orderTotal * 0.2;\n contextData.needsManagerApproval = true;\n}\nreturn contextData;"
}Your script runs in an async function and has access to several globally-injected objects:
-
contextData(object): This is the heart of your workflow's state. It contains:-
triggerData: The data from the event that initiated the workflow (e.g., the newly created document in aDataAddedtrigger). - Any data added by previous steps.
- Your script can read from and write to
contextData. The returned object from your script will become the newcontextDatafor subsequent steps.
-
-
db(object): A secure API to interact with the database. All methods areasyncand must beawait-ed. They automatically respect the permissions of the user who triggered the workflow.await db.create(modelName, dataObject)await db.find(modelName, filter)await db.findOne(modelName, filter)await db.update(modelName, filter, updateObject)await db.delete(modelName, filter)
-
logger(object): A safe logging utility to help with debugging.logger.info(...)logger.warn(...)logger.error(...)
-
env(object): Provides access to user-defined variables stored in theenvmodel.await env.get(variableName)await env.getAll()
Imagine a workflow triggered when a ticket is created. If the ticket priority is "high", we want to create a new task for a manager.
-
Trigger:
onEvent: DataAdded,targetModel: ticket. -
Step 1: "Check Priority and Create Task"
-
Action:
ExecuteScript -
Script:
// Check if the priority is high if (contextData.triggerData.priority !== 'high') { logger.info('Ticket priority is not high, skipping task creation.'); return contextData; // Exit script } // Find the manager's user ID (assuming a 'manager' role exists) const manager = await db.findOne('user', { role: { $find: { name: 'manager' } } }); if (manager) { // Create a new task and assign it to the manager await db.create('task', { title: `High-priority ticket: ${contextData.triggerData.subject}`, assignedTo: manager._id, relatedTicket: contextData.triggerData._id, status: 'todo' }); logger.info(`Task created for manager ${manager.username}.`); } else { logger.warn('No manager found to assign the task to.'); } return contextData; // Always return the context
-
Action:
By leveraging the ExecuteScript action, you can build sophisticated, stateful, and dynamic workflows that precisely match your application's business rules.