Workflows
Workflows (also called Onify Flow) are BPMN processes that be initiated either via a form, schedule or via API. A workflow can also be a presentation of a specific workflow or process from an process, external system or a script. This gives the user a clear view of where the process is. The process state and status can then be updated via API or the BPMN process.
Introduction
Workflows one of the ways to do automation in Onify. Workflows are a declaration of a workflow and when you start a workflow, this will create a process. It is then the process you interact with for managing state and status. A workflow can also be scheduled in the BPMN diagram.
A workflow can also be a declaration of a external workflow and can in this case be used to inform the user about the current process.
Creating new workflow
You can either create a workflow via the admin interface, via Camunda Modeler or via the API. If you deploy or run a BPMN diagram via the Camunda modeler, some of the below parameters are automatically set.
key
- Unique key (id) for the workflowname
- Name of the workflowdescription
- Description (external) for workflowbpmnresource
- The BPMN resource to be used (see Onify Flow)icon
- Icon for workflowtag
- Tag(s) for workflowowner
- Who is the owner of this workflow/process. This is only used for information purposerole
- Role(s) that have access to start workflow. If not set, every logged in user can start this workflow.domain
- Domains that have access to workflow (if multi-tenant is enabled). If not set, all users in all domains have access.state
- States are a declaration of the different states (milestones) of a workflow/process. These can either be manually created when you create the workflow or set in the BPMN process.state.order
- Order of the statestate.id
- The unique id of the statestate.name
- The name of the statestate.description
- The description of the statestate.required
-meta
- Metadata for the workflow. This could be used for eg. cost savings or other data related to the workflow/process.
Running a workflow
If the workflow is associated to a BPMN resource (Onify Flow) the process can either be started via admin interface, via Camunda Modeler or via the API.
A workflow can also be scheduled and this must be defined within the BPMN diagram.
When you start a workflow, a process is created and this holds all information about the current running process.
Process state
When you have a process running you have the ability to both add new states or update a state. The purpose of state is to show and visualize the user where in the process it is.
However, if the process is running a flow (BPMN), updating the state can also have a impact of signaling a activity, eg. a user task.
You can update process state via flow or via API.
Note: For more information about state and how to manipulate it, see Process state under Building flows.
Process status
The status is something that is set for the entire process, not for a specific state.
Here are the different statuses that can be set:
continue
- To continue the processcomplete
- The process should be considered completed with successpause
- The processes should be considered to be pausedstop
- The processes should be considered to be stopped
To mark something to be wrong, set error
to true
.
Note: For more information about state and how to manipulate it, see Process status under Building flows.
Forms
Forms are a great way to interact with a workflow and/or flow (BPMN).
Starting workflow using form
In the form configuration (process.*
) we can start a process based on the selected workflow:
workflow
- The workflow to be startedtitle
- Title to set to the process. Supports Handlebarsdescription
- Description to set to the process. Supports Handlebarsaction
- Actions to be made visible for the user in "Your processes" view (not implemented yet)action.id
- Unique id for the actionaction.name
- Name for the actionaction.url
- Url for the actionaction.status
- In what process status will this action be visible?
Here are some examples on how to set title and description using handlebars.
{
"workflow": "onboarding",
"title": "Employee Onboarding",
"description": "Onboarding for {{submit.firstname}} {{submit.lastname}}"
}
{
"workflow": "request-services",
"title": "Request services by {{user.name}}",
"description": "Requested {{#csv form.items}}{{name}}{{/csv}}"
}
Signaling process using form
If you are using flow, you can signal a process activity by sending processid
and stateid
in the queryparams when opening the flow, eg. ./form/<SLUG>?processid=<PROCESSID>&stateid=<ACTIVITYID>
.
This will signal flow to continue the process if stateid
is set on any of these element types:
- Receive Task
- User Task
- Manual Task
- Message Intermediate Catch Event
- Signal Intermediate Catch Event
When signaling the activity, data from the form will be added to the output of that activity, eg. content.output.*
. The data that will be available are example:
user.*
- The user object like,name
,mail
, etcform.*
- Information about the form that is sending the dataform.queryparam.*
- Query parameters from the formform.submit.item.*
- Submitted items (eg. {{form.submit.item.manager.[0].key}})form.submit.option.*
- Submitted options (eg. {{form.submit.option.memory.[0].key}})submit.*
- Submitted data from the form, eg. field values
For more information about
Onify Flow
Onify flow is based on the open source workflow engine bpmn-engine.
Requirements
- Camunda Modeler version 5.0 or later
- Onify Hub API version 2.2.0 or later
BPMN modeler
You can draw BPMN diagrams in many different products but Onify best supports the Camunda Modeler. We both support drawing the diagrams and also deploying and running diagram directly in the modeler.
Learn more about BPMN
Here is a great post how to get started with BPMN. Good luck ;-)
Building flows
Timers
Onify flow supports timers, i.e. TimerEventDefinition's with one addition. Onify also supports time cycle using cron.
timeDuration
timeDuration
Suitable for activity timeouts. Duration is defined using ISO8601 duration
timeCycle
timeCycle
Suitable for scheduled flows. Cycle is defined using cron.
timeDate
timeDate
Suitable for scheduled flows. Date should be set using new Date()
or in ISO format.
Input/Output
When modelling a flow for Onify it is possible to define activity Input/Output parameters. Onify has some special handling of the content of that.
- If a parameter with the same name appears the parameter will be overwritten with the new value
- If a Map is used the Map will be converted into an object
- If a Map contains fields with the same name the field will be converted into an Array and the values will be pushed
Expressions
Input/output parameters can be set using expressions. The bpmn-engine has built in expression handling that is documented here.
Tip! Since all parameter values are treated as strings, typed booleans and numbers can defined using: ${true}
, ${false}
, or ${1234}
.
Input parameters
Input parameters will be available under content.input
.
Process state
If a state
input parameter is defined it will be mapped as process state. States can be one or many. The input parameter can be either a Map or a script returning an object.
Example Map:
field name | type | description |
---|---|---|
id | string | example: state-1 |
name | (optional) string | example: My first state |
order | (optional) integer | display order |
description | (optional) string | description |
user | (optional) array | allowed user |
role | (optional) array | allowed roles |
Output parameters
Input parameters will be available under content.output
.
Process state
If a state
output parameter is defined it will be mapped as process state. States can be one or many. The output parameter can be either a Map or a script returning an object.
A script can be preferred since a complex object can be set:
next(null, {
id: 'state-1',
result: {
done: true,
error: false,
skipped: false,
timestamp: new Date(), // defaults to current date/time if not set
statuscode: 200, // defaults to 200 if not an error
statusmessage: 'OK',
link: '/',
link_text: 'Back to root',
user: 'username' // defaults to current user if not set,
meta: {} // se example below
}
});
Not all properties of result has to be used
The meta
field can be used to set custom fields, here is example code:
next(null, {
id: content.id,
result: {
done: true,
meta: {
elapsed_time_for_this_step: elapsedTimeForThisStep
},
}
});
NB! It is not recommended to update state for the current running process via API. This can cause conflicts. If you want to set state for the current process, always do it in flow via
state
input/output.
Process status
Input/Output can also be used to manipulate process status using a parameter named status
. The status can contain the following properties:
Example Map:
field name | type | description |
---|---|---|
statuskey | (optional) string | can be one of start , continue , complete , pause , or stop |
statuscode | (optional) integer | HTTP status code |
statusmessage | (optional) string | Status message |
error | (optional) boolean | has the process errored |
data | (optional) object | object with additional data |
NB! The status should only be set at the end of a process, typically in an end event. Setting the status at any other stage in the process flow may lead to unexpected behavior, especially concerning the
statuskey
.
ServiceTasks
The name is also the same name you use as Connector Id
in the Camunda modeler. First, select Connector
as Implementation in the service task. Arguments can then be used as input parameters.
onifyApiRequest(options[, callback])
onifyApiRequest(options[, callback])
Make an Onify API request with the user currently running the flow.
Arguments:
options
: a string with the requested URI, or an object with:url
: (required) the request URL, accepts relative api URL e.g./my/settings
without api versionquery
: (optional) optional object containing search parameters. Will be stringified using node.js built in functionquerystring.stringify
method
: (optional) the request HTTP method (e.g.POST
). Defaults toGET
headers
: (optional) an object with optional request headers where each key is the header name and the value is the header contentauthorization
: (optional) override authorization
throwHttpErrors
: (optional) boolean indicating that non 200 responses will throw an error, defaults totrue
payload
: (optional) a string, buffer or object containing the request payload
Returns:
statusCode
: the HTTP status codestatusMessage
: the HTTP status messageheaders
: an object containing the headers setpayload
: the response raw payloadbody
: response body, parsed as JSON
onifyElevatedApiRequest(options[, callback])
onifyElevatedApiRequest(options[, callback])
Same as onifyApiRequest
but with admin privilegies.
httpRequest(options[, callback])
httpRequest(options[, callback])
Make an external HTTP request. The request library used is npm module got.
Arguments:
options
: required object passed to got:url
: (required) the request URLquery
: (optional) optional object containing search parameters. Will be stringified using node.js built in functionquerystring.stringify
method
: (optional) the request HTTP method (e.g.POST
). Defaults toGET
headers
: (optional) an object with optional request headers where each key is the header name and the value is the header contentauthorization
: (optional) override authorization
throwHttpErrors
: (optional) boolean indicating that non 200 responses will throw an error, defaults totrue
payload
: (optional) a string, buffer or object containing the request payload
Returns:
statusCode
: the HTTP status codestatusMessage
: the HTTP status messageheaders
: an object containing the headers setbody
: response body
Signal Process Activity via API
This feature (requires API version 2.30+) enables signaling a process to continue from a paused or waiting activity by sending a custom payload.
The process can be signaled when it is waiting for any of the following activities:
- Receive Task
- User Task
- Manual Task
- Message Intermediate Catch Event
- Signal Intermediate Catch Event
Signal Activity (User)
Endpoint: PUT /api/v2/my/processes/{id}/signal/{activity}
Description: Signal a specific activity within a user's process to proceed.
Path Parameters:
id
(string, required): The unique identifier of the process.activity
(string, required): The activity identifier to signal.
Request Body: (object, optional)
- An arbitrary JSON payload relevant to the process or the activity.
Headers:
Authorization
(required): Bearer token.
Example cURL Request:
curl -X PUT "http://0.0.0.0:8181/api/v2/my/processes/1234/signal/userTask1" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"inputData": "value",
"userAction": "approve"
}'
Signal Activity (Admin)
Endpoint: PUT /api/v2/admin/processes/{id}/signal/{activity}
Description: Signal a specific activity within an administrative process to proceed.
Path Parameters:
id
(string, required): The unique identifier of the process.activity
(string, required): The activity identifier to signal.
Request Body: (object, optional)
- An arbitrary JSON payload relevant to the process or the activity.
Headers:
Authorization
(required): Bearer token.
Example cURL Request:
curl -X PUT "http://0.0.0.0:8181/api/v2/admin/processes/5678/signal/messageCatchEvent1" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"messageContent": "data",
"triggerReason": "externalSignal"
}'
JavaScript
Onify flow supports javascript in a ScriptTask, as SequenceFlow condition, or in Input/Output parameters.
NB! The flow execution stalls until next has to be called for the flow to continue.
NB! All scripts timeout after 60 seconds (unless you use async functionality). So keep them short and simple. You can also override the script timeout by setting extension property
scriptTimeout
(in milliseconds), eg.${120000}
.
Global context
Since script will be sandboxed they have some specific global properties and functions that can be addressed directly or under this
.
When in doubt on where to find your information insert this script:
console.log(this);
next();
fields
fields
Object with information regarding the message that executed activity.
content
content
Object with information of the current running activity.
Here you can find input and/or output that was defined for the activity execution.
properties
properties
Object with properties of the message that executed activity.
environment
environment
Flow execution environment.
contextName
contextName
Name of running flow.
next(err, result)
next(err, result)
Must be called when script is completed.
Buffer.from(...args)
Buffer.from(...args)
Node.js function Buffer.from.
Useful for encoding and decoding Base64.
Encode as base64
Example:
Buffer.from('Hello world').toString('base64');
Decode base64
Example:
Buffer.from('SGVsbG8gd29ybGQ=', 'base64').toString();
console.log(...args)
console.log(...args)
Basic javascript console.log('Hello world')
. Write something on stdout. Will end up in console or in a container log.
decrypt(encryptedText, encoding = 'hex')
decrypt(encryptedText, encoding = 'hex')
Decrypt an encrypted text with defined Onify client secret.
encrypt(text, encoding = 'hex')
encrypt(text, encoding = 'hex')
Encrypt text with defined Onify client secret.
jwt.sign(...)
jwt.sign(...)
Create a signed JWT using npm module jsonwebtoken sign function.
jwt.verify(...)
jwt.verify(...)
Verify a signed JWT using npm module jsonwebtoken verify function.
Cleaning Up Process Instances Using History TTL
Starting from API version 2.30, it is possible to configure when process instances should be removed, streamlining workflow maintenance and keeping your process history manageable. The History Time-to-Live (TTL) setting allows you to define the retention period for completed process instances on a per-workflow basis.
The History TTL specifies how long completed process instances should remain in the database. You can configure this as either a specific date or a duration using the ISO 8601 format. Additionally, the TTL can be dynamically set using variables and logic to adapt to different workflows and business rules. The cleanup operation is executed once per day, and instances exceeding the TTL value are automatically removed during this routine task.
If no TTL is specified for a workflow, the process instances will remain indefinitely, ensuring that historical data is not deleted unless explicitly configured.
Configuration
The History TTL can be configured directly in the BPMN modeler. You can set this value per workflow to customize the retention period for each workflow. The TTL can be defined as either:
- A specific date (e.g.,
2024-12-31T23:59:59Z
). - A duration in ISO 8601 format (e.g.,
P30D
for 30 days). - A dynamic value using workflow variables and logic to calculate the TTL based on the process context (e.g.
${calculatedTTL}
).
By setting an appropriate TTL, you can ensure that your process history is efficiently managed, reducing database clutter and improving performance. If indefinite retention is desired, simply leave the TTL unset.
Screenshots
Your processes
BPMN 2.0 diagram
Blueprints
To more easily get started. Have a look at our Blueprints for Flow on GitHub.
API endpoints
Workflow API endpoints
Here you can find out more information about the different API endpoints for workflows.
- Admin endpoints: https://support.onify.co/reference#workflows-1
- My endpoints: https://support.onify.co/reference#workflows
Process API endpoints
Here you can find out more information about the different API endpoints for running processes.
- Admin endpoints: https://support.onify.co/reference#processes-1
- My endpoints: https://support.onify.co/reference#processes
Updated 19 days ago