Aestron targets Python 3.12, discord.py 2.7, Wavelink 3.5, and Lavalink 4.
The actively maintained runtime features are split into focused modules:
aestron_bot/lavalink.pyowns node connection, health, and reconnection.aestron_bot/music.pyowns searches, queues, playback, controls, and errors.aestron_bot/fun.pyandaestron_bot/fun_ui.pyprovide image-first interactive games and social commands with replay, scoring, elimination, live voting, invoker-only controls, and bounded input.aestron_bot/moderation.pyowns validated moderation commands, native timeouts, hierarchy checks, and warning records.aestron_bot/antiraid.py,automod.py, andaudit_logging.pyprovide bounded raid detection, native timeout-based message enforcement, persistent incident/event history, and one server-safety overview.aestron_bot/tickets.py,verification.py, andgiveaways.pyregister stable persistent component IDs so panels continue working after restarts.aestron_bot/leveling.pyprovides cached, anti-spam message progression and rank/leaderboard views without temporary image files.aestron_bot/calls.pyprovides consent-based private DM calls with bounded attachment relay, opt-in privacy, and explicit hangup controls.aestron_bot/profiles.pyrenders bounded Discord profiles without scanning the full ban list or calling unrelated vote services.aestron_bot/database.pyowns the async PostgreSQL pool lifecycle and readiness checks; command code no longer depends on module-levelconnorpoolglobals.aestron_bot/diagnostics.pyformats chained tracebacks without capturing local variables or secrets.aestron_bot/statistics.pybatches persistent activity counters without adding a database query to every command.aestron_bot/valorant.pyandaestron_bot/valorant_ui.pyprovide secure account linking, official on-demand match retrieval, and rendered post-match dashboards without pickle caches or unofficial rank APIs.aestron_bot/feedback.pysends/suggestand/reportbugsubmissions to one website queue, with a configured Discord channel as a fallback.website/is the standalone FastAPI product site and versioned API. The main pages cover the entire bot; VALORANT has a dedicated consent-aware area./updatespublishes recent command and fix notes with the running version, uptime, and a credential-free link to the exact deployed Git commit. The same data is available as JSON from/api/v1/updates.
Create an isolated environment and install the pinned, verified dependency set:
py -3.12 -m venv .venv
.venv\Scripts\python.exe -m pip install -r requirements.txtThe dependency pins are current as of this audit. libretranslatepy remains at
2.1.1 because the latest translate release requires that exact version;
forcing 2.1.4 produces a resolver conflict. PyNaCl is pinned at 1.5.0 because
discord.py 2.7.1's voice extra explicitly requires PyNaCl below 1.6.
For development checks, install requirements-dev.txt instead, then run:
.venv\Scripts\python.exe -m pytest -q
.venv\Scripts\python.exe -m ruff check .
.venv\Scripts\python.exe -m ruff format --check .
.venv\Scripts\python.exe -m scripts.check_commandsThe command validator registers the same cogs as production without logging in.
It rejects duplicate names/aliases and commands missing a summary, description,
help body, or parameter usage. The in-bot help command, category help, command
help, and /usage <command> views all use this validated metadata; usage
remains available even when no demonstration GIF exists. The prefix defaults to
a! and can be changed with DEFAULT_PREFIX.
Copy .env.example to .env and fill in only the services you use. Database
credentials remain in database.env for compatibility with the existing setup.
The only required application value is DISCORD_TOKEN. Add optional service
keys only for features you enable:
CHATBOT_IDandCHATBOT_TOKENenable Brainshop chat responses.GCOM_TOKENenables Perspective API message analysis.VAL_API_TOKENenables official VALORANT match retrieval after the website and approved Riot Sign On product are configured.DBL_TOKENenables Top.gg vote checks and links.OPENWEATHER_API_KEYenables weather lookup.
Store bot and optional integration settings in .env and PostgreSQL credentials
in database.env. Do not commit either file. Create the bot in the Discord
developer portal and set DISCORD_TOKEN.
Music playback requires Lavalink 4 and the maintained YouTube source plugin.
Use docs/lavalink.md and the included
lavalink/application.yml.example; setting only a Lavalink URL is not enough
when the node has no working audio source.
/play <song name or URL>— connect, search, queue, and start playback./currentlyplaying— show the current track and progress./queue— show upcoming tracks./pause,/skip,/stop,/volume <0-150>— control playback./music loop <mode>,/music shuffle,/music remove <position>,/music clear, and/music seek <time>— advanced repeat and queue controls. The matching prefix commands area!loop,a!shuffle,a!remove,a!clearqueue, anda!seek./voicehealth— diagnose the Lavalink node and latest voice error./stats— show commands used, successful/failed invocations, current and historical guild activity, uptime, latency, process activity, and music health./updates subscribe [channel],/updates unsubscribe, and/updates statuslet server managers explicitly opt one channel into official release and service-status announcements. Aestron never searches for a fallback channel./botadmin activity,/botadmin broadcast, and/botadmin broadcastsare owner-only fleet tools for private aggregate activity reports, confirmed subscriber broadcasts, and persisted delivery history. No message content or author data is stored for activity tracking. SetOPERATIONS_GUILD_IDto register both/updatesand/botadminonly in one server; startup performs the separate guild sync and removes stale global copies./botadmin prune [inactive_days] [farewell_message] [invite_url]privately previews guilds observed for the complete inactivity window, protects the operations guild, requires confirmation, rechecks activity, optionally sends a farewell in a writable public channel, and exports the result as CSV./help(or/help topic:<command or category>) privately presents eight task-based categories instead of exposing internal cog boundaries. It acknowledges immediately, supports autocomplete, and shares the same interactive command details asa!help./suggest <title> <details>and/reportbug <feature> <details>— submit validated feedback to the shared website/admin queue./valorant linkand/valorant unlink— secure opt-in Riot account linking./valorant stats [member] [matches]— image-first overview, history, agent/map trends, match selector, review prompts, and metric guide./valorant history,/valorant match, and/valorant coach— rendered dashboards with per-round timelines, personal economy efficiency, opponent duel matrices, official minimap kill/death plots, round selection, player-card banners, agent art, weapon/shield loadout cards, store costs, hit profiles, damage differentials, and evidence-based review. Public artwork and map-coordinate transforms are loaded asynchronously from valorant-api.com and cached in memory; Riot match data remains the only statistics source. Aestron does not invent personal MMR/ELO because Riot's supported player-match APIs do not expose it and Riot policy prohibits replacement ranking calculators./fun rpsruns a first-to-three match and/fun triviaruns a scored five-question session. Coin flips, dice, decisions, and eight-ball answers can replay in place; would-you-rather uses a public one-vote-per-member poll./social welcomeand/social wanted— generated 1200×480 cards with visual themes, fictional bounty levels, and rate-limited community reaction buttons. Prefix equivalents remaina!welcomeanda!wanted./community youtubeand/community chess— start Discord activities in your current voice channel./antiraid enable|disable|status|configure— configure a bounded destructive audit-event window and choose log-only or dangerous-role removal. Bot owners, the guild owner, and managed roles are protected from automated action./automod setup|set|status— apply one persistent policy to as many as 25 text, announcement, forum/media, voice, or stage channels at once, or make a single-channel adjustment. Spam count/window, timeout length, and Perspective profanity threshold are configurable per channel. Forum/media policies cover messages inside their posts. Actions use Discord-native timeouts, private notices when DMs are available, and the configured event log./logs setup|disable|overview— configure audit/event output and inspect permission health, recent event counts, anti-raid state, AutoMod coverage, verification, active tickets, and active giveaways./ticket setup|claim|lock|transcript|close|add|remove— create a restart-safe panel in a text, announcement, forum, or media channel. Setup can create a non-mentionable Support Team role, Support Tickets category, and private log automatically. Opening is concurrency-safe, transcripts are delivered privately, and closed tickets are archived instead of silently deleted./verification setup|status|disable|access|start— configure a persistent verification panel and issue each member a private, expiring CAPTCHA. Guided setup creates or reuses the Verified role, auto-selects channels currently visible to members, supports every guild channel type, and shows the access plan before applying it. Community Onboarding default channels are detected, reported, and left public because Discord requires them for Onboarding./serverguide— reopen the permission-aware setup guide sent when Aestron joins. It recommends logging, AutoMod, verification, and ticket setup in a safe order without enabling disruptive features automatically./leveling rank|leaderboard|configure— inspect progress or configure a channel. Only one message per member every 15 seconds earns progress./giveaway start|end|reroll|status— run database-backed button giveaways that resume after a restart. Native Discord polls remain available through the prefix poll command./minecraft balance|daily|weekly|pay|inventory|shop|pvp|leaderboard|server— the grouped Minecraft economy and competitive game. Inventory and PvP use rendered boards with cached in-game item sprites. Reward cooldowns persist across restarts, transfers and forge purchases are transaction-safe, trade-ins return 60%, and PvP acknowledges every click before rendering, audio, or reward writes. Abandoned fights release their temporary voice connection after five minutes./call <member> [reason],/calls privacy|status|hangup, anda!hangup— opt-in private calls. Invitations use DM buttons, only DM messages are relayed, attachments are bounded, and either participant can stop the relay immediately./profile [member]or the Profile message context action — show a private, bounded Discord profile including roles, badges, timeout state, and sensitive permissions./template backup|list|preview|sync|delete— private, official-URL-only template management. Mutations are serialized per guild and protected by runtime permission checks and cooldowns; preview never applies or deletes channels.
Ticket, verification, and giveaway buttons are persistent across process restarts. Sensitive results such as ticket transcripts, verification challenges, configuration confirmations, and help command details are ephemeral or sent by DM where Discord supports it. Interactive help and game views remain deliberately session-bound because they are tied to the member who invoked them.
Install requirements-web.txt and run the product site separately from the bot:
.venv\Scripts\python.exe -m pip install -r requirements-web.txt
.venv\Scripts\python.exe -m uvicorn website.main:app --host 0.0.0.0 --port 27004 --env-file website.envThe generalized product site is at /, the bot overview is /dashboard, the
VALORANT product and prototype dashboard are /valorant and
/valorant/dashboard, and OpenAPI documentation is at /api/docs. Production
Pterodactyl, HTTPS proxy, Riot callback, environment, and rollout instructions
are in docs/website-deployment.md.
For Pterodactyl production starts, use python scripts/deploy_start.py bot for
the Discord process and python scripts/deploy_start.py website --port 27004 --env-file website.env for the separate website process. The bootstrap fetches
on every start, pins the expected remote, accepts fast-forward updates only,
installs only the relevant changed requirements, and publishes commit/version
metadata to /stats and /api/health. Configuration and read-only deploy-key
guidance are in docs/deployment.md.
Keep AESTRON_SITE_BASE_URL empty in the bot environment until the public site
is deployed and verified. Then set it to the HTTPS origin and copy the exact same
AESTRON_SERVICE_TOKEN into both bot and website environments.
Frequently used moderation commands are typed hybrid commands, so they work as both slash and prefix commands with the same validation and help text:
/ban,/kick,/unban, and/softban— hierarchy-checked member actions with Discord audit-log reasons./timeout <member> <duration>and/untimeout— Discord-native timeouts; durations accept forms such as30m,2h, or1d12hup to 28 days./warn,/warnings, and/clearwarnings— bounded, parameterized warning history operations./lock,/unlock,/setslowmode, and/purge— bounded channel tools that preserve unrelated permission overwrites./nick— set or clear a member nickname after hierarchy validation.
Invalid members, unsafe hierarchy targets, out-of-range values, missing bot permissions, and failed Discord API operations now reach the shared command error handler instead of being silently ignored.
All music failures are logged with guild/channel context and also produce a
clear Discord response. /voicehealth also loads an encoded test track, so it
detects a connected node whose search plugin is not actually usable. Lavalink
reconnection runs in the background.
Configure comma-separated bot owners and optional operational channels in
.env; no source edit is required:
BOT_OWNER_IDS=your-discord-user-id,another-owner-id
CHANNEL_ERROR_LOGGING_ID=your-error-channel-id
CHANNEL_BUG_LOGGING_ID=your-bug-channel-id
CHANNEL_DEV_ID=your-development-channel-id
SUPPORT_SERVER_INVITE=https://discord.gg/your-invite
DEFAULT_PREFIX=a!
SYNC_COMMANDS_ON_STARTUP=true
# Optional: make /updates and /botadmin immediately available only in this guild.
OPERATIONS_GUILD_ID=your-discord-server-id
BOT_VERSION=developmentAll values except DISCORD_TOKEN and database credentials are optional. When
BOT_OWNER_IDS is empty, discord.py's application-owner check is used. Unset
logging channels, support links, and external integrations are disabled cleanly
instead of falling back to deployment-specific IDs or credentials.
Legacy owner IDs, bot IDs, channel IDs, custom-emoji IDs, avatar URLs, webhook credentials, and private network addresses are not embedded in the source. Bot ownership falls back to the Discord application owner, invite and Top.gg links use the authenticated bot ID, and mutable maintenance/rate-limit state belongs to the running bot instance.
The old arbitrary Python execution, public code runner, token generator/parser, webhook sender, dashboard control channel, automatic GitHub self-updater, website screenshot commands, and third-party-bot answer scraper were removed. The calculator now accepts bounded arithmetic only and never evaluates Python code. Optional integrations fail with a clear response when their environment settings are absent.
The modular safety, ticket, verification, call, giveaway, logging, and leveling cogs create and migrate their own tables. For a completely fresh database, the remaining economy, prefix, custom-command, and compatibility tables below can be created before first start. Runtime statistics tables are managed automatically as described afterward.
CREATE TABLE callsettings
(settingbool boolean ,userid bigint PRIMARY KEY);
CREATE TABLE spamchannels
(channelid bigint PRIMARY KEY);
CREATE TABLE leveling
(messagecount bigint ,memberid bigint,guildid bigint);
CREATE TABLE snipelog
(timedeletion timestamp without time zone ,embeds text ,content text ,username text ,channelid bigint PRIMARY KEY);
CREATE TABLE logchannels
(channelid bigint ,guildid bigint PRIMARY KEY);
CREATE TABLE customcommands
(commandoutput text ,commandname text ,guildid bigint );
CREATE TABLE polls
(messageid bigint PRIMARY KEY);
CREATE TABLE verifychannels
(channelid bigint,guildid bigint PRIMARY KEY);
CREATE TABLE levelconfig
(messagecount bigint ,channelid bigint);
CREATE TABLE antiraid
(channelid bigint ,guildid bigint);
CREATE TABLE prefixes
(prefix text ,guildid bigint PRIMARY KEY);
CREATE TABLE ticketchannels
(emoji text ,roleid bigint ,messageid bigint ,channelid bigint );
CREATE TABLE profanechannels
(channelid bigint PRIMARY KEY);
CREATE TABLE linkchannels
(channelid bigint PRIMARY KEY);
CREATE TABLE automod_channel_settings
(channel_id bigint PRIMARY KEY, guild_id bigint, spam_messages smallint,
spam_window_seconds smallint, timeout_seconds integer,
profanity_threshold real, updated_at timestamptz);
CREATE TABLE levelsettings
(setting boolean ,channelid bigint PRIMARY KEY);
CREATE TABLE verifymsg
(messageid bigint ,channelid bigint ,guildid bigint PRIMARY KEY);
CREATE TABLE leaderboard
(mention text PRIMARY KEY, wins bigint NOT NULL DEFAULT 0);
CREATE TABLE cautionraid
(guildid bigint PRIMARY KEY);
CREATE TABLE warnings
(messageid bigint ,warning text ,guildid bigint ,userid bigint );
CREATE TABLE commandguildstatus
(commandname text ,guildid bigint);
CREATE TABLE mceconomy
(memberid bigint PRIMARY KEY,balance bigint,inventory text);
CREATE TABLE restrictedUsers
(guildid bigint, memberid bigint, epochtime bigint);
The bot_runtime_stats and bot_command_usage tables are created and migrated
automatically at startup. Statistics are collected in memory and flushed in
batches every five seconds for low command latency. If the database account
cannot create those tables, /stats continues with session-only counters and
reports that persistence is unavailable.
The website creates and migrates its Riot identity and feedback tables. The bot retrieves recent matches on demand from official Riot endpoints with bounded parallelism, short-lived caching, current VAL-CONTENT names, and rate-limit handling. Analytics include match score, K/D/A, ACS, ADR, dealt-minus-received damage per round, headshot-hit percentage, opening duels, survival, multikill rounds, objectives, utility casts, round economy, opponent duels, and spatial kill/death events. They use completed-match fields only and do not estimate hidden MMR, KAST, or live tactical advice. Visual metadata and artwork come from the community-run valorant-api.com service; all VALORANT game assets remain Riot Games property. The old fixed-shard pollers, pickled match objects, static metadata extractors, and third-party MMR endpoint are not used.
After doing this, run the bot with:
.venv\Scripts\python.exe main.py