Repository navigation
Home
Welcome to the JohnnyBot wiki! JohnnyBot does all of the stuff Discord bizarrely won't let you do! Designed to automate tons of server management and enforce some rules while you're at it.
- Setup Guide - Installation, configuration, and getting started
- Commands Reference - Complete command documentation
- Safety Systems - Raid protection, anti-nuke, and spam filtering in depth
- GitHub Repository - Source code and issues
JohnnyBot provides features such as automatic role assignment, message deletion, and user management to ensure a smooth server experience. Most commands require the Manage Messages permission — no role to create or name, so it works on any server the bot joins with zero setup. Server backup/restore commands require the stricter Administrator permission. PetBot commands can be leveraged by all users.
- Provides moderators with slash commands to manage members, messages, and post announcements
- Mass role assignment for efficient user management
-
/server_backupsnapshots roles, categories, channels, permission overwrites, and emoji to a JSON file DMed to you -
/server_restorereplays a backup with a preview, an explicit confirm step, and an automatic pre-restore safety snapshot — matches existing objects by name so it's safe to run more than once -
/auto_backupruns backups on an interval, but only actually creates one when the server's structure changed since the last one - Requires Administrator; never touches Administrator/managed/above-hierarchy roles or grants moderation-level permissions, even from a hand-edited backup file
- A burst of joins (default 6 in 30 seconds) pauses invites and member-to-member DMs and alerts moderators
- Uses Discord's own incident actions, which expire on their own — no timer to survive, and a bot restart mid-raid changes nothing
- The alert includes an avatar-cluster breakdown ("12 of 14 share one image"), since bulk-created raid accounts reuse profile pictures — that's what separates a raid from a legitimate surge of arrivals
-
/raid recent_joinsand/raid kick_recent(dry run by default) for review and cleanup;/raid lockdownfor manual control
- Watches the audit log for a compromised moderator account or rogue integration — the case the bot's own commands can't see, because the attacker acts directly against the Discord API
- Triggers on a destructive burst (channel/role deletes, kicks, bans, webhook creation), a member prune, or any grant of a dangerous permission
- Strips the offending account's roles and reverts the permission change itself — neutralizing the actor while leaving the alt account holding administrator would mean the attack still succeeded
- Reversible by design: a moderator restores the account with
/assign_rolein seconds if it's a false alarm. Deliberately not a kick
- Catches what a raid does once inside: the same link blasted across several channels, and mass pings
- Link detection is behavioral, not a domain blocklist — scam domains burn within days, so a list is stale before it ships, while the cross-posting pattern holds whatever the domain is
- Deletes every copy, times the offender out, or kicks them if the account is under two days old
See Safety Systems for detection details, thresholds, tuning guidance, and the bot permissions these need.
- Anyone who DMs the bot is kicked from every server they share with it, and the kick is reported to the moderators channel
- Exempt: users with the Manage Messages permission, and anyone the bot DMed in the last 24 hours (so replying to a
/message_dumparchive or/log_tailoutput is safe) - Separately, no slash command can be invoked in a DM — every command requires a server context, so Discord simply won't offer them there
- Monitors voice channels and mutes all members if only one adult and one child are present
- Sends a single alert to the moderators channel per incident
- Lifts the mute automatically once the channel is no longer one adult and one child, when a muted member moves to a safe channel, or when the feature is disabled — outstanding mutes are persisted to
chaperone_mutes.jsonso they survive a bot restart - Only mutes the bot applied are lifted; a manual moderator mute is never undone
- Set recurring reminders to be sent to specific channels at regular intervals
- Persistent reminder storage with automatic scheduling
- Subscribe to calendar (iCal) or RSS feeds (including Meetup.com) and automatically create Discord Scheduled Events
- Per-feed announcement channel configured when the feed is added
- Automatic schedule: weekly feed check (Monday 9am), "This Week" preview (Monday 10am), and day-of reminders (Tuesday–Sunday 10am; Monday is skipped because the weekly preview already covers it) — timezone configurable via
BOT_TIMEZONE
- Logs actions and errors to a rotating log file in the bot directory
- Moderators can DM themselves a tail of the log with
/log_tail
- Allows moderators to dump and archive user messages from specific channels
- Delivers the archive as a zipped file via DM (25 MB Discord attachment cap)
- Automatically cleans up old archive files
- Deletes any non-moderator messages posted in the
PROTECTED_CHANNELSyou define in yourconfig.py(copied fromconfig_example.py) - This is a hack to get around Discord's requirement of a minimum number of messageable channels
- Includes PetBot functionality with time-themed messages
- Python 3.11+ — tested on 3.11, 3.12, 3.13, and 3.14 in CI. The bot's dependencies technically allow 3.10, but 3.10 reaches end-of-life in October 2026, so 3.11 is the supported floor.
- All modules in
requirements.txt
- Follow the Setup Guide for complete installation instructions
- Browse the Commands Reference to learn about available commands
- Configure your bot according to your server's needs
Important: The bot is asyncio-first, with threading used narrowly for state a background scheduler job can touch outside the event loop. DO NOT CHANGE THIS:
- All Discord API interactions (primary event loop)
- Recurring work — feed checks, event announcements, reminders, auto-backups, update checks — which run as jobs on a single shared
AsyncIOScheduler, not as separate threads - Command handling and network operations
- Blocking file writes are pushed off the loop with
asyncio.to_threadrather than made synchronous inline
-
threading.Lock()guarding a small number of dicts written from more than one place (autoreply rules, auto-backup configs, per-feed state) — not a general-purpose cache
This keeps the bot to one event loop with no background threads of its own, while still protecting the handful of dicts that scheduler jobs and command handlers can touch concurrently.
Contributions are welcome! If you encounter any bugs or have suggestions, feel free to open an issue or submit a pull request on the GitHub repository.
Bot interaction functionality adapted from PetBot under MIT License.
This project is licensed under the GNU General Public License v3.0.