A powerful Discord bot.
Gemini for README.md, Claude for debugging and GitHub Copilot for code completion
A powerful Discord bot.
Gemini for README.md, Claude for debugging and GitHub Copilot for code completion
Integrated a complete music playback system with 12 commands, admin message control via say, and context menu interactions, all wired into the help system and interaction handler.
Built a voice-based music player using MusicManager and MusicPlayer classes with the @discordjs/voice library. Added 12 commands: play, stop, skip, pause, resume, queue, volume, loop, shuffle, np, leave, and clear. Interactive music buttons (MUSIC_PAUSE_RESUME, MUSIC_SKIP, MUSIC_LOOP, MUSIC_SHUFFLE, MUSIC_STOP) are validated with voice channel checks and return ephemeral errors if conditions arenât met. The system handles guild-specific players, audio streaming, queue synchronization, and now-playing embeds with dynamic controls.
The say command lets admins send/edit/reply to messages in any channel with optional @everyone pings. Parameters include message content, target channel, message ID for edits or replies, edit/ping flags, and ephemeral responses with user feedback. Enforces ManageMessages permission with proper error handling.
Context menus (right-click user/message interactions) use ApplicationCommandType.User and inherit the same cooldown/permission validation. Implemented the avatar context that displays user avatars with links to 6 resolution sizes (x64âx2048). The context.js handler defers replies, checks permissions, applies cooldowns, and catches errors with logging.
All three systems integrate into the main bot: MUSIC category added to help browsing and category order, say listed under ADMIN commands, and contexts registered with dedicated interaction handling.
Log in to leave a comment
Added the OWNER command set to Cyborg: eval, leaveserver, and listservers (with findserver/findservers aliases). These are prefix-first administrative commands for bot owners: runtime code evaluation, leaving a guild by ID, and listing/searching joined guilds with pagination.
Integrated owner-only access through the existing command handler owner gate (config.OWNER_IDS) and aligned the commands to project conventions (message.reply flow, config-based embed color, and stable guild-leave reply sequence). Finalized runtime fixes for initial integration errors so owner commands execute cleanly with command loading and interaction registration intact.
Log in to leave a comment
Implemented the Automod system in Cyborg with a full command and runtime setup. Added three commands under the AUTOMOD category: automod (main configuration), anti (anti-spam/ghostping/caps/repeat/massmention controls), and autodelete (attachments/invites/links/max-lines filtering).
Ported and adapted Automod storage to the botâs unified JSON database by adding a new automod namespace in data.json. Added a dedicated automod database helper to manage per-guild settings and strike counts.
Integrated live moderation checks through a new automod handler and message event wiring. Message create now tracks potential ghost pings and runs automod checks for non-command messages. Message delete now processes ghost ping detection when enabled.
Detection and moderation flow now supports:
TIMEOUT/KICK/BAN)Updated category/config/help integration by adding AUTOMOD category metadata, config category toggle support, and help menu ordering for the new category.
Verified command loading and diagnostics after integration, with automod, anti, and autodelete all registering successfully
Log in to leave a comment
Implemented a new weather utility command for fetching current weather and short forecast by location. Supports both prefix (!weather <location>) and slash (/weather location:<location>) formats with aliases forecast and temp.
Integrated PopCat weather API (/v2/weather?q=...) and mapped the response shape using the message array. When multiple matching locations are returned, the command uses the first result and displays weather details in an embed.
The embed includes current temperature, feels-like, sky condition, humidity, wind, and a 3-day forecast summary (high/low/precipitation). If available, weather icon image is shown as a thumbnail.
Added graceful handling for empty/no-match responses and API failures with clear error replies. Cooldown is set to 3 seconds.
Verified command loading, API response parsing, and successful registration in utility commands.
Implemented the full giveaway system in Cyborg with both prefix and slash support. Added all required subcommands: start, pause, resume, end, reroll, edit, and list.
The command supports channel-based giveaway creation with duration parsing (s/m/h/d/w), winner count, and prize text. Management actions work through giveaway message ID, and active giveaways can be listed with channel and message reference.
Integrated discord-giveaways with a custom manager backed by the botâs unified JSON storage. Added a new giveaways namespace in data.json, plus a dedicated database helper for load/save/edit/delete operations.
Wired the system into startup flow by initializing giveawaysManager in the client and running manager init on ready. Added giveaway config options (ENABLED, REACTION, start/end embed colors), category metadata (GIVEAWAY), and help menu ordering support for the new category.
Verified command loading and slash registration with no diagnostics errors after integration.
Log in to leave a comment
Implemented new encode and decode utility commands for binary conversion. Both support prefix and slash usage:
!encode <text> and /encode text:<text>
!decode <binary> and /decode binary:<binary>
Integrated PopCat API endpoints for conversion:
/v2/encode?text=...
/v2/decode?binary=...
Both commands parse the API response from message.text, return embed-based results, and include clear failure messages for bad input or API issues. Added truncation safeguards to keep output within Discord embed limits and set cooldown to 3 seconds.
Verified command loading and successful registration for both commands.
Log in to leave a comment
Implemented a new urban utility command for searching Urban Dictionary terms. Supports both prefix (!urban <term>) and slash (/urban term:<term>) formats with aliases ud and urbandictionary.
The command fetches definitions from Urban Dictionary API (/v0/define), selects the best-rated result using net votes (thumbs_up - thumbs_down), and displays it in an embed. Output includes definition, example, vote counts, author, and source link.
Added cleanup for bracketed Urban text (for cleaner Discord output), truncation safeguards to stay within Discord embed limits, and friendly error handling for no results or API failures. Cooldown is set to 3 seconds.
Verified command loading and command registration with utility command totals updated.
Log in to leave a comment
Implemented a new translate utility command for translating text between languages. Supports both prefix (!translate <text> [language]) and slash (/translate text:<text> to:<language>) formats with alias trans.
Switched translation requests to PopCat API (/v2/translate) and updated response parsing to use message.translated. Also fixed embed creation by using EmbedUtils.embed() so translation replies render correctly.
The command supports language code input, keeps a 3-second cooldown, and returns an embed with original and translated text plus language labels. Verified command loading and successful translation response handling.
Log in to leave a comment
Added a bigemoji utility command that enlarges custom Discord and Unicode emojis. Supports both prefix (!bigemoji <emoji>) and slash formats with aliases jumbo and emoji. Custom emojis are extracted via CDN, Unicode emojis fall back to Twemoji CDN.
Returns an embed with the enlarged image, emoji type, animation status, and direct link. Has 3s cooldown. Brings total bot commands to 70.
Log in to leave a comment
Added a full AFK system with both prefix and slash support through the new afk command. Users can set AFK with an optional reason, and that reason is stored with a timestamp. When an AFK user sends a new message, their AFK status is automatically removed and they get a welcome-back confirmation. If someone mentions users who are currently AFK, the bot replies with their AFK reason and how long ago they went AFK.
Also merged local data storage into one shared file so the bot now reads and writes from a single database file instead of separate JSON files. Warnings data and AFK data are both namespaced in the same structure, which keeps file management cleaner and makes future systems easier to add. Existing warning data was preserved during the merge.
Updated database helpers to use the shared file and removed the old split JSON files. Verified that AFK set/remove works, AFK mention detection works, warning lookups still work, and command loading still succeeds with all commands registered.
Log in to leave a comment
Rebuilt the help command from a plain embed into an interactive menu. It now shows a main page with all categories and their command counts, a StringSelectMenu dropdown to browse any category, a Home button to jump back, and a Close button to dismiss. Selecting a category shows every command in it with its description, split into chunks of 10 if needed. The collector runs for 60 seconds of idle time then auto-removes the components. Added !h and !commands as aliases. The command detail view now also shows required permissions and bot permissions alongside the existing fields.
Split the old FUN category into three FUN (7 text-based commands), IMAGE (28 filter/generator/overlay commands), and ANIME (10 reaction GIF commands). Updated CommandCategory.js with description and image fields for all categories. Batch-updated all 38 command files to use their new category.
Expanded config.js with four new sections: EMBED (default color/footer), PRESENCE (configurable activities, interval, status supports {commands} placeholder), COOLDOWN (default seconds and owner bypass toggle), and CATEGORIES (enable/disable entire categories). The command handler now checks COOLDOWN.OWNER_BYPASS to skip cooldowns for owners. clientReady.js reads presence config instead of hardcoded activities. BotClient.loadCommand() checks both CommandCategory and config.CATEGORIES for disabled categories. Validator now warns about missing prefix, test guild ID, and empty presence activities.
Log in to leave a comment
Added 28 standalone image commands /blur, !invert, /wasted, !jail, etc. Each accepts an optional @user or image URL, defaulting to the callerâs avatar. All work with both slash and prefix.
Filters (11): blur, brighten, burn, darken, distort, greyscale, invert, pixelate, sepia, sharpen, threshold powered by some-random-api. Generators (10): ad, beautiful, jokeoverhead, wanted (Popcat API), plus circle, heart, lolice, its-so-stupid, horny, simpcard (some-random-api misc). Overlays (7): wasted, jail, gay, passed, triggered, comrade, glass some-random-api overlays. Several original Popcat endpoints (bobross, facepalm, delete, approved, thuglife) were dead so the set was rebuilt around working APIs.
Had an issue where Discord avatar URLs include ?size=256 which got double-encoded as %3Fsize%3D256 breaking the API calls. Fixed by stripping query params with .split("?")[0] before encoding.
Log in to leave a comment
Added ten individual anime reaction commands, hug, kiss, slap, pat, cuddle, poke, tickle, feed, smug, and wink. Each one is its own standalone command instead of a single /react with subcommands, so you use them directly like /hug @user, !kiss @user, /slap @user, etc. Eight of them (hug, kiss, slap, pat, cuddle, poke, tickle, feed) are targeted reactions that require a @user argument and display a message like âđ¤ user hugged targetâ with a random anime GIF. The other two (smug and wink) are self-targeted, no argument needed, they just show something like âđ user is smugâ or âđ user winksâ.
Created a shared helper at src/helpers/reactions.js that holds a REACTIONS map with emoji, verb, and API endpoint info for all ten types, plus a getReactionGif() function that fetches random GIFs. Nine of the ten types use the nekos.life API (nekos.life/api/v2/img/{type}) which works without any npm package, just a direct fetch. Wink is the exception since nekos.life doesnât have a wink endpoint, so it pulls from some-random-api (some-random-api.com/animu/wink) instead. All ten command files import from this shared helper so thereâs zero duplicated fetch logic.
Log in to leave a comment
Added the pickupline command (/pickupline and !pickupline) which fetches a random pickup line from the Popcat API. Displays the line in an embed with a đ emoji. No arguments needed, just run it and get a random line. 5-second cooldown and 10-second API timeout.
Log in to leave a comment
Added the facts command (/facts and !facts) which fetches random animal facts from the some-random-api.com service. Supports the same 9 animal types as the animal command, cat, dog, panda, fox, red panda, koala, bird, raccoon, and kangaroo. Displays the fact as the main embed description with a small animal thumbnail image. Slash command has a dropdown for animal selection. 5-second cooldown and 10-second API timeout.
Log in to leave a comment
Added the animal command (/animal and !animal) which fetches random animal pictures with fun facts from the some-random-api.com service. Supports 9 animal types: cat, dog, panda, fox, red panda, koala, bird, raccoon, and kangaroo. The slash command provides a dropdown with all choices for easy selection. Each response shows the animal image as an embed with a fun fact pulled from the same API response. Has a 5-second cooldown and 10-second API timeout.
Log in to leave a comment
Added the hack command (/hack and !hack) which runs a fake hacking simulation against a mentioned user. Plays an 11-stage animated sequence with 2-second delays between each step, starting with gaining server access, bypassing firewalls, extracting emails and passwords, scanning social media accounts, and locating hidden files. The final reveal is a rickroll with the âNever Gonna Give You Upâ lyrics and a GIF, sent via DM to the command user. If DMs are closed it falls back to posting the results in the channel. Blocks targeting bots and has a 10-second cooldown.
Log in to leave a comment
Added the wyr command (/wyr and !wyr) which fetches random âWould You Ratherâ questions from the Popcat API. Displays two options in an embed and adds 1ď¸âŁ and 2ď¸âŁ reactions for voting. After 30 seconds the voting closes and the embed updates to show results with vote counts, percentages, and total votes. Reads the actual reaction counts from the message cache at the end instead of manually tracking increments. Had to add the GuildMessageReactions gateway intent to BotClient.js since without it Discord doesnât send reaction events and the collector receives nothing. Command has a 5-second cooldown and a 10-second API timeout.
Log in to leave a comment
Added the meme command (/meme and !meme) which fetches random memes from Reddit via the meme-api.com service. Supports an optional category parameter to pull from a specific subreddit. Each meme embed displays the post title, image, upvote count, and subreddit name with a random color. Includes a đ regenerate button that lets the user fetch up to 3 new memes within a 20-second window, after which the button auto-disables. NSFW posts are automatically skipped and re-fetched. Originally tried hitting the Reddit API directly but it returns 403, so switched to meme-api.com as a reliable proxy. Also fixed an âUnknown interactionâ error caused by button interactions not being properly caught, added .catch() to all deferUpdate and edit calls in the button collector.
Log in to leave a comment
Added the flip command (/flip and !flip) with two subcommands: coin and text. The coin flip uses crypto.randomInt(2) for cryptographically secure 50/50 randomness instead of Math.random(). It plays a three-stage animation, first showing âflipped a coinâŚâ, then âthe coin is in the airâŚâ after 2 seconds, and finally revealing the result with a heads or tails image after another 2 seconds. The text subcommand takes any input string and flips it upside down using a character mapping table that converts each letter and symbol to its Unicode inverted equivalent. Both subcommands work as prefix and slash commands.
Log in to leave a comment
Added a webhook logging system (WebhookLogger.js) that sends embeds to Discord webhooks configured in .env, ERROR_LOG_WEBHOOK for errors and GUILD_LOG_WEBHOOK for server join/leave. Created guildCreate.js and guildDelete.js events, and wired WebhookLogger.logError() into Logger.error() using setImmediate so every error in the codebase goes to the webhook automatically.
Created help and botinfo commands. Help shows commands grouped by category or details for a specific command. Botinfo shows developer, version, uptime, stats, and system info. Created EmbedUtils.js with success, error, warning, and embed methods, then updated all 23 commands and handlers to use embeds instead of plain text. Added a startup banner, rotating activity status, and a polished bot mention response.
Stray requires got injected into guildCreate.js, guildDelete.js, and EmbedUtils.js again, the EmbedUtils.js one pulled in handlers/command.js which created a circular dependency since command.js already imports EmbedUtils. That caused the âAccessing non-existent property âerrorâ inside circular dependencyâ warning. Also hit a Logger -> WebhookLogger -> Logger circular loop, fixed by using console.error directly in WebhookLogger. Banner showed 0 prefix commands because client.commands is an array (.length not .size).
Log in to leave a comment
Added the nick command with two subcommands, set and reset. Nick set (/nick set and !nick set) changes a memberâs nickname to whatever you specify. Nick reset (/nick reset and !nick reset) clears it back to their username by passing null to setNickname. Both require ManageNicknames for the bot and the user. Uses target.manageable to make sure the bot can actually modify the member, plus the usual role hierarchy check with server owner bypass. Quick and painless, no issues this time.
Log in to leave a comment
This one took way too long because of a lot of errors.
Added six voice moderation commands, vmute, vunmute, deafen, undeafen, disconnect, and move. Vmute (/vmute and !vmute) server mutes a member in a voice channel, and vunmute (/vunmute and !vunmute) removes the server mute. Deafen (/deafen and !deafen) server deafens a member, and undeafen (/undeafen and !undeafen) removes it. Disconnect (/disconnect and !disconnect) kicks a member out of their voice channel entirely. Move (/move and !move) moves a member to a different voice or stage channel. All six check target.voice.channel to confirm the user is actually in voice before doing anything.
Punitive commands (vmute, deafen, disconnect, move) enforce role hierarchy with a server owner bypass. Restorative commands (vunmute, undeafen) skip hierarchy since undoing a punishment shouldnât require outranking the target. Vmute and vunmute require MuteMembers, deafen and undeafen require DeafenMembers, and disconnect and move require MoveMembers.
The biggest issue was voice state detection in slash commands, target.voice.channel kept returning null even when the user was in a call. Turned out GuildVoiceStates and GuildMembers intents were both missing. Even after adding them, REST-fetched members donât always have a populated voice state since voice data comes from the gateway cache, not the API. The fix was using guild.members.cache.get(user.id) first (which has live gateway voice state) and only falling back to guild.members.fetch(user.id) if the member isnât cached. On top of all that, stray CyborgBot require() statements kept getting injected into the files by an external tool, breaking the module loader repeatedly.
Log in to leave a comment
This one took me way too long to make.
Added five purge commands for message management, purge, purgeuser, purgebots, purgelinks, and purgeattachment. Purge (/purge and !purge) deletes 1-100 messages from a channel using bulkDelete. Purgeuser (/purgeuser and !purgeuser) scans up to 100 messages and deletes only those from a specific user. Purgebots (/purgebots and !purgebots) filters for bot-authored messages. Purgelinks (/purgelinks and !purgelinks) targets messages matching a URL regex. Purgeattachment (/purgeattachment and !purgeattachment) removes messages that have file attachments. All five require ManageMessages and ReadMessageHistory permissions.
Each command has a shared helper function for the core logic, used by both prefix and slash. Prefix replies auto-delete after 3 seconds to keep the channel clean. Slash commands use ephemeral: true so the deferred reply is invisible to the channel and canât be accidentally deleted by bulkDelete, a fix inspired by CyborgBotâs approach after the original implementation kept crashing with DiscordAPIError[10008]: Unknown Message.
Log in to leave a comment
Added warn and warnings commands backed by a JSON file store (src/database/warnings.js). Warn (/warn and !warn) issues a warning to a member, stores it with the reason, issuer, and timestamp, DMs the user (silently fails if DMs are closed), and replies with their total warning count. Warnings (/warnings and !warnings) lists all warnings for a user with numbered entries showing reason, issuer, and date, pass clear (prefix) or clear: true (slash) to wipe all warnings. Both require ModerateMembers permission with role hierarchy enforcement and owner bypass.
Log in to leave a comment
Added timeout and untimeout commands. Timeout (/timeout and !timeout) mutes a member for a chosen duration using Discordâs native timeout feature, with preset options from 1 minute to 28 days. Slash uses a choices dropdown, prefix takes a duration string (e.g. 1h, 7d). Untimeout (/untimeout and !untimeout) removes an active timeout by passing null to the timeout method, and checks if the member is actually timed out first. Both require ModerateMembers permission and include the standard role hierarchy check with server owner bypass.
Log in to leave a comment
Added the softban command (/softban and !softban). It bans a member then immediately unbans them, effectively purging their messages without a permanent ban. Defaults to deleting 7 days of messages. Same safety checks as ban, bannable guard, role hierarchy enforcement, and server owner bypass.
Log in to leave a comment
Added the ban command (/ban and !ban). It permanently bans a member from the server with an optional days parameter (0-7) to delete their recent messages. Same safety checks as kick â bannable guard, role hierarchy enforcement, and server owner bypass. For prefix usage, if the second argument is a number 0-7 itâs treated as the days value, otherwise itâs part of the reason. Also added the unban command (/unban and !unban), which takes a user ID since banned users canât be mentioned, verifies the user is actually banned before attempting to unban, and records the reason with issuer attribution in the audit log.
Log in to leave a comment
Added the kick command (/kick and !kick) as the first moderation command for Cyborg. It supports both slash and prefix usage, requires KickMembers permission for both the bot and the user, and includes a role hierarchy check that prevents moderators from kicking members with equal or higher roles, server owners bypass this check entirely.
Log in to leave a comment
A custom BotClient class that extends the Discord.js Client powers the auto-loading commands, events, handlers, helpers, and structures that make up the botâs base, which was built with a clear modular architecture. Config-driven toggles with settings in config.js and credentials in.env for prefix commands, slash commands, and context menus. aliases to module paths for clean imports. The first command to measure actual round-trip latency was added: /ping. Slash commands use the clientReady event to automatically register at startup.
Log in to leave a comment