Use Cases
Automations are useful for:- Notifications: Send messages to team members when a user receives a new award or promotion
- External integrations: Trigger webhooks to sync data with external systems like Discord, Slack, or custom applications
- Approval workflows: Notify supervisors when new form submissions require review
- Audit trails: Send automated messages when critical personnel changes occur
- Onboarding: Welcome new users with automated messages when their accounts are created
How Automations Work
Each automation consists of three components:- Trigger: The event that starts the automation (e.g., “User Created” or “Award Record Updated”)
- Condition (optional): An expression that determines whether the action should execute
- Action: What happens when the automation runs (send a webhook or create a message)
Create an Automation
- In the sidebar, select Integrations > Automations.
- Select New automation.
-
Configure the automation settings:
- Name: A descriptive name for the automation
- Description: Optional explanation of what the automation does
- Priority: Lower numbers run first when multiple automations share the same trigger (default is 0)
- Enabled: Toggle to activate or deactivate the automation
- Select the 1. Trigger tab and choose the event that starts this automation.
- (Optional) Select the 2. Condition tab to add a conditional expression.
- Select the 3. Action tab and configure either a webhook or message action.
- Select Create.
Triggers
Triggers define which events start your automation. Select one trigger per automation. To respond to multiple events, create separate automations for each.Available Triggers
| Category | Events |
|---|---|
| User | User Created, User Updated, User Deleted |
| Assignment Record | Assignment Record Created, Updated, Deleted |
| Award Record | Award Record Created, Updated, Deleted |
| Combat Record | Combat Record Created, Updated, Deleted |
| Qualification Record | Qualification Record Created, Updated, Deleted |
| Rank Record | Rank Record Created, Updated, Deleted |
| Service Record | Service Record Created, Updated, Deleted |
| Calendar | Calendar Created, Updated, Deleted |
| Event | Event Created, Updated, Deleted |
| Message | Message Created, Updated, Deleted |
| Submission | Submission Created, Updated, Deleted |
Conditions
Conditions allow you to control when an automation executes based on the data in the triggered event. Conditions use expression syntax to evaluate whether the action should run.Expression Syntax
Conditions use the Symfony Expression Language syntax. Expressions must evaluate totrue for the action to execute.
Basic comparisons:
Available Context Variables
When writing conditions, you have access to these variables:| Variable | Type | Description |
|---|---|---|
model | object | The record that triggered the event (e.g., the user or award record) |
model_type | string | The fully qualified class name of the model (e.g., App\Models\User) |
model_id | integer | The ID of the model that triggered the event |
changes | object | An object containing changed fields with old and new values for each (update triggers only) |
causer | object | The user who triggered the event, if available |
causer_id | integer | The ID of the user who triggered the event |
now | datetime | The current date and time when the automation runs |
model["name"], model["email"], causer["id"].
The Changes Object
For update triggers, thechanges object contains only the fields that were modified. Each changed field has old and new properties:
changes.rank_id.old— The previous rank IDchanges.rank_id.new— The new rank ID
Full Context Example
Here’s an example of the complete context data available for a user update trigger:Built-in Functions
Use these functions in your condition expressions:| Function | Description | Example |
|---|---|---|
in_array(needle, haystack) | Check if a value exists in an array | in_array(model["status_id"], [1, 2, 3]) |
contains(haystack, needle) | Check if a string contains a substring | contains(model["email"], "@example.com") |
starts_with(haystack, needle) | Check if a string starts with a prefix | starts_with(model["name"], "Admin") |
ends_with(haystack, needle) | Check if a string ends with a suffix | ends_with(model["email"], ".gov") |
changed(key) | Check if a specific field was changed (checks if key exists in changes) | changed("rank_id") |
old_value(key) | Get the previous value of a changed field (shorthand for changes.key.old) | old_value("rank_id") |
new_value(key) | Get the new value of a changed field (shorthand for changes.key.new) | new_value("rank_id") |
blank(value) | Check if a value is empty | blank(model["notes"]) |
filled(value) | Check if a value is not empty | filled(model["discord_user_id"]) |
Condition Examples
Run only when a user is approved:Testing Conditions
Before saving your automation, test your condition:- Select a trigger to populate the available fields.
- Enter your condition expression.
- Select Test to evaluate the expression against sample data.
- Select View Fields to see all available fields for the selected trigger.
- Select View Functions to see all available functions.
Actions
Actions define what happens when an automation triggers and conditions pass. Each automation performs one action.Webhook Action
Webhook actions send HTTP requests to external URLs, enabling integration with third-party services.- Select Send Webhook as the action type.
- Choose an existing webhook from the dropdown.
- (Optional) Define a custom payload template using JSON and Twig syntax.
Note: Before creating a webhook automation, you must first create a webhook in Integrations > Webhooks.
Custom Payload Templates
Create custom JSON payloads using Twig template syntax. Use{{ variable }} to insert dynamic values.
Example: Discord webhook payload
Message Action
Message actions create notifications sent through your configured notification channels.- Select Send Message as the action type.
- Select one or more notification channels (Email, Database, Discord, SMS).
- Enter the message content using Twig syntax for dynamic values.
- (Optional) Specify a recipients expression to target specific users.
Message Content
Write your message content using Twig template syntax:Recipients Expression
Define who receives the message using an expression that returns user IDs: Send to the affected user:Update Resource Action
Update Resource actions modify existing records in your system based on automation triggers. This enables you to automatically update user profiles or other resources when events occur.Note: Currently, only User resources are supported for updates.
- Select Update Resource as the action type.
- Select the Target Resource (currently Users).
- Choose a Lookup Type to identify which record to update:
- Expression: Write an expression that returns the ID of the record to update
- Query: Define field conditions to find the record
- Configure the Field Updates with the fields and values to set.
Lookup Types
Expression Lookup Use an expression that evaluates to the ID of the record you want to update:| Field | Value |
|---|---|
email | {{ model.email }} |
status_id | 1 |
Field Updates
Define which fields to update and their new values. Values support Twig template syntax, giving you access to all context variables plus a specialtarget variable.
| Field | Value |
|---|---|
status_id | 2 |
notes | Updated by automation on {{ now | date('Y-m-d') }} |
rank_id | {{ target.rank_id | increment }} |
The Target Variable
When configuring field updates, you have access to atarget variable containing the current data of the record being updated. This allows you to reference existing values when setting new ones.
Example: Increment a user’s rank:
Resource Update Examples
Update user status when a form is submitted:- Trigger: Submission Created
- Condition:
model["form_id"] == 5 - Action: Update Resource
- Lookup Type: Expression
- Lookup Expression:
model["user_id"] - Field Updates:
Field Value status_id2
- Trigger: Award Record Created
- Condition:
model["award_id"] == 10 - Action: Update Resource
- Lookup Type: Expression
- Lookup Expression:
model["user_id"] - Field Updates:
Field Value rank_id{{ target.rank_id | increment }}
- Trigger: User Updated
- Condition:
changed("external_id") and filled(model["external_id"]) - Action: Update Resource
- Lookup Type: Query
- Query Conditions:
Field Value id{{ model.id }} - Field Updates:
Field Value verifiedtrueverified_at{{ now | date('Y-m-d H:i:s') }}
Twig Filters
Use Twig filters to transform values in your templates. Apply filters using the pipe syntax:{{ value | filter }}.
| Filter | Description | Example |
|---|---|---|
capitalize | Capitalize the first character | {{ model.name | capitalize }} |
date | Format a date | {{ model.created_at | date("Y-m-d") }} |
decrement(n) | Subtract from a number (default: 1) | {{ model.rank_id | decrement(2) }} |
default | Provide a fallback value | {{ model.nickname | default("N/A") }} |
escape | Escape HTML entities | {{ model.notes | escape }} |
first | Get the first array element | {{ model.tags | first }} |
increment(n) | Add to a number (default: 1) | {{ model.rank_id | increment(5) }} |
join | Join array elements | {{ model.tags | join(", ") }} |
json_encode | Encode value as JSON | {{ model | json_encode }} |
last | Get the last array element | {{ model.tags | last }} |
length | Get string or array length | {{ model.name | length }} |
lower | Convert to lowercase | {{ model.name | lower }} |
nl2br | Convert newlines to HTML breaks | {{ model.notes | nl2br }} |
raw | Output without escaping | {{ model.html_content | raw }} |
replace | Replace text | {{ model.text | replace({"foo": "bar"}) }} |
round | Round a number | {{ model.score | round }} |
slice | Extract a portion | {{ model.notes | slice(0, 100) }} |
split | Split string into array | {{ model.tags_string | split(",") }} |
striptags | Remove HTML tags | {{ model.description | striptags }} |
title | Convert to title case | {{ model.name | title }} |
trim | Remove surrounding whitespace | {{ model.notes | trim }} |
upper | Convert to uppercase | {{ model.name | upper }} |
View Automation Logs
Every automation execution is logged for debugging and auditing purposes.Access Logs
- In the sidebar, select Integrations > Automations.
- Select an automation to view its details.
- Scroll down to the Logs section to see execution history.
- In the sidebar, select Integrations > Automations > Logs.
Log Details
Each log entry includes:| Field | Description |
|---|---|
| Status | The execution result: Executed, Condition Failed, or Failed |
| Trigger | The event that triggered the automation |
| Subject | The record type and ID that triggered the event |
| Execution Time | How long the automation took to run (in milliseconds) |
| Executed At | When the automation ran |
- Overview: Status, timing, and error messages (if any)
- Subject: The triggering record details and the user who caused the event
- Condition: The expression evaluated and whether it passed
- Context: The full data context available to the automation
- Action Result: The payload sent or message created
Log Statuses
| Status | Description |
|---|---|
| Executed | The automation ran successfully |
| Condition Failed | The condition expression evaluated to false; no action was taken |
| Failed | An error occurred during execution |
Debugging Automations
When an automation doesn’t work as expected, use these strategies to diagnose the issue.Check the Automation Is Enabled
Disabled automations do not run. Verify the Enabled toggle is active on the automation’s settings page.Review Log Entries
- Open the automation and check the Logs section.
- Look for entries with Failed or Condition Failed status.
- Select a log entry to view the error message and context.
Test Your Condition
- Edit the automation and go to the 2. Condition tab.
- Select Test to evaluate your expression against sample data.
- Select View Fields to verify you’re using the correct field paths.
Verify Field Paths
Field paths are case-sensitive and must use array syntax in expressions. Use View Fields to see the exact structure of the context data, including:- Property names (e.g.,
model["name"], notmodel["Name"]) - Nested relationships (e.g.,
model["user"]["email"]) - Available fields for the selected trigger type
Common Issues
Condition always fails:- Verify the field path matches the actual data structure
- Check for typos in field names
- Ensure you’re using the correct comparison operators
- Verify the webhook URL is correct and accessible
- Check that the target service is running
- Review the webhook configuration in Integrations > Webhooks
- Verify the notification channels are configured correctly
- Check the recipients expression returns valid user IDs
- Ensure users have the appropriate notification settings enabled
Preview Templates
Before saving, preview your templates to catch errors:- For webhooks: Select Preview next to the payload template field
- For messages: Select Preview next to the message content field
Best Practices
- Use descriptive names: Name automations clearly so their purpose is obvious (e.g., “Notify Discord on User Promotion”)
- Start with conditions: Add conditions to prevent automations from running unnecessarily
- Test before enabling: Use the test and preview features to verify your expressions and templates
- Monitor logs: Regularly review automation logs to catch failures early
- Use priority: Set priority values to control execution order when multiple automations share triggers
- Keep templates simple: Complex templates are harder to debug; break complex workflows into multiple automations