Skip to main content
Righteous

Sticky messages

Pin a message to the bottom of a busy channel: how the re-post is triggered, what happens to the old copy, and how to pick a limit that does not spam your own channel.

A sticky message is a message that will not stay scrolled away. You give a channel an embed code and a number; once that many messages have gone by, Righteous posts the code again at the bottom of the channel and deletes the copy above. It is for anything that stops working the moment it leaves the screen: a support-channel format, rules people read, a "check this before you ask".

Sticky messages are Server Premium

,stickymessage (,sticky, or /stickymessage) is gated on Server Premium (the whole command, every subcommand, including the ones that only read), and needs Manage Server on top. Self Premium on your own account does not open it; the gate is on the guild, and no permission change gets past it. Premium tiers explains which product covers a server.

Stick a message to the bottom of a channel

,stickymessage add takes a channel and an embed code, posts the code back to you as a preview, and posts the real copy into the channel you named.

Syntax

,stickymessage add <channel> <code>

Example

,stickymessage add #support {color: #fb4868}$p{title: Before you ask}$p{description: Say what you tried and paste the error. A screenshot of the whole window beats a crop.}
FlagMeansAcceptsDefault
<channel>Where the sticky livesA mention, a channel ID, or part of a channel nameRequired
<code>The message itselfAny embed codeRequired
++delete <seconds>Deletes each re-post after a delay1 to 600, written as digits, at the very end of the codeOff

One sticky per channel, as many channels as you like. Running add again replaces that channel's code but does not clean up the copy already sitting there. Name the channel with a mention: a bare word is matched as a fragment, so support finds the first channel with "support" anywhere in its name. And the channel has to accept the bot: if the first post fails, add refuses and says so, and nothing is saved, so a confirmation means the sticky is live, not merely written down.

On slash, the code arrives in a pop-up

/stickymessage add asks only for the channel, then opens a modal for the code. That is not a missing option: an embed code runs across several lines and a slash text option collapses newlines as you type. The modal is a paragraph box taking up to 4,000 characters, so the code survives intact and can run longer than a prefix message could carry. Submit it within ten minutes; emote shortcodes like :party: are resolved for you there, which Discord's own client does not do inside a modal.

A sticky is only as good as the channel it is aimed at, so aim it before you write it.

Start from a code that already works

A support-channel sticky that tells people what to include and gives them somewhere else to go:

Syntax

,stickymessage add <channel> <code>

Example

,stickymessage add #support {color: #fb4868}$p{title: How to get help fast}$p{description: Post the full error, what you already tried, and your server ID. Screenshots of the whole window, not a crop.}$p{footer: {guild.name} && {guild.icon}}$p{button: link && Read the rules && https://discord.com}

A rules reminder for a busy general chat, addressed to whoever is talking at the time:

Syntax

,stickymessage add <channel> <code>

Example

,stickymessage add #general {color: #2b2d31}$p{description: {user.mention} — keep it civil, keep it in English, keep the drama in DMs. {guild.membercount} people are reading.}$p{thumbnail: {guild.icon}}

Nothing above is sticky-specific syntax; both are ordinary embed codes, and Embed codes is where the language is explained. Three things are worth copying out of them:

  • {user} is whoever triggered the re-post, not you. The code is rendered fresh every time, against the member whose message tipped the counter over, so {user.mention} pings a different person on every re-post and {user.avatar} is theirs. That is either exactly what you want or the last thing you want: a rules reminder that names the person who just spoke reads as a callout even when it is not one.
  • A token the parser does not know posts its own name. {sticky.limit} is not a variable, so a code containing it publishes the literal text sticky.limit: it does not go blank and it does not error. Draft with ,customembed create first, and ,customembed variables lists the tokens that do resolve.
  • A sticky is not restricted to an embed. Plain text, buttons and Components V2 layouts render here too, and a code that renders nothing at all is refused when you save it.

Write the code for the tenth time somebody reads it: that is the copy they will see.

Choose how often it re-posts

,stickymessage limit sets how many messages pass before the sticky moves itself back to the bottom. The channel must already have one.

Syntax

,stickymessage limit <channel> <number>

Example

,stickymessage limit #support 15
FlagMeansAcceptsDefault
<channel>Which sticky to changeA mention, a channel ID, or part of a channel nameRequired
<number>Messages between re-postsA whole number from 1 to 100, digits only10

The bounds leave plenty of room to get this wrong, which is why it deserves a paragraph. Too low and you spam your own channel: at 1 the sticky re-posts after every single message, so a conversation between two people becomes a wall of your own reminder with their replies wedged between the copies. Too high and it stops being sticky: at the 100 ceiling, in a channel that sees thirty messages a day, the reminder is buried for three days at a time. Adjust from the default by how far you will let it drift: ten messages in a fast channel is a minute, ten in a quiet one is a week.

A limit is a promise about how far the message may scroll, not about how often it appears.

Know what actually moves the message

The counter watches one thing: messages people send in that channel. When the count reaches your limit, the bot renders the code again, sends the new copy, points the sticky at it and deletes the previous copy, in that order, so a failed re-post leaves the old copy where it is rather than leaving the channel with nothing.

  • Only human messages count. Bots and webhooks, the sticky's own re-post included, never advance the counter, and a message deleted a second after it arrives has already been counted.
  • The count is not permanent. It starts over whenever the bot restarts.
  • ++delete applies to the re-posts only. The first copy, the one add posts, is never put on a timer, and a sticky with ++delete 30 spends most of the gap between re-posts with nothing in the channel at all, which is almost never what someone wanted.

Bot chatter buries a sticky without moving it

Because only people advance the counter, a channel full of other bots' output pushes your sticky a long way up the screen while the count barely moves. Where a sticky shares a channel with an ,automessage, a music panel or a logging feed, either give it a lower limit or give the noisy feature its own channel.

The message that stays visible is the one the channel keeps pushing back into view.

Know what happens when Server Premium ends

The gate sits on the re-poster as well as on the commands, so a server whose premium lapses stops re-posting on the very next message. Nothing is deleted. Every channel, code and limit stays saved and they all resume the moment premium comes back, with no re-adding to do. The copy already in the channel stays too: an ordinary message from then on, removable by anyone with Manage Messages.

Lapsing pauses the feature; it never throws the configuration away.

Read, list and remove what you have set

,stickymessage check prints one channel's raw code, the text you saved rather than the rendered result, so it is what you copy out and edit. ,stickymessage list pages through every channel that has one with its limit beside it, which is how you find the sticky you forgot about.

Syntax

,stickymessage check <channel>

Example

,stickymessage check #support

Syntax

,stickymessage list

,stickymessage remove stops one channel's sticky; ,stickymessage reset stops every sticky in the server. Neither deletes the copy already posted: the message at the bottom of the channel becomes an ordinary one you delete like any other.

Syntax

,stickymessage remove <channel>

Example

,stickymessage remove #support

Syntax

,stickymessage reset

`reset` has no short form, and that is deliberate

r, d and delete all belong to remove, the one that takes a channel. The server-wide wipe is the one command here you have to type in full, because it runs with no confirmation and no undo. On slash they are two separate entries, so the choice is in front of you either way.

Removing a sticky is the one part of this feature with no second chance, so spell it out.

Common issues

Server Premium Only. The whole command is behind Server Premium, check and list included; Manage Server alone is not enough and Self Premium does not cover a guild. Premium tiers has the products.

I could not post in #channel — check I have Send Messages and Embed Links there, then try again. Nothing was saved. add posts the real copy before it stores anything, so a channel the bot cannot write in is refused outright rather than half-saved. Fix View Channel, Send Messages and Embed Links in that channel's overrides, then run add again.

Two copies of the sticky are in the channel. Either you ran add a second time (only a re-post clears the previous copy) or the bot could not reach the old one to delete it. Reaching it means fetching it first, so the bot needs View Channel and Read Message History there; deleting its own message needs nothing more than that. Check both, then remove the stray yourself: for you, deleting somebody else's message is a Manage Messages job.

Limit must be a whole number, like 3. Digits and nothing else, so 1m and -5 are refused and the stored limit is left alone. Limit must be at least 1. and Limit must be 100 or less. are the ends of the range: 0 is not a way to post constantly, 1 is.

Note that a trailing word is not refused, it is ignored: ,sticky limit #support 10 messages reads the 10 and stops, so it quietly sets 10 rather than complaining about messages. That is the answer you wanted, but check the reply rather than assuming: the same shape is how 1m would have become 1 if it were still allowed through.

There was never a sticky messages in that channel. limit only edits a sticky that exists already: run add first.

The sticky disappears seconds after it posts. Your code ends in ++delete: run ,stickymessage check to see it, then re-add it without the flag.

Server Premium lapsed and nothing re-posts any more. That is the gate, not a fault: the stickies are still saved and start again when premium does. The last copy posted stays in the channel as an ordinary message. Delete it yourself if you want it gone.

Everything the codes themselves do (tags, variables, buttons, $p) is one language shared by every surface that takes a code, and Embed codes explains it.