Drafting
/news create opens a staged builder. Each step opens a focused modal or select, and the
result is written to the database the moment you submit it — there’s no separate in-memory
draft that could be lost if an interaction expires mid-flow. Reopening the draft (/news draft edit, or the history panel’s Edit Draft) always rebuilds the builder from what’s actually saved.
1
Title & Body
Title up to 256 characters, body up to 3000 characters. Both are optional individually, but
an announcement needs at least some content before it’s worth publishing.
2
Media
An image URL (banner/artwork), a thumbnail URL (small logo), and an accent color — a named
color (
blurple, gold, red, green, orange, teal, gray, blue, purple, pink,
white, black) or a hex code.3
CTA buttons
Up to 5 link buttons, each with a label (1-80 characters) and a URL that must start with
http:// or https://. Added and removed one at a time from the builder.4
Footer
An optional custom footer up to 200 characters. Leave it blank for the default
“Published <time>” footer.
5
Mention policy
No Ping,
@here, @everyone, or a specific role. See Mentions are opt-in
below.6
Target channels
Discord’s native multi-channel picker, optionally pre-filled from a saved preset or the “All
Configured News Channels” shortcut. See Channel Presets.
Mentions are opt-in
The default is No Ping. A brand-new draft, and a guild that hasn’t set adefault_mention_policy, both start there.
Choosing anything beyond No Ping — in the builder, via
/news config default_mention_policy, or
per-template — shows a confirmation screen naming exactly who gets notified and how many
channels are targeted, before the publish actually happens.
The mention (if any) is a short, deliberately-chosen string that only ever goes into the
message’s top-level content, gated by an explicit allowed-mentions setting. The title, body,
and footer render inside a Components V2 text block, which Discord has never parsed for
mention syntax — so an admin literally typing “@everyone” into the body cannot trigger a
notification. Only a mention policy someone actually chose can ever ping anyone.
Multi-channel, fault-tolerant publishing
Publishing sends to every target channel independently. A missing-permissions or deleted-channel failure on one channel never stops delivery to the rest — the announcement ends up:
The publish report names exactly which channels failed and why:
A retryable failure (a transient Discord error, or rate limiting) is retried automatically with
backoff, up to a bounded number of attempts, before it becomes terminally
failed. Publishing
never re-sends to a target that already succeeded — resend, retry, and crash recovery all reduce
to calling publish again, and it always picks up only the work that’s actually left. Once a
target has exhausted its automatic retries, only an explicit Resend / Retry (from
/news history) reclaims it.
Two publishers can never both deliver to the same target. Every send is claimed with a
conditional database update before Discord is ever called, and resolved with a separate write
only after that call returns — so a scheduler tick racing a manual resend (or two bot
processes sharing one database) can’t double-post.
Restart-safe scheduling
/news draft → Schedule, or the builder’s Schedule button, saves a future publish time to
the database — never an in-memory timer. A poll loop checks for due work on a short interval
(about every 30 seconds by default), and every cycle, not just at startup:
1
Reconcile stale claims
Any target whose send was claimed but never resolved — a crash mid-send — is reclaimed
automatically once it’s been stuck for a couple of minutes. Nothing waits for a restart.
2
Reprocess in-flight announcements
Anything still marked
publishing (from a prior cycle, or a crash) is picked back up.
Calling publish again is always safe: it’s idempotent per already-sent target.3
Pick up newly-due schedules
Announcements whose scheduled time has arrived are published, with bounded concurrency so
one slow channel can’t delay unrelated announcements.
If a scheduled announcement’s guild looks missing, News Bot distinguishes a gateway cache
that just hasn’t warmed up yet (retried automatically, no alarm) from an authoritative check
confirming the bot was actually removed from the server (logged and audited, but still
retried automatically in case the bot is re-added later — nothing is force-failed just because
a check came back negative once).
Editing and deleting a live announcement
Edit Live (from/news history) updates the already-sent message’s content, layout, and
mentions together, so they can never drift out of sync with each other. It defaults to
suppressing a fresh notification — a role, @everyone, or @here that already pinged once
when the announcement was first published is never silently re-pinged just because the copy was
edited. Save & Notify Again is a deliberate, separate choice, and goes through the same
mass-notification confirmation as a first publish whenever the current mention policy would
actually ping someone.
Delete (from /news history) also removes the live messages, where they still exist. It
distinguishes a message that’s already gone, a channel that’s gone or inaccessible, missing
permissions, and a transient Discord failure — only the first two are treated as done; the rest
leave the target in a state where a later delete attempt can simply try again.
Templates
/news template create captures a reusable starting point — title, body, media, mention policy,
CTAs. /news create template:<name>, or Use from the template browser, pre-fills a fresh
draft from it. Using a template never locks anything: the result is an ordinary, fully-editable
draft. See Templates.
History
/news history browses every announcement regardless of status. Depending on status, the
available actions are View, Clone (into a new draft), Resend/Retry (failed targets), Edit Draft
or Edit Live, Cancel Schedule, and Delete. See Commands → Announcements
and Installation & Permissions for exactly how those actions
are permissioned.