Learn how to use triggers to build logic in apps without writing code.
This topic is featured in the Basic App Design and Logic course in Tulip University.
In this article, you will learn:
- Trigger commands, logic, and execution behavior
- Best practices for building and organizing triggers
- Common use cases
Triggers allow you to add logic to your app. You can use triggers to interact with devices, send alerts, write data, communicate with backend systems, and more - all without writing a single line of code.
Common trigger use cases include:
-
Navigate within an app: Use a transition to go to a different step.
-
Complete an app: Log the metadata of the app.
-
Run a connector function to access a back-end system: Use Connectors to enable Tulip to interact with third-party systems and run a connector function via a trigger.
-
Send alerts: Send emails or SMS alerts from an app to an administrator. These messages can include images, status information about the process, or other relevant information.
-
Store data: Store input data from an app into variables or tables.
-
Use a device : For operators using both hands during a process, add a trigger for a device event, such as a footpedal, to advance to the next step.
How do triggers work?
Logic
Triggers use a when, if, then, else logic structure:
- when "event registers in Tulip"
- then "take action" or "make transition".
Triggers can also contain conditional logic:
- when "event registers in Tulip"
- if "condition is met"
- then "take action"
- else "take a different action"
Learn more about conditional trigger logic here.
Triggers are bundled by a Trigger Event and consist of Action and conditionals.
Triggers can be simple like the example below:
When a button is pressed, then go to the next Step.
Or, triggers can be more complex, like a barcode scan that queries a backend database to return order information as a variable.
When the barcode scanner outputs at the current Station, then an API Call (run through a Connector Function) retrieves the order details from an external database and stores the value in a Variable. The trigger also then Transitions to the next step.
Types of commands
You can use two types of commands in a trigger:
-
Action: A change in the app that is not related to changing steps (ex. show an error message, send an email, capture an app screenshot)
-
Transition: A navigation event in the app itself (ex. go to the next step, complete an app, cancel an app).
Transitions are can allow other triggers to fire (i.e. start). For example, you can create a app level trigger that fires every time the app is completed.
Trigger queue
Trigger Events (e.g. clicking on a button) adds Triggers to a sequential single-threaded Trigger Queue to be executed in the Tulip Player.
The Trigger Queue impacts:
- Functions:
- Functions are included in the Trigger Queue
- Custom Widgets:
- Execution of logic in a Custom Widget may impact the Trigger Queue
Automations run in the background, not in an app (even if the Automation is initiated by an action performed in the app), and therefore are not added to the trigger queue.
Order of execution
Triggers run in a series and in order based on the Trigger Event (i.e. button click, timer, table row select).
Triggers run sequentially, meaning the first trigger in the series must complete before the second trigger starts executing. This order of trigger execution is known as the trigger queue.
The trigger queue is separate from other tasks within an app, such as operator interactions (i.e. typing into inputs, clicking buttons, or using custom widgets) or custom widget JavaScript.
How are input values used in triggers?
Input values (i.e. variables) are passed by reference to triggers.
Triggers reference the input value of a variable at the time of the trigger execution. If the input value changes before a trigger executes, the trigger will reference the most up-to-date value.
Variables are global to an app, which makes them changeable by other logic in the app.
When do triggers cancel?
Triggers in the trigger queue are canceled, and therefore will not execute, when:
-
A trigger is queued after a transition
When a Transition is executed (i.e. Next, Complete app, Go to step by name, etc.), any triggers remaining in the queue are canceled. -
Force closing the Tulip Player
If an operator force closes the Player (i.e. if an app is unresponsive), any remaining actions in a running trigger and all remaining triggers in the queue are canceled.
Error handling
Trigger errors and subsequent cancellation will occur during the following scenarios:
- Trigger action error
- Trigger time out
Trigger action error
The Show Error action (show a message to the operator with a red background) does not count as a trigger error.
When an action in a trigger errors, the remaining Actions in that trigger are skipped/cancelled:
After an error, by default, any remaining triggers in the queue and in the trigger event will not execute for the following app and step-level triggers:
- App started
- App completed
- App cancelled
- On step enter
- On step exit
For all other types of triggers (e.g. When button is pressed), the “Stop remaining triggers on error” toggle is disabled by default.
Trigger time out
If a trigger is timed out (see Trigger Timeouts), all remaining triggers in the queue will be cancelled.
Technical behavior
Trigger runtime
- Triggers are executed sequentially in a single trigger runtime. A trigger runtime is the period when a trigger is actively executing in Tulip.
- Triggers never execute in parallel or in the background of other triggers. A new trigger cannot begin executing until the current, running trigger is finished.
- Operators can still interact with the app (e.g. click on buttons, interact with tables) while a trigger is executing. These button clicks and other trigger events will add new triggers to the trigger queue.
Trigger timeouts - updated as of LTS15 / r332
The default trigger timeout period is 10 minutes, after which the trigger and any remaining actions will cancel, and all other triggers in the queue will be canceled.
The 10 minute timeout period applies to the Trigger Event. For example, if a button click has 5 triggers, all 5 triggers in the trigger queue and their respective actions must execute within the 10 minutes.
After 30 seconds of trigger runtime, the app displays the following message to the operator:
After 100 seconds of trigger runtime, the app displays the following message to the operator:
After 10 minutes, the trigger is canceled and the app displays the following error message:
Optional timeout settings
Edit timeout settings for an instance via the methods below:
-
Tulip can enable or disable a setting that allows operators to manually cancel a long-running trigger after the first 100 seconds. Contact Tulip Support to enable this feature.
-
Tulip Support can decrease or increase the timeout period.
Note that Tulip recommends the 10 minute timeout period as a starting point, to increase the likelihood that your logic runs to completion.
If a trigger consistently takes longer than a few minutes to execute, consider the following:- Simplifying the trigger logic to improve operator experience and reduce likelihood of trigger failure.
- If possible, initiate an Automation in the background to offload the logic execution and mitigate blocking the operator’s continued work.
- Review and optimize any dependencies on third party systems in the trigger logic (e.g. slow Connector Functions, nonoptimal API used).
Table record actions
Inconsistent sequencing of Trigger Actions will result in inconsistent user experience when reviewing audit trails in the Record History Widget.
Table record create
For creation of a new Table Record, best practice is to immediately follow the Table Record / Create Record action with the corresponding Data Manipulation actions to populate the other columns of the newly-created table record.
If there are other actions between the Table Record / Create action and the actions to populate the other columns, the generation of that table record will show as separate events in the record history widget.
Table record create – as of LTS15 / r332
As of LTS15, sequential table actions of Table Record / Create Record and Data Manipulation / Store will bundle for the same record. This means the Create and Data Manipulation actions in a trigger execute in one transaction.
The Create Record and Data Manipulation / Store actions will not bundle in one transaction if any other actions reside between them (e.g. data manipulations to variables or other table records, connector functions, etc…).
In the following example triggers, the Create Record action and Data Manipulation / Store actions will be bundled and either all succeed or all fail. If the actions all fail, they will be retried together with resilient retries.
Example 1: Sequential Create and Data Manipulations to the same table record
These would either all succeed or all fail in LTS15, but not pre-LTS12.
Example 2: Sequential Create and Data Manipulations to the same table record followed by a Connector Function action
The Table Record Create and Data Manipulation actions themselves would be bundled in LTS15. The Connector Function action could fail regardless of the table actions succeeding.
In the following trigger, Data Manipulation / Store actions are occurring for two different table records, and thus the actions will not be bundled in a single transaction.
Example 3: Table Record / Create and Data Manipulation / Store to the same table record separated by another Data Manipulation action
These actions will not be bundled in a single transaction.
In the following trigger, the Table Record and Data Manipulation / Store actions will not be bundled because metadata from the table record created in the preceding action is being used as the data input of the Data Manipulation / Store action.
Example 4: Create and update reading data from itself
These actions will not be bundled in a single transaction.
When using an aggregation in a bundled table update action, the aggregation value is taken before the update occurs. The aggregation value will not reflect the bundled table record update.
Example 5: Create and update with aggregations
These actions will be bundled, and the aggregation value is taken before the the create action occurs.
Table record update
Sequential Data Manipulation actions to the same table record are bundled to be executed in one network request, so they all happen together
Trigger Actions involving Table Records are grouped based on their action type and order. Store actions that have the same store location are grouped in one network request. Whereas, actions such as Load record or Create record are treated as individual transactions.
For best performance, we recommend sequencing updates to the same record together – i.e. not breaking up updates to the same record with other table or data actions.
Example 1: Sequential updates to the same record
These actions will bundle in one transaction:
Example 2: Updates to the same record separated by other actions
These actions will not bundle together, because the same table records are not sequential:
In the following trigger, Data Manipulation / Store actions are occurring for two different table records, and thus the actions will not be bundled in a single transaction.
Example 3: Updates to two different records
These actions will not be bundled in a single transaction.
When using an aggregation in a bundled table update action, the aggregation value is taken before the update occurs. The aggregation value will not reflect the bundled table record update.
Example 4: Updates that include aggregations
These actions will be bundled, which means the aggregation value computed is before the update occurs.
Trigger (table action) retries - new as of LTS15 / r332
Triggers only retry table actions (e.g. table data writes, table data updates, table interactions, etc.).
Within the 10 minutes of trigger runtime, if a single table action fails then it will retry for up to 2 minutes. If the action fails to execute after 2 minutes, any remaining actions and triggers within the trigger queue will cancel.
For a network resilient trigger, ensure a trigger’s actions include only table interactions and data updates. See Table Record Actions for guidance about resilient table actions.
Connector function calls, send emails, and machine monitoring would not be network resilient in LTS15.
Trigger action retries will not duplicate the outcome if the action accidentally runs twice. This ensures that a table action will not write multiples of the same data.
Limits and Timeouts
Setting / Description | Limit |
---|---|
Triggers Event Timeout - Once this time limit is reached, all triggers associated with that event will error and clear from the trigger queue. | - LTS15/r332: Trigger Events have a timeout of 10 minutes. - (pre LTS15/r332): Trigger events have a timeout of 100 seconds. |
Trigger Queue - Once this limit is reached, new trigger events will cancel and not execute. | The trigger queue can hold up to 100 trigger events by default. |
# of Consecutive Triggers caused by a Transition | The trigger queue will execute up to 100 consecutive triggers caused by a transition, i.e. button trigger transition to step 1 → step open runs 2 triggers → transition to step 2 → step close runs 3 triggers → step open runs 1 trigger, etc. Once this limit is reached, new transition triggers will be canceled. |
Transition Trigger Timeout - Timeout for transition triggers such as “Go to Step” to complete | - LTS15/r332: 25 Seconds (Configurable) |
Types of triggers
There are three types of triggers:
App level triggers
You can apply App Level Triggers to the following events:
- App start
- App completed
- App canceled
Access app level triggers from the App Tab.
Learn more about app level triggers here.
Step level triggers
You can apply Step Level Triggers to the following events:
- At regular time intervals (“time fires”)
- When there is an input from a machine or device (“machines & devices”)
- When the Step is opened
- When the Step is closed
Access step level triggers from the Step Tab.
Learn more about step level triggers available here
Widget triggers
Widget triggers are activated when a button is pressed. There can be multiple button Triggers on a Step that are triggered when the respective button is pressed by an operator in the Tulip Player.
Select the desired widget, and then access widget triggers from the Widget Tab.
Learn more about widget triggers here.
Create a trigger
- From the Side Pane, click + in the Triggers section. The trigger editor will open.
- Name your trigger to identify what it does in the app. You can also include a description for more details.
Best practices
- Configure triggers to accommodate errors
Triggers should be configured to proceed or stop in the event of an error. A Trigger can error due to invalid inputs, an execution error, or a failed connector function or table write attempt.- When a trigger is configured to proceed, the trigger that errored will stop, but the next trigger will proceed
- When a trigger is configured to stop, the other triggers in the Trigger Event will be cancelled.
-
Avoid having long-running triggers on a step with interactive widgets
Widgets visually change state immediately upon interaction. While the operator sees the action take place immediately on the widget, the logic may execute with a slight delay because of slow network or a long-running connector. -
Train operators to wait after clicking a transition (e.g. Next Step)
On a step, triggers queued after a transition will not execute. If an operator engages with a widget that has a transition, they will remain on the step until the transition is executed. For example, if the operator clicks “Next step” and then engages another trigger while waiting, the remaining trigger after the transition will not execute. -
Perform a long-running connector and data updates on separate steps
Interactions with sensitive data should not be performed on the same step as long-running connector logic. In the event an operator interacts with the step after clicking on a long-running trigger or transition, there is a risk of critical data not being stored. -
Ensure variables have a single input for each step
Variables should not be shared with competing input logic (i.e. multiple buttons in an app updating the same variable) to avoid race conditions. For example, a trigger capture the current value of a variable. If the value of the variable changes before a trigger captures it, then the data will be incorrect.
Further reading
- List of trigger actions and transitions
- Conditional trigger logic
- Best practices for high performance apps