Flows
A flow is what the bot does when something happens. Each flow is one file, and it’s either a command flow (a slash command) or an event flow (something that happens on Discord).
Blocks, ports and connections
Section titled “Blocks, ports and connections”Every flow starts at exactly one Start block. When the command or event fires, the runtime begins there and follows the connections:
- It runs the current block.
- The block picks an output port. Most blocks have a single
nextport. Condition hastrueandfalse. - The runtime follows the connection leaving that port to the next block.
- The flow ends when a port has no connection.
Each port carries one connection. Connecting a port again replaces the old connection, and the Problems panel warns about files where a port has more than one.
Editing on the canvas
Section titled “Editing on the canvas”- Shift, Ctrl or ⌘ click adds blocks to the selection, and Shift drag selects an area.
- Ctrl+C, Ctrl+X and Ctrl+V copy, cut and paste blocks with the connections between them, also from one flow to another. Ctrl+D duplicates and Ctrl+A selects everything. Right-click a block or empty space for the same actions.
- Add note in the palette or the right-click menu puts a sticky note on the canvas. Notes are saved in the flow file and ignored by the bot.
In the Project panel, right-click a file or folder to rename, duplicate or delete it, or to create files and folders. Renaming a message design updates the blocks that use it.
Command flows
Section titled “Command flows”A command flow defines a slash command: its name, description and options. Pick the Start block, or click empty space on the canvas, and edit them in the Properties panel.
-
Names are lowercase, without spaces, up to 32 characters.
-
Up to 25 options, each with a type: text, whole number, number, yes/no, user, channel, role, user or role, or file. Numbers can have a min and max value, text a min and max length. A file option gives its URL.
-
Read an option’s value in the flow as
{{options.name}}. Foruser,channelandroleoptions this is the ID. -
string,integerandnumberoptions can have up to 25 choices. Discord then shows a list instead of a text box. Write one per line, orLabel = valueto store something other than the label. -
Who can use it hides the command from members who lack the ticked permissions. Server admins can override this in Server Settings › Integrations.
-
Can be used in DMs with the bot makes the command work in direct messages too. By default commands only work in servers.
Subcommands
Section titled “Subcommands”Tick This flow is a subcommand to turn the flow into one part of a bigger command. Every flow with the same command name adds a subcommand, so /config show and /config reset can be two flows. A group adds one more level, like /config role add. The command description is shared, and each subcommand has its own description and options. A command can’t mix a plain flow with subcommand flows, and the Problems panel says so.
User and message menus
Section titled “User and message menus”Switch the type to User menu or Message menu to add the command to the right-click menu, under Apps. These commands have a name that can contain spaces and capital letters, and no options. In the flow, {{target.*}} is the user that was clicked, or the author of the message, and {{message.*}} is the message.
Autocomplete
Section titled “Autocomplete”Tick Suggest values while typing on a text or number option, then create an event flow for When someone types in an autocomplete option. Set its target to command.option, like search.query, or command.subcommand.option for subcommands. In the flow, {{focused.value}} is what the person typed so far, and the Suggest Choices block answers with up to 25 suggestions. Autocomplete flows have to answer within 3 seconds.
The bot registers its commands when it starts and again whenever the set of commands changes.
Event flows
Section titled “Event flows”An event flow runs when Discord sends the bot an event. Supported events:
| Event | When it runs | Needs intent |
|---|---|---|
clientReady |
Once, when the bot comes online | — |
guildMemberAdd |
A member joins a server | GuildMembers |
guildMemberRemove |
A member leaves a server | GuildMembers |
messageCreate |
Someone sends a message (messages from bots are ignored) | GuildMessages |
messageUpdate |
Someone edits a message | GuildMessages |
messageDelete |
A message is deleted | GuildMessages |
messageReactionAdd |
Someone adds a reaction | GuildMessageReactions |
messageReactionRemove |
Someone removes a reaction | GuildMessageReactions |
messagePollVoteAdd |
Someone votes in a poll | GuildMessagePolls |
guildMemberUpdate |
A member’s roles, nickname, boost or timeout changes | GuildMembers |
guildBanAdd, guildBanRemove |
Someone is banned, or a ban is lifted | GuildModeration |
voiceStateUpdate |
Someone joins, leaves, moves or mutes in voice | GuildVoiceStates |
channelCreate, channelDelete |
A channel is created or deleted | Guilds |
threadCreate |
A thread is created | Guilds |
roleCreate, roleDelete |
A role is created or deleted | Guilds |
inviteCreate |
An invite is created | GuildInvites |
guildCreate, guildDelete |
The bot is added to, or removed from, a server | Guilds |
autoModerationActionExecution |
AutoMod blocks or flags something | AutoModerationExecution |
autocomplete |
Someone types in an option with autocomplete | — |
buttonClick |
Someone clicks one of the bot’s buttons | — |
selectMenu |
Someone picks from one of the bot’s menus | — |
modalSubmit |
Someone submits a form opened with Show Form | — |
schedule |
Every N minutes, or every day at a set time | — |
GuildMembers is a privileged intent: turn on Server Members Intent under Bot in the Developer Portal as well. To read the text of messages you also need MessageContent, which is privileged too.
Buttons, menus and forms
Section titled “Buttons, menus and forms”Buttons, menus and forms carry a custom ID that you choose. Menus can list your own options, or let people pick members, roles, both, or channels; {{values}} holds the picked IDs. Set the same ID on the event flow and it runs only for that component. End the ID with * to match everything that starts with it: vote:* catches vote:yes and vote:no, and {{customId}} tells you which one it was. Leave it empty to catch them all.
These flows can answer the person with Reply, Defer Reply and, for buttons and menus, Show Form. Discord expects an answer within 3 seconds, so put Defer Reply first when the flow does something slow. Wait does this for you when it waits longer than 2 seconds.
Schedules
Section titled “Schedules”A schedule flow runs every N minutes (1 to 10080) or every day at HH:MM, using the clock of the machine the bot runs on. It runs only while the bot is online, and a run that was missed while the bot was offline doesn’t catch up later.
Live reload
Section titled “Live reload”While the bot runs from the IDE, the runtime watches your flow files. When you save one, flows reload immediately and slash commands are re-registered if anything about them changed. Changes to makecord.json need a restart.
The file format
Section titled “The file format”You rarely need to edit flow files by hand, but they’re meant to be readable:
{ "specVersion": 1, "kind": "command", "command": { "name": "ping", "description": "Shows the bot's latency", "options": [] }, "nodes": [ { "id": "start", "type": "core.trigger", "position": { "x": 0, "y": 0 }, "data": {} }, { "id": "reply", "type": "core.reply", "position": { "x": 320, "y": 0 }, "data": { "content": "Pong! {{client.ping}} ms", "ephemeral": false } } ], "edges": [{ "id": "e1", "source": "start", "sourceHandle": "next", "target": "reply" }]}type names the block (see the Blocks reference), data holds its settings and sourceHandle is the output port a connection leaves from.