Skip to content

Setup Guide

Johnny Xmas edited this page Sep 22, 2026 · 12 revisions

Setup Guide

This guide will walk you through installing, configuring, and running JohnnyBot on your Discord server.

Navigation

Table of Contents

  1. Prerequisites
  2. Installation
  3. Discord Bot Token Registration
  4. Required Discord Permissions
  5. Configuration
  6. Running the Bot
  7. Troubleshooting

Prerequisites

Before you begin, ensure you have:

  • Python 3.11 or higher — tested on 3.11, 3.12, 3.13, and 3.14 in CI
  • Git for cloning the repository
  • A Discord server where you have administrative permissions

Installation

Step 1: Clone the Repository

git clone https://github.com/burbsec/johnnybot.git
cd johnnybot

Step 2: Install Dependencies

pip install -r requirements.txt

Note: Consider using a virtual environment to avoid conflicts with other Python packages:

python -m venv johnnybot-env
source johnnybot-env/bin/activate  # On Windows: johnnybot-env\Scripts\activate
pip install -r requirements.txt

Discord Bot Token Registration

Follow these steps to create a Discord bot and get your token:

Step 1: Create a Discord Application

  1. Go to the Discord Developer Portal
  2. Click "New Application"
  3. Give your application a name (e.g., "JohnnyBot")
  4. Click "Create"

Step 2: Create a Bot User

  1. In your application, navigate to the "Bot" section in the left sidebar
  2. Click "Add Bot"
  3. Confirm by clicking "Yes, do it!"
  4. Under the "Token" section, click "Copy" to copy your bot token
  5. Keep this token secure - you'll need it to run the bot

Step 3: Generate Invite Link

  1. Navigate to the "OAuth2" section in the left sidebar
  2. Click on "URL Generator"
  3. In "Scopes", select "bot" and "applications.commands"
  4. In "Bot Permissions", select the permissions listed in the Required Discord Permissions section below
  5. Copy the generated URL and open it in your browser
  6. Select your Discord server and authorize the bot

Required Discord Permissions

JohnnyBot requires specific Discord permissions to function properly. When creating your bot application and generating an invite link, ensure these permissions are selected:

General Permissions

Permission Required For
Manage Server Server management features; pausing invites/DMs during a raid lockdown
Manage Roles Role permission cloning, voice channel safety features, stripping a compromised account's roles (anti-nuke)
Manage Channels Channel permission cloning and management
Kick Members /kick, /raid kick_recent, kicking new-account spammers
Manage Nicknames Voice channel safety (muting members)
Manage Events Creating Discord events from calendar feeds
View Channels Access and monitor channels
Moderate Members /timeout command, timing out spam offenders

If you're upgrading an existing install, check that the bot's role has Manage Server, Moderate Members, and Kick Members — the safety systems need them to act. Detection still works without them and you'll still get alerts, but the response is reported as blocked rather than applied. See Safety Systems.

The bot also cannot act on anyone whose highest role is at or above its own. This matters most for anti-nuke, where a compromised Administrator typically outranks the bot — the alert says so explicitly when that happens. Position the bot's role accordingly; it can never outrank the server owner.

Text Permissions

Permission Required For
Send Messages Bot responses and notifications
Manage Messages Purge commands and protected channel enforcement
Read Message History Message dump functionality and purge commands
Use Slash Commands All slash command functionality
Embed Links Rich embed messages (event notifications)
Attach Files Log file attachments
Kick Members /kick, /kick_role, and the automatic DM kick (see below)
Manage Roles /server_restore, role management, permission cloning commands
Manage Channels /server_restore, permission cloning commands
Manage Emojis and Stickers /server_restore (recreating custom emoji)

Note on the two different "permission" checks: the table above is what the bot's own role needs (set once, when you invite it). Separately, most commands check whether the person running the command has the Manage Messages permission (or Administrator for /server_backup, /server_restore, /auto_backup) — see Commands Reference. There's no role name to configure for either check.

Before You Deploy: the DM Policy

Anyone who sends the bot a direct message is kicked from every server they share with it, and the kick is posted to the moderators channel. This is always on and has no config toggle.

Exempt from the kick:

  • Users with the Manage Messages permission
  • Anyone the bot DMed in the last 24 hours, so replying to a /message_dump archive or /log_tail output is safe

Make sure your members know this before you invite the bot, and confirm the bot's role sits high enough in the hierarchy to kick the members you expect it to — a kick it cannot perform is logged as an error and reported, not silently ignored.

Voice Permissions

Permission Required For
Connect Monitor voice channels for safety features
Mute Members Voice channel chaperone functionality
Move Members Voice channel management

Important Notes

  • The bot's own role does NOT need Administrator — grant it the specific permissions in the table above instead. (Separately, the user running /server_backup, /server_restore, or /auto_backup does need Administrator — that's a command-access check, not a bot-invite permission.)
  • Ensure the bot's role is positioned high enough in the role hierarchy to manage the roles and channels it needs to work with
  • For permission cloning commands, the bot cannot clone permissions to/from roles higher than its own highest role

Configuration

Step 1: Configure Bot Settings

Copy the example config and edit it for your server (config.py is gitignored, so your customizations won't conflict with git pull):

cp config_example.py config.py

Then modify the constants in config.py according to your server's setup:

# Required Configuration
PROTECTED_CHANNELS = {'announcements', 'rules'}  # Read-only channels
MODERATORS_CHANNEL_NAME = 'moderators_only'  # Channel for bot notifications

There's no moderator role to name — command access and the exemptions above are based on the Discord Manage Messages / Administrator permissions directly, so a fresh server with no custom roles works out of the box as long as the members who should have mod access hold one of those permissions.

Configuration Options

Setting Description Example
PROTECTED_CHANNELS Set of channels you wish to force to read-only when Discord requires them not to be {'announcements', 'rules'}
MODERATORS_CHANNEL_NAME Name of the moderators chat channel for bot notifications 'moderators_only'
VOICE_CHAPERONE_ENABLED Default state of the voice chaperone functionality True
ADULT_ROLE_NAMES Names of the roles assigned to verified adults (used for voice chaperone) {'Dads', 'GrownUps'}
CHILD_ROLE_NAMES Names of the roles assigned to children (used for voice chaperone) {'Kids', 'Bambinos', 'Girls'}
UPDATE_CHECKING_ENABLED Default setting for bot to check for updates True
UPDATE_CHECK_REPO_URL Repo to check for updates "https://github.com/BurbSec/JohnnyBot"
AUTO_UPDATE_ENABLED When True, the bot automatically pulls updates that passed CI and don't change config_example.py, then restarts itself. Requires running from a git checkout False
BOT_TIMEZONE Timezone for scheduled jobs and event announcements 'America/Chicago'

Safety System Options

The three automatic protection systems are enabled by default. Full explanations of what each value does — and guidance on sizing the thresholds against your own server — are on the Safety Systems page.

Setting Default Description
RAID_PROTECTION_ENABLED True Join-burst detection and automatic lockdown
RAID_JOIN_THRESHOLD 6 Joins within the window that trigger it
RAID_JOIN_WINDOW_SECONDS 30 The sliding detection window
RAID_LOCKDOWN_MINUTES 60 How long invites/DMs stay paused
RAID_NEW_ACCOUNT_HOURS 24 Accounts younger than this are flagged in review/kick
RAID_AVATAR_CLUSTERING_ENABLED True Group joiners by identical profile picture
RAID_AVATAR_SCAN_LIMIT 50 Skip the avatar scan past this many members
RAID_AVATAR_CACHE_TTL 300 Seconds to reuse a hashed avatar
ANTI_NUKE_ENABLED True Audit-log monitoring for a compromised account
ANTI_NUKE_THRESHOLD 3 Destructive actions by one actor that trigger it
ANTI_NUKE_WINDOW_SECONDS 60 The window they must fall inside
ANTI_NUKE_ACTION 'strip_roles' 'strip_roles' to neutralize the actor, or 'alert' to only notify
SPAM_PROTECTION_ENABLED True Cross-channel link spam and mention filtering
SPAM_CROSSPOST_WINDOW_SECONDS 30 Same link in 2+ channels this fast
SPAM_MENTION_THRESHOLD 3 Distinct mentions in one message
SPAM_TIMEOUT_MINUTES 10 Timeout length for an offender
SPAM_NEW_ACCOUNT_DAYS 2 Younger offenders are kicked rather than timed out

Existing installs keep working without any of these. Every value is read with a built-in fallback, so a config.py written before these features existed runs fine on the defaults above — copy the new block out of config_example.py only if you want to change something.

/raid protection, /nuke_protection and /spam_protection toggle these at runtime for the current session, which is what you want mid-incident. They don't persist — config.py decides again on restart.

Step 2: Set Environment Variable

Add your Discord bot token to an OS environment variable called DISCORD_BOT_TOKEN:

On Linux/macOS:

export DISCORD_BOT_TOKEN="your_bot_token_here"

On Windows (Command Prompt):

set DISCORD_BOT_TOKEN=your_bot_token_here

On Windows (PowerShell):

$env:DISCORD_BOT_TOKEN="your_bot_token_here"

Security Note: For production use, consider using more secure methods like:

  • System environment variables
  • Docker secrets
  • Cloud provider secret management services

Running the Bot

Step 1: Start the Bot

python bot.py

Step 2: Verify Operation

  1. The bot should now show as online/active in your Discord server
  2. Try using a simple command like /bot_mood to test functionality
  3. Check the console output for any error messages

Running as a Service (Recommended)

For production use, consider running the bot as a system service that starts at boot:

Using systemd (Linux):

Every name and path below is a placeholder — substitute your own.

  1. Create a service file (<service-name> is whatever you want to call it):
sudo nano /etc/systemd/system/<service-name>.service
  1. Add the following content:
[Unit]
Description=JohnnyBot Discord Bot
After=network.target

[Service]
Type=simple
User=<user-to-run-as>
WorkingDirectory=<path-to-the-bot-directory>
EnvironmentFile=<path-to-the-bot-directory>/.env
ExecStart=<path-to-python> bot.py
Restart=always

[Install]
WantedBy=multi-user.target

Put the token in the referenced env file rather than an Environment= line in the unit — unit files under /etc/systemd/system are world-readable by default, so an inline token is readable by every account on the machine:

echo 'DISCORD_BOT_TOKEN=<your-token>' > <path-to-the-bot-directory>/.env
chmod 600 <path-to-the-bot-directory>/.env
  1. Enable and start the service:
sudo systemctl enable <service-name>
sudo systemctl start <service-name>

Troubleshooting

Common Issues

Bot Not Responding

  • Verify the bot token is correct and properly set as an environment variable
  • Check that the bot has the required permissions in your Discord server
  • Ensure the bot's role is positioned high enough in the role hierarchy
  • Check the console output for error messages

Permission Errors

  • Verify the bot has all required permissions listed above
  • Check that the bot's role is above the roles it needs to manage
  • If the bot replies "I don't have the Discord server permissions needed to do that", grant it the missing permission from the table above and retry — it always responds rather than failing silently

Commands Not Working

  • Verify you have the Manage Messages permission (Administrator for /server_backup, /server_restore, /auto_backup) — most commands are restricted
  • Check that slash commands are enabled in your server
  • Try restarting the bot to refresh command registration

Message Archive Issues

  • Check that the bot has "Read Message History" permission
  • Verify the user and channel exist and are accessible
  • Archives are DM'd as zip attachments; Discord caps attachments at 25 MB, so reduce the limit or narrow the start_date if the dump is too large

Getting Help

If you encounter issues:

  1. Check the logs using the /log_tail command (moderators only)
  2. Review the console output for error messages
  3. Open an issue on the GitHub repository
  4. Check existing issues for similar problems and solutions

Log Files

JohnnyBot creates rotating log files in the bot directory. Moderators can use the /log_tail command to get recent log entries sent to their DMs for troubleshooting. The command is restricted because the log records deleted message content from protected channels, member names and IDs, and moderation actions.

Runtime State Files

JohnnyBot writes these alongside the code. They are gitignored and recreated as needed, but back them up if you care about the state they hold:

File Contents
reminders.json Active recurring reminders and their next trigger times
event_feeds.json Feed subscriptions, announcement channels, and posted-event IDs
event_announce.json Per-guild announcement channel configuration
autoreplies.json Autoreply rules
chaperone_mutes.json Members the voice chaperone has muted but not yet unmuted; loaded at startup so a restart does not strand anyone muted
johnnybot.log Rotating log (5 MB, 2 backups)

The safety systems add no state files. Join-burst, audit-log and spam-tracking windows are in memory and reset on restart, which is harmless for a seconds-wide detector. Raid lockdown state isn't stored locally at all — it lives on the guild via Discord's incident actions and expires on its own, so a restart mid-raid neither strands a lockdown nor loses one.

Upgrade Notes

If you're upgrading from a version older than the September 2026 fix release, a bug in event-time handling meant any Discord Event created from a feed entry with a floating local time (no explicit Z or TZID) or an all-day date was created hours off, or on the wrong day. The fix does not repair events already created — those events' UIDs are already recorded in event_feeds.json, so the normal weekly check skips them, and the corrected time will never match the old one closely enough to be treated as the same event.

To clean up existing mistimed events after upgrading:

  1. Run /check_event_feeds once. This runs a full reconciliation pass that ignores the posted-event history and creates a fresh, correctly-timed Discord Event for anything in the next 30 days.
  2. Open your server's Events tab and manually delete the old, mistimed duplicates it left behind.

This is a one-time cleanup; new events created going forward are unaffected.


Next Steps

Once your bot is running successfully:

  1. Explore the Commands Reference to learn about all available commands
  2. Configure reminders for your server's needs
  3. Set up event feeds if you use external calendars or RSS feeds
  4. Test moderation commands in a safe environment

← Back to Home | Commands Reference →