Variables

Anywhere you can type text, you can type {something} and FlaviBot replaces it when the rule runs.

Welcome {user.mention} to {server.name}!

Variable names follow a tree. Everything about the member sits under user. or member., everything about the message under message., and so on, so once you know one, you can guess the rest.

Always available

{user}, {user.mention}, {user.id}, {channel.mention}, {channel.id}, {server.id}.

Triggers with no member behind them (a scheduled rule, a channel event) do not offer the user. family, because there is nobody to name.

From the trigger

Each trigger adds its own. A few examples:

TriggerAdds
message_create{message.content}, {message.id}, {mentions.count}
message_edit{message.content} (after), {message.old_content} (before)
message_delete{message.content}, {message.author.mention}
reaction_add{reaction.emoji}, {reaction.name}, {reaction.count}
member_join{member.mention}, {member.account_age_days}, {member.join_type}
member_leave{member.mention}, {member.time_in_server}, {member.roles}
boost_end{member.mention}, {boost.duration}
ticket_close{ticket.duration}, {ticket.closer.mention}, {ticket.claimed_by.mention}
level_up{level.new}, {level.old}, {user.display_name}, {user.avatar_url}
music_track_start{track.name}, {track.author}, {track.duration}
automod_action{message.content}, {automod.action}, {message.url}
select_menu{select.value}, {select.values}, {select.count}
custom_event{event.name} plus every key of the payload

The editor lists the ones your trigger actually provides, so you never have to memorise them. If a variable is offered, it resolves: a name in that list that the bot could not fill would be a bug, not a blank.

A rule that belongs to a group also gets {group.panel_message_id}, which is how a rule edits the panel its group published.

From earlier steps

{steps.2.value} is the value the second step returned. This is how a counter reaches the message that announces it.

Your own stored values

The data store keeps values between runs: they survive restarts, and they are per server.

  • Scope: guild (one value for the server), member (one per member), or channel
  • Type: text, number, boolean, list or JSON
  • Expiry: optional; a strike that fades after 30 days is just a counter with an expiry

Read one into a variable and use it: {vars.<name>.value}, plus {vars.<name>.exists} and, for lists, {vars.<name>.length}.

Counters are atomic: two members clicking at the exact same moment get 4 and 5, never 4 and 4. A missing counter starts at the default you set (usually 0) instead of failing.

An unknown variable is left alone

If you type {user.birthday} and nothing provides it, the text stays exactly as you typed it. It is never silently replaced by an empty string, so a typo is visible instead of quietly producing a broken message.

flav-codeWritten on 8 August 2026