Custom Commands V3Flows and the editor
Custom Commands V3Beta

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

ActiveSave

Trigger

Change

Schedule, every day at 09:00

#1

Get storage value(get-storage-value)

Read the question catalogue from{questions}

#2

Pick the next entry(array-at)

The one after yesterday's

#3

Send message(send-message)

Input parameters

Channel:#general

Message:Question of the day

#4

Create thread(start-thread-from-message)

Open a thread on that message

#5

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.

general
Online
Your botBOT09:00

Question of the day

What is the one game you keep coming back to, no matter how old it gets?

Question 42 of 120

Mira09:04

Terraria. I reinstall it every winter.

Message #general

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

ActiveSave

Trigger

Change

Schedule, every day at 09:00

#1

Get storage value(get-storage-value)

Read the question catalogue from{questions}

#2

Pick the next entry(array-at)

The one after yesterday's

#3

Send message(send-message)

Input parameters

Channel:#general

Message:Question of the day

#4

Create thread(start-thread-from-message)

Open a thread on that message

#5

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

ActiveSave

Trigger

Change

Schedule, every day at 09:00

#1

Get storage value(get-storage-value)

Read the question catalogue from{questions}

#2

If(if-condition)

The catalogue is empty: post a reminder in #staff and stop

#3

For each item(for-each)

Walk the catalogue until an unused question turns up

#4

Send message(send-message)

Post the question as an embed in#general

#5

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

ActiveSave

Trigger

Change

Modal submitted, Suggest a question

#1

Send message(send-message)

Post the suggestion with an Approve button in#staff

#2

Wait for button(wait-for-interaction)

Pause until a moderator clicks

#3

Set storage value(set-storage-value)

Add the question to{questions}

#4

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 sent

Get 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.

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.