Skip to main content
Several fields you configure - ticket channel names, welcome messages, application titles, submission messages, DM messages support a small templating syntax so the text can adapt to who’s involved. It’s a purpose-built engine, not a general-purpose template library - it only implements the handful of features below, which keeps it fast and predictable. This page covers the syntax itself and exactly which variables you can use where.

Output tags: {{ }}

Wrap a variable name in double curly braces to insert its value.
If author.username is alex, this renders as:
Variables can be nested with dots, e.g. {{author.username}}, {{server.name}}. Spacing inside the braces doesn’t matter - {{author.username}} and {{ author.username }} are the same. If a variable doesn’t exist in the current context (see the tables below), the tag renders as empty rather than erroring. There’s also always a {{now}} variable available everywhere, even without any context - the current time, as a Unix timestamp in seconds. It’s mainly useful inside a Discord timestamp tag:

Conditional tags: {% if %}

Wrap alternate text in {% if condition %}...{% else %}...{% endif %} to show different text depending on a variable. A condition can be:
  • Truthy - just a variable name, e.g. {% if fruit %}. True when fruit has any value at all; false when it’s unset.
  • Equality - {% if fruit == "apple" %} or {% if fruit != "apple" %}. Quotes are optional for a single word (fruit == apple works too), but required if the value has spaces in it.
  • If fruit is set to apple, this renders as: You picked apple.
  • If fruit isn’t set at all, this renders as: No fruit picked yet.
The right-hand side of ==/!= can also be another variable (instead of a fixed word) as long as it’s a dotted path - this is how you compare two things from the context against each other, like checking whether the ticket’s author is the server owner:
  • If author is the server owner, this renders as: You are the server owner.
For more than two branches, chain {% elsif %} between {% if %} and {% else %}:
A real example from the default channel name, using claimer (only set once a ticket is claimed):
Both % symbols matter - {% if claimer %} is valid, {% if claimer} is not and will be left as literal, broken text. Most malformed tags only affect themselves - a typo’d {{ }} or an unrecognized {% %} just renders as literal text in place, while everything else around it (before and after) still works normally. A broken {% if %} is the one exception worth knowing about: if it’s missing its {% endif %} or has an unparseable condition, the parser can’t tell which of the following tags were meant to be inside that conditional versus after it - so rather than guess, it treats everything from that broken {% if %} to the end of the message as raw text (anything before it still renders fine).
In a channel name specifically, Discord’s channel-name sanitizer will mangle any raw, unrendered {% %}/{{ }} text into something unreadable. Double-check your tags render as expected before saving, especially around {% if %} blocks.

The random tag: {{random: ...}}

A custom tag that picks one option at random each time the message is rendered. Separate options with commas.
This is what the default welcome message uses, so new tickets don’t all open with identical wording. If an option needs to contain a literal comma (not a separator between options), escape it with a backslash: \,.
renders one of: Hello! Please wait, we'll be right with you. or See you soon! - two options, not three.

What happens to invalid tags

Rendering never throws or shows broken output. A malformed {{ }} or an unrecognized {% %} just renders as literal text in place - everything else in the message, before and after it, still renders normally. A broken {% if %} (see the note above) is the exception: it and everything after it in the message falls back to raw text, though anything before it is unaffected. Always write complete tags, and preview the result before saving.

Common variables

These are available in both ticket and application messages - only the meaning of author changes depending on context (the ticket’s author, or the applicant).
number
Always available, everywhere - even outside ticket/application messages. The current time as a Unix timestamp in seconds, mainly for Discord timestamp tags like <t:{{now}}:R>.
string
The Discord user ID of the person the message is about - the ticket’s author, or the applicant.
string
Their Discord username.
string
Their display name.
string
The reason tied to the current action, when there is one - a ticket close reason, or an application accept/deny reason.
string
The server’s Discord ID.
string
The server’s name.
string
The server owner’s Discord user ID.
number
The server’s member count.

Where you can use variables

Tickets

Ticket variables

On top of the common variables above (where author means the ticket’s author):
string
The ticket category’s identifier.
string
The claimer’s Discord user ID. Only set once claimed - always check with {% if claimer %} first.
string
The claimer’s Discord username. Only set once claimed.
string
The claimer’s display name. Only set once claimed.
Default channel name:
Default footer text:

Applications

Application variables

On top of the common variables above (where author means the applicant):
string
The reviewer’s Discord user ID. Only set on the decided-by footer - check with {% if reviewer %} first.
string
The reviewer’s Discord username. Only set on the decided-by footer.
string
The reviewer’s display name. Only set on the decided-by footer.
string
The formatted question/answer list. Submission message only - see below.
string
"Accepted" or "Denied", once decided.
string
When the decision was made, once decided.
Default submission message:
{{qa}} inserts every question and answer, formatted as a numbered list. You can only use it once per submission message - a second occurrence is rejected when you save, since it’d re-render a potentially large block twice.
Default accept/deny DM messages:
Every accepted or denied submission also gets a decided-by footer appended automatically (not user-editable), which is what adds the “Accepted by … on …” line to the submission message.