📖 Official Documentation

OreoBot Wiki

A feature-rich Discord bot written in Go. This guide covers everything from first-time setup to every command available.

Go 1.21+ Slash Commands SQLite / MongoDB Lavalink / yt-dlp Minecraft RCON en / fr

Requirements

Before running OreoBot, make sure you have the following installed and configured:

RequirementNotes
Go 1.21+The language OreoBot is built with
Discord Bot TokenCreate one at discord.com/developers
SQLite (default) or MongoDBFor storing warnings, mod cases, etc. SQLite works out of the box
ffmpegOnly needed with the direct music backend
yt-dlpOnly needed with the direct music backend
Lavalink serverOnly needed with the lavalink music backend
Minecraft + RCONOnly needed for /mc commands

First-Time Setup

1
Create your Discord Bot

Go to discord.com/developers/applicationsNew Application. Under the Bot tab, click Add Bot.

Enable these Privileged Gateway Intents:

  • Server Members Intent — required for welcome/leave & auto-role
  • Message Content Intent — required for auto-moderation

Copy your Bot Token — you'll need it in config.json.

Go to OAuth2 → URL Generator, select scopes bot + applications.commands, then invite the bot with at minimum: Manage Roles, Manage Channels, Kick, Ban, Moderate Members, Send Messages, Embed Links, Read History, Connect, Speak.

2
Configure the Bot

Copy the example config and fill in your values:

cp config.example.json config.json

See the config.json reference for a full explanation of every field.

3
Build & Run
go build -o oreobot .
./oreobot

# Or run directly:
go run .

The bot registers all slash commands with Discord on startup. In a new server it can take up to 1 minute to appear — set guild_id for instant registration.

Running the Bot

On startup OreoBot performs the following in order:

Core

Loads config.json → lang.yml → initializes database (SQLite/MongoDB)

Integrations

Connects to Minecraft RCON (if enabled) → starts music system (if enabled)

Discord

Logs in → registers slash commands → restores active giveaway timers

Polling

Starts Minecraft link polling (if enabled)

💡 Slash commands can take up to 1 hour to appear globally. Setting guild_id in config.json makes them appear instantly in that server.

config.json — Full Reference

Every field in config.json is annotated below.

Discord

"discord": {
  "token": "YOUR_BOT_TOKEN_HERE",  // Bot token from Developer Portal
  "guild_id": "YOUR_GUILD_ID",     // Right-click server → Copy Server ID
  "prefix": "!"                    // Unused — bot uses slash commands only
}

Database

"database": {
  "driver": "sqlite",              // "sqlite" or "mongodb"
  "sqlite": {
    "path": "data/bot.db"          // Auto-created on first run
  },
  "mongodb": {
    "uri": "mongodb://localhost:27017",
    "database": "discord_bot"
  }
}

Permissions

"permissions": {
  "admin_roles":     ["Admin", "Owner"],       // Can use admin commands
  "moderator_roles": ["Moderator", "Mod"],     // Can use mod commands
  "dj_roles":        ["DJ", "Music"]           // Can control music
}
⚠️Role names are case-sensitive and must exactly match what's in your Discord server.

Music

"music": {
  "enabled": true,
  "backend": "lavalink",           // "direct" or "lavalink"
  "max_queue_size": 100,
  "max_song_duration": 600,        // seconds (0 = no limit)
  "allow_playlists": true,
  "default_volume": 50,
  "direct": {
    "ytdlp_path": "./yt-dlp",
    "ffmpeg_path": "ffmpeg"
  },
  "lavalink": {
    "host": "localhost",
    "port": 2333,
    "password": "youshallnotpass",
    "secure": false
  }
}

Minecraft

"minecraft": {
  "enabled": false,
  "rcon_ip": "localhost",
  "rcon_port": 25575,
  "rcon_password": "your_rcon_password",
  "link_backend": "file"           // "file" or "mongodb"
}

Welcome / Leave

"welcome": {
  "enabled": true,
  "channel_id": "CHANNEL_ID",
  "embed": {
    "colour": "#f74343",
    "title": "Welcome to Our Server!",
    "message": "Welcome %joined_user%! Glad to have you here.",
    "thumbnail": "USER",           // "BOT", "USER", or any image URL
    "image_enabled": false,
    "image_url": ""
  }
}

The leave block has the exact same structure.

Tickets

"tickets": {
  "enabled": true,
  "panel_channel": "CHANNEL_ID",
  "log_channel": "CHANNEL_ID",
  "staff_roles": "ROLE_ID_1,ROLE_ID_2",
  "discord_category": "CATEGORY_ID",
  "max_open_per_user": 3,
  "categories": [
    {
      "id": "support",
      "name": "Support",
      "emoji": "🛠️",
      "description": "Get help with any issue",
      "staff_role": "ROLE_ID",
      "subcategories": [
        { "id": "bug", "name": "Bug Report", "emoji": "🐛", "description": "Report a bug" }
      ]
    }
  ]
}

Auto-Mod

"moderation": {
  "mod_log_channel": "CHANNEL_ID",
  "auto_mod": {
    "enabled": true,
    "max_mentions": 5,
    "max_lines": 30,
    "anti_spam_seconds": 5,
    "anti_spam_count": 5
  }
}

Chat Bridge

"chat_bridge": {
  "enabled": true,
  "rabbitmq_uri": "amqp://user:password@host:5672/%2F",
  "channel_id": "DISCORD_CHANNEL_ID",
  "mc_channel_id": "global",   // OreoEssentials channel (global / local / trade / staff / help / announcements)
  "ban_sync": false,            // Sync Discord bans → Minecraft bans via RCON
  "mod_sync": false             // Sync Discord /mute → Minecraft MuteService via RabbitMQ
}

No-Ping

"no_ping": {
  "enabled": true,
  "protected_roles": ["ROLE_ID_1", "ROLE_ID_2"],  // Role IDs (right-click role → Copy ID)
  "message": "{user} You are not allowed to ping **{role}**!",
  "delete_message": true
}

Counting Game

"counting_game": {
  "enabled": true,
  "channel_id": "COUNTING_CHANNEL_ID",
  "fail_resets": true,           // Reset to 0 on wrong number
  "delete_wrong": true,          // Delete wrong numbers
  "delete_non_numbers": true     // Delete non-number messages
}

Custom Commands

"custom_commands": [
  {
    "name": "rules",
    "description": "Server rules",
    "message": "**Rules:**\n1. Be respectful\n2. No spam",
    "ephemeral": true
  }
]

lang.yml — Language Settings

All bot messages are defined in lang.yml. Open it and change the first line to switch languages:

# Options: "en" (English) or "fr" (French)
active_language: en
CodeLanguage
enEnglish
frFrench
Restart the bot after changing the language.

Permission System

OreoBot uses a layered permission system:

LevelWho has itHow it's determined
AdminServer owners + members with roles in admin_rolesRole name match
ModeratorMembers with roles in moderator_roles OR Discord "Ban Members" permissionRole name or Discord permission
DJMembers with roles in dj_rolesRole name match
EveryoneAll server members

Commands — Moderation

All moderation commands require Moderator or Admin unless noted.

/ban
Ban a member from the server.
OptionRequiredDescription
userRequiredThe member to ban
reasonOptionalReason for the ban
delete_daysOptionalDays of messages to delete (0–7)
/ban user:@BadUser reason:Spamming delete_days:1
/unban
Unban a previously banned user.
OptionRequiredDescription
user_idRequiredThe Discord user ID of the banned user
reasonOptionalReason for unbanning
/kick
Remove a member from the server (they can rejoin).
OptionRequiredDescription
userRequiredThe member to kick
reasonOptionalReason for the kick
/mute
Temporarily timeout a member using Discord's native timeout. Max 28 days.
OptionRequiredDescription
userRequiredThe member to mute
durationRequired10m, 2h, 1d, 7d
reasonOptionalReason
/mute user:@Spammer duration:1h reason:Spam
/unmute
Remove a timeout from a member.
OptionRequiredDescription
userRequiredThe member to unmute
/warn
Issue a formal warning. Warnings are saved and can be reviewed later.
OptionRequiredDescription
userRequiredThe member to warn
reasonRequiredReason for the warning
/warnings
View all warnings for a user.
OptionRequiredDescription
userRequiredThe member whose warnings to view
/clearwarnings
Remove all warnings from a user's record.
OptionRequiredDescription
userRequiredThe member to clear warnings for
/purge
Delete multiple messages from the current channel. Discord only allows bulk-deletion of messages under 14 days old.
OptionRequiredDescription
countRequiredNumber of messages to delete (1–100)
userOptionalOnly delete messages from this user
/slowmode
Set a cooldown between messages in the current channel.
OptionRequiredDescription
secondsRequiredDelay in seconds (0 disables, max 21600)
/lock / /unlock
Prevent / allow @everyone from sending messages in the current channel. No options needed.
/modlog
Set the channel where moderation actions are logged.
OptionRequiredDescription
channelRequiredThe channel to use as the mod log
/userinfo
Display information about a member — username, account & join dates, all roles, and warning count.
OptionRequiredDescription
userOptionalThe member to look up (defaults to yourself)

Commands — Ticket System

Initial Setup

1
Enable tickets

Set tickets.enabled to true in config.json and fill in panel_channel, log_channel, staff_roles, discord_category.

2
Add categories

Add your categories in the categories array, or use /ticket addcategory at runtime.

3
Post the panel

Run /ticket panel to post the ticket creation panel in the configured channel.

Commands

/ticket setup Admin
Configure the ticket system through Discord (overrides config.json).
OptionRequiredDescription
panel_channelRequiredChannel for the ticket panel
log_channelRequiredChannel for ticket logs
staff_roleRequiredRole that can manage all tickets
categoryRequiredDiscord category for ticket channels
max_per_userOptionalMax open tickets per user (default: 3)
/ticket panel Admin
Post or refresh the ticket creation panel. Run this after any category changes.
/ticket addcategory Admin
Add a new ticket category at runtime without editing config.json. Run /ticket panel after adding.
OptionRequiredDescription
idRequiredUnique ID (no spaces)
nameRequiredDisplay name
emojiRequiredEmoji next to the name
descriptionRequiredShort description
staff_roleOptionalRole ID specific to this category
/ticket removecategory Admin
Remove a runtime category. Only categories added via /ticket addcategory can be removed this way.
OptionRequiredDescription
idRequiredThe category ID to remove
/ticket addsubcategory Admin
Add a subcategory under an existing runtime category.
OptionRequiredDescription
parent_idRequiredID of the parent category
idRequiredUnique ID for the subcategory
nameRequiredDisplay name
emojiRequiredEmoji
descriptionRequiredShort description
/ticket list Admin / Mod
List all currently open tickets.
/ticket config Admin
Display the current ticket system configuration.
/close
Close the current ticket channel. Must be run inside a ticket. A confirmation prompt appears before closing. The ticket is logged to the log channel.
Can be used by Staff, Admin, or the ticket owner.
/add Staff / Admin
Add a user to the current ticket.
OptionRequiredDescription
userRequiredThe member to add
/remove Staff / Admin
Remove a user from the current ticket.
OptionRequiredDescription
userRequiredThe member to remove

Commands — Auto-Role

Automatically assign a role to every new member when they join.

⚠️The bot's role must be above the target role in Server Settings → Roles.
/joinrole set Admin
Set the role to automatically give to new members.
OptionRequiredDescription
roleRequiredThe role to assign
/joinrole disable Admin
Disable automatic role assignment.
/joinrole status Admin
Check if auto-role is enabled and which role is configured.
/joinrole check Admin
Verify that the bot has permission to assign the configured role. Useful for diagnosing issues.

Commands — Role Menus

Create self-assignable role menus that members can interact with using buttons. A menu can hold up to 20 roles.

Quick Start

/rolemenu create title:Pick your roles mode:multi
/rolemenu add menu_id:MENU_ID role:@Gamer label:Gamer
/rolemenu post menu_id:MENU_ID channel:#roles
/rolemenu create Admin
Create a new role menu. Returns a menu ID for the next steps.
OptionRequiredDescription
titleRequiredTitle of the role menu
modeRequiredmulti (pick many) or single (pick one)
/rolemenu add Admin
Add a role button to an existing menu.
OptionRequiredDescription
menu_idRequiredThe menu ID
roleRequiredThe role to add
labelRequiredText shown on the button
/rolemenu post Admin
Post the role menu in a channel.
OptionRequiredDescription
menu_idRequiredThe menu ID
channelRequiredChannel to post in
/rolemenu list Admin
List all role menus and their IDs.
/rolemenu delete Admin
Delete a role menu.
OptionRequiredDescription
menu_idRequiredThe menu ID to delete

Commands — Giveaways

Run giveaways with automatic timer, random winner selection, and reroll support. Giveaway timers survive bot restarts.

/giveaway create Admin
Start a new giveaway. Posts an embed with an Enter Giveaway button. When the timer ends, winners are picked and announced.
OptionRequiredDescription
prizeRequiredWhat you're giving away
durationRequired10m, 2h, 1d, 7d
winnersRequiredHow many winners to pick
channelOptionalChannel to post in (defaults to current)
/giveaway create prize:Discord Nitro duration:1d winners:1 channel:#giveaways
/giveaway end Admin
End a giveaway early and immediately pick winners.
OptionRequiredDescription
giveaway_idRequiredID of the giveaway
/giveaway reroll Admin
Pick new winners for an already-ended giveaway.
OptionRequiredDescription
giveaway_idRequiredID of the ended giveaway
/giveaway list Admin
Show all currently active giveaways with their IDs, prizes, and end times.

Commands — Music

Play music in voice channels. Requires music.enabled: true in config.json. Music controls require a DJ role.

Direct Backend

Requires yt-dlp + ffmpeg installed locally. Easy setup, good for small bots.

Lavalink Backend

Connects to a Lavalink server. Recommended for stability and larger bots. Requires extra server setup.

/play
Play a song or add it to the queue. You must be in a voice channel.
OptionRequiredDescription
queryRequiredSong name or YouTube URL
/skip DJ
Skip the currently playing song.
/stop DJ
Stop playback, clear the queue, and disconnect the bot from the voice channel.
/queue
Show the current song queue including the now-playing song.
/nowplaying
Show details about the currently playing song (title, duration, requester).
/pause / /resume
Pause or resume playback.
/volume DJ
Change the playback volume.
OptionRequiredDescription
levelRequiredVolume from 0 to 100

Commands — Minecraft Integration

Connect your Discord server to a Minecraft server via RCON.

Setup

In your Minecraft server.properties:

enable-rcon=true
rcon.port=25575
rcon.password=your_password

In config.json:

"minecraft": {
  "enabled": true,
  "rcon_ip": "your.server.ip",
  "rcon_port": 25575,
  "rcon_password": "your_password"
}
/mc status
Check if the Minecraft server is online and RCON is connected.
/mc players
List all players currently online on the Minecraft server.
/mc command Admin
Execute any RCON command on the server.
OptionRequiredDescription
commandRequiredThe command to run (without the /)
/mc command command:give PlayerName diamond 64
/mc whitelist Admin
Add or remove a player from the server whitelist.
OptionRequiredDescription
actionRequiredadd or remove
playerRequiredMinecraft username
/mc link
Link your Discord account to your Minecraft account. The bot sends you a DM with a 6-character code (expires in 10 minutes). Then in Minecraft run:
/discord link YOURCODE
/mc unlink
Remove the link between your Discord and Minecraft account.
/mc profile
View your linked Minecraft profile (username, balance, homes).
OptionRequiredDescription
userOptionalView another member's profile (Admin only)
/mc linked Admin
List all Discord↔Minecraft linked accounts on the server.

OreoEssentials Plugin

OreoEssentials is a companion Minecraft plugin that extends OreoBot's Minecraft integration. It must be installed on your Minecraft server to enable account linking and live player-data lookups.

🧩 OreoEssentials handles the Minecraft side of the bridge. OreoBot handles the Discord side. The two communicate exclusively through RCON — no shared database, no port changes needed beyond what you already have.

How the bridge works

When a user runs a bot command that needs Minecraft data (like /mc profile), OreoBot sends a special RCON command to your server. OreoEssentials intercepts that command, reads the requested data (balance, homes, online status…), and replies through the RCON response. OreoBot then formats the reply and posts it as a Discord embed.

Discord side — OreoBot

Receives slash command → sends oe-discord <sub> <uuid> via RCON → parses response → posts embed to Discord

Minecraft side — OreoEssentials

Registers the oe-discord command → reads economy / homes / online data → replies with a one-line OK: … or ERR: … string

Account linking system

The linking flow is a two-step handshake between Discord and Minecraft. OreoEssentials owns the in-game half; OreoBot owns the Discord half.

1
User runs /mc link in Discord

OreoBot generates a short 6-character code, saves a pending entry (Discord ID + expiry), and DMs the code to the user. The code expires in 10 minutes.

2
User runs /discord link <code> in Minecraft

OreoEssentials' DiscordLinkCommand receives the code, calls DiscordLinkManager.confirmLink(), validates the pending file/document, and writes a confirmed link entry (Discord ID ↔ UUID ↔ username). If the code doesn't exist or is expired, the player gets a clear error message.

3
OreoBot polls and finalises the link

OreoBot detects the confirmed entry on its next polling cycle (≤ 15 seconds) and updates the Discord member's nickname and linked role automatically.

In-game command — /discord

OreoEssentials registers the /discord command for players inside Minecraft:

/discord link <code>
Confirm the link between your Minecraft account and your Discord account using the code you received via DM from OreoBot.
/discord link AB12CD
/discord status
Check whether your Minecraft account is currently linked and see your Discord ID if it is.

Link storage backend — config.yml

OreoEssentials stores pending and confirmed link data. The backend is configured in OreoEssentials' config.yml:

discord:
  link_backend: "file"   # "file" (default) or "mongodb" for cross-network
ValueStorage locationBest for
"file" data/mc_links/pending/ — one .json file per code Single-server setups, no extra dependencies
"mongodb" Collections: discord_link_pending, discord_link_confirmed, discord_links Multi-server / BungeeCord networks sharing one database
⚠️ OreoBot's config.json has its own minecraft.link_backend setting — keep it in sync with OreoEssentials' config.yml so both sides read from the same store.

RCON extension commands (oe-discord)

These are server-side-only commands registered by DiscordRconExtension. They are called automatically by OreoBot over RCON — players cannot run them. Each returns a one-line OK: … result or ERR: … on failure.

RCON commandReturnsUsed by
oe-discord balance <uuid> Player's economy balance (e.g. OK: 1,250) /mc profile
oe-discord homes <uuid> Comma-separated list of name@server (e.g. OK: base@survival,farm@survival) /mc profile
oe-discord online <uuid> OK: ONLINE <name> or OK: OFFLINE <name> LASTSEEN <epoch> /mc profile
oe-discord inventory <uuid> Top 12 items by quantity (e.g. OK: Diamond x64, Iron Ingot x32) Future — reserved for /mc inventory
The inventory sub-command works even for offline players — OreoEssentials reads the last saved inventory snapshot via InventoryService if the player is not currently online.

What REQUIRES OreoEssentials

/mc profile — balance

Shows *(fetch failed)* without the plugin

/mc profile — homes

Shows *(no data)* without the plugin

/mc profile — online status

Shows *(fetch failed)* without the plugin

Account linking

/discord link in-game requires the plugin to be present on the server

Link status check

/discord status in-game requires the plugin

Inventory lookup

Future /mc inventory support via oe-discord inventory

What works WITHOUT OreoEssentials

Everything that doesn't require live player data or in-game linking still works normally:

  • Check server status — /mc status
  • List online players — /mc players
  • Run RCON commands — /mc command
  • Manage the whitelist — /mc whitelist
  • Broadcast messages in-game — /mc say
⚠️ Without OreoEssentials, /mc link in Discord will generate a code but users will have no way to confirm it in-game — the /discord link command won't exist on the server.

Commands — Utility

/say Admin
Make the bot send a plain text message in a Discord channel.
⚠️ Discord only — this has nothing to do with Minecraft. To send a message into the Minecraft game chat, use /mc say instead.
OptionRequiredDescription
channelRequiredThe Discord channel to send the message in
messageRequiredThe message text (use \n for line breaks)
/say channel:#announcements message:Server maintenance in 10 minutes!
/mc say Admin
Broadcast a message in the Minecraft game chat via RCON. This is the Minecraft counterpart to /say — it sends to the in-game chat, not to Discord.
The message appears in-game as: [Discord] YourUsername: your message
OptionRequiredDescription
messageRequiredThe message to broadcast in-game

Requires Minecraft integration to be enabled in config.json.

/embed Admin
Create and send a custom embed message in a Discord channel.
OptionRequiredDescription
channelRequiredChannel to send the embed in
titleRequiredEmbed title
descriptionRequiredEmbed body text (use \n for line breaks)
colourOptionalHex color code (e.g. #ff0000)
imageOptionalURL of a large image shown at the bottom
thumbnailOptionalURL of a small image in the top right corner
footerOptionalFooter text
authorOptionalAuthor name shown at the top of the embed
author-iconOptionalURL of a small icon shown next to the author name
urlOptionalURL that the embed title links to when clicked

Commands — Custom Commands

Define your own slash commands that reply with a fixed message. They appear alongside all built-in commands and are registered with Discord automatically on every startup.

Configuration

"custom_commands": [
  {
    "name": "rules",           // Slash command name — users type /rules
    "description": "Server rules",
    "message": "**Rules:**\n1. Be respectful\n2. No spam",
    "ephemeral": true          // true = only the caller sees the reply
  },
  {
    "name": "discord",
    "description": "Join our Discord",
    "message": "Join us at: https://discord.gg/example",
    "ephemeral": false         // false = reply visible to the whole channel
  }
]
FieldTypeDescription
namestringThe slash command name (lowercase, no spaces). Users type /name to trigger it.
descriptionstringShort description shown in the Discord command picker.
messagestringThe reply message. Supports Discord markdown. Use \n for line breaks.
ephemeralbooltrue — only the user who ran the command sees the reply. false — visible to everyone in the channel.
Add as many commands as you need. The bot re-registers them with Discord every time it restarts.
⚠️ Command names must not conflict with built-in commands like ban, play, ticket, etc. Conflicting names will be silently overridden by the built-in handler.

Chat Bridge — Discord ↔ Minecraft

The Chat Bridge creates a live, bidirectional link between a Discord text channel and your Minecraft server's chat. Messages sent in the Discord channel appear in Minecraft, and Minecraft chat appears in Discord — in real time, over RabbitMQ.

🌉 Requires a RabbitMQ server running on your network and the OreoEssentials plugin installed on your Minecraft server.

How it works

Discord → Minecraft

A linked Discord user sends a message in the bridge channel → OreoBot publishes a CHANMSG payload to the chat_sync RabbitMQ fanout exchange → OreoEssentials receives it and routes it to the configured Minecraft channel (e.g. global). The message appears in-game as [Discord] PlayerName: text.

Minecraft → Discord

A player chats in-game → OreoEssentials publishes a CHANMSG payload to the chat_sync exchange → OreoBot receives it, resolves the player's linked Discord account (if any), and posts the message to the bridge channel as PlayerName (@mention): text.

⚠️ Only linked Discord accounts can send messages into Minecraft via the bridge. Unlinked users' messages are silently ignored in the Discord→Minecraft direction. Minecraft→Discord works for all players regardless of linking status.

Configuration — config.json

"chat_bridge": {
  "enabled": true,
  "rabbitmq_uri": "amqp://user:password@your-server:5672/%2F",
  "channel_id": "YOUR_DISCORD_CHANNEL_ID",   // The Discord channel used for the bridge
  "mc_channel_id": "global",                 // OreoEssentials channel name (see table below)
  "ban_sync": false,                          // true = Discord ban → Minecraft ban via RCON
  "mod_sync": false                           // true = Discord /mute → Minecraft mute via RabbitMQ
}
FieldDescription
rabbitmq_uriAMQP connection URI for your RabbitMQ server. Format: amqp://user:pass@host:port/vhost. The default vhost %2F represents /.
channel_idDiscord channel ID where bridged messages are posted and read from. Right-click the channel → Copy Channel ID.
mc_channel_idThe OreoEssentials channel name to route messages to/from. Must match a channel ID defined in OreoEssentials' config.yml. Set to "global" for the default channel. This field is required for Discord→Minecraft to work when the OreoEssentials channel system is enabled. Leaving it empty causes the bot to send legacy-format messages that OreoEssentials ignores.
ban_syncWhen true, banning a linked user from Discord automatically bans their Minecraft account via RCON (ban username Banned from Discord). Lifting the Discord ban also pardons them in Minecraft.
mod_syncWhen true, using /mute on a linked Discord user publishes a CTRL;;MUTE control packet to RabbitMQ. OreoEssentials' MuteService receives it and applies the mute in-game. /unmute publishes CTRL;;UNMUTE to lift it.

OreoEssentials Channels — mc_channel_id values

OreoEssentials' channel system separates different types of in-game chat. The mc_channel_id in your bot config must exactly match one of the channel IDs configured in OreoEssentials' config.yml. The default channels are:

Channel IDWho can see itTypical use
globalAll players on all connected servers (cross-server)General chat — recommended for the bridge
localPlayers within a configurable radiusProximity / area chat
tradeAll playersBuying and selling
staffStaff-permission players onlyInternal staff communication
helpAll playersPlayer questions and support
announcementsAll players (read-only for non-staff)Server announcements
Set mc_channel_id to "global". It is the default OreoEssentials channel, cross-server, and reaches every online player.

OreoEssentials — Required config.yml Changes

For the chat bridge to work end-to-end, OreoEssentials' config.yml must match the bot config on two critical points:

# OreoEssentials config.yml — chat bridge relevant settings

discord:
  link_backend: "mongodb"   # MUST match minecraft.link_backend in bot config.json
                             # "mongodb" → shared MongoDB store (works across servers)
                             # "file"    → local JSON files (single-server only)

chat_sync:
  enabled: true
  rabbitmq_uri: "amqp://user:password@your-server:5672/%2F"  # Identical to bot config

  channels:
    - id: "global"
      name: "Global"
      default: true
      cross_server: true
    - id: "local"
      name: "Local"
      radius: 100
    - id: "trade"
      name: "Trade"
    - id: "staff"
      name: "Staff"
      staff_only: true
    - id: "help"
      name: "Help"
    - id: "announcements"
      name: "Announcements"

  default_channel: "global"
⚠️ The rabbitmq_uri must be identical in the bot's config.json and in OreoEssentials' config.yml. Both sides subscribe/publish to the same chat_sync fanout exchange.
⚠️ discord.link_backend in OreoEssentials must match minecraft.link_backend in the bot's config.json. A mismatch causes "Invalid or Expired Code" errors when players try to link their accounts — the two sides look in different data stores and can never see each other's codes.

Ban & Mod Sync

Ban Sync (ban_sync: true)

When a linked user is banned from Discord, OreoBot automatically runs ban <username> Banned from Discord via RCON. Lifting the Discord ban also pardons them with pardon <username>. Requires Minecraft RCON to be configured and connected.

Mod Sync (mod_sync: true)

When /mute is used on a linked Discord user, OreoBot publishes CTRL;;MUTE;;DISCORD;;uuid;;expiryMs;;b64(reason);;b64(by) to RabbitMQ. All connected Minecraft servers running OreoEssentials receive it and mute the player. /unmute publishes CTRL;;UNMUTE to remove it.

Message Format

DirectionAppears as
Discord → Minecraft[Discord] PlayerName: message text
Minecraft → DiscordPlayerName (@DiscordUser if linked): message text

The Discord @mention only appears next to the player name if the Minecraft player has a linked Discord account.

Troubleshooting the Bridge

Discord messages don't appear in Minecraft
  • Ensure mc_channel_id is set to a real OreoEssentials channel name (e.g. "global") — an empty value sends legacy format which OreoEssentials ignores when its channel system is active.
  • Verify your Discord account is linked (/mc link). Only linked accounts can bridge to Minecraft.
  • Make sure discord.link_backend in OreoEssentials matches minecraft.link_backend in bot config.
Minecraft messages don't appear in Discord
  • Check that OreoEssentials has chat_sync.enabled: true and the same RabbitMQ URI.
  • Look for [ChatBridge] Sub connect error in the bot logs — it retries every 5 seconds.
  • If OreoEssentials previously used a durable chat_sync exchange, delete it from RabbitMQ management and restart both sides.

No-Ping Protection

Automatically detect and delete messages that ping a protected role, then post a warning. Useful for protecting Admin, VIP, or any sensitive role from unsolicited @mentions.

Configuration

"no_ping": {
  "enabled": true,
  "protected_roles": ["ROLE_ID_1", "ROLE_ID_2"],   // Role IDs, NOT role names
  "message": "{user} You are not allowed to ping **{role}**!",
  "delete_message": true    // true = also delete the offending message
}
FieldDescription
protected_rolesArray of role IDs (not role names) that cannot be pinged. Multiple IDs are supported. Enable Discord Developer Mode to copy role IDs.
messageWarning message sent to the channel when a protected role is pinged. Placeholders: {user} = mention of the offending user, {role} = name of the pinged role.
delete_messagetrue — the offending message is deleted before the warning is posted. false — only the warning is sent, the message stays.

How to get a Role ID

1
Enable Developer Mode

Go to Discord User Settings → Advanced → toggle on Developer Mode.

2
Copy the Role ID

Go to Server Settings → Roles → right-click the role you want to protect → Copy Role ID. Paste it into the protected_roles array in your config.

You can protect as many roles as you want by adding multiple IDs to the protected_roles array. The bot checks all of them on every message in every channel.

Counting Game

Turn a dedicated channel into a collaborative counting game. Members take turns posting the next number in sequence. Wrong numbers, repeated users, and non-number messages are all handled automatically.

Configuration

"counting_game": {
  "enabled": true,
  "channel_id": "YOUR_COUNTING_CHANNEL_ID",
  "fail_resets": true,           // true = reset count to 0 on a wrong number
  "delete_wrong": true,          // true = delete wrong-number messages automatically
  "delete_non_numbers": true     // true = delete any non-number messages from the channel
}
FieldDescription
channel_idThe ID of the Discord channel dedicated to the counting game. Only messages in this channel are processed by the counting logic.
fail_resetstrue — the count resets back to 0 when someone sends the wrong number. false — wrong messages are handled (deleted / warned) but the count is not reset.
delete_wrongtrue — wrong numbers are automatically deleted to keep the channel clean.
delete_non_numberstrue — any message that is not a valid integer is deleted. Keeps only actual counting messages in the channel.
Create a dedicated channel (e.g. #counting), copy its ID (right-click → Copy Channel ID), and paste it into channel_id. The bot starts from 1 and tracks the current count and last counter in the database.
💡 The same user cannot count two numbers in a row. The bot enforces that each consecutive number must come from a different member.

Welcome & Leave Messages

Automatically post an embed when someone joins or leaves your server.

Placeholders

PlaceholderReplaced with
%joined_user%The member's mention (e.g. @Username)
%username%The member's plain username

Thumbnail Options

ValueShows
"BOT"The bot's profile picture
"USER"The joining/leaving member's profile picture
Any URLA custom image from that URL
💡The leave block has the exact same structure as welcome.

Auto-Moderation

Automatically handle common spam and abuse patterns.

RuleWhat it does
max_mentionsIf a message mentions more than N users, auto-mod acts
max_linesIf a message has more than N lines, auto-mod acts
Anti-spamIf a user sends more than anti_spam_count messages within anti_spam_seconds seconds, auto-mod acts
"auto_mod": {
  "enabled": true,
  "max_mentions": 5,
  "max_lines": 30,
  "anti_spam_seconds": 5,
  "anti_spam_count": 5
}
Set enabled: false to turn off auto-moderation entirely.

Database & Storage

Guild State

Saved to data/guilds/{guild_id}.json. Contains warnings, auto-role config, role menus, giveaways, and ticket runtime state. Created automatically.

SQLite (default)

Creates data/bot.db automatically. No extra setup needed. Best for most use cases.

MongoDB

Set database.driver to "mongodb" and fill in your URI. Used for warnings and moderation cases.

Minecraft Links

Stored in data/mc_links/ as JSON by default. Set minecraft.link_backend to "mongodb" to use MongoDB instead.

Troubleshooting

Slash commands aren't showing up
  • Commands can take up to 1 hour to appear globally
  • Set guild_id in config.json to your server ID for instant registration
  • Make sure the bot has the applications.commands scope when invited
Bot can't assign roles
  • The bot's role must be above the target role in Server Settings → Roles
  • Use /joinrole check to diagnose auto-role issues
Music isn't working
  • Check that music.enabled is true in config.json
  • Direct backend: verify yt-dlp and ffmpeg are installed and paths are correct
  • Lavalink backend: make sure your Lavalink server is running and credentials match
  • You must be in a voice channel before using /play
Minecraft: "RCON not initialized"
  • Check that minecraft.enabled is true
  • Verify rcon_ip, rcon_port, and rcon_password are correct
  • Make sure enable-rcon=true is set in server.properties
  • Check that the RCON port is not blocked by a firewall
Ticket panel won't post
  • Make sure tickets.enabled is true
  • Make sure panel_channel is set to a valid channel ID
  • Make sure at least one category is configured
  • Run /ticket panel after any configuration changes
"No permission" errors
  • Role names in permissions.admin_roles / permissions.moderator_roles must exactly match Discord role names (case-sensitive)
  • Easiest fix: give the bot the Administrator permission
💡 Giveaway timers are automatically restored on bot restart. If a giveaway ended while the bot was offline, winners will be picked when it comes back online.