Your bot's logic, step by step
A flow is a list of steps. The Daily question flow is five of them: read the catalogue, pick the next question, post it, open a thread, count it. Add a step, wire a value into it, test it, then switch it on.
Daily question
ActiveSaveTrigger
ChangeSchedule, every day at 09:00
Get storage value(get-storage-value)
Read the question catalogue from{questions}
Pick the next entry(array-at)
The one after yesterday's
Send message(send-message)
Input parameters
Channel:#general
Message:Question of the day
Create thread(start-thread-from-message)
Open a thread on that message
Increase storage value(increment-storage-value)
Count the question as asked in{asked}
Illustration only - actual interface may differ
What those five steps produce at 09:00
The five steps produce one message. The thread under it is where the answers land, and the counter makes sure tomorrow gets the next question.
Illustration only - actual interface and behavior may differ
Steps, not scripts
Each step is one action from the catalogue with its own inputs, and the value a step produces can be wired into any later step. The editor only ever offers you the values that fit. There are 691 actions and 181 parameter types behind that picker.
Fixed value, wired variable or template
Every input takes one of the three. A template mixes your own writing with inserted variables.
The variable picker is type aware
It hides values that do not fit, drills into object properties, warns you about values that can be empty, and can add a conversion step for you.
Wired values show up as chips
The chips on these rows are the question catalogue and the channel, so you can see where a value came from.
Every step carries a cost
From Free to Very heavy, and the flow shows you its worst case before you activate it.
You do not have to start from an empty flow. The dashboard ships templates you can open and change: a greeting responder, welcome new members, a /warn command, a /remind command, an XP system, suggestions and an event signup.
Daily question
ActiveSaveTrigger
ChangeSchedule, every day at 09:00
Get storage value(get-storage-value)
Read the question catalogue from{questions}
Pick the next entry(array-at)
The one after yesterday's
Send message(send-message)
Input parameters
Channel:#general
Message:Question of the day
Create thread(start-thread-from-message)
Open a thread on that message
Increase storage value(increment-storage-value)
Count the question as asked in{asked}
Illustration only - actual interface may differ
Branches and loops
Automations need decisions. If, Switch, Random branch and Branch on subcommand split the flow, For each item, For each map entry and Repeat walk lists and maps with Break and Continue, and a Try block gives you somewhere to put the recovery when Discord says no.
Every branch carries its own variables
A value set inside a branch belongs to that branch.
Try, with an On error branch
It can switch on the error code: Missing permissions, Not found, Invalid input, Storage error, Timeout, Interaction expired.
Stop where stopping is the right answer
The If in this flow posts a reminder in the staff channel and stops, instead of posting an empty question.
A loop that runs away stops on its own, so a mistake stops instead of running all morning.
Daily question
ActiveSaveTrigger
ChangeSchedule, every day at 09:00
Get storage value(get-storage-value)
Read the question catalogue from{questions}
If(if-condition)
The catalogue is empty: post a reminder in #staff and stop
For each item(for-each)
Walk the catalogue until an unused question turns up
Send message(send-message)
Post the question as an embed in#general
Create thread(start-thread-from-message)
Open a thread on that message
Illustration only - actual interface may differ
Flows can call other flows, and waiting is a step
Write a behaviour once and call it from wherever you need it. And when a flow needs an answer before it continues, that wait is written down rather than held in memory, so a bot restart does not lose it.
Call another flow
Hand values in and read results back. Flows that would end up calling each other in a circle are refused.
A called flow belongs to the caller's run
The run history says so and links back to the caller. Custom events are the looser variant: one flow sends, another listens.
Waits survive a restart
Ask for confirmation, ask for a choice, wait for a message, show a modal and wait for the submit. A restart in between does not lose the wait.
Scheduled runs
Schedule flow run books a later run from inside a flow, and there are actions to cancel and list what is pending.
If you edit a flow while a run of it is waiting for someone, that waiting run stops, and the log says so. For something that should stay usable for months, a button that starts a flow is the better tool: it costs nothing while nobody clicks it and it never expires.
Review a suggestion
ActiveSaveTrigger
ChangeModal submitted, Suggest a question
Send message(send-message)
Post the suggestion with an Approve button in#staff
Wait for button(wait-for-interaction)
Pause until a moderator clicks
Set storage value(set-storage-value)
Add the question to{questions}
Call another flow(call-flow)
Daily question, with the new question as an argument
Illustration only - actual interface may differ
See it before you ship it
A test run simulates the flow against your own server data. Nothing is sent, changed or deleted. You pick who it runs as, which channel it runs in and what the trigger hands it, and the result shows every step with what it would have done. Testing costs your server nothing.
A flow is also checked before it can go active, so a problem turns up in the editor rather than at nine in the morning. And a loop that runs away cannot take your bot down: it stops itself.
Draft or active
Drafts are saved and checked, and they never run.
Saving an active flow takes effect right away
Your bot picks up the new version as soon as you save. If that does not go through, the version that was already running keeps handling the flow and you can try again.
Nothing is lost by accident
If someone else saved the flow while you had it open, you get a warning instead of overwriting their work. Deleted flows and modules can be restored for 30 days.
One thing to be clear about: only test runs show you every step. A live run records its status, its timing and the step it failed at, not everything it walked through.
Test run
Simulated run, nothing was sentGet storage value
Read the catalogue, 120 entries
Pick the next entry
Question 42
Send message
Would have posted in #general
Create thread
Would have opened a thread on that message
Increase storage value
The asked counter would go from 41 to 42
Illustration only - actual interface may differ
Questions about flows
A flow that is waiting for someone does. Waits like Ask for confirmation or Wait for a message are written down rather than held in memory, so they survive a restart. One exception worth knowing: if you edit the flow while a run of it is waiting, that run stops, and the log says so.
More of Custom Commands V3
Want your server in the beta?
V3 is a large system and it still moves fast, so servers come in one at a time instead of all at once. Every application is read by a person, and you hear back within a few days.
The servers already in the beta decide a good part of what we build next. What you build is yours: flows and modules stay when the beta ends.