Documentation
C0D loads module files from bot/modules/. Each
.cod file lists commands, optional slash options, and
either a reply string or an action chain.
Install & run
You need Node.js 18+ and a Discord application (bot token + client
ID). The bot code lives in the bot/ folder.
1. Get the project
Clone the repo or copy the bot/ directory to your
machine.
2. Install dependencies
cd bot
npm install
3. Configure environment
Copy .env.example to .env and fill in
values from the
Discord Developer Portal.
DISCORD_TOKEN=your_bot_token
DISCORD_CLIENT_ID=your_application_id
# Optional for instant guild command updates while developing:
# DISCORD_GUILD_ID=your_server_id
Under Bot → Privileged Gateway Intents, enable Server Members Intent for moderation features. Enable Message Content Intent only if you add code that reads message text.
4. Start the bot
npm start
.cod file format
A minimal module with a plain text reply (no action chain) looks like this:
{
"meta": { "name": "ping", "version": "1.0.0" },
"commands": [
{
"name": "ping",
"description": "Health check",
"response": "Pong!",
"ephemeral": false
}
]
}
Simple replies
If a command has response and no actions
array (or an empty one), the bot sends that text once. Use
ephemeral: true for replies only visible to the user who
ran the command.
Action chains
If actions is a non-empty array, the bot
defers the reply, runs each action in order, then
sends one combined message (truncated to Discord limits). Mix
moderation and channel actions with reply steps as
needed.
"actions": [
{ "type": "purge_messages", "count_option": "amount" },
{ "type": "reply", "text": "Cleanup finished." }
]
Action types
reply-text(orcontent)-
purge_messages-countfixed number, orcount_optionfor a slash integer option name -
create_channel-nameorname_option; optionalname_templatewith{user},{userid},{random};ticket_style: truehides the channel from @everyone and grants access to the user who invoked the action -
delete_channel-channel_option(slash channel option name) -
ban_member-user_option,delete_message_days, optionalreason_option -
kick_member-user_option, optionalreason_option -
timeout_member-user_option,minutesorminutes_option -
lock_channel/unlock_channel- optionalchannel_option(defaults to current channel) -
slowmode-secondsorseconds_option, optionalchannel_option -
send_message-channel_option(slash channel) orchannel_id;contentorcontent_optionfor slash string -
send_embed- same channel targeting;embedobject (title, description, color, fields, footer); optionalcomponentsarray (see below)
Buttons, dropdowns & ticket panels
A root interactions object maps
custom_id strings to action lists. When someone
clicks a button or uses a string select menu, those actions run
(slash options are not available - use placeholders like
{select_value} in reply text).
Inside send_embed, components is an array
of rows. Each row has "type": "ACTION_ROW" and
components: buttons with
type: "BUTTON", custom_id,
label, style (PRIMARY,
SECONDARY, SUCCESS, DANGER), or
type: "STRING_SELECT" with options array
(label, value, optional
description).
Slash options
Declare options on each command with an options array.
Option type values: STRING,
INTEGER, BOOLEAN, USER,
CHANNEL, ROLE. Use
required: false for optional inputs.
Default permissions
Set default_member_permissions to one of:
Administrator, BanMembers,
KickMembers, ModerateMembers,
ManageChannels, ManageMessages - so only
members with that permission see the command in the picker.
Discord Developer Portal
Enable Server Members Intent and
Message Content Intent (if you extend the bot to
read message bodies) under Bot → Privileged Gateway Intents. The
bot uses Guilds, GuildMembers,
GuildModeration, and GuildMessages.
Invite the bot with scopes bot and
applications.commands, and grant permissions for the
actions you use (Manage Channels, Moderate Members, Ban Members,
Manage Messages, etc.).
How loading works
On startup, index.js parses every *.cod in
modules/, merges slash commands, and registers them.
Duplicate slash names are overwritten - watch the console.
Set DISCORD_GUILD_ID in .env for instant
guild command updates while developing. Omit it for global commands
(propagation can take up to an hour).