Message Templates
Message templates allow you to customize email and SMS notifications sent by Fentrica. Templates use the Handlebars templating engine with additional custom helpers for advanced logic.
Accessing Message Templates
Message templates have their own page, available to organization admins:
- Open the account menu (your organization name, top-right)
- Choose Message Templates
- Click on a template to edit, or use New to create one
When creating a template you choose only a Name, Type, and Scope; the body is pre-filled with the platform default for that type and can then be edited.
Template Scope
Each template is scoped to either the whole organization or a single property:
- Organization-wide (default,
propertyIdis empty) — applies to every site in the organization. - Property-specific — applies only to the selected property and overrides the organization-wide template of the same type for that site.
At send time the template is resolved with the following precedence:
- Property-specific template for the message's property
- Organization-wide template of that type
- Built-in platform default
There can be at most one organization-wide template per type, and at most one template per (property, type). Use an organization-wide template as the baseline and add property-specific templates only where a site needs different content.
Editing in the template editor
The Body and HTML Body fields use a code editor with syntax highlighting for {{ }} expressions. Typing inside {{ }} offers autocomplete for the available variables (e.g. user.firstname, ticket.title) and helpers (if, each, compare, …). The HTML Body editor additionally highlights HTML markup.
Template Types
Fentrica supports the following message template types:
Access & Authentication
| Type | Description |
|---|---|
| Access PIN E-mail | PIN code delivery via email to Access Group Users |
| Access PIN SMS | PIN code delivery via SMS to Access Group Users |
| Access App Invitation E-mail | App invitation via email to Access Group Users |
| Access App Invitation SMS | App invitation via SMS to Access Group Users |
Task Notifications (to Service Providers)
| Type | Description |
|---|---|
| Task Assigned E-mail | Notification when a task is assigned |
| Task Updated E-mail | Notification when a task receives comments |
| Next Week Tasks E-mail | Weekly summary of upcoming tasks |
| Task Closed E-mail | Notification when a task is closed |
Maintenance Request Notifications (to Reporters)
| Type | Description |
|---|---|
| Maintenance Request Commented E-mail | Notification when a request receives comments |
| Maintenance Request Resolved E-mail | Notification when a request is resolved |
| Maintenance Request Closed E-mail | Notification when a request is closed |
Automation
| Type | Description |
|---|---|
| General Automation Template | Custom templates for rule-based automations |
Template Fields
Each template has the following configurable fields:
| Field | Description | SMS | |
|---|---|---|---|
| Name | Template identifier | Yes | Yes |
| Type | Template type (see above) | Yes | Yes |
| Body | Plain text message content | Yes | Yes |
| HTML Body | Rich HTML content | Yes | No |
| Subject | Email subject line | Yes | No |
| From Name | Sender display name | Yes | Yes |
| Reply-to Name | Reply-to display name | Yes | No |
| Reply-to Address | Reply-to email address | Yes | No |
Template Syntax
Templates use Handlebars syntax. Variables are inserted using double curly braces.
Basic Variable Insertion
Hello {{user.firstname}} {{user.lastname}}!
Your access PIN is: {{user.pin}}
Conditional Blocks
{{#if user.title}}
Dear {{user.title}} {{user.lastname}},
{{else}}
Dear {{user.firstname}},
{{/if}}
Iterating Over Arrays
{{#each tasks}}
- {{this.name}}: {{this.description}}
{{/each}}
Available Variables
Variables can be injected into templates using {{variable}} syntax. Available variables depend on the context of the message.
User Variables
| Variable | Description |
|---|---|
user.firstname | User's first name |
user.lastname | User's last name |
user.title | User's title |
user.email | User's email address |
user.phone | User's phone number |
user.pin | User's access PIN code |
Organization Variables
| Variable | Description |
|---|---|
org.name | Organization name |
org.alias | Organization alias |
org.regno | Registration number |
org.vatno | VAT number |
org.street | Street address |
org.zip | Postal code |
org.city | City |
org.state | State/Province |
org.country | Country |
Access Group Variables
| Variable | Description |
|---|---|
accessGroup.name | Access group name |
Property & Unit Variables
| Variable | Description |
|---|---|
property.name | Property name |
property.timezone | Property timezone |
unit.name | Unit name |
Alarm Variables
| Variable | Description |
|---|---|
alarm.priority | Alarm priority level |
alarm.class | Alarm classification |
alarm.source | Alarm source |
alarm.state | Current alarm state |
alarm.activatedAt | Activation timestamp |
alarm.resolvedAt | Resolution timestamp |
deviceAlarmDefinition.name | Device alarm name |
deviceAlarmDefinition.description | Device alarm description |
deviceAlarmDefinition.nodeId | Device node ID |
analyticAlarmDefinition.name | Analytic alarm name |
analyticAlarmDefinition.description | Analytic alarm description |
Maintenance Request, Task & Comment Variables
| Variable | Description |
|---|---|
ticket.number | Maintenance request number |
ticket.title | Request title |
ticket.description | Request description |
ticket.state | Request state |
task.number | Work order number |
task.name | Work order name |
task.description | Work order description |
task.deadline | Work order deadline |
comment.content | Comment text |
externalPartner.firstname | Service provider first name |
externalPartner.lastname | Service provider last name |
externalPartner.email | Service provider email |
Some variables may be undefined if the associated resource is not attached to the message job. Always use conditional blocks when a variable might not be present.
Custom Helpers
Fentrica extends Handlebars with additional helper functions for advanced template logic.
Comparison Helper
The compare helper allows comparing two values with various operators.
Syntax: {{#if (compare value1 "operator" value2)}}...{{/if}}
Supported operators: ==, ===, !=, !==, <, <=, >, >=
{{#if (compare alarm.priority ">" 3)}}
URGENT: This is a high priority alarm!
{{/if}}
{{#if (compare alarm.state "==" "active")}}
Alarm is currently active.
{{/if}}
Logical Operators
Or Helper
Returns true if ANY of the arguments are truthy.
{{#if (or user.email user.phone)}}
We can contact you via {{user.email}}{{user.phone}}
{{/if}}
And Helper
Returns true if ALL of the arguments are truthy.
{{#if (and user.firstname user.lastname)}}
Full name: {{user.firstname}} {{user.lastname}}
{{/if}}
Array Helpers
Index Helper
Get an element at a specific index from an array.
Syntax: {{index array position}}
First item: {{index items 0}}
Second item: {{index items 1}}
Last Helper
Get the last element from an array.
Syntax: {{last array}}
Most recent: {{last readings}}
String Helpers
Split Helper
Split a string by a delimiter, returning an array.
Syntax: {{split string "delimiter"}}
{{#each (split address ",")}}
{{this}}
{{/each}}
Trim Helper
Remove leading and trailing whitespace from a string.
Syntax: {{trim string}}
Name: {{trim user.firstname}}
Number Helpers
ToNumber Helper
Convert a value to a number.
Syntax: {{toNumber value}}
{{#if (compare (toNumber stringValue) ">" 100)}}
Value exceeds 100
{{/if}}
Between Helper
Check if a value falls between a minimum and maximum (inclusive).
Syntax: {{#if (between value min max)}}...{{/if}}
{{#if (between temperature 18 24)}}
Temperature is in comfortable range.
{{else}}
Temperature is outside comfortable range!
{{/if}}
Examples
Access PIN Email
Dear {{user.firstname}},
Welcome to {{org.name}}!
Your access credentials for {{accessGroup.name}}:
PIN Code: {{user.pin}}
Best regards,
{{org.name}}
Alarm Notification
{{#if deviceAlarmDefinition.name}}
Alarm: {{deviceAlarmDefinition.name}}
{{/if}}
{{#if analyticAlarmDefinition.name}}
Alarm: {{analyticAlarmDefinition.name}}
{{/if}}
Priority: {{alarm.priority}}
{{#if (compare alarm.priority ">=" 4)}}
⚠️ This is a HIGH PRIORITY alarm requiring immediate attention!
{{/if}}
Status: {{alarm.state}}
Triggered: {{alarm.activatedAt}}
{{#if alarm.resolvedAt}}
Resolved: {{alarm.resolvedAt}}
{{/if}}
Property: {{property.name}}
Task Assignment with Conditional Logic
Hello {{user.firstname}},
A new task has been assigned to you.
Task: {{task.name}}
{{#if task.description}}
Description: {{task.description}}
{{/if}}
{{#if (and task.dueDate (compare task.priority ">" 3))}}
⚠️ This is a high-priority task due on {{task.dueDate}}.
{{/if}}
Property: {{property.name}}
{{#if unit.name}}
Unit: {{unit.name}}
{{/if}}
Using String Manipulation
{{#with (split sensor.location "/")}}
Building: {{index this 0}}
Floor: {{index this 1}}
Room: {{last this}}
{{/with}}