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 | Description |
|---|---|
model | The record that triggered the event (e.g., the user or award record) |
original | The original values before the update (for update triggers) |
causer | The user who triggered the event, if available |
model.name, model.email, causer.id.
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 | changed("rank_id") |
old_value(key) | Get the previous value of a changed field | old_value("rank_id") |
new_value(key) | Get the new value of a changed field | 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: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") }} |
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 }} |
join | Join array elements | {{ model.tags | join(", ") }} |
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 }} |
upper | Convert to uppercase | {{ model.name | upper }} |
title | Convert to title case | {{ model.name | title }} |
trim | Remove surrounding whitespace | {{ model.notes | trim }} |
striptags | Remove HTML tags | {{ model.description | striptags }} |
slice | Extract a portion | {{ model.notes | slice(0, 100) }} |
replace | Replace text | {{ model.text | replace({"foo": "bar"}) }} |
nl2br | Convert newlines to HTML breaks | {{ model.notes | nl2br }} |
round | Round a number | {{ model.score | round }} |
split | Split string into array | {{ model.tags_string | split(",") }} |
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. 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