K
Docs
Building Bots

Sparks

Sparks are dynamic values you inject into any piece config using {{path}} syntax. They make your bot respond to real Discord data instead of hardcoded strings.

⚙️How Sparks Work

Type a spark anywhere in a piece's config field. When the Engine runs the piece, it replaces the spark with the live value from the current context.

Here's a Reply piece using sparks to personalize its message:

💬
Reply
base.reply
Messages
contentrequired
Hey {{input.user.name}}, you just joined! Welcome 🎉
ephemeral
boolean
💡Good to know

If a spark path doesn't exist in the current context (e.g. an optional option that wasn't provided), it resolves to an empty string — no error. Use base.coalesce to provide fallbacks.

📐Under the hood — sparks are just variables
TypeScript
// Sparks use {{path}} in config fields — paths match the Canvas autocomplete.

// Spells: {{input.user.id}}, {{input.user.name}}, {{input.options.target.id}}
// messageCreate: {{message.content}}, {{message.author.id}}
// After Save Spark: {{score}}
// After Read Vault (as: "result"): {{result}}, {{result.0.coins}}
// After Split Text (as: "parts"): {{parts}}, {{parts.0}}, {{parts.length}}
// Packs: {{lib.filter.profanity}}

Utility pieces like Split Text save a list spark. Use the whole list in Loop or Join ({{parts}}), or pick one item with an index ({{parts.0}} is the first).

✂️
Split Text
base.text.split
Utility
textrequired
apple,banana,cherry
delimiter
,
asrequired
parts
🔗
Join List
base.text.join
Utility
listrequired
{{parts}}
separator
·
asrequired
menu

💫All Spark Categories

🪄

Context sparks (Spells)

Live data when a user runs a slash command.

PathTypeDescription
{{input.guild.id}}stringYour Discord server's unique ID
{{input.guild.name}}stringYour server's name
{{input.guild.memberCount}}stringHow many members are in the server
{{input.user.id}}stringWho ran the command — Discord ID
{{input.user.name}}stringWho ran the command — username
{{input.user.displayName}}stringWho ran the command — nickname in this server
{{input.channel.id}}stringThe channel this command was used in
{{input.channel.name}}stringThe channel's name
📝

Flow sparks

Named by upstream pieces — use the name you set in as / name fields.

PathTypeDescription
{{<name>}}variesNamed spark you set — use {{score}}, not vars.score
{{<as>}}arrayAll matching rows — e.g. {{result}}
{{<as>.length}}numberNumber of rows returned
{{<as>.0.<column>}}variesFirst row column — e.g. {{result.0.coins}}
{{<as>}}variesCurrent loop item — name from “Call each item” field
{{<as>}}string | numberResult spark named in the piece config
🎴

Library sparks (Packs)

Pre-built values from Booster Packs.

PathTypeDescription
{{lib.filter.profanity}}arrayArray of common profanity and strong language
{{lib.filter.slurs}}arrayArray of racial, ethnic, and identity-based slurs
{{lib.filter.spam_phrases}}arrayArray of common spam and scam phrases
{{lib.filter.discord_invite}}string (regex)Regex — detects Discord invite links (discord.gg/...)
{{lib.filter.external_links}}string (regex)Regex — detects any http or https URL
{{lib.filter.excessive_caps}}string (regex)Regex — detects 4+ consecutive uppercase characters (SHOUTING)
{{lib.validate.email}}string (regex)Regex — validates email address format (user@domain.tld)
{{lib.validate.url}}string (regex)Regex — validates http/https URLs
{{lib.validate.phone}}string (regex)Regex — validates international phone numbers (E.164 style, optional +)
{{lib.validate.discord_id}}string (regex)Regex — validates Discord snowflake IDs (17–20 digit numbers)
{{lib.validate.discord_invite}}string (regex)Regex — validates a Discord invite link or code
{{lib.validate.hex_color}}string (regex)Regex — validates hex color codes (#RGB or #RRGGBB)
{{lib.validate.ip_address}}string (regex)Regex — validates IPv4 addresses (0.0.0.0 – 255.255.255.255)
{{lib.validate.number_only}}string (regex)Regex — validates that a string contains only digits (0–9)

🔀Using Sparks in Conditions

Condition pieces evaluate expressions — use sparks to compare live values.

🔀
Condition
base.condition
Logic
leftrequired
{{score}}
operatorrequired
gt
rightrequired
100
true
false
Supported operators

Pick a rule in the Condition piece inspector — these are the operator ids the Engine understands:

Value checks
isemptyisnotemptyistrueisfalse
Equal / not equal
eqneqeqci
Text contains & edges
containscontainscinotcontainsnotcontainscistartswithstartswithciendswithendswithci
Numbers
gtltgtelte
Lists
inlistinlistcinotinlistcontainsanystartswithanyendswithany
Patterns
matchesnotmatches
left: {{score}}, operator: gte, right: 100number comparison
left: {{input.user.id}}, operator: eq, right: {{targetId}}string equality
left: {{message.content}}, operator: startswith, right: !prefix command check
left: {{result}}, operator: isnotemptycheck if Read Vault found rows
Full Condition reference →

🎴Library Sparks from Packs

Booster Packs add pre-built values to your bot's spark library.

Once a pack is added to your bot, its sparks appear in the Canvas autocomplete under the Library category. Use them in any condition or config field.

🔀
Condition
base.condition
Logic
leftrequired
{{message.content}}
operatorrequired
matches
rightrequired
{{lib.filter.discord_invite}}
true
false
Packs docs →