Variables fill in real details when a workflow runs, like the client's first name or the appointment's start time. You can use them in any text field of a step: recipients, subjects, message content, conditions, URLs and request bodies.
A variable is an expression between double curly braces, like {{ $event.data.object.client.firstName }}. When the run reaches the step, Softalon replaces it with the value. Anything inside the braces works like a small piece of JavaScript.
Insert a variable
Click Insert Variable next to a field. The Select Variable dialog opens with Suggested Variables for that field. Click View All Variables to browse everything, or search by name. Pick a group to go deeper, then pick a value.
In fields like Recipient, the dialog only shows values that fit, for example email addresses for an email.
Below the text, a Preview shows how the message looks with example values.
Variable groups
What you can pick depends on the trigger and on the step before the current one.
Other is available in every workflow. Event and the record groups aren't available for Webhook and Manual workflows, because no event starts them.
Related records
For an appointment trigger, the appointment comes with its Client, Member, Service and Location. For example:
{{ $event.data.object.client.firstName }}: the client's first name{{ $event.data.object.member.firstName }}: the team member's first name{{ $event.data.object.service.name }}: the service name
Softalon loads related records, like the client or the service, when a step uses them as a plain variable, such as {{ $event.data.object.client.emailAddress }}. If you only use a related record inside a function or a comparison, also use it as a plain variable somewhere in the workflow. Otherwise its values may come out empty.
Previous values
On Updated triggers and other triggers that react to a change, $event.data.previousAttributes holds the old values of the fields that changed. Fields that didn't change aren't in it. For example, on Rescheduled, {{ $event.data.previousAttributes.startAt }} is the old start time.
Format dates, money and addresses
Date, amount and location variables offer formatted versions in the picker. You can also write them yourself:
Dates and times use your salon's time zone. In a message to the trigger's client who booked from another time zone, they use the client's time zone.
Action links
actionLink creates a short link that lets a client act on an appointment or invoice without signing in. Pass the record's ID and the action:
{{ actionLink($event.data.object.id, "confirm") }}{{ actionLink($event.data.object.id, "reschedule") }}{{ actionLink($event.data.object.id, "cancel") }}{{ actionLink($event.data.object.id, "review") }}
See Send a client a confirm, reschedule or review link for what each link does.
Expressions
Because the inside of the braces is JavaScript, you can do small transformations, like {{ $event.data.object.client.firstName.toUpperCase() }} or {{ $event.data.object.notes || "No notes" }}.
Some code isn't allowed for safety, such as defining functions, assigning values or reaching system objects. If you use it, the workflow can't be saved.
If an expression fails when the workflow runs, it's replaced with empty text and the run continues.
Common questions
The record may not have that value, like a client without a last name. Also check that related records are used as a plain variable somewhere in the workflow.