Macros: reusable replies with Liquid variables
Updated Sep 18, 2026
A macro is a saved reply you can drop into the composer. Macros live in
Settings → Macros and are available from the ticket composer.
What a macro has
- Name — how you find it in the picker.
- Content — the text, which may contain Liquid template syntax.
- Shortcut (optional, up to 20 characters) — a short handle such as
/refund. - Category and tags — for organising a growing library.
- Visibility —
team(default, everyone in the workspace) orpersonal
(just you).
Aigento counts how often each macro is used and when it was last used, so you
can see which ones are earning their keep.
Variables
Macro content is rendered with Liquid, so it supports both variable
substitution and conditionals. The picker renders the macro against the ticket
you have open before inserting it, so what lands in the composer is the final
text, not a template.
The Variables button next to the Content field lists everything a macro
can say and inserts it at the cursor, including this workspace's custom
fields.
The following values are available:
| Variable | Value |
|---|---|
{{ customer.name }} | The customer's name, or Customer if unknown |
{{ customer.email }} | The customer's email address |
{{ ticket.subject }} | The ticket subject |
{{ ticket.status }} | Current status |
{{ ticket.priority }} | Current priority |
{{ agent.name }} | Your name, or Agent if not set |
{{ agent.email }} | Your email address |
Your custom fields are available under the same names you gave them:{{ ticket.<key> }} and {{ customer.<key> }}. A field whose key matches one
of the built-ins above is not reachable — the built-in wins — so those are left
out of the Variables list.
Store and orders
The ticket's Shopify store and its orders are available too, under Shopify's
own field names:
| Variable | Value |
|---|---|
{{ ticket.store.name }} | The ticket's store |
{{ ticket.store.domain }} | Its domain |
{{ ticket.orders[0].name }} | The first order linked to this ticket |
{{ ticket.orders[0].fulfillment_status }} | fulfilled, partial, or empty |
{{ ticket.orders[0].total_price }} | The order total |
{{ ticket.orders[0].line_items[0].sku }} | The first item's SKU |
{{ customer.orders[0].name }} | The customer's most recent order |
ticket.orders are the orders linked to the ticket, oldest first;customer.orders are the customer's ten most recent orders for that store.
Both are empty when nothing is linked yet, when the orders have not been
fetched from Shopify, or when Aigento cannot tell which store the ticket
belongs to — so wrap them in a condition before promising anything:
{% if ticket.orders[0] %}Your order {{ ticket.orders[0].name }} is on its way.{% endif %}Because it is Liquid, conditionals work too:
Hi {% if customer.name %}{{ customer.name }}{% else %}there{% endif %},
Thanks for getting in touch about "{{ ticket.subject }}".
— {{ agent.name }}Nothing else is exposed to the template. If a macro references a variable that
does not exist it renders as empty rather than failing.
Previewing
Under the Content field, Preview with a real ticket renders the macro
against a ticket you pick, so you can see what a customer would read before
saving. It runs when you press Render preview — not while you type. If the
Liquid has a mistake the error appears there instead of the output.
A macro that fails to render inserts nothing in the composer and shows the
error, so an unfinished {% if %} can never reach a customer.
After inserting
A macro is only a starting point — the rendered text lands in the composer and
you can edit it before sending. Inserting a macro does not send anything and
does not change the ticket.