Automations
Automations let the bot react to things that happen in your server: a member joins, a role changes, someone is banned, or a message contains a trigger word. You can react with a built-in template or build your own chain of actions.
The Automations feature is on by default. Open Automations in the sidebar. It has two tabs: Default and Custom.
Bot messages and changes the bot itself makes are ignored, so automations never loop on their own activity.
Changes made to other bots and apps in your server do count, just like changes to any other member. When a bot or app gets or loses a role, has its nickname changed, or is timed out, the matching automations and log posts fire too.
Applied retroactively
If the bot is offline for a short while, it looks back for anything it missed once it is online again and applies it where it can. A log post that was created this way says Applied retroactively at the bottom. Not everything can be detected or applied after the fact, so a few events from that time may not show up. Nickname changes, timeouts and boosts are not posted this way, because the bot can't tell how long ago they happened. Voice joins, leaves and moves are never posted afterwards either, because the bot only sees them while it is online.
Default automations
The Default tab is a fixed set of ready-made templates. Each one posts a nicely formatted message to a channel you choose. Every template starts out pointed at the bot's logs channel, so you can switch it on right away. Pick another channel if you want it somewhere else (and, optionally, exclude some roles so posts about members with those roles are skipped). Only the server owner can change the default automations.
The templates are grouped into sections, so related ones sit together: Members, Moderation, Server and channels, Messages and Voice channels. A section only shows up when it has at least one template in it.
| Section | Template | Posts when... |
|---|---|---|
| Members | Member joined | Someone joins (a profile card). |
| Members | Member left | Someone leaves (their nickname, roles, and join date). When they were kicked, the post says so and shows who kicked them and why. |
| Members | Role assigned to member | A role is granted (lists what changed). |
| Members | Role removed from member | A role is removed (lists what changed). |
| Members | Nickname changed | A member's server nickname changes (the old and new nickname, and who changed it). |
| Members | Started boosting | A member starts boosting this server. |
| Members | Stopped boosting | A member stops boosting this server (and how long they boosted). |
| Moderation | Member banned | A user is banned (with the ban reason when readable). |
| Moderation | Member unbanned | A previously banned user is unbanned. |
| Moderation | Member timed out | A member is timed out (who did it, when the timeout ends, and the reason). |
| Moderation | Timeout removed | Someone lifts a member's timeout early (who did it). A timeout that simply runs out may not post. |
| Moderation | Warning added | A member gets a warning, with /warn or from the dashboard (who did it, the case number when there is one, and the reason). |
| Moderation | Note added | A member gets an internal note, with /note or from the dashboard (who wrote it, the case number when there is one, and the note). The bot also writes notes by itself, for example after a timeout, kick or ban. Those do not post here, because the timeout, kick or ban post already covers them. Keep this channel staff only, because notes are meant to stay private. |
| Server and channels | Channel created | A channel is created. |
| Server and channels | Channel deleted | A channel is deleted. |
| Server and channels | Channel updated | Someone edits a channel, like its name, topic, slowmode, category or permissions (what changed, and who did it). |
| Server and channels | Role created | A role is created (the role, its colour, and who made it). |
| Server and channels | Role updated | Someone edits a role, like its name, colour or permissions (what changed, and who did it). |
| Server and channels | Role deleted | A role is deleted (the name it had, and who deleted it). |
| Server and channels | Server updated | Someone changes the server settings, like the name, icon or verification level (what changed, and who did it). |
| Server and channels | Invite created | Someone makes an invite (the link, its channel, how long it lasts, how many uses, and who made it). |
| Server and channels | Invite deleted | An invite is deleted, and who did it. An invite that expired or ran out of uses shows up here too. |
| Server and channels | Emoji changed | A custom emoji is added, renamed or deleted, and who did it. |
| Server and channels | Sticker changed | A sticker is added, renamed or deleted, and who did it. |
| Server and channels | Thread created | Someone starts a thread or forum post (where, and who). |
| Server and channels | Thread deleted | A thread or forum post is deleted, and who did it. |
| Server and channels | Webhook changed | A webhook is created, edited or deleted, and who did it. |
| Messages | Message edited | A message is edited (old + new content, plus a link that jumps to the message). Requires Message logging. |
| Messages | Message deleted | A message is deleted (content, author, and who deleted it). Requires Message logging. |
| Voice channels | Joined voice | A member connects to a voice channel (who, and which channel). |
| Voice channels | Left voice | A member leaves voice (who, which channel, and the moderator who disconnected them, if one did). |
| Voice channels | Moved voice channel | A member switches voice channel (the old and new channel, and the moderator who moved them, if one did). |
For each one you enable, set:
- Target channel (required, starts out as the logs channel).
- Excluded roles (optional): when the member the post is about has any of these roles, nothing is posted. This looks at the member it happened to (the one who joined, got a role, or wrote the message), not at the person who made the change. For example, excluding a "Bots" role keeps your bots' role changes out of the log. Templates for events that are not about a member do not have this option. Those are the ones for channels, roles, threads, invites, emojis, stickers and webhooks, and server updated. Bans and unbans do not have it either, because a banned person is no longer in your server, so the bot can't see their roles. Member left does keep it, because the bot remembers the roles the member had.
Who did it
Most log posts have a By line that says who made the change: a member, a moderator, another bot or app, or SnowstormBot itself (for example when it gives a role from a role menu or a level reward). The bot reads this from your server's audit log, which needs the View Audit Log permission. Without it the line says Unknown. When a moderator uses one of the bot's commands, like /nick, /timeout, /untimeout, /kick, /ban, /tempban or /unban, the post names that moderator instead of the bot, and shows the reason they typed. Custom automations can show the same with the {actor.*} placeholders. Changes the bot makes itself still never fire custom automations, so nothing can loop.
Channel and role edits
The Channel updated and Role updated posts read what changed from your server's audit log (Discord's own record of who changed what). Permissions are listed by name, for example "Now allowed: Send Messages" or "Permissions added: Kick Members", together with the role or member they apply to.
When you drag roles or channels into a new order, Discord reports every role or channel that moved, even though nobody edited them. To keep your log tidy, these two templates only post when the audit log shows a real edit, they skip a change that is only a new position, and one save never posts twice. Because of that, they need the View Audit Log permission to post at all. Without it the bot cannot tell an edit apart from a reorder, so it stays quiet. Role created and Role deleted still post without it, with Unknown on the By line.
Boosts, names and avatars
Discord's audit log (the list of changes Discord keeps for each server) does not record boosts, so the boost posts have no By line. A boost can also end on its own when the member's subscription runs out.
Like role changes, the bot needs to have seen the member once before it can spot a change. The very first change for a member it has never seen only records the new state.
If Discord ever sends a member update without the boost date in it, the bot reads that as the member having stopped boosting, so you may very rarely see a Stopped boosting post for someone who still boosts.
The bot does not post when a member changes their Discord username, display name or profile picture (avatar). On a big server people do that all the time, so those posts would bury everything else in the log. Nickname changes are still posted, because a nickname belongs to your server.
Voice logs get busy
People hop in and out of voice all the time, so the Voice channels templates can post a lot. It works best to give them a channel of their own (for example #voice-log) instead of the main logs channel, so the other log posts do not get buried.
A Moved by or Disconnected by line only shows up when a moderator did it. When the member switched channel or left by themselves, there is no such line. To find the moderator the bot reads the server's audit log (this needs the View Audit Log permission). Without that permission the posts still appear, just without the line.
The audit log is not perfect for this. Discord only writes down which channel a member was moved to and how many members were moved, not their names. The bot matches each post to an audit entry written at the same moment, which works well almost always. It can still name the wrong moderator now and then, for example when two moderators move people into the same channel at the very same time, or when one moderator keeps moving or disconnecting several people in a row while others leave on their own.
When someone joins the lobby of a temporary voice channel, SnowstormBot moves them into their own new channel right away. That counts as part of joining, so you get a single Joined voice post that names their new channel, and no Moved voice channel post. Custom automations for moving channels do not run for it either. The same goes for someone who moves from another voice channel into the lobby: you get one Moved voice channel post from their old channel straight to their new one, and custom automations for moving into that new channel run as normal.
If the new channel cannot be made, the post names the lobby instead. If making the channel takes longer than about 5 seconds, the bot does not wait any longer. It posts the join (or move) naming the lobby, and then posts the move into the new channel as a separate Moved voice channel post once it happens. This works with or without the View Audit Log permission.
Each member's voice posts arrive in the order things happened, so someone who quickly leaves and comes back shows up as a leave followed by a join. Mute, deafen, screen sharing and camera changes are not posted.
Why keep an eye on webhooks
A webhook is a little doorway that lets an app or a person post messages in a channel, under any name and any profile picture they like. That makes webhooks a favourite tool for scams: someone with the right permission quietly adds one and later uses it to post fake announcements. The Webhook changed post tells you the moment one appears, changes or disappears, and who did it. If you don't recognise a new webhook, remove it in Server Settings, Integrations, Webhooks. Discord only tells the bot that "something changed in this channel", so the bot reads the audit log to find out what. Without the View Audit Log permission the post can only say that something changed. Once in a while the bot can't be sure which channel a webhook edit belongs to. It then leaves the channel out of the post rather than guess.
Invites need one more permission
Discord only tells the bot about new and deleted invites in channels where the bot has the Manage Channels permission. Give it that permission (or leave it on the bot's role) if you want the invite posts.
When a whole channel is deleted, its invites disappear with it. The bot doesn't post those, because the channel's own delete already tells the story. And if a lot of invites in one channel vanish within a few seconds, only the first three get a post, so your log channel doesn't fill up.
Role changes on a brand-new member
To report which role changed, the bot compares the member's roles against the last set it recorded for them. A member the bot has never recorded yet (it has only just been added to the server, and that member has not appeared in any server event since) has nothing to compare against, so their very first role change records the new state instead of posting. Every change after that posts normally.
Custom automations
The Custom tab is where you build your own. Click New automation. Custom automations can be managed by the owner or a delegated manager.
A custom automation has three parts: metadata, a trigger, and one or more actions.
Metadata
- Name (required) and an optional Description.
- Active: turn the automation on or off without deleting it.
Trigger (the event)
Pick the event that fires the automation:
| Event | Fires when... | What you configure |
|---|---|---|
| Member joined | A member joins. | nothing |
| Member left | A member leaves, either by themselves or because they were kicked. {leave.kicked} says true for a kick and false for a normal leave. For a kick, {actor.*} is the person who kicked them and the kick reason is in {message.content}. Telling a kick apart needs the View Audit Log permission. Without it, a kick done with the bot's own /kick command is still recognised, but any other kick counts as a normal leave. | nothing |
| Role assigned / removed from member | Any of the watched roles is added / removed. | the watched role(s) |
| Message contains words | A message contains any listed word (whole-word, case-insensitive). | the word list, filters |
| Message starts with | A message starts with any listed prefix (case-insensitive). | the prefix list, filters |
| Message updated / deleted | A message is edited / deleted. | filters |
| Member tagged in a message | Someone tags one of the watched members in a message. | the watched members (empty means any member), filters |
| Role tagged in a message | Someone tags one of the watched roles in a message. | the watched roles (empty means any role), filters |
| Channel linked in a message | Someone links one of the watched channels in a message. | the watched channels (empty means any channel), filters |
| Member gained XP / leveled up / lost XP | A member earns XP, reaches a new level, or has XP eroded by decay. | nothing |
| Member nickname changed | A member's server nickname changes. | nothing |
| Member started / stopped boosting | A member starts or stops boosting the server. When the boost started is in {profile.boostsince}. | nothing |
| Member warned / noted | A warning or note is recorded against a member, with /warn, /note, or from the dashboard (the reason is in {message.content}). Notes the bot writes by itself, for example after a timeout or a kick, fire this too. | nothing |
| Member timed out | A member is timed out, by anyone (your bot command, auto-mod, or a moderator acting directly in Discord). | nothing |
| Member timeout removed | A member's timeout is lifted. Reliable when a timeout is cleared; a timeout that simply expires on its own may not fire it. | nothing |
| Member kicked | A member is kicked, by anyone (the kick reason is in {message.content}). "Member left" fires for the same kick too, so pick one of the two if you only want a single message. Needs the View Audit Log permission to tell a kick apart from a normal leave. Without it, only kicks done with the bot's own /kick command are recognised, and any other kick is treated as a plain leave. | nothing |
| Channel updated | A channel is edited. What changed is in {changes.list}. | nothing |
| Role created / updated / deleted | A role is created, edited, or deleted. For an edit, what changed is in {changes.list}. | nothing |
| Server updated | Someone changes the server settings, like the name, icon or verification level. What changed is in {changes.list}. Without the View Audit Log permission it only notices a new name or icon. | nothing |
| Invite created / deleted | An invite is made or deleted. The invite is in the {invite.*} placeholders. An invite that expires or runs out of uses also counts as deleted. | nothing |
| Emoji created, renamed or deleted | A custom emoji changes. {emoji.change} says which of the three happened. | nothing |
| Sticker created, renamed or deleted | A sticker changes. {sticker.change} says which of the three happened. | nothing |
| Thread created / deleted | A thread or forum post is started or deleted. Being added to an old thread does not count. | nothing |
| Webhook created, updated or deleted | A webhook changes. {webhook.change} says which, and for an edit {changes.list} says what changed. Needs the View Audit Log permission. | nothing |
| Member joined voice | A member connects to a voice channel. | filters |
| Member left voice | A member leaves voice, by themselves or because a moderator disconnected them. | filters |
| Member moved voice channel | A member switches voice channel, by themselves or because a moderator moved them. {oldchannel.*} is the channel they came from. | filters (a move counts when either the old or the new channel passes) |
| Achievement earned | A member earns an achievement. Carries the {achievement.*} placeholders. | optional achievement filter |
| API triggered (your own app) | Your own program calls the developer API. The program sends the member, channel, role and custom variables ({api.name}). If it leaves out something the automation needs, nothing runs. Paid plans with the API only. | nothing (the editor shows what callers must send) |
{changes.list} now reads more clearly: permissions are listed by name, times like slowmode show in minutes or hours, and on or off settings say Yes or No. If you already use it in a custom message, that message will look a little different than before.
For the message-edit and message-delete triggers, the old/new content comes from the Message logging feature. Without it on (and the source channel logged), those placeholders fall back to neutral text. The channel and role triggers carry the affected channel/role placeholders; "DM the user" is hidden for them since they have no member. The same goes for the invite, emoji, sticker, thread and webhook triggers.
The three voice triggers carry the member and the voice channel, so {channel.name} and {channel.mention} (and the channel conditions under If / else) describe the voice channel. For a leave that is the channel they left, and for a move it is the channel they moved into. {actor.mention} is the moderator who moved or disconnected the member, or the member themselves when nobody else did it. Use the channel filter to watch only some voice channels.
A join through a temporary voice channel lobby counts as joining the member's new channel, not the lobby. So a trigger that watches only the lobby channel does not fire for those joins, and the bot's own move out of the lobby does not fire the move trigger.
Filters
The message triggers (contains words, starts with, edited, deleted and the three tag triggers) and the three voice triggers have two filters. Both are optional, and when you use both, a message has to pass both of them.
- Channels: pick some channels, then choose Only in these (the automation only fires in those channels) or Everywhere except these (it fires everywhere else). A message in a thread counts as being in the channel the thread belongs to.
- Roles: these are the roles of the person who sent the message (or who joined, left or moved in voice). Choose Only members with (they need at least one of the picked roles) or Everyone except (anyone holding one of the picked roles is ignored).
For example, "Only in #help and #support" plus "Everyone except Staff" makes an automation that only reacts to normal members asking for help, and stays quiet when your staff talk in those channels.
An empty list means that filter does nothing. Automations you made before the filters existed keep working: their single channel shows up as "Only in" and their excluded roles as "Everyone except".
When the bot doesn't know someone's roles
For a deleted message the bot can only know who wrote it if Message logging saved the message. If it didn't, "Everyone except" lets the message through and "Only members with" skips it, because the bot can't tell whether they had the role.
Reacting to tags
The three tag triggers fire when someone tags a member (@name), tags a role (@Support) or links a channel (#rules) in a message. Pick which ones you care about, or leave the list empty to react to any of them.
A few things to know:
- Only tags someone actually typed count. A tag inside a code block doesn't count,
@everyoneand@herearen't role tags, and the automatic ping Discord adds when you reply to someone doesn't count either. - Tagging yourself doesn't fire Member tagged in a message.
- If a message tags several watched things, the automation still fires only once, for the first one in the message.
{tagged.name}and{tagged.mention}are what was tagged,{user.mention}is the person who wrote the message and{message.content}is the message itself.
Example: answer everyone who tags your support team.
- Trigger Role tagged in a message, watched role Support.
- Roles filter Everyone except your Staff role, so staff tagging each other doesn't trigger it.
- Action Send a message to a channel, channel Channel of the triggering message, with Reply to the message that started this switched on and the text
Hey {user.mention}, {tagged.name} has been notified and will be with you soon.
Actions
After the trigger, add a chain of actions. The number of actions per automation depends on your plan (the editor shows your current limit as you build).
| Action | What it does |
|---|---|
| Send a message to a channel | Posts a message. For message and tag triggers you can target the channel the event came from, and switch on Reply to the message that started this so it shows as a Discord reply on that message. Supports placeholders. |
| DM the user | Sends the message as a direct message to the member, with an optional fallback channel used if their DMs are closed. Only where the trigger has a member. |
| Give / remove roles | Grants or removes one or more roles on the member. |
| Kick member | Kicks the member, with an optional reason for the Discord audit log. |
| Grant achievement | Awards an achievement to the member (no-op if they already have it; shows the card and fires the Achievement earned trigger). |
| Ask a question | Posts a prompt with buttons and branches on the answer (see below). |
| If / else | Branches on conditions you choose (see below). |
| Wait | Pauses the automation for a number of days and hours (up to 31 days), then carries on with the next action (see below). |
| Open ticket | Opens a support ticket in the category you pick, about the member the trigger is about or the person who caused it, with an optional subject. Switch off Give them access to the ticket for a staff-only ticket. You can create a ticket category right from the action. Only shows up when Tickets is on. |
| Close ticket | Closes the ticket in the channel the trigger happened in, all of the member's open tickets, or (for channel and thread triggers) the ticket that channel or thread belongs to. Closing locks the ticket and keeps it as an archive. |
| Reopen ticket | Reopens the closed ticket in the channel the trigger happened in, the member's most recently closed ticket, or (for channel and thread triggers) the closed ticket that channel or thread belongs to. |
Ticket actions are written into the ticket's timeline and the audit log as done by the automation, together with the person who set it off. For an automation started through the developer API, that is the owner of the API key.
About the reply switch: the reply doesn't ping the person by itself, so add {user.mention} to the text if you want them to get a notification. If the original message was deleted, or a Wait step ran first, the bot posts a normal message instead.
Every message field is a rich-text editor: format the text the way Discord allows and insert placeholders from the { } menu. See the placeholder reference for everything you can put in a message.
Branching with "Ask a question"
The Ask a question action posts a prompt in a channel with 1 to 10 buttons. Only the member who triggered the automation can click. Each button leads to its own follow-up actions, so you can build a branching flow (for example a reaction-role or onboarding prompt: "Pick your region" → grant the matching role).
Branching with "If / else"
The If / else action checks conditions and runs a different set of actions depending on the answer, no buttons or member input needed. Build a ladder of if / else-if / else arms; each arm tests one or more conditions combined with match all (AND) or match any (OR). Conditions cover the member (has a role, member for N days, XP level/amount, has a nickname), the message text, the channel (type, name, topic, NSFW), the role (name, position, mentionable), and — on the Achievement earned trigger — the achievement (name, rarity tier, or a specific achievement), so one automation can do different things for different achievements. On the API triggered trigger you can also test an API variable: a value your own program sent along, such as tier is Gold. On the Member left trigger you can test Was kicked, which is "Yes" when the member was kicked and "No" when they left by themselves. That way one automation can say goodbye to people who leave and post something different for people who were kicked. The first arm that matches runs; otherwise the otherwise branch does. The gate counts as one action and its conditions are free, so stack as many as you need (up to 10 per arm, 20 arms).
Self-assignable roles
If all you want is a message members click to give themselves roles, the Role menus feature does that directly, without building an automation.
Waiting with "Wait"
The Wait action pauses an automation and carries on later. A common example is a role that only lasts a day:
- Give roles: give the member the "Trial" role.
- Wait: 1 day.
- Remove roles: take the "Trial" role away again.
Set the wait with the Days and Hours fields. It has to be at least 1 hour and at most 31 days. You can use several Wait steps in one automation, but the waits a member passes through can add up to 31 days at most. Waits that sit in different answers of a question, or in different arms of a condition, are counted separately, because a member only ever goes down one of them. The editor shows the longest total next to the action count. The steps after the wait happen at about that time. When a lot is going on, they can be a few minutes late, because waiting automations step aside for everything that has to happen right now.
While an automation waits, it remembers who and what it was about (the member, the channel, the role and any API variables). Right before it carries on, the bot checks that all of that still exists. The waiting run is dropped, and nothing more happens, when:
- the member left the server
- the channel or role it was about was deleted (a thread the automation started in is not checked, so a run from a thread always carries on)
- the automation was deleted or switched off, or automations were switched off for the server
- the bot left the server
If the bot is only paused in your server, the run waits and tries again every hour. The Delayed tab then shows it as "Due, waiting for the bot to resume". If the pause lasts more than 7 days past the run's due time, the run is dropped. Every dropped run is written to the audit log with the reason.
One wait per member. When the same member sets off the same automation again while an earlier run is still waiting at the same Wait step, the earlier run is replaced and the timer starts over. Someone who leaves and rejoins ten times therefore has one waiting run, not ten.
Editing an automation that is waiting. A waiting run keeps the steps the automation had when it started waiting, so your edits only apply to new runs. The editor tells you how many runs are still waiting on the old version, and lets you delete them all at once.
Message text is not kept while an automation waits, so {message.content} after a Wait shows "Message content not available".
The Problems tab
The Problems tab lists automation runs from the last 7 days that did not fully work, with a plain explanation of what went wrong. A run is marked:
- Failed when it stopped because of an error, or did not run at all (for example because too many automations fired at once and the loop protection skipped it).
- Partly done when it ran, but some steps did not do what they should. Examples are a role the bot could not give, a member whose DMs are closed, a step that needed a member or channel the event did not have, a Wait that stopped because the limit was reached, or a waiting run that was dropped.
The same problem happening again within an hour is counted on the same row, so a busy server does not get a flood of rows. Rows disappear after 7 days, and you can remove them yourself. The last result column on the Custom tab says "Completed with problems" when the latest run had any.
The Delayed tab
The Delayed tab on the Automations page lists every run that is currently waiting: which automation it belongs to, when it carries on, who and what it is about, and which step comes next. Use the delete button to cancel a run you no longer want. Runs that already finished are in the audit log.
Managing your automations
The Custom tab lists each automation with its event, an Active switch, when it last fired, and its last result. Use the icons to edit or delete one. Deleting an automation also stops any of its pending question buttons from responding.
Role hierarchy
"Give roles" and "Remove roles" only work on roles below the bot's own role. If an action does nothing, drag SnowstormBot's role above the roles it manages in Server Settings → Roles.
Limits
The number of active automations per server, the number of actions per automation, and how many runs may be waiting on a Wait at the same time in one server, depend on your plan. When the waiting limit is reached, new runs stop at the Wait (this is written to the audit log) until older ones finish. The bot posts a message in your #snowstormbot-logs channel when that happens, and another one when there is room again. The second message comes once the number of waiting runs has dropped to about 90% of your limit, so a server that sits right at the limit does not get a stream of messages. The page shows your current usage (for example "2 / 3 active"). See Plans & limits.
Tagging roles, members and channels
In the message boxes of the Send message, Reply and Ask a question actions you can type @ to tag a role or member, or # to link a channel, the same way as on Send a message. Each role and member tag gets a Ping switch underneath. Ping means Discord sends those people a notification, and Tag only shows the tag without notifying anyone. @everyone and @here start on Tag only, so nobody pings the whole server by accident.
If a member leaves, or a role or channel is deleted, the tag keeps showing its old name when you edit the message, but you can no longer pick it again. In Discord it then shows as a broken tag.
The DM the user action offers members and channels only, without Ping switches, because it is a direct message.