How Tos
Prerequisites
Before deploying the bot, make sure you have the following ready:
- A Bot Token and Client ID from the Discord Developer Portal.
- No Privileged Intents are required! The bot relies entirely on modern slash commands.
- If running locally: Node.js (v16.14.0 or higher)
- If running via containers: Docker and Docker Compose (Recommended)
Deployment & Setup Guide
Follow these steps to deploy and run Scotch Egg. The setup below details the recommended containerized installation using Docker Compose.
Recommended Deployment: Docker Compose
Using Docker Compose is strongly recommended for hosting Scotch Egg. It pre-configures Node.js, database folders, and permission environments inside an isolated container, making installation foolproof and keeping background process monitoring automated.
1. Download the Bot
First, download the bot's files and extract the ZIP file into a folder on your computer.
2. Discord Credentials & Environment Setup
Before configuring the bot, you need to grab a few credentials from Discord:
- Go to the Discord Developer Portal and click New Application.
- On the "General Information" page, copy your Application ID (this
will
be your
CLIENT_ID). - Navigate to the "Bot" tab on the left, click Reset Token, and copy
the
new password token (this will be your
DISCORD_TOKEN). - Go to "OAuth2" > "OAuth2 URL Generator". Check the
botandapplications.commandsscopes.Tip: After checking theCopy the generated URL at the bottom and open it in your browser to invite the bot to your server.botscope, a Bot Permissions grid will appear below it. It is highly recommended to select Send Messages, Read Message History, View Channels, Embed Links, and Create Public Threads (if using the auto-thread feature) so the bot's role is automatically configured.Important: You must select BOTH scopes. If you miss the
applications.commandsscope, slash commands will not appear in your server!
Now, rename the provided .env.example file to .env inside your
bot's
folder and paste those credentials in like so:
# The authentication token for your Discord bot (Keep this secret!) DISCORD_TOKEN=your_actual_token_here # The application ID of your Discord bot CLIENT_ID=your_actual_client_id_here # (Optional) Default reminder intervals for new events if you don't use /settings intervals # Format: comma-separated list of values with units (m, h, d) DEFAULT_INTERVALS="24h, 1h" # (Optional) The Discord User ID of the bot administrator to receive DM alerts about critical errors ADMIN_USER_ID=your_discord_user_id_here # (Optional) The default fallback channel ID for event announcements. # Best practice is to set this from inside Discord using: /settings channel #events ANNOUNCEMENT_CHANNEL_ID=your_optional_fallback_channel_id_here
3. Start the Bot
Make sure Docker is open and running on your computer. Then, open your terminal (Command Prompt, PowerShell, or Terminal), navigate to the bot's folder, and run:
docker compose up -d --build
You can now see the bot running smoothly inside Docker!
4. Register Slash Commands (Once)
After the bot is running, you must register its commands with Discord. You only need to do this once. Run the following command in your terminal:
docker exec -it scotch-egg node deploy-commands.js
Alternative: Local Node.js Installation (No Docker)
If you prefer not to use Docker, you can run the bot directly on your host system using Node.js. Make sure you have installed Node.js (v16.14.0 or higher).
1. Install Dependencies
Navigate to the bot's root directory in your terminal and install the required npm packages:
npm install
2. Register Slash Commands
Register the bot's commands with Discord by running:
node deploy-commands.js
3. Start the Bot
Start the bot process using node:
node index.js
Note: In a production environment, it is highly recommended to use a process manager like PM2 to ensure the bot automatically restarts if it crashes or the system reboots.
Using the Bot
1. Set the Announcement Channel
Administrators must tell the bot which text channel to use for event announcements. Type the following command in any channel:
/settings channel
2. Creating Events
Simply use Discord's native Create Event button at the top of your channel list. The moment you create an event, the bot will instantly post a rich-embed announcement in your configured channel.
3. Opting In (The "Remind Me!" Button)
Users who want to be notified can click the β° Remind Me! button on the announcement. Depending on the server's configuration mode, the bot will either DM them or publicly @ ping them in the channel at the configured intervals.
Updating the Bot
If you ever edit the code or download an updated version of the bot, applying the changes is simple and won't delete your data.
- Run the following command to rebuild the container with the new code:
docker compose up -d --build
- If your update includes changes to slash commands, register them by running:
docker exec -it scotch-egg node deploy-commands.js
Migrating from Legacy (Pre-v2.0)
If you are upgrading from an older version of the bot where your databases lived directly in the root directory rather than in a persistent data/ folder, follow these steps to preserve your server's data:
-
Stop the bot:
docker compose down
-
Download the latest code into your bot directory (e.g. via git pull):
git pull
-
Create a new folder named
datainside your bot directory:mkdir data
-
Important: Move your existing database files into the new
datafolder. You can usecpinstead ofmvto safely copy them without deleting your backups:cp events.json data/events.json cp config.json data/config.json
-
Rebuild the container:
docker compose up -d --build
-
Re-register the slash commands:
docker exec -it scotch-egg node deploy-commands.js
Commands
All Commands
Server Management Commands
-
/settings channelSets or changes the server's announcement channel. -
/settings modeSets the reminder delivery mode:Public(channel posts + @ mentions),Private(DM-only alerts), orHybrid(channel posts with zero mentions + private DMs). -
/settings viewAdmin command that shows current bot configurations. -
/settings calendarToggles the "Add to Calendar" button on announcements. -
/settings threadsToggles the automatic creation of discussion threads. -
/settings autodeleteToggles whether event announcements are completely deleted when the event ends, rather than just being gracefully archived. (Note: If enabled, deleting the announcement will also automatically delete any attached discussion thread). -
/settings intervalsSets custom reminder intervals using a comma-separated list. -
/settings testreminderDisplays a mock preview of what a reminder message will look like with the server's current settings. -
/settings silenceeventDisables reminder scheduling for a specific event (stops DMs and channel pings), updating the announcement message and disabling the "Remind Me!" button. -
/settings unsilenceeventRe-enables reminder scheduling for a silenced event. -
/settings cleanupScans the announcement channel's recent messages, automatically archives (or deletes) concluded event announcements, and performs a deep fail-safe scan (matching event links and event names) to delete all matching public event reminder messages to reduce channel clutter. -
/announceeventManually forces the bot to post an announcement for an existing event (useful if the bot was offline when the event was originally created). -
/statsAdmin command to view opt-in statistics for upcoming events in this server.
Public Commands
-
/upcomingPublic command to view a paginated list of upcoming events and quickly opt in to reminders. -
/myremindersLists a paginated view of all upcoming events you are currently receiving reminders for. -
/helpDisplays information on how to use the bot and a list of available commands (dynamically filtered to only show Server Management commands to server managers).
Miscellaneous
Core Features
Scotch Egg is designed to be highly reliable, private, and fully automated. Below is a detailed overview of the bot's features, categorized by user-facing Discord capabilities and the robust technical architecture under the hood.
π¬ Discord & User-Facing Features
Native Discord Events
Just create an event using Discord's built-in scheduled event UI, and the bot handles the rest instantly. No need to learn any complicated commands to create events.
Strictly Opt-In Reminders
No mass @everyone spam. Members click a simple "Remind Me!" button to explicitly choose which events they want to be notified about via Private DMs, Public Mentions, or Hybrid Mode.
Flexible Delivery Modes
Choose between three configuration options: Public channel reminders with pings, Private DM-only alerts, or Hybrid mode (un-pinged public reminders + private DMs).
Custom Reminder Intervals
Admins can fully customize when reminders are sent (e.g., 24h, 1h, 15m before start) to suit the community using interactive slash command settings.
Add to Calendar & View Buttons
Features interactive link buttons. The "Add to Calendar" button populates Google Calendar with event details, while "View Event" links directly to native Discord events.
Automated Discussion Threads
Automatically creates dedicated discussion threads under server event announcements to encourage community interaction and keep chatter organized.
High-Contrast Archiving & Cleanups
Grays out concluded
announcements, strikes through obsolete timestamps, and deletes all public
pings. Admins can run /settings cleanup to sweep legacy messages.
Automatic Reminder Cleanup
Reliably sweeps and deletes old reminder messages from the public channel when the associated event concludes or rolls over, significantly reducing channel clutter over time.
Multi-Language Support (Localization)
Fully translated at both server announcements and client slash command levels across 5 languages: English, Spanish, German, French, and Portuguese.
β‘ Runtime & Technical Features
SD-Card Friendly Architecture
Explicitly optimized for single-board computers like the Raspberry Pi. Implements a lightweight JSON storage schema with batched minified disk writes to prevent SD card wear.
Automatic Database Self-Healing
Resilient dual-layer mechanism
maintaining atomic .bak copies of configurations. If damaged, a
recursive Regex-based JSON salvage parser rebuilds database files automatically.
Offline Startup Sync & Garbage Collection
Syncs live events with Discord upon boot. Schedules reminders for any newly created events and safely archives announcements/deletes reminders of events that concluded while the bot was offline.
Real-Time Event Hook Synchronization
Dynamically reschedules, deletes, or recreates scheduled reminder jobs in response to real-time Discord scheduled event creations, start time updates, or cancellations.
Example Announcements & Reminders
See high-fidelity mockups of how the bot's dynamic event announcements and opt-in reminders render inside Discord, including the automated changes when an event concludes.
π’ Active / Upcoming Event Formatting
Server Announcement (Rich Embed)
Posted in the configured #events channel the moment a Discord Scheduled Event is created. Displays duration, time range, and a clickable Host user pill without sending unwanted push pings.
New Event: Sunday Brunch at Eggcellent CafΓ©
ποΈ Time: Sunday, May 31, 2026 11:00 AM to 1:00 PM (in 5 days)
π Location: Eggcellent CafΓ© (123 Yolk Street)
It's been far too long since we've had eggs benedict, french toast, and bottomless mimosas together. Also, we need our yearly consumption of Scotch eggs as well!
*Click the button below to receive a DM reminder at: 24h, 1h before the event begins!*
Reminder Alerts (Public Ping, Private DM, & Hybrid Mode)
DMs are sent in plain text for high-priority mobile push notifications. Reminders can be sent via public channel pings (Public), private DMs (Private), or a mixture of both where public reminders have zero mentions while pings are delivered privately via DM (Hybrid).
Public Channel Reminder (Public Mode: with mentions | Hybrid Mode: identical, but zero mentions)
π’ 1h until Sunday Brunch at Eggcellent CafΓ©!
ποΈ Sunday, May 31, 2026 11:00 AM (in 1 hour)
π Eggcellent CafΓ©
@Daniel
@Admin
Private DM Reminder (Plain Text)
π’ 1h until Sunday Brunch at Eggcellent CafΓ©!
ποΈ Sunday, May 31, 2026 11:00 AM (in 1 hour)
π Eggcellent CafΓ©
π΄ Concluded / Concluded Event Archiving
Concluded Announcement (Archived Embed)
Automatically updated when the event completes. Strikes through the title and metadata using clean web styling, blockquotes descriptions, removes cover images, and replaces actions with a disabled Completed button.
New Event: Sunday Brunch at Eggcellent
CafΓ©
βΉοΈ This event has concluded.
ποΈ Time: Sunday, May 31, 2026 11:00 AM to 1:00 PM
π Location: Eggcellent CafΓ© (123 Yolk Street)It's been far too long since we've had eggs benedict, french toast, and bottomless mimosas together. Also, we need our yearly consumption of Scotch eggs as well!
How It Works (Storage Architecture)
To minimize disk wear on single-board computers (like the Raspberry Pi):
- When an announcement is posted, it creates a record for that event in a local
data/events.jsonfile. - When a user clicks "Remind Me!", their Discord User ID is added to an object of opted-in users associated with that event's record. This object-based storage is highly efficient for lookups.
- When it is time to send a reminder, the bot reads the opted-in users directly from the database and either DMs them or pings them publicly.
- The database is automatically pruned when events are deleted, canceled, or completed to keep it lightweight.
Frequently Asked Questions
Does the bot support multiple servers (Guilds)?
Yes! You can invite the bot to as many servers as you want. Just use /settings channel
in each server to configure where announcements should be posted.
What happens if the bot goes offline?
Every time the bot starts up, it performs "Offline Garbage Collection." It
automatically
syncs with Discord, schedules reminders for any new events it missed, deletes data
for
canceled events, and automatically archives or deletes announcements for events that
concluded while it was offline. Additionally, administrators can run the /settings cleanup
command at any time to scan the channel and clean up any legacy concluded events.
What happens if a scheduled event is rescheduled (time changed)?
When an event's start time is updated in Discord, the bot automatically archives the old announcement in the channel with a disabled button labeled "Rescheduled" and strikes through the outdated details. It then posts a new, active announcement message with the updated time. This ensures all server members see a fresh notification, while the new announcement's "Remind Me!" button automatically carries over the count and list of already registered users.
Why are the DM reminders plain text instead of Rich Embeds?
This is intentional. When an event URL is sent in a DM, Discord automatically generates a Rich Embed preview for it. If the bot sent an Embed, it would result in a cluttered "double-embed" in the user's DM.
What is the Hybrid delivery mode and when should I use it?
Hybrid mode is the best of both worlds! It posts all event reminders in your public announcement channel (providing a gorgeous, searchable, and clean chronological stream of events) but with zero pings or user mentions to avoid public chat disruption. Simultaneously, the bot delivers private, custom-localized direct messages directly to each opted-in member. Use this to keep channels tidy while guaranteeing that interested users never miss a notification.
Can users opt out of reminders?
Yes! Users can click the "Remind Me!" button again, click "Cancel Reminders" in a DM,
or
use the /myreminders
command to opt out.
How does the Multi-Language support work?
Scotch Egg automatically detects the preferred language of your Discord server to translate public event announcements. It also dynamically detects each user's specific Discord client language to instantly translate interactive slash commands, options, select menus, confirmation replies, and DM reminder alerts on the fly! The bot is fully localized in English, Spanish, German, French, and Portuguese.
How does Database Self-Healing protect my data?
If your host device (like a Raspberry Pi) experiences a sudden power outage during a disk write, the active database file can get truncated or corrupted. On startup, Scotch Egg automatically attempts to load the database, falling back to a `.bak` copy if the primary is damaged. If both are corrupted, it executes a Regex salvage parser to scan the damaged file, extract all intact records, and rebuild the database structure automatically.
How does the bot handle a single canceled occurrence in a recurring event series?
Scotch Egg handles this seamlessly! When you cancel a single occurrence of a recurring series on Discord, the bot automatically detects the cancellation via the API. It updates the original announcement message in-place to clean up the canceled date, purges the scheduled reminders for that specific occurrence, and safely rolls over to the next upcoming occurrence in the seriesβall without posting a new announcement message.
Can I prevent the bot from announcing certain events, or disable reminders for specific events?
Yes! You have two ways to do this:
- Title/Description Tags: Adding
[exclude]in your Discord event title or description will prevent the bot from posting an announcement entirely. Adding[silent]will announce the event but prevent users from opting into reminders. - Slash Commands: Administrators can use the
/settings silenceeventand/settings unsilenceeventcommands to dynamically toggle whether users can register for reminders on a specific event's announcement message.
How does canceling reminders via DM work for recurring event series?
When you click the "Cancel Reminders" button on a direct message alert for a recurring event series, the bot will display an interactive choice. You can choose to opt out of the next occurrence only (leaving your reminders active for future weeks) or completely unsubscribe from the entire series.
Can we disable pings/mentions on public channel reminders to avoid chat spam?
Yes! Administrators can run the /settings mentions command to toggle public reminder mentions. When disabled, public channel reminders will still post at your configured intervals (updating the opt-in counter) but will not ping any users.
Can I set global default reminder intervals for all servers hosting my bot?
Yes! If you are hosting the bot, you can define a DEFAULT_INTERVALS variable in your .env file (for example, DEFAULT_INTERVALS="24h, 1h"). Any Discord server that hasn't explicitly set their own intervals using the /settings intervals command will automatically inherit these global defaults.
How does the bot handle timezone differences?
Scotch Egg relies on Discord's dynamic timestamp tag formatting (e.g., <t:TIMESTAMP:F>). Epoch timestamps are computed in Unix time (which is timezone-independent), and the Discord client renders the dates and relative countdowns dynamically in the viewing user's local timezone. You do not need to configure timezones on your host machine or within the bot!
Troubleshooting
Bot shows as online, but slash commands don't work / don't appear
You likely forgot to run the command registration script! Make sure your bot is running, then execute the command from Step 5 of the setup guide. You might need to restart your Discord client afterwards to see the commands.
The bot is not posting announcements or shows permission errors in the channel
The bot requires explicit role permissions in your configured announcement channel to operate. Make sure that the bot's integration role (or the bot itself) is granted the following permissions in the target channel's settings: View Channel, Send Messages, and Embed Links. If the bot is missing any of these, it will fail to post announcements or return descriptive permission warning responses.
Why aren't some users receiving their private DM reminders?
This is almost always due to Discord direct message privacy settings. If a user
blocks
DMs from server members, the bot is blocked from messaging them. To fix this, the
user
must go to their Server Privacy Settings in Discord and toggle
"Allow direct messages from server members" to On.
Alternatively, server admins can switch the server's mode to Public so
reminders are posted directly in the channel with pings.
I see "Interaction Failed" when clicking buttons
This usually means the bot is offline or has crashed. Check your Docker logs to see what happened. If you are not using Docker, check the terminal window where you started the bot.
I see "Unknown Interaction (10062)" warnings/errors in the bot logs
Discord requires slash command interactions to be acknowledged within 3 seconds. If your host machine (e.g. Raspberry Pi) is under heavy CPU load or has high network latency, the acknowledgment may arrive too late, and Discord will discard the interaction. The bot gracefully catches these and prints a diagnostic warning. To prevent this, ensure your hosting server has stable system resources and a low-latency connection to Discord.