Skip to content

Discord

Everything Discord lives in discord.yml. There are two ways an alert can leave the server, and DaisyFilter always prefers the first:

BotWebhook fallback
SendsMetadata and the masked preview; the message itself only via Reveal, or if you turn show-full-message onMetadata and the masked preview only
Staff can act from DiscordYes — buttons on every alertNo
Needs a bot applicationYesNo
Used whenIt is configured and connectedThe bot could not deliver

The webhook is a safety net, not a second feed — nothing is ever posted twice. It takes over when the bot is not configured, is not connected, or when Discord rejects a specific post. It inherits the bot’s min-severity and enforced-only, so an outage cannot quietly change which incidents staff hear about.

It stays metadata-only even during a failover. A webhook URL usually points somewhere less restricted than the bot’s channel, so an outage must not become the moment player content starts going there. A failover alert therefore tells you less than the bot’s would have.

Set only the webhook URL and no bot token, and it behaves as a plain metadata log, without the JDA download. There is no separate webhook.yml: everything Discord lives in this one file.

By default an alert shows the masked preview — who, category, severity, and the action buttons — plus a Reveal full message button. Only roles mapped daisyfilter.view.raw can use it, and the message is returned privately to whoever clicked, so nobody else in the channel sees it.

That is the arrangement you want for a shared logs channel: a moderator can mute or kick straight from the alert without the whole team reading what a child typed, and a senior staff member can pull up the exact wording when a flag needs judging.

show-full-message: true puts the message straight into the alert instead. Turn it on only where every member of the channel is already trusted with exact evidence, because:

  • The channel’s permissions become the only access control. The roles map stops protecting message content — anyone who can read the channel reads every flagged message, including people added later.
  • Discord history does not expire. DaisyFilter purges its own records after 30 days; alerts stay until someone deletes them, and it cannot be undone after the fact.
  • Content lives on Discord’s servers under Discord’s terms. If your players are children, or you have data-protection obligations, that is a decision to take deliberately.
  1. Create an application at https://discord.com/developers/applications, add a bot, and copy the token. No privileged intents are required.
  2. Invite it to your server with Send Messages in the alert channel.
  3. Fill in discord.yml — or open the dashboard and click Integrations, which writes the same settings without touching the file.
  4. Restart. The token and the enabled switch are read once, when the gateway connects; everything else takes effect immediately.
enabled: true
bot-token: "..."
guild-id: "112233445566778899"
alert-channel-id: "998877665544332211"
min-severity: 3
enforced-only: true
show-full-message: false # true puts the message in the alert for everyone
link-required: true
roles:
"112233445566778899": # Moderator role ID
- daisyfilter.punish.mute
- daisyfilter.punish.kick
"998877665544332211": # Admin role ID
- daisyfilter.punish.ban
webhook:
url: "https://discord.com/api/webhooks/..." # optional fallback

Quote the role IDs. Unquoted, YAML reads a snowflake as a number rather than text. DaisyFilter compares them as text either way, so it works — but quoted is what the file should look like.

Two things must both hold.

A linked account. Run /df link in game; you get a one-time code, valid five minutes. Run /link <code> in Discord. The code is generated in game on purpose — redeeming it proves the Discord user controls that Minecraft account, which is the claim worth establishing before handing out punishment powers.

The link supplies the identity written to the staff audit log, so a punishment issued from Discord is indistinguishable from one issued in game in /daisyfilter audit. That is deliberate: they have identical consequences for the player.

A mapped role. Permissions come only from the roles map — never from the staff member’s in-game rank, which cannot be consulted while they are offline. An unlisted role grants nothing, and there is no inheritance: mapping daisyfilter.admin does not confer daisyfilter.punish.ban. List every node you intend to grant.

The role map is editable only in the file, not from the GUI. It decides who can punish, so a change should be reviewable.

Everything is re-checked when a button is clicked, not when the alert was posted. Revoking a Discord role immediately disarms buttons that were posted before you revoked it, and a user who cannot use an action is told which permission is missing rather than having the click silently ignored.

Each alert carries a button per enabled punishment profile from actions.yml, so the actions match what the in-game punish menu offers. Profiles with durations (mute, temp ban) open a short prompt pre-filled with the first preset. A Reveal full message button appears whenever the alert is not already showing the message.

Replies are ephemeral — only the clicker sees them. One short public line is added to the alert recording who acted and what they did, so the channel shows an incident as handled at a glance.

Nothing is posted. Check enabled, the token, and alert-channel-id, then that the bot can see and post in that channel. Incidents below min-severity, and monitor-only ones while enforced-only: true, are dropped by design.

/link does not appear in Discord. Slash commands are registered against guild-id when the gateway connects. If it is blank or wrong, the command is registered globally instead and can take up to an hour to appear.

A button says the action is unavailable. The message names the reason — usually the profile is disabled in actions.yml, or the clicker’s Discord role is not mapped to that permission.

First boot is slow or fails offline. JDA and the database drivers are fetched from Maven Central by Paper’s library loader on first start, then cached. This happens whether or not Discord is enabled.